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,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 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
197 ;; This is used for add, logical, shift, exts, mul.
198 (define_attr "dot" "no,yes" (const_string "no"))
200 ;; Does this instruction sign-extend its result?
201 ;; This is used for load insns.
202 (define_attr "sign_extend" "no,yes" (const_string "no"))
204 ;; Does this instruction use indexed (that is, reg+reg) addressing?
205 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
206 ;; it is automatically set based on that. If a load or store instruction
207 ;; has fewer than two operands it needs to set this attribute manually
208 ;; or the compiler will crash.
209 (define_attr "indexed" "no,yes"
210 (if_then_else (ior (match_operand 0 "indexed_address_mem")
211 (match_operand 1 "indexed_address_mem"))
213 (const_string "no")))
215 ;; Does this instruction use update addressing?
216 ;; This is used for load and store insns. See the comments for "indexed".
217 (define_attr "update" "no,yes"
218 (if_then_else (ior (match_operand 0 "update_address_mem")
219 (match_operand 1 "update_address_mem"))
221 (const_string "no")))
223 ;; Is this instruction using operands[2] as shift amount, and can that be a
225 ;; This is used for shift insns.
226 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
228 ;; Is this instruction using a shift amount from a register?
229 ;; This is used for shift insns.
230 (define_attr "var_shift" "no,yes"
231 (if_then_else (and (eq_attr "type" "shift")
232 (eq_attr "maybe_var_shift" "yes"))
233 (if_then_else (match_operand 2 "gpc_reg_operand")
236 (const_string "no")))
238 ;; Is copying of this instruction disallowed?
239 (define_attr "cannot_copy" "no,yes" (const_string "no"))
241 ;; Define floating point instruction sub-types for use with Xfpu.md
242 (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"))
244 ;; Length (in bytes).
245 ; '(pc)' in the following doesn't include the instruction itself; it is
246 ; calculated as if the instruction had zero size.
247 (define_attr "length" ""
248 (if_then_else (eq_attr "type" "branch")
249 (if_then_else (and (ge (minus (match_dup 0) (pc))
251 (lt (minus (match_dup 0) (pc))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
260 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261 ppc750,ppc7400,ppc7450,
262 ppc403,ppc405,ppc440,ppc476,
263 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264 power4,power5,power6,power7,power8,power9,
265 rs64a,mpccore,cell,ppca2,titan"
266 (const (symbol_ref "rs6000_cpu_attr")))
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273 (eq_attr "dot" "yes"))
274 (and (eq_attr "type" "load")
275 (eq_attr "sign_extend" "yes"))
276 (and (eq_attr "type" "shift")
277 (eq_attr "var_shift" "yes")))
278 (const_string "always")
279 (const_string "not")))
281 (automata_option "ndfa")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
310 (include "predicates.md")
311 (include "constraints.md")
313 (include "darwin.md")
318 ; This mode iterator allows :GPR to be used to indicate the allowable size
319 ; of whole values in GPRs.
320 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
322 ; Any supported integer mode.
323 (define_mode_iterator INT [QI HI SI DI TI PTI])
325 ; Any supported integer mode that fits in one register.
326 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
328 ; Integer modes supported in VSX registers with ISA 3.0 instructions
329 (define_mode_iterator INT_ISA3 [QI HI SI DI])
331 ; Everything we can extend QImode to.
332 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
334 ; Everything we can extend HImode to.
335 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
337 ; Everything we can extend SImode to.
338 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
340 ; QImode or HImode for small integer moves and small atomic ops
341 (define_mode_iterator QHI [QI HI])
343 ; QImode, HImode, SImode for fused ops only for GPR loads
344 (define_mode_iterator QHSI [QI HI SI])
346 ; HImode or SImode for sign extended fusion ops
347 (define_mode_iterator HSI [HI SI])
349 ; SImode or DImode, even if DImode doesn't fit in GPRs.
350 (define_mode_iterator SDI [SI DI])
352 ; Types that can be fused with an ADDIS instruction to load or store a GPR
353 ; register that has reg+offset addressing.
354 (define_mode_iterator GPR_FUSION [QI
357 (DI "TARGET_POWERPC64")
359 (DF "TARGET_POWERPC64")])
361 ; Types that can be fused with an ADDIS instruction to load or store a FPR
362 ; register that has reg+offset addressing.
363 (define_mode_iterator FPR_FUSION [DI SF DF])
365 ; The size of a pointer. Also, the size of the value that a record-condition
366 ; (one with a '.') will compare; and the size used for arithmetic carries.
367 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
369 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
370 ; PTImode is GPR only)
371 (define_mode_iterator TI2 [TI PTI])
373 ; Any hardware-supported floating-point mode
374 (define_mode_iterator FP [
375 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
376 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
377 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
378 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
379 (KF "TARGET_FLOAT128_TYPE")
383 ; Any fma capable floating-point mode.
384 (define_mode_iterator FMA_F [
385 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
386 (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
387 || VECTOR_UNIT_VSX_P (DFmode)")
388 (V2SF "TARGET_PAIRED_FLOAT")
389 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
390 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
391 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
392 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
395 ; Floating point move iterators to combine binary and decimal moves
396 (define_mode_iterator FMOVE32 [SF SD])
397 (define_mode_iterator FMOVE64 [DF DD])
398 (define_mode_iterator FMOVE64X [DI DF DD])
399 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
400 (IF "FLOAT128_IBM_P (IFmode)")
401 (TD "TARGET_HARD_FLOAT")])
403 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
404 (IF "FLOAT128_2REG_P (IFmode)")
405 (TD "TARGET_HARD_FLOAT")])
407 ; Iterators for 128 bit types for direct move
408 (define_mode_iterator FMOVE128_GPR [TI
416 (KF "FLOAT128_VECTOR_P (KFmode)")
417 (TF "FLOAT128_VECTOR_P (TFmode)")])
419 ; Iterator for 128-bit VSX types for pack/unpack
420 (define_mode_iterator FMOVE128_VSX [V1TI KF])
422 ; Whether a floating point move is ok, don't allow SD without hardware FP
423 (define_mode_attr fmove_ok [(SF "")
425 (SD "TARGET_HARD_FLOAT")
428 ; Convert REAL_VALUE to the appropriate bits
429 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
430 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
431 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
432 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
434 ; Whether 0.0 has an all-zero bit pattern
435 (define_mode_attr zero_fp [(SF "j")
444 ; Definitions for 64-bit VSX
445 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
447 ; Definitions for 64-bit direct move
448 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
450 ; Definitions for 64-bit use of altivec registers
451 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
453 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
454 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
456 ; These modes do not fit in integer registers in 32-bit mode.
457 (define_mode_iterator DIFD [DI DF DD])
459 ; Iterator for reciprocal estimate instructions
460 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
462 ; Iterator for just SF/DF
463 (define_mode_iterator SFDF [SF DF])
465 ; Like SFDF, but a different name to match conditional move where the
466 ; comparison operands may be a different mode than the input operands.
467 (define_mode_iterator SFDF2 [SF DF])
469 ; Iterator for 128-bit floating point that uses the IBM double-double format
470 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
471 (TF "FLOAT128_IBM_P (TFmode)")])
473 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
474 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
475 (TF "FLOAT128_IEEE_P (TFmode)")])
477 ; Iterator for 128-bit floating point
478 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
479 (IF "TARGET_FLOAT128_TYPE")
480 (TF "TARGET_LONG_DOUBLE_128")])
482 ; Iterator for signbit on 64-bit machines with direct move
483 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
484 (TF "FLOAT128_VECTOR_P (TFmode)")])
486 ; Iterator for ISA 3.0 supported floating point types
487 (define_mode_iterator FP_ISA3 [SF DF])
489 ; SF/DF suffix for traditional floating instructions
490 (define_mode_attr Ftrad [(SF "s") (DF "")])
492 ; SF/DF suffix for VSX instructions
493 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
495 ; SF/DF constraint for arithmetic on traditional floating point registers
496 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
498 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
499 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
500 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
502 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
504 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
505 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
506 ; instructions added in ISA 2.07 (power8)
507 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
509 ; SF/DF constraint for arithmetic on altivec registers
510 (define_mode_attr Fa [(SF "wu") (DF "wv")])
512 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
513 (define_mode_attr Fs [(SF "s") (DF "d")])
516 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
517 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
519 ; Conditional returns.
520 (define_code_iterator any_return [return simple_return])
521 (define_code_attr return_pred [(return "direct_return ()")
522 (simple_return "1")])
523 (define_code_attr return_str [(return "") (simple_return "simple_")])
526 (define_code_iterator iorxor [ior xor])
527 (define_code_iterator and_ior_xor [and ior xor])
529 ; Signed/unsigned variants of ops.
530 (define_code_iterator any_extend [sign_extend zero_extend])
531 (define_code_iterator any_fix [fix unsigned_fix])
532 (define_code_iterator any_float [float unsigned_float])
534 (define_code_attr u [(sign_extend "")
539 (define_code_attr su [(sign_extend "s")
544 (unsigned_float "u")])
546 (define_code_attr az [(sign_extend "a")
551 (unsigned_float "z")])
553 (define_code_attr uns [(fix "")
556 (unsigned_float "uns")])
558 ; Various instructions that come in SI and DI forms.
559 ; A generic w/d attribute, for things like cmpw/cmpd.
560 (define_mode_attr wd [(QI "b")
571 ;; How many bits in this mode?
572 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
575 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
577 ;; ISEL/ISEL64 target selection
578 (define_mode_attr sel [(SI "") (DI "64")])
580 ;; Bitmask for shift instructions
581 (define_mode_attr hH [(SI "h") (DI "H")])
583 ;; A mode twice the size of the given mode
584 (define_mode_attr dmode [(SI "di") (DI "ti")])
585 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
587 ;; Suffix for reload patterns
588 (define_mode_attr ptrsize [(SI "32bit")
591 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
592 (DI "TARGET_64BIT")])
594 (define_mode_attr mptrsize [(SI "si")
597 (define_mode_attr ptrload [(SI "lwz")
600 (define_mode_attr ptrm [(SI "m")
603 (define_mode_attr rreg [(SF "f")
610 (define_mode_attr rreg2 [(SF "f")
613 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
614 (DF "TARGET_FCFID")])
616 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
617 (DF "TARGET_DOUBLE_FLOAT")])
619 ;; Mode iterator for logical operations on 128-bit types
620 (define_mode_iterator BOOL_128 [TI
622 (V16QI "TARGET_ALTIVEC")
623 (V8HI "TARGET_ALTIVEC")
624 (V4SI "TARGET_ALTIVEC")
625 (V4SF "TARGET_ALTIVEC")
626 (V2DI "TARGET_ALTIVEC")
627 (V2DF "TARGET_ALTIVEC")
628 (V1TI "TARGET_ALTIVEC")])
630 ;; For the GPRs we use 3 constraints for register outputs, two that are the
631 ;; same as the output register, and a third where the output register is an
632 ;; early clobber, so we don't have to deal with register overlaps. For the
633 ;; vector types, we prefer to use the vector registers. For TI mode, allow
636 ;; Mode attribute for boolean operation register constraints for output
637 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
639 (V16QI "wa,v,&?r,?r,?r")
640 (V8HI "wa,v,&?r,?r,?r")
641 (V4SI "wa,v,&?r,?r,?r")
642 (V4SF "wa,v,&?r,?r,?r")
643 (V2DI "wa,v,&?r,?r,?r")
644 (V2DF "wa,v,&?r,?r,?r")
645 (V1TI "wa,v,&?r,?r,?r")])
647 ;; Mode attribute for boolean operation register constraints for operand1
648 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
656 (V1TI "wa,v,r,0,r")])
658 ;; Mode attribute for boolean operation register constraints for operand2
659 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
667 (V1TI "wa,v,r,r,0")])
669 ;; Mode attribute for boolean operation register constraints for operand1
670 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
671 ;; is used for operand1 or operand2
672 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
680 (V1TI "wa,v,r,0,0")])
682 ;; Reload iterator for creating the function to allocate a base register to
683 ;; supplement addressing modes.
684 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
685 SF SD SI DF DD DI TI PTI KF IF TF])
687 ;; Iterate over smin, smax
688 (define_code_iterator fp_minmax [smin smax])
690 (define_code_attr minmax [(smin "min")
693 (define_code_attr SMINMAX [(smin "SMIN")
696 ;; Iterator to optimize the following cases:
697 ;; D-form load to FPR register & move to Altivec register
698 ;; Move Altivec register to FPR register and store
699 (define_mode_iterator ALTIVEC_DFORM [DF
700 (SF "TARGET_P8_VECTOR")
701 (DI "TARGET_POWERPC64")])
704 ;; Start with fixed-point load and store insns. Here we put only the more
705 ;; complex forms. Basic data transfer is done later.
707 (define_insn "zero_extendqi<mode>2"
708 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
709 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
716 [(set_attr "type" "load,shift,fpload,vecperm")])
718 (define_insn_and_split "*zero_extendqi<mode>2_dot"
719 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
720 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
722 (clobber (match_scratch:EXTQI 0 "=r,r"))]
727 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
729 (zero_extend:EXTQI (match_dup 1)))
731 (compare:CC (match_dup 0)
734 [(set_attr "type" "logical")
735 (set_attr "dot" "yes")
736 (set_attr "length" "4,8")])
738 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
739 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
740 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
742 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
743 (zero_extend:EXTQI (match_dup 1)))]
748 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
750 (zero_extend:EXTQI (match_dup 1)))
752 (compare:CC (match_dup 0)
755 [(set_attr "type" "logical")
756 (set_attr "dot" "yes")
757 (set_attr "length" "4,8")])
760 (define_insn "zero_extendhi<mode>2"
761 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
762 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
766 rlwinm %0,%1,0,0xffff
769 [(set_attr "type" "load,shift,fpload,vecperm")])
771 (define_insn_and_split "*zero_extendhi<mode>2_dot"
772 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
773 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
775 (clobber (match_scratch:EXTHI 0 "=r,r"))]
780 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
782 (zero_extend:EXTHI (match_dup 1)))
784 (compare:CC (match_dup 0)
787 [(set_attr "type" "logical")
788 (set_attr "dot" "yes")
789 (set_attr "length" "4,8")])
791 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
792 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
793 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
795 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
796 (zero_extend:EXTHI (match_dup 1)))]
801 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
803 (zero_extend:EXTHI (match_dup 1)))
805 (compare:CC (match_dup 0)
808 [(set_attr "type" "logical")
809 (set_attr "dot" "yes")
810 (set_attr "length" "4,8")])
813 (define_insn "zero_extendsi<mode>2"
814 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
815 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
824 xxextractuw %x0,%x1,4"
825 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
827 (define_insn_and_split "*zero_extendsi<mode>2_dot"
828 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
829 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
831 (clobber (match_scratch:EXTSI 0 "=r,r"))]
836 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
838 (zero_extend:DI (match_dup 1)))
840 (compare:CC (match_dup 0)
843 [(set_attr "type" "shift")
844 (set_attr "dot" "yes")
845 (set_attr "length" "4,8")])
847 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
848 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
849 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
851 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
852 (zero_extend:EXTSI (match_dup 1)))]
857 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
859 (zero_extend:EXTSI (match_dup 1)))
861 (compare:CC (match_dup 0)
864 [(set_attr "type" "shift")
865 (set_attr "dot" "yes")
866 (set_attr "length" "4,8")])
869 (define_insn "extendqi<mode>2"
870 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
871 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
876 [(set_attr "type" "exts,vecperm")])
878 (define_insn_and_split "*extendqi<mode>2_dot"
879 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
880 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
882 (clobber (match_scratch:EXTQI 0 "=r,r"))]
887 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
889 (sign_extend:EXTQI (match_dup 1)))
891 (compare:CC (match_dup 0)
894 [(set_attr "type" "exts")
895 (set_attr "dot" "yes")
896 (set_attr "length" "4,8")])
898 (define_insn_and_split "*extendqi<mode>2_dot2"
899 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
900 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
902 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
903 (sign_extend:EXTQI (match_dup 1)))]
908 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
910 (sign_extend:EXTQI (match_dup 1)))
912 (compare:CC (match_dup 0)
915 [(set_attr "type" "exts")
916 (set_attr "dot" "yes")
917 (set_attr "length" "4,8")])
920 (define_expand "extendhi<mode>2"
921 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
922 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
926 (define_insn "*extendhi<mode>2"
927 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
928 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
935 [(set_attr "type" "load,exts,fpload,vecperm")
936 (set_attr "sign_extend" "yes")
937 (set_attr "length" "4,4,8,4")])
940 [(set (match_operand:EXTHI 0 "altivec_register_operand")
942 (match_operand:HI 1 "indexed_or_indirect_operand")))]
943 "TARGET_P9_VECTOR && reload_completed"
947 (sign_extend:EXTHI (match_dup 2)))]
949 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
952 (define_insn_and_split "*extendhi<mode>2_dot"
953 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
954 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
956 (clobber (match_scratch:EXTHI 0 "=r,r"))]
961 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
963 (sign_extend:EXTHI (match_dup 1)))
965 (compare:CC (match_dup 0)
968 [(set_attr "type" "exts")
969 (set_attr "dot" "yes")
970 (set_attr "length" "4,8")])
972 (define_insn_and_split "*extendhi<mode>2_dot2"
973 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
974 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
976 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
977 (sign_extend:EXTHI (match_dup 1)))]
982 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
984 (sign_extend:EXTHI (match_dup 1)))
986 (compare:CC (match_dup 0)
989 [(set_attr "type" "exts")
990 (set_attr "dot" "yes")
991 (set_attr "length" "4,8")])
994 (define_insn "extendsi<mode>2"
995 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
996 "=r, r, wl, wu, wj, wK, wH, wr")
998 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
999 "Y, r, Z, Z, r, wK, wH, ?wIwH")))]
1010 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1011 (set_attr "sign_extend" "yes")
1012 (set_attr "length" "4,4,4,4,4,4,8,8")])
1015 [(set (match_operand:EXTSI 0 "int_reg_operand")
1016 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1017 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1021 (sign_extend:DI (match_dup 2)))]
1023 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1027 [(set (match_operand:DI 0 "altivec_register_operand")
1028 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1029 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1032 rtx dest = operands[0];
1033 rtx src = operands[1];
1034 int dest_regno = REGNO (dest);
1035 int src_regno = REGNO (src);
1036 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1037 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1039 if (VECTOR_ELT_ORDER_BIG)
1041 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1042 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1046 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1047 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1052 (define_insn_and_split "*extendsi<mode>2_dot"
1053 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1054 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1056 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1061 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1063 (sign_extend:EXTSI (match_dup 1)))
1065 (compare:CC (match_dup 0)
1068 [(set_attr "type" "exts")
1069 (set_attr "dot" "yes")
1070 (set_attr "length" "4,8")])
1072 (define_insn_and_split "*extendsi<mode>2_dot2"
1073 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1074 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1076 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1077 (sign_extend:EXTSI (match_dup 1)))]
1082 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1084 (sign_extend:EXTSI (match_dup 1)))
1086 (compare:CC (match_dup 0)
1089 [(set_attr "type" "exts")
1090 (set_attr "dot" "yes")
1091 (set_attr "length" "4,8")])
1093 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1095 (define_insn "*macchwc"
1096 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1097 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1098 (match_operand:SI 2 "gpc_reg_operand" "r")
1101 (match_operand:HI 1 "gpc_reg_operand" "r")))
1102 (match_operand:SI 4 "gpc_reg_operand" "0"))
1104 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1105 (plus:SI (mult:SI (ashiftrt:SI
1113 [(set_attr "type" "halfmul")])
1115 (define_insn "*macchw"
1116 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1117 (plus:SI (mult:SI (ashiftrt:SI
1118 (match_operand:SI 2 "gpc_reg_operand" "r")
1121 (match_operand:HI 1 "gpc_reg_operand" "r")))
1122 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1125 [(set_attr "type" "halfmul")])
1127 (define_insn "*macchwuc"
1128 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1129 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1130 (match_operand:SI 2 "gpc_reg_operand" "r")
1133 (match_operand:HI 1 "gpc_reg_operand" "r")))
1134 (match_operand:SI 4 "gpc_reg_operand" "0"))
1136 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1137 (plus:SI (mult:SI (lshiftrt:SI
1145 [(set_attr "type" "halfmul")])
1147 (define_insn "*macchwu"
1148 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1149 (plus:SI (mult:SI (lshiftrt:SI
1150 (match_operand:SI 2 "gpc_reg_operand" "r")
1153 (match_operand:HI 1 "gpc_reg_operand" "r")))
1154 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1157 [(set_attr "type" "halfmul")])
1159 (define_insn "*machhwc"
1160 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1161 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1162 (match_operand:SI 1 "gpc_reg_operand" "%r")
1165 (match_operand:SI 2 "gpc_reg_operand" "r")
1167 (match_operand:SI 4 "gpc_reg_operand" "0"))
1169 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1170 (plus:SI (mult:SI (ashiftrt:SI
1179 [(set_attr "type" "halfmul")])
1181 (define_insn "*machhw"
1182 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1183 (plus:SI (mult:SI (ashiftrt:SI
1184 (match_operand:SI 1 "gpc_reg_operand" "%r")
1187 (match_operand:SI 2 "gpc_reg_operand" "r")
1189 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1192 [(set_attr "type" "halfmul")])
1194 (define_insn "*machhwuc"
1195 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1196 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1197 (match_operand:SI 1 "gpc_reg_operand" "%r")
1200 (match_operand:SI 2 "gpc_reg_operand" "r")
1202 (match_operand:SI 4 "gpc_reg_operand" "0"))
1204 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1205 (plus:SI (mult:SI (lshiftrt:SI
1214 [(set_attr "type" "halfmul")])
1216 (define_insn "*machhwu"
1217 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1218 (plus:SI (mult:SI (lshiftrt:SI
1219 (match_operand:SI 1 "gpc_reg_operand" "%r")
1222 (match_operand:SI 2 "gpc_reg_operand" "r")
1224 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1227 [(set_attr "type" "halfmul")])
1229 (define_insn "*maclhwc"
1230 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1231 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1232 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1234 (match_operand:HI 2 "gpc_reg_operand" "r")))
1235 (match_operand:SI 4 "gpc_reg_operand" "0"))
1237 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1238 (plus:SI (mult:SI (sign_extend:SI
1245 [(set_attr "type" "halfmul")])
1247 (define_insn "*maclhw"
1248 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1249 (plus:SI (mult:SI (sign_extend:SI
1250 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1252 (match_operand:HI 2 "gpc_reg_operand" "r")))
1253 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1256 [(set_attr "type" "halfmul")])
1258 (define_insn "*maclhwuc"
1259 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1260 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1261 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1263 (match_operand:HI 2 "gpc_reg_operand" "r")))
1264 (match_operand:SI 4 "gpc_reg_operand" "0"))
1266 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1267 (plus:SI (mult:SI (zero_extend:SI
1274 [(set_attr "type" "halfmul")])
1276 (define_insn "*maclhwu"
1277 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1278 (plus:SI (mult:SI (zero_extend:SI
1279 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1281 (match_operand:HI 2 "gpc_reg_operand" "r")))
1282 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1285 [(set_attr "type" "halfmul")])
1287 (define_insn "*nmacchwc"
1288 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1289 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1290 (mult:SI (ashiftrt:SI
1291 (match_operand:SI 2 "gpc_reg_operand" "r")
1294 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1296 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1297 (minus:SI (match_dup 4)
1298 (mult:SI (ashiftrt:SI
1305 [(set_attr "type" "halfmul")])
1307 (define_insn "*nmacchw"
1308 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1309 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1310 (mult:SI (ashiftrt:SI
1311 (match_operand:SI 2 "gpc_reg_operand" "r")
1314 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1317 [(set_attr "type" "halfmul")])
1319 (define_insn "*nmachhwc"
1320 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1321 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1322 (mult:SI (ashiftrt:SI
1323 (match_operand:SI 1 "gpc_reg_operand" "%r")
1326 (match_operand:SI 2 "gpc_reg_operand" "r")
1329 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330 (minus:SI (match_dup 4)
1331 (mult:SI (ashiftrt:SI
1339 [(set_attr "type" "halfmul")])
1341 (define_insn "*nmachhw"
1342 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1343 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1344 (mult:SI (ashiftrt:SI
1345 (match_operand:SI 1 "gpc_reg_operand" "%r")
1348 (match_operand:SI 2 "gpc_reg_operand" "r")
1352 [(set_attr "type" "halfmul")])
1354 (define_insn "*nmaclhwc"
1355 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1356 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1357 (mult:SI (sign_extend:SI
1358 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1360 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1362 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1363 (minus:SI (match_dup 4)
1364 (mult:SI (sign_extend:SI
1370 [(set_attr "type" "halfmul")])
1372 (define_insn "*nmaclhw"
1373 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1374 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1375 (mult:SI (sign_extend:SI
1376 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1378 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1381 [(set_attr "type" "halfmul")])
1383 (define_insn "*mulchwc"
1384 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1385 (compare:CC (mult:SI (ashiftrt:SI
1386 (match_operand:SI 2 "gpc_reg_operand" "r")
1389 (match_operand:HI 1 "gpc_reg_operand" "r")))
1391 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1392 (mult:SI (ashiftrt:SI
1399 [(set_attr "type" "halfmul")])
1401 (define_insn "*mulchw"
1402 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1403 (mult:SI (ashiftrt:SI
1404 (match_operand:SI 2 "gpc_reg_operand" "r")
1407 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1410 [(set_attr "type" "halfmul")])
1412 (define_insn "*mulchwuc"
1413 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1414 (compare:CC (mult:SI (lshiftrt:SI
1415 (match_operand:SI 2 "gpc_reg_operand" "r")
1418 (match_operand:HI 1 "gpc_reg_operand" "r")))
1420 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1421 (mult:SI (lshiftrt:SI
1428 [(set_attr "type" "halfmul")])
1430 (define_insn "*mulchwu"
1431 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1432 (mult:SI (lshiftrt:SI
1433 (match_operand:SI 2 "gpc_reg_operand" "r")
1436 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1439 [(set_attr "type" "halfmul")])
1441 (define_insn "*mulhhwc"
1442 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1443 (compare:CC (mult:SI (ashiftrt:SI
1444 (match_operand:SI 1 "gpc_reg_operand" "%r")
1447 (match_operand:SI 2 "gpc_reg_operand" "r")
1450 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1451 (mult:SI (ashiftrt:SI
1459 [(set_attr "type" "halfmul")])
1461 (define_insn "*mulhhw"
1462 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1463 (mult:SI (ashiftrt:SI
1464 (match_operand:SI 1 "gpc_reg_operand" "%r")
1467 (match_operand:SI 2 "gpc_reg_operand" "r")
1471 [(set_attr "type" "halfmul")])
1473 (define_insn "*mulhhwuc"
1474 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1475 (compare:CC (mult:SI (lshiftrt:SI
1476 (match_operand:SI 1 "gpc_reg_operand" "%r")
1479 (match_operand:SI 2 "gpc_reg_operand" "r")
1482 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1483 (mult:SI (lshiftrt:SI
1491 [(set_attr "type" "halfmul")])
1493 (define_insn "*mulhhwu"
1494 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1495 (mult:SI (lshiftrt:SI
1496 (match_operand:SI 1 "gpc_reg_operand" "%r")
1499 (match_operand:SI 2 "gpc_reg_operand" "r")
1503 [(set_attr "type" "halfmul")])
1505 (define_insn "*mullhwc"
1506 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1507 (compare:CC (mult:SI (sign_extend:SI
1508 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1510 (match_operand:HI 2 "gpc_reg_operand" "r")))
1512 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1513 (mult:SI (sign_extend:SI
1519 [(set_attr "type" "halfmul")])
1521 (define_insn "*mullhw"
1522 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1523 (mult:SI (sign_extend:SI
1524 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1526 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1529 [(set_attr "type" "halfmul")])
1531 (define_insn "*mullhwuc"
1532 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1533 (compare:CC (mult:SI (zero_extend:SI
1534 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1536 (match_operand:HI 2 "gpc_reg_operand" "r")))
1538 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1539 (mult:SI (zero_extend:SI
1545 [(set_attr "type" "halfmul")])
1547 (define_insn "*mullhwu"
1548 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1549 (mult:SI (zero_extend:SI
1550 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1552 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1555 [(set_attr "type" "halfmul")])
1557 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1558 (define_insn "dlmzb"
1559 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1560 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1561 (match_operand:SI 2 "gpc_reg_operand" "r")]
1563 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1564 (unspec:SI [(match_dup 1)
1570 (define_expand "strlensi"
1571 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1572 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1573 (match_operand:QI 2 "const_int_operand" "")
1574 (match_operand 3 "const_int_operand" "")]
1575 UNSPEC_DLMZB_STRLEN))
1576 (clobber (match_scratch:CC 4 "=x"))]
1577 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1579 rtx result = operands[0];
1580 rtx src = operands[1];
1581 rtx search_char = operands[2];
1582 rtx align = operands[3];
1583 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1584 rtx loop_label, end_label, mem, cr0, cond;
1585 if (search_char != const0_rtx
1586 || GET_CODE (align) != CONST_INT
1587 || INTVAL (align) < 8)
1589 word1 = gen_reg_rtx (SImode);
1590 word2 = gen_reg_rtx (SImode);
1591 scratch_dlmzb = gen_reg_rtx (SImode);
1592 scratch_string = gen_reg_rtx (Pmode);
1593 loop_label = gen_label_rtx ();
1594 end_label = gen_label_rtx ();
1595 addr = force_reg (Pmode, XEXP (src, 0));
1596 emit_move_insn (scratch_string, addr);
1597 emit_label (loop_label);
1598 mem = change_address (src, SImode, scratch_string);
1599 emit_move_insn (word1, mem);
1600 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1601 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1602 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1603 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1604 emit_jump_insn (gen_rtx_SET (pc_rtx,
1605 gen_rtx_IF_THEN_ELSE (VOIDmode,
1611 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1612 emit_jump_insn (gen_rtx_SET (pc_rtx,
1613 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1615 emit_label (end_label);
1616 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1617 emit_insn (gen_subsi3 (result, scratch_string, addr));
1618 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1622 ;; Fixed-point arithmetic insns.
1624 (define_expand "add<mode>3"
1625 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1626 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1627 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1630 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1632 rtx lo0 = gen_lowpart (SImode, operands[0]);
1633 rtx lo1 = gen_lowpart (SImode, operands[1]);
1634 rtx lo2 = gen_lowpart (SImode, operands[2]);
1635 rtx hi0 = gen_highpart (SImode, operands[0]);
1636 rtx hi1 = gen_highpart (SImode, operands[1]);
1637 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1639 if (!reg_or_short_operand (lo2, SImode))
1640 lo2 = force_reg (SImode, lo2);
1641 if (!adde_operand (hi2, SImode))
1642 hi2 = force_reg (SImode, hi2);
1644 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1645 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1649 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1651 rtx tmp = ((!can_create_pseudo_p ()
1652 || rtx_equal_p (operands[0], operands[1]))
1653 ? operands[0] : gen_reg_rtx (<MODE>mode));
1655 /* Adding a constant to r0 is not a valid insn, so use a different
1656 strategy in that case. */
1657 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1659 if (operands[0] == operands[1])
1661 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1662 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1666 HOST_WIDE_INT val = INTVAL (operands[2]);
1667 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1668 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1670 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1673 /* The ordering here is important for the prolog expander.
1674 When space is allocated from the stack, adding 'low' first may
1675 produce a temporary deallocation (which would be bad). */
1676 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1677 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1682 (define_insn "*add<mode>3"
1683 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1684 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1685 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1691 [(set_attr "type" "add")])
1693 (define_insn "addsi3_high"
1694 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1695 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1696 (high:SI (match_operand 2 "" ""))))]
1697 "TARGET_MACHO && !TARGET_64BIT"
1698 "addis %0,%1,ha16(%2)"
1699 [(set_attr "type" "add")])
1701 (define_insn_and_split "*add<mode>3_dot"
1702 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1703 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1704 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1706 (clobber (match_scratch:GPR 0 "=r,r"))]
1707 "<MODE>mode == Pmode"
1711 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1713 (plus:GPR (match_dup 1)
1716 (compare:CC (match_dup 0)
1719 [(set_attr "type" "add")
1720 (set_attr "dot" "yes")
1721 (set_attr "length" "4,8")])
1723 (define_insn_and_split "*add<mode>3_dot2"
1724 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1725 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1726 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1728 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1729 (plus:GPR (match_dup 1)
1731 "<MODE>mode == Pmode"
1735 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1737 (plus:GPR (match_dup 1)
1740 (compare:CC (match_dup 0)
1743 [(set_attr "type" "add")
1744 (set_attr "dot" "yes")
1745 (set_attr "length" "4,8")])
1747 (define_insn_and_split "*add<mode>3_imm_dot"
1748 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1749 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1750 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1752 (clobber (match_scratch:GPR 0 "=r,r"))
1753 (clobber (reg:GPR CA_REGNO))]
1754 "<MODE>mode == Pmode"
1758 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1760 (plus:GPR (match_dup 1)
1763 (compare:CC (match_dup 0)
1766 [(set_attr "type" "add")
1767 (set_attr "dot" "yes")
1768 (set_attr "length" "4,8")])
1770 (define_insn_and_split "*add<mode>3_imm_dot2"
1771 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1772 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1773 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1775 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1776 (plus:GPR (match_dup 1)
1778 (clobber (reg:GPR CA_REGNO))]
1779 "<MODE>mode == Pmode"
1783 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1785 (plus:GPR (match_dup 1)
1788 (compare:CC (match_dup 0)
1791 [(set_attr "type" "add")
1792 (set_attr "dot" "yes")
1793 (set_attr "length" "4,8")])
1795 ;; Split an add that we can't do in one insn into two insns, each of which
1796 ;; does one 16-bit part. This is used by combine. Note that the low-order
1797 ;; add should be last in case the result gets used in an address.
1800 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1801 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1802 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1804 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1805 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1807 HOST_WIDE_INT val = INTVAL (operands[2]);
1808 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1809 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1811 operands[4] = GEN_INT (low);
1812 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1813 operands[3] = GEN_INT (rest);
1814 else if (can_create_pseudo_p ())
1816 operands[3] = gen_reg_rtx (DImode);
1817 emit_move_insn (operands[3], operands[2]);
1818 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1826 (define_insn "add<mode>3_carry"
1827 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1828 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1829 (match_operand:P 2 "reg_or_short_operand" "rI")))
1830 (set (reg:P CA_REGNO)
1831 (ltu:P (plus:P (match_dup 1)
1836 [(set_attr "type" "add")])
1838 (define_insn "*add<mode>3_imm_carry_pos"
1839 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1840 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1841 (match_operand:P 2 "short_cint_operand" "n")))
1842 (set (reg:P CA_REGNO)
1843 (geu:P (match_dup 1)
1844 (match_operand:P 3 "const_int_operand" "n")))]
1845 "INTVAL (operands[2]) > 0
1846 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1848 [(set_attr "type" "add")])
1850 (define_insn "*add<mode>3_imm_carry_0"
1851 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1852 (match_operand:P 1 "gpc_reg_operand" "r"))
1853 (set (reg:P CA_REGNO)
1857 [(set_attr "type" "add")])
1859 (define_insn "*add<mode>3_imm_carry_m1"
1860 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1861 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1863 (set (reg:P CA_REGNO)
1868 [(set_attr "type" "add")])
1870 (define_insn "*add<mode>3_imm_carry_neg"
1871 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1872 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1873 (match_operand:P 2 "short_cint_operand" "n")))
1874 (set (reg:P CA_REGNO)
1875 (gtu:P (match_dup 1)
1876 (match_operand:P 3 "const_int_operand" "n")))]
1877 "INTVAL (operands[2]) < 0
1878 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1880 [(set_attr "type" "add")])
1883 (define_expand "add<mode>3_carry_in"
1885 (set (match_operand:GPR 0 "gpc_reg_operand")
1886 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1887 (match_operand:GPR 2 "adde_operand"))
1888 (reg:GPR CA_REGNO)))
1889 (clobber (reg:GPR CA_REGNO))])]
1892 if (operands[2] == const0_rtx)
1894 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1897 if (operands[2] == constm1_rtx)
1899 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1904 (define_insn "*add<mode>3_carry_in_internal"
1905 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1906 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1907 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1908 (reg:GPR CA_REGNO)))
1909 (clobber (reg:GPR CA_REGNO))]
1912 [(set_attr "type" "add")])
1914 (define_insn "add<mode>3_carry_in_0"
1915 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1916 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1917 (reg:GPR CA_REGNO)))
1918 (clobber (reg:GPR CA_REGNO))]
1921 [(set_attr "type" "add")])
1923 (define_insn "add<mode>3_carry_in_m1"
1924 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1925 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1928 (clobber (reg:GPR CA_REGNO))]
1931 [(set_attr "type" "add")])
1934 (define_expand "one_cmpl<mode>2"
1935 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1936 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1939 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1941 rs6000_split_logical (operands, NOT, false, false, false);
1946 (define_insn "*one_cmpl<mode>2"
1947 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1948 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1952 (define_insn_and_split "*one_cmpl<mode>2_dot"
1953 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1954 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1956 (clobber (match_scratch:GPR 0 "=r,r"))]
1957 "<MODE>mode == Pmode"
1961 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1963 (not:GPR (match_dup 1)))
1965 (compare:CC (match_dup 0)
1968 [(set_attr "type" "logical")
1969 (set_attr "dot" "yes")
1970 (set_attr "length" "4,8")])
1972 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1973 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1974 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1976 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1977 (not:GPR (match_dup 1)))]
1978 "<MODE>mode == Pmode"
1982 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1984 (not:GPR (match_dup 1)))
1986 (compare:CC (match_dup 0)
1989 [(set_attr "type" "logical")
1990 (set_attr "dot" "yes")
1991 (set_attr "length" "4,8")])
1994 (define_expand "sub<mode>3"
1995 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1996 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1997 (match_operand:SDI 2 "gpc_reg_operand" "")))]
2000 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2002 rtx lo0 = gen_lowpart (SImode, operands[0]);
2003 rtx lo1 = gen_lowpart (SImode, operands[1]);
2004 rtx lo2 = gen_lowpart (SImode, operands[2]);
2005 rtx hi0 = gen_highpart (SImode, operands[0]);
2006 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2007 rtx hi2 = gen_highpart (SImode, operands[2]);
2009 if (!reg_or_short_operand (lo1, SImode))
2010 lo1 = force_reg (SImode, lo1);
2011 if (!adde_operand (hi1, SImode))
2012 hi1 = force_reg (SImode, hi1);
2014 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2015 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2019 if (short_cint_operand (operands[1], <MODE>mode))
2021 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2026 (define_insn "*subf<mode>3"
2027 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2028 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2029 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2032 [(set_attr "type" "add")])
2034 (define_insn_and_split "*subf<mode>3_dot"
2035 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2036 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2037 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2039 (clobber (match_scratch:GPR 0 "=r,r"))]
2040 "<MODE>mode == Pmode"
2044 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2046 (minus:GPR (match_dup 2)
2049 (compare:CC (match_dup 0)
2052 [(set_attr "type" "add")
2053 (set_attr "dot" "yes")
2054 (set_attr "length" "4,8")])
2056 (define_insn_and_split "*subf<mode>3_dot2"
2057 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2058 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2059 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2061 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2062 (minus:GPR (match_dup 2)
2064 "<MODE>mode == Pmode"
2068 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2070 (minus:GPR (match_dup 2)
2073 (compare:CC (match_dup 0)
2076 [(set_attr "type" "add")
2077 (set_attr "dot" "yes")
2078 (set_attr "length" "4,8")])
2080 (define_insn "subf<mode>3_imm"
2081 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2082 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2083 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2084 (clobber (reg:GPR CA_REGNO))]
2087 [(set_attr "type" "add")])
2089 (define_insn_and_split "subf<mode>3_carry_dot2"
2090 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2091 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2092 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2094 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2095 (minus:P (match_dup 2)
2097 (set (reg:P CA_REGNO)
2098 (leu:P (match_dup 1)
2100 "<MODE>mode == Pmode"
2104 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2105 [(parallel [(set (match_dup 0)
2106 (minus:P (match_dup 2)
2108 (set (reg:P CA_REGNO)
2109 (leu:P (match_dup 1)
2112 (compare:CC (match_dup 0)
2115 [(set_attr "type" "add")
2116 (set_attr "dot" "yes")
2117 (set_attr "length" "4,8")])
2119 (define_insn "subf<mode>3_carry"
2120 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2121 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2122 (match_operand:P 1 "gpc_reg_operand" "r")))
2123 (set (reg:P CA_REGNO)
2124 (leu:P (match_dup 1)
2128 [(set_attr "type" "add")])
2130 (define_insn "*subf<mode>3_imm_carry_0"
2131 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2132 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2133 (set (reg:P CA_REGNO)
2138 [(set_attr "type" "add")])
2140 (define_insn "*subf<mode>3_imm_carry_m1"
2141 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2142 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2143 (set (reg:P CA_REGNO)
2147 [(set_attr "type" "add")])
2150 (define_expand "subf<mode>3_carry_in"
2152 (set (match_operand:GPR 0 "gpc_reg_operand")
2153 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2155 (match_operand:GPR 2 "adde_operand")))
2156 (clobber (reg:GPR CA_REGNO))])]
2159 if (operands[2] == const0_rtx)
2161 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2164 if (operands[2] == constm1_rtx)
2166 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2171 (define_insn "*subf<mode>3_carry_in_internal"
2172 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2173 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2175 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2176 (clobber (reg:GPR CA_REGNO))]
2179 [(set_attr "type" "add")])
2181 (define_insn "subf<mode>3_carry_in_0"
2182 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2183 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2184 (reg:GPR CA_REGNO)))
2185 (clobber (reg:GPR CA_REGNO))]
2188 [(set_attr "type" "add")])
2190 (define_insn "subf<mode>3_carry_in_m1"
2191 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2192 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2193 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2195 (clobber (reg:GPR CA_REGNO))]
2198 [(set_attr "type" "add")])
2200 (define_insn "subf<mode>3_carry_in_xx"
2201 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2202 (plus:GPR (reg:GPR CA_REGNO)
2204 (clobber (reg:GPR CA_REGNO))]
2207 [(set_attr "type" "add")])
2210 (define_insn "neg<mode>2"
2211 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2212 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2215 [(set_attr "type" "add")])
2217 (define_insn_and_split "*neg<mode>2_dot"
2218 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2219 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2221 (clobber (match_scratch:GPR 0 "=r,r"))]
2222 "<MODE>mode == Pmode"
2226 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2228 (neg:GPR (match_dup 1)))
2230 (compare:CC (match_dup 0)
2233 [(set_attr "type" "add")
2234 (set_attr "dot" "yes")
2235 (set_attr "length" "4,8")])
2237 (define_insn_and_split "*neg<mode>2_dot2"
2238 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2239 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2241 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2242 (neg:GPR (match_dup 1)))]
2243 "<MODE>mode == Pmode"
2247 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2249 (neg:GPR (match_dup 1)))
2251 (compare:CC (match_dup 0)
2254 [(set_attr "type" "add")
2255 (set_attr "dot" "yes")
2256 (set_attr "length" "4,8")])
2259 (define_insn "clz<mode>2"
2260 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2261 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2264 [(set_attr "type" "cntlz")])
2266 (define_expand "ctz<mode>2"
2267 [(set (match_operand:GPR 0 "gpc_reg_operand")
2268 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2273 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2277 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2278 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2279 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2283 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2284 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2285 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2286 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2290 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2291 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2292 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2293 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2299 (define_insn "ctz<mode>2_hw"
2300 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2301 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2304 [(set_attr "type" "cntlz")])
2306 (define_expand "ffs<mode>2"
2307 [(set (match_operand:GPR 0 "gpc_reg_operand")
2308 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2311 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2312 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2313 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2314 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2315 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2316 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2317 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2322 (define_expand "popcount<mode>2"
2323 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2324 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2325 "TARGET_POPCNTB || TARGET_POPCNTD"
2327 rs6000_emit_popcount (operands[0], operands[1]);
2331 (define_insn "popcntb<mode>2"
2332 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2333 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2337 [(set_attr "type" "popcnt")])
2339 (define_insn "popcntd<mode>2"
2340 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2341 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2344 [(set_attr "type" "popcnt")])
2347 (define_expand "parity<mode>2"
2348 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2349 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2352 rs6000_emit_parity (operands[0], operands[1]);
2356 (define_insn "parity<mode>2_cmpb"
2357 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2358 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2359 "TARGET_CMPB && TARGET_POPCNTB"
2361 [(set_attr "type" "popcnt")])
2363 (define_insn "cmpb<mode>3"
2364 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2365 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2366 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2369 [(set_attr "type" "cmp")])
2371 ;; Since the hardware zeros the upper part of the register, save generating the
2372 ;; AND immediate if we are converting to unsigned
2373 (define_insn "*bswap<mode>2_extenddi"
2374 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2376 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2379 [(set_attr "length" "4")
2380 (set_attr "type" "load")])
2382 (define_insn "*bswaphi2_extendsi"
2383 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2385 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2388 [(set_attr "length" "4")
2389 (set_attr "type" "load")])
2391 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2392 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2393 ;; load with byte swap, which can be slower than doing it in the registers. It
2394 ;; also prevents certain failures with the RELOAD register allocator.
2396 (define_expand "bswap<mode>2"
2397 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2398 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2401 rtx dest = operands[0];
2402 rtx src = operands[1];
2404 if (!REG_P (dest) && !REG_P (src))
2405 src = force_reg (<MODE>mode, src);
2408 emit_insn (gen_bswap<mode>2_load (dest, src));
2409 else if (MEM_P (dest))
2410 emit_insn (gen_bswap<mode>2_store (dest, src));
2412 emit_insn (gen_bswap<mode>2_reg (dest, src));
2416 (define_insn "bswap<mode>2_load"
2417 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2418 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2421 [(set_attr "type" "load")])
2423 (define_insn "bswap<mode>2_store"
2424 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2425 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2428 [(set_attr "type" "store")])
2430 (define_insn_and_split "bswaphi2_reg"
2431 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
2433 (match_operand:HI 1 "gpc_reg_operand" "r")))
2434 (clobber (match_scratch:SI 2 "=&r"))]
2439 (and:SI (lshiftrt:SI (match_dup 4)
2443 (and:SI (ashift:SI (match_dup 4)
2445 (const_int 65280))) ;; 0xff00
2447 (ior:SI (match_dup 3)
2450 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2451 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2453 [(set_attr "length" "12")
2454 (set_attr "type" "*")])
2456 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2457 ;; zero_extract insns do not change for -mlittle.
2458 (define_insn_and_split "bswapsi2_reg"
2459 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
2461 (match_operand:SI 1 "gpc_reg_operand" "r")))]
2465 [(set (match_dup 0) ; DABC
2466 (rotate:SI (match_dup 1)
2468 (set (match_dup 0) ; DCBC
2469 (ior:SI (and:SI (ashift:SI (match_dup 1)
2471 (const_int 16711680))
2472 (and:SI (match_dup 0)
2473 (const_int -16711681))))
2474 (set (match_dup 0) ; DCBA
2475 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2478 (and:SI (match_dup 0)
2479 (const_int -256))))]
2482 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2483 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2486 (define_expand "bswapdi2"
2487 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2489 (match_operand:DI 1 "reg_or_mem_operand" "")))
2490 (clobber (match_scratch:DI 2 ""))
2491 (clobber (match_scratch:DI 3 ""))])]
2494 rtx dest = operands[0];
2495 rtx src = operands[1];
2497 if (!REG_P (dest) && !REG_P (src))
2498 operands[1] = src = force_reg (DImode, src);
2500 if (TARGET_POWERPC64 && TARGET_LDBRX)
2503 emit_insn (gen_bswapdi2_load (dest, src));
2504 else if (MEM_P (dest))
2505 emit_insn (gen_bswapdi2_store (dest, src));
2507 emit_insn (gen_bswapdi2_reg (dest, src));
2511 if (!TARGET_POWERPC64)
2513 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2514 that uses 64-bit registers needs the same scratch registers as 64-bit
2516 emit_insn (gen_bswapdi2_32bit (dest, src));
2521 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2522 (define_insn "bswapdi2_load"
2523 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2524 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2525 "TARGET_POWERPC64 && TARGET_LDBRX"
2527 [(set_attr "type" "load")])
2529 (define_insn "bswapdi2_store"
2530 [(set (match_operand:DI 0 "memory_operand" "=Z")
2531 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2532 "TARGET_POWERPC64 && TARGET_LDBRX"
2534 [(set_attr "type" "store")])
2536 (define_insn "bswapdi2_reg"
2537 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2538 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2539 (clobber (match_scratch:DI 2 "=&r"))
2540 (clobber (match_scratch:DI 3 "=&r"))]
2541 "TARGET_POWERPC64 && TARGET_LDBRX"
2543 [(set_attr "length" "36")])
2545 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2546 (define_insn "*bswapdi2_64bit"
2547 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2548 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2549 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2550 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2551 "TARGET_POWERPC64 && !TARGET_LDBRX
2552 && (REG_P (operands[0]) || REG_P (operands[1]))
2553 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2554 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2556 [(set_attr "length" "16,12,36")])
2559 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2560 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2561 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2562 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2563 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2567 rtx dest = operands[0];
2568 rtx src = operands[1];
2569 rtx op2 = operands[2];
2570 rtx op3 = operands[3];
2571 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2572 BYTES_BIG_ENDIAN ? 4 : 0);
2573 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2574 BYTES_BIG_ENDIAN ? 4 : 0);
2580 addr1 = XEXP (src, 0);
2581 if (GET_CODE (addr1) == PLUS)
2583 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2584 if (TARGET_AVOID_XFORM)
2586 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2590 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2592 else if (TARGET_AVOID_XFORM)
2594 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2599 emit_move_insn (op2, GEN_INT (4));
2600 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2603 word1 = change_address (src, SImode, addr1);
2604 word2 = change_address (src, SImode, addr2);
2606 if (BYTES_BIG_ENDIAN)
2608 emit_insn (gen_bswapsi2 (op3_32, word2));
2609 emit_insn (gen_bswapsi2 (dest_32, word1));
2613 emit_insn (gen_bswapsi2 (op3_32, word1));
2614 emit_insn (gen_bswapsi2 (dest_32, word2));
2617 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2618 emit_insn (gen_iordi3 (dest, dest, op3));
2623 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2624 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2625 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2626 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2627 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2631 rtx dest = operands[0];
2632 rtx src = operands[1];
2633 rtx op2 = operands[2];
2634 rtx op3 = operands[3];
2635 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2636 BYTES_BIG_ENDIAN ? 4 : 0);
2637 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2638 BYTES_BIG_ENDIAN ? 4 : 0);
2644 addr1 = XEXP (dest, 0);
2645 if (GET_CODE (addr1) == PLUS)
2647 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2648 if (TARGET_AVOID_XFORM)
2650 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2654 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2656 else if (TARGET_AVOID_XFORM)
2658 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2663 emit_move_insn (op2, GEN_INT (4));
2664 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2667 word1 = change_address (dest, SImode, addr1);
2668 word2 = change_address (dest, SImode, addr2);
2670 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2672 if (BYTES_BIG_ENDIAN)
2674 emit_insn (gen_bswapsi2 (word1, src_si));
2675 emit_insn (gen_bswapsi2 (word2, op3_si));
2679 emit_insn (gen_bswapsi2 (word2, src_si));
2680 emit_insn (gen_bswapsi2 (word1, op3_si));
2686 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2687 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2688 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2689 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2690 "TARGET_POWERPC64 && reload_completed"
2694 rtx dest = operands[0];
2695 rtx src = operands[1];
2696 rtx op2 = operands[2];
2697 rtx op3 = operands[3];
2698 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2699 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2700 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2701 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2702 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2704 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2705 emit_insn (gen_bswapsi2 (dest_si, src_si));
2706 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2707 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2708 emit_insn (gen_iordi3 (dest, dest, op3));
2712 (define_insn "bswapdi2_32bit"
2713 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2714 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2715 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2716 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2718 [(set_attr "length" "16,12,36")])
2721 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2722 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2723 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2724 "!TARGET_POWERPC64 && reload_completed"
2728 rtx dest = operands[0];
2729 rtx src = operands[1];
2730 rtx op2 = operands[2];
2731 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2732 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2738 addr1 = XEXP (src, 0);
2739 if (GET_CODE (addr1) == PLUS)
2741 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2742 if (TARGET_AVOID_XFORM
2743 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2745 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2749 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2751 else if (TARGET_AVOID_XFORM
2752 || REGNO (addr1) == REGNO (dest2))
2754 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2759 emit_move_insn (op2, GEN_INT (4));
2760 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2763 word1 = change_address (src, SImode, addr1);
2764 word2 = change_address (src, SImode, addr2);
2766 emit_insn (gen_bswapsi2 (dest2, word1));
2767 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2768 thus allowing us to omit an early clobber on the output. */
2769 emit_insn (gen_bswapsi2 (dest1, word2));
2774 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2775 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2776 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2777 "!TARGET_POWERPC64 && reload_completed"
2781 rtx dest = operands[0];
2782 rtx src = operands[1];
2783 rtx op2 = operands[2];
2784 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2785 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2791 addr1 = XEXP (dest, 0);
2792 if (GET_CODE (addr1) == PLUS)
2794 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2795 if (TARGET_AVOID_XFORM)
2797 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2801 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2803 else if (TARGET_AVOID_XFORM)
2805 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2810 emit_move_insn (op2, GEN_INT (4));
2811 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2814 word1 = change_address (dest, SImode, addr1);
2815 word2 = change_address (dest, SImode, addr2);
2817 emit_insn (gen_bswapsi2 (word2, src1));
2818 emit_insn (gen_bswapsi2 (word1, src2));
2823 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2824 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2825 (clobber (match_operand:SI 2 "" ""))]
2826 "!TARGET_POWERPC64 && reload_completed"
2830 rtx dest = operands[0];
2831 rtx src = operands[1];
2832 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2833 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2834 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2835 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2837 emit_insn (gen_bswapsi2 (dest1, src2));
2838 emit_insn (gen_bswapsi2 (dest2, src1));
2843 (define_insn "mul<mode>3"
2844 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2845 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2846 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2851 [(set_attr "type" "mul")
2853 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2855 (match_operand:GPR 2 "short_cint_operand" "")
2856 (const_string "16")]
2857 (const_string "<bits>")))])
2859 (define_insn_and_split "*mul<mode>3_dot"
2860 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2861 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2862 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2864 (clobber (match_scratch:GPR 0 "=r,r"))]
2865 "<MODE>mode == Pmode"
2869 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2871 (mult:GPR (match_dup 1)
2874 (compare:CC (match_dup 0)
2877 [(set_attr "type" "mul")
2878 (set_attr "size" "<bits>")
2879 (set_attr "dot" "yes")
2880 (set_attr "length" "4,8")])
2882 (define_insn_and_split "*mul<mode>3_dot2"
2883 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2884 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2885 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2887 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2888 (mult:GPR (match_dup 1)
2890 "<MODE>mode == Pmode"
2894 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2896 (mult:GPR (match_dup 1)
2899 (compare:CC (match_dup 0)
2902 [(set_attr "type" "mul")
2903 (set_attr "size" "<bits>")
2904 (set_attr "dot" "yes")
2905 (set_attr "length" "4,8")])
2908 (define_expand "<su>mul<mode>3_highpart"
2909 [(set (match_operand:GPR 0 "gpc_reg_operand")
2911 (mult:<DMODE> (any_extend:<DMODE>
2912 (match_operand:GPR 1 "gpc_reg_operand"))
2914 (match_operand:GPR 2 "gpc_reg_operand")))
2918 if (<MODE>mode == SImode && TARGET_POWERPC64)
2920 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2925 if (!WORDS_BIG_ENDIAN)
2927 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2933 (define_insn "*<su>mul<mode>3_highpart"
2934 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2936 (mult:<DMODE> (any_extend:<DMODE>
2937 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2939 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2941 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2942 "mulh<wd><u> %0,%1,%2"
2943 [(set_attr "type" "mul")
2944 (set_attr "size" "<bits>")])
2946 (define_insn "<su>mulsi3_highpart_le"
2947 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2949 (mult:DI (any_extend:DI
2950 (match_operand:SI 1 "gpc_reg_operand" "r"))
2952 (match_operand:SI 2 "gpc_reg_operand" "r")))
2954 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2956 [(set_attr "type" "mul")])
2958 (define_insn "<su>muldi3_highpart_le"
2959 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2961 (mult:TI (any_extend:TI
2962 (match_operand:DI 1 "gpc_reg_operand" "r"))
2964 (match_operand:DI 2 "gpc_reg_operand" "r")))
2966 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2968 [(set_attr "type" "mul")
2969 (set_attr "size" "64")])
2971 (define_insn "<su>mulsi3_highpart_64"
2972 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2975 (mult:DI (any_extend:DI
2976 (match_operand:SI 1 "gpc_reg_operand" "r"))
2978 (match_operand:SI 2 "gpc_reg_operand" "r")))
2982 [(set_attr "type" "mul")])
2984 (define_expand "<u>mul<mode><dmode>3"
2985 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2986 (mult:<DMODE> (any_extend:<DMODE>
2987 (match_operand:GPR 1 "gpc_reg_operand"))
2989 (match_operand:GPR 2 "gpc_reg_operand"))))]
2990 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2992 rtx l = gen_reg_rtx (<MODE>mode);
2993 rtx h = gen_reg_rtx (<MODE>mode);
2994 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2995 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2996 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2997 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3001 (define_insn "*maddld4"
3002 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3003 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3004 (match_operand:DI 2 "gpc_reg_operand" "r"))
3005 (match_operand:DI 3 "gpc_reg_operand" "r")))]
3007 "maddld %0,%1,%2,%3"
3008 [(set_attr "type" "mul")])
3010 (define_insn "udiv<mode>3"
3011 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3012 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3013 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3016 [(set_attr "type" "div")
3017 (set_attr "size" "<bits>")])
3020 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3021 ;; modulus. If it isn't a power of two, force operands into register and do
3023 (define_expand "div<mode>3"
3024 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3025 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3026 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3029 if (CONST_INT_P (operands[2])
3030 && INTVAL (operands[2]) > 0
3031 && exact_log2 (INTVAL (operands[2])) >= 0)
3033 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3037 operands[2] = force_reg (<MODE>mode, operands[2]);
3040 (define_insn "*div<mode>3"
3041 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3042 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3043 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3046 [(set_attr "type" "div")
3047 (set_attr "size" "<bits>")])
3049 (define_insn "div<mode>3_sra"
3050 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3051 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3052 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3053 (clobber (reg:GPR CA_REGNO))]
3055 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3056 [(set_attr "type" "two")
3057 (set_attr "length" "8")])
3059 (define_insn_and_split "*div<mode>3_sra_dot"
3060 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3061 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3062 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3064 (clobber (match_scratch:GPR 0 "=r,r"))
3065 (clobber (reg:GPR CA_REGNO))]
3066 "<MODE>mode == Pmode"
3068 sra<wd>i %0,%1,%p2\;addze. %0,%0
3070 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3071 [(parallel [(set (match_dup 0)
3072 (div:GPR (match_dup 1)
3074 (clobber (reg:GPR CA_REGNO))])
3076 (compare:CC (match_dup 0)
3079 [(set_attr "type" "two")
3080 (set_attr "length" "8,12")
3081 (set_attr "cell_micro" "not")])
3083 (define_insn_and_split "*div<mode>3_sra_dot2"
3084 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3085 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3086 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3088 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3089 (div:GPR (match_dup 1)
3091 (clobber (reg:GPR CA_REGNO))]
3092 "<MODE>mode == Pmode"
3094 sra<wd>i %0,%1,%p2\;addze. %0,%0
3096 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3097 [(parallel [(set (match_dup 0)
3098 (div:GPR (match_dup 1)
3100 (clobber (reg:GPR CA_REGNO))])
3102 (compare:CC (match_dup 0)
3105 [(set_attr "type" "two")
3106 (set_attr "length" "8,12")
3107 (set_attr "cell_micro" "not")])
3109 (define_expand "mod<mode>3"
3110 [(set (match_operand:GPR 0 "gpc_reg_operand")
3111 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3112 (match_operand:GPR 2 "reg_or_cint_operand")))]
3119 if (GET_CODE (operands[2]) != CONST_INT
3120 || INTVAL (operands[2]) <= 0
3121 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3126 operands[2] = force_reg (<MODE>mode, operands[2]);
3130 temp1 = gen_reg_rtx (<MODE>mode);
3131 temp2 = gen_reg_rtx (<MODE>mode);
3133 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3134 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3135 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3140 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3141 ;; mod, prefer putting the result of mod into a different register
3142 (define_insn "*mod<mode>3"
3143 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3144 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3145 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3148 [(set_attr "type" "div")
3149 (set_attr "size" "<bits>")])
3152 (define_insn "umod<mode>3"
3153 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3154 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3155 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3158 [(set_attr "type" "div")
3159 (set_attr "size" "<bits>")])
3161 ;; On machines with modulo support, do a combined div/mod the old fashioned
3162 ;; method, since the multiply/subtract is faster than doing the mod instruction
3166 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3167 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3168 (match_operand:GPR 2 "gpc_reg_operand" "")))
3169 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3170 (mod:GPR (match_dup 1)
3173 && ! reg_mentioned_p (operands[0], operands[1])
3174 && ! reg_mentioned_p (operands[0], operands[2])
3175 && ! reg_mentioned_p (operands[3], operands[1])
3176 && ! reg_mentioned_p (operands[3], operands[2])"
3178 (div:GPR (match_dup 1)
3181 (mult:GPR (match_dup 0)
3184 (minus:GPR (match_dup 1)
3188 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3189 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3190 (match_operand:GPR 2 "gpc_reg_operand" "")))
3191 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3192 (umod:GPR (match_dup 1)
3195 && ! reg_mentioned_p (operands[0], operands[1])
3196 && ! reg_mentioned_p (operands[0], operands[2])
3197 && ! reg_mentioned_p (operands[3], operands[1])
3198 && ! reg_mentioned_p (operands[3], operands[2])"
3200 (udiv:GPR (match_dup 1)
3203 (mult:GPR (match_dup 0)
3206 (minus:GPR (match_dup 1)
3210 ;; Logical instructions
3211 ;; The logical instructions are mostly combined by using match_operator,
3212 ;; but the plain AND insns are somewhat different because there is no
3213 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3214 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3216 (define_expand "and<mode>3"
3217 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3218 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3219 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3222 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3224 rs6000_split_logical (operands, AND, false, false, false);
3228 if (CONST_INT_P (operands[2]))
3230 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3232 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3236 if (logical_const_operand (operands[2], <MODE>mode))
3238 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3242 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3244 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3248 operands[2] = force_reg (<MODE>mode, operands[2]);
3253 (define_insn "and<mode>3_imm"
3254 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3255 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3256 (match_operand:GPR 2 "logical_const_operand" "n")))
3257 (clobber (match_scratch:CC 3 "=x"))]
3258 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3259 "andi%e2. %0,%1,%u2"
3260 [(set_attr "type" "logical")
3261 (set_attr "dot" "yes")])
3263 (define_insn_and_split "*and<mode>3_imm_dot"
3264 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3265 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3266 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3268 (clobber (match_scratch:GPR 0 "=r,r"))
3269 (clobber (match_scratch:CC 4 "=X,x"))]
3270 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3271 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3275 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3276 [(parallel [(set (match_dup 0)
3277 (and:GPR (match_dup 1)
3279 (clobber (match_dup 4))])
3281 (compare:CC (match_dup 0)
3284 [(set_attr "type" "logical")
3285 (set_attr "dot" "yes")
3286 (set_attr "length" "4,8")])
3288 (define_insn_and_split "*and<mode>3_imm_dot2"
3289 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3290 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3291 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3293 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3294 (and:GPR (match_dup 1)
3296 (clobber (match_scratch:CC 4 "=X,x"))]
3297 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3298 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3302 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3303 [(parallel [(set (match_dup 0)
3304 (and:GPR (match_dup 1)
3306 (clobber (match_dup 4))])
3308 (compare:CC (match_dup 0)
3311 [(set_attr "type" "logical")
3312 (set_attr "dot" "yes")
3313 (set_attr "length" "4,8")])
3315 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3316 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3317 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3318 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3320 (clobber (match_scratch:GPR 0 "=r,r"))]
3321 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3322 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3326 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3328 (and:GPR (match_dup 1)
3331 (compare:CC (match_dup 0)
3334 [(set_attr "type" "logical")
3335 (set_attr "dot" "yes")
3336 (set_attr "length" "4,8")])
3338 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3339 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3340 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3341 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3343 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3344 (and:GPR (match_dup 1)
3346 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3347 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3351 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3353 (and:GPR (match_dup 1)
3356 (compare:CC (match_dup 0)
3359 [(set_attr "type" "logical")
3360 (set_attr "dot" "yes")
3361 (set_attr "length" "4,8")])
3363 (define_insn "*and<mode>3_imm_dot_shifted"
3364 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3367 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3368 (match_operand:SI 4 "const_int_operand" "n"))
3369 (match_operand:GPR 2 "const_int_operand" "n"))
3371 (clobber (match_scratch:GPR 0 "=r"))]
3372 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3373 << INTVAL (operands[4])),
3375 && (<MODE>mode == Pmode
3376 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3378 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3379 return "andi%e2. %0,%1,%u2";
3381 [(set_attr "type" "logical")
3382 (set_attr "dot" "yes")])
3385 (define_insn "and<mode>3_mask"
3386 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3387 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3388 (match_operand:GPR 2 "const_int_operand" "n")))]
3389 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3391 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3393 [(set_attr "type" "shift")])
3395 (define_insn_and_split "*and<mode>3_mask_dot"
3396 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3397 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3398 (match_operand:GPR 2 "const_int_operand" "n,n"))
3400 (clobber (match_scratch:GPR 0 "=r,r"))]
3401 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3402 && !logical_const_operand (operands[2], <MODE>mode)
3403 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3405 if (which_alternative == 0)
3406 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3410 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3412 (and:GPR (match_dup 1)
3415 (compare:CC (match_dup 0)
3418 [(set_attr "type" "shift")
3419 (set_attr "dot" "yes")
3420 (set_attr "length" "4,8")])
3422 (define_insn_and_split "*and<mode>3_mask_dot2"
3423 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3424 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3425 (match_operand:GPR 2 "const_int_operand" "n,n"))
3427 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3428 (and:GPR (match_dup 1)
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")])
3452 (define_insn_and_split "*and<mode>3_2insn"
3453 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3454 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3455 (match_operand:GPR 2 "const_int_operand" "n")))]
3456 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3457 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3458 || logical_const_operand (operands[2], <MODE>mode))"
3463 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3466 [(set_attr "type" "shift")
3467 (set_attr "length" "8")])
3469 (define_insn_and_split "*and<mode>3_2insn_dot"
3470 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3471 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3472 (match_operand:GPR 2 "const_int_operand" "n,n"))
3474 (clobber (match_scratch:GPR 0 "=r,r"))]
3475 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3476 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3477 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3478 || logical_const_operand (operands[2], <MODE>mode))"
3480 "&& reload_completed"
3483 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3486 [(set_attr "type" "shift")
3487 (set_attr "dot" "yes")
3488 (set_attr "length" "8,12")])
3490 (define_insn_and_split "*and<mode>3_2insn_dot2"
3491 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3492 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3493 (match_operand:GPR 2 "const_int_operand" "n,n"))
3495 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3496 (and:GPR (match_dup 1)
3498 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3499 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3500 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3501 || logical_const_operand (operands[2], <MODE>mode))"
3503 "&& reload_completed"
3506 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3509 [(set_attr "type" "shift")
3510 (set_attr "dot" "yes")
3511 (set_attr "length" "8,12")])
3514 (define_expand "<code><mode>3"
3515 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3516 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3517 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3520 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3522 rs6000_split_logical (operands, <CODE>, false, false, false);
3526 if (non_logical_cint_operand (operands[2], <MODE>mode))
3528 rtx tmp = ((!can_create_pseudo_p ()
3529 || rtx_equal_p (operands[0], operands[1]))
3530 ? operands[0] : gen_reg_rtx (<MODE>mode));
3532 HOST_WIDE_INT value = INTVAL (operands[2]);
3533 HOST_WIDE_INT lo = value & 0xffff;
3534 HOST_WIDE_INT hi = value - lo;
3536 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3537 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3541 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3542 operands[2] = force_reg (<MODE>mode, operands[2]);
3546 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3547 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3548 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3551 (iorxor:GPR (match_dup 1)
3554 (iorxor:GPR (match_dup 3)
3557 operands[3] = ((!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 operands[4] = GEN_INT (hi);
3566 operands[5] = GEN_INT (lo);
3569 (define_insn "*bool<mode>3_imm"
3570 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3571 (match_operator:GPR 3 "boolean_or_operator"
3572 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3573 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3576 [(set_attr "type" "logical")])
3578 (define_insn "*bool<mode>3"
3579 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3580 (match_operator:GPR 3 "boolean_operator"
3581 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3582 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3585 [(set_attr "type" "logical")])
3587 (define_insn_and_split "*bool<mode>3_dot"
3588 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3589 (compare:CC (match_operator:GPR 3 "boolean_operator"
3590 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3591 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3593 (clobber (match_scratch:GPR 0 "=r,r"))]
3594 "<MODE>mode == Pmode"
3598 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3602 (compare:CC (match_dup 0)
3605 [(set_attr "type" "logical")
3606 (set_attr "dot" "yes")
3607 (set_attr "length" "4,8")])
3609 (define_insn_and_split "*bool<mode>3_dot2"
3610 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3611 (compare:CC (match_operator:GPR 3 "boolean_operator"
3612 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3613 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3615 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3617 "<MODE>mode == Pmode"
3621 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3625 (compare:CC (match_dup 0)
3628 [(set_attr "type" "logical")
3629 (set_attr "dot" "yes")
3630 (set_attr "length" "4,8")])
3633 (define_insn "*boolc<mode>3"
3634 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3635 (match_operator:GPR 3 "boolean_operator"
3636 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3637 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3640 [(set_attr "type" "logical")])
3642 (define_insn_and_split "*boolc<mode>3_dot"
3643 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3644 (compare:CC (match_operator:GPR 3 "boolean_operator"
3645 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3646 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3648 (clobber (match_scratch:GPR 0 "=r,r"))]
3649 "<MODE>mode == Pmode"
3653 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3657 (compare:CC (match_dup 0)
3660 [(set_attr "type" "logical")
3661 (set_attr "dot" "yes")
3662 (set_attr "length" "4,8")])
3664 (define_insn_and_split "*boolc<mode>3_dot2"
3665 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3666 (compare:CC (match_operator:GPR 3 "boolean_operator"
3667 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3668 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3670 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3672 "<MODE>mode == Pmode"
3676 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3680 (compare:CC (match_dup 0)
3683 [(set_attr "type" "logical")
3684 (set_attr "dot" "yes")
3685 (set_attr "length" "4,8")])
3688 (define_insn "*boolcc<mode>3"
3689 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3690 (match_operator:GPR 3 "boolean_operator"
3691 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3692 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3695 [(set_attr "type" "logical")])
3697 (define_insn_and_split "*boolcc<mode>3_dot"
3698 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3699 (compare:CC (match_operator:GPR 3 "boolean_operator"
3700 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3701 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3703 (clobber (match_scratch:GPR 0 "=r,r"))]
3704 "<MODE>mode == Pmode"
3708 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3712 (compare:CC (match_dup 0)
3715 [(set_attr "type" "logical")
3716 (set_attr "dot" "yes")
3717 (set_attr "length" "4,8")])
3719 (define_insn_and_split "*boolcc<mode>3_dot2"
3720 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3721 (compare:CC (match_operator:GPR 3 "boolean_operator"
3722 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3723 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3725 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3727 "<MODE>mode == Pmode"
3731 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3735 (compare:CC (match_dup 0)
3738 [(set_attr "type" "logical")
3739 (set_attr "dot" "yes")
3740 (set_attr "length" "4,8")])
3743 ;; TODO: Should have dots of this as well.
3744 (define_insn "*eqv<mode>3"
3745 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3746 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3747 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3750 [(set_attr "type" "logical")])
3752 ;; Rotate-and-mask and insert.
3754 (define_insn "*rotl<mode>3_mask"
3755 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3756 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3757 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3758 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3759 (match_operand:GPR 3 "const_int_operand" "n")))]
3760 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3762 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3764 [(set_attr "type" "shift")
3765 (set_attr "maybe_var_shift" "yes")])
3767 (define_insn_and_split "*rotl<mode>3_mask_dot"
3768 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3770 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3771 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3772 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3773 (match_operand:GPR 3 "const_int_operand" "n,n"))
3775 (clobber (match_scratch:GPR 0 "=r,r"))]
3776 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3777 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3779 if (which_alternative == 0)
3780 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3784 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3786 (and:GPR (match_dup 4)
3789 (compare:CC (match_dup 0)
3792 [(set_attr "type" "shift")
3793 (set_attr "maybe_var_shift" "yes")
3794 (set_attr "dot" "yes")
3795 (set_attr "length" "4,8")])
3797 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3798 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3800 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3801 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3802 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3803 (match_operand:GPR 3 "const_int_operand" "n,n"))
3805 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3806 (and:GPR (match_dup 4)
3808 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3809 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3811 if (which_alternative == 0)
3812 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3816 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3818 (and:GPR (match_dup 4)
3821 (compare:CC (match_dup 0)
3824 [(set_attr "type" "shift")
3825 (set_attr "maybe_var_shift" "yes")
3826 (set_attr "dot" "yes")
3827 (set_attr "length" "4,8")])
3829 ; Special case for less-than-0. We can do it with just one machine
3830 ; instruction, but the generic optimizers do not realise it is cheap.
3831 (define_insn "*lt0_disi"
3832 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3833 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3836 "rlwinm %0,%1,1,31,31"
3837 [(set_attr "type" "shift")])
3841 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3842 ; both are an AND so are the same precedence).
3843 (define_insn "*rotl<mode>3_insert"
3844 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3845 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3846 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3847 (match_operand:SI 2 "const_int_operand" "n")])
3848 (match_operand:GPR 3 "const_int_operand" "n"))
3849 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3850 (match_operand:GPR 6 "const_int_operand" "n"))))]
3851 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3852 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3854 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3856 [(set_attr "type" "insert")])
3857 ; FIXME: this needs an attr "size", so that the scheduler can see the
3858 ; difference between rlwimi and rldimi. We also might want dot forms,
3859 ; but not for rlwimi on POWER4 and similar processors.
3861 (define_insn "*rotl<mode>3_insert_2"
3862 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3863 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3864 (match_operand:GPR 6 "const_int_operand" "n"))
3865 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3866 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3867 (match_operand:SI 2 "const_int_operand" "n")])
3868 (match_operand:GPR 3 "const_int_operand" "n"))))]
3869 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3870 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3872 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3874 [(set_attr "type" "insert")])
3876 ; There are also some forms without one of the ANDs.
3877 (define_insn "*rotl<mode>3_insert_3"
3878 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3879 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3880 (match_operand:GPR 4 "const_int_operand" "n"))
3881 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3882 (match_operand:SI 2 "const_int_operand" "n"))))]
3883 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3885 if (<MODE>mode == SImode)
3886 return "rlwimi %0,%1,%h2,0,31-%h2";
3888 return "rldimi %0,%1,%H2,0";
3890 [(set_attr "type" "insert")])
3892 (define_insn "*rotl<mode>3_insert_4"
3893 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3894 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3895 (match_operand:GPR 4 "const_int_operand" "n"))
3896 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3897 (match_operand:SI 2 "const_int_operand" "n"))))]
3898 "<MODE>mode == SImode &&
3899 GET_MODE_PRECISION (<MODE>mode)
3900 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3902 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3903 - INTVAL (operands[2]));
3904 if (<MODE>mode == SImode)
3905 return "rlwimi %0,%1,%h2,32-%h2,31";
3907 return "rldimi %0,%1,%H2,64-%H2";
3909 [(set_attr "type" "insert")])
3911 (define_insn "*rotlsi3_insert_5"
3912 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3913 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3914 (match_operand:SI 2 "const_int_operand" "n,n"))
3915 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3916 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3917 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3918 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3919 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3923 [(set_attr "type" "insert")])
3925 (define_insn "*rotldi3_insert_6"
3926 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3927 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3928 (match_operand:DI 2 "const_int_operand" "n"))
3929 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3930 (match_operand:DI 4 "const_int_operand" "n"))))]
3931 "exact_log2 (-UINTVAL (operands[2])) > 0
3932 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3934 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3935 return "rldimi %0,%3,0,%5";
3937 [(set_attr "type" "insert")
3938 (set_attr "size" "64")])
3940 (define_insn "*rotldi3_insert_7"
3941 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3942 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3943 (match_operand:DI 4 "const_int_operand" "n"))
3944 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3945 (match_operand:DI 2 "const_int_operand" "n"))))]
3946 "exact_log2 (-UINTVAL (operands[2])) > 0
3947 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3949 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3950 return "rldimi %0,%3,0,%5";
3952 [(set_attr "type" "insert")
3953 (set_attr "size" "64")])
3956 ; This handles the important case of multiple-precision shifts. There is
3957 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3959 [(set (match_operand:GPR 0 "gpc_reg_operand")
3960 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3961 (match_operand:SI 3 "const_int_operand"))
3962 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3963 (match_operand:SI 4 "const_int_operand"))))]
3964 "can_create_pseudo_p ()
3965 && INTVAL (operands[3]) + INTVAL (operands[4])
3966 >= GET_MODE_PRECISION (<MODE>mode)"
3968 (lshiftrt:GPR (match_dup 2)
3971 (ior:GPR (and:GPR (match_dup 5)
3973 (ashift:GPR (match_dup 1)
3976 unsigned HOST_WIDE_INT mask = 1;
3977 mask = (mask << INTVAL (operands[3])) - 1;
3978 operands[5] = gen_reg_rtx (<MODE>mode);
3979 operands[6] = GEN_INT (mask);
3983 [(set (match_operand:GPR 0 "gpc_reg_operand")
3984 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3985 (match_operand:SI 4 "const_int_operand"))
3986 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3987 (match_operand:SI 3 "const_int_operand"))))]
3988 "can_create_pseudo_p ()
3989 && INTVAL (operands[3]) + INTVAL (operands[4])
3990 >= GET_MODE_PRECISION (<MODE>mode)"
3992 (lshiftrt:GPR (match_dup 2)
3995 (ior:GPR (and:GPR (match_dup 5)
3997 (ashift:GPR (match_dup 1)
4000 unsigned HOST_WIDE_INT mask = 1;
4001 mask = (mask << INTVAL (operands[3])) - 1;
4002 operands[5] = gen_reg_rtx (<MODE>mode);
4003 operands[6] = GEN_INT (mask);
4007 ; Another important case is setting some bits to 1; we can do that with
4008 ; an insert instruction, in many cases.
4009 (define_insn_and_split "*ior<mode>_mask"
4010 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4011 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4012 (match_operand:GPR 2 "const_int_operand" "n")))
4013 (clobber (match_scratch:GPR 3 "=r"))]
4014 "!logical_const_operand (operands[2], <MODE>mode)
4015 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4021 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4024 (and:GPR (match_dup 1)
4028 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4029 if (GET_CODE (operands[3]) == SCRATCH)
4030 operands[3] = gen_reg_rtx (<MODE>mode);
4031 operands[4] = GEN_INT (ne);
4032 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4034 [(set_attr "type" "two")
4035 (set_attr "length" "8")])
4038 ;; Now the simple shifts.
4040 (define_insn "rotl<mode>3"
4041 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4042 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4043 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4045 "rotl<wd>%I2 %0,%1,%<hH>2"
4046 [(set_attr "type" "shift")
4047 (set_attr "maybe_var_shift" "yes")])
4049 (define_insn "*rotlsi3_64"
4050 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4052 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4053 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4055 "rotlw%I2 %0,%1,%h2"
4056 [(set_attr "type" "shift")
4057 (set_attr "maybe_var_shift" "yes")])
4059 (define_insn_and_split "*rotl<mode>3_dot"
4060 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4061 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4062 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4064 (clobber (match_scratch:GPR 0 "=r,r"))]
4065 "<MODE>mode == Pmode"
4067 rotl<wd>%I2. %0,%1,%<hH>2
4069 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4071 (rotate:GPR (match_dup 1)
4074 (compare:CC (match_dup 0)
4077 [(set_attr "type" "shift")
4078 (set_attr "maybe_var_shift" "yes")
4079 (set_attr "dot" "yes")
4080 (set_attr "length" "4,8")])
4082 (define_insn_and_split "*rotl<mode>3_dot2"
4083 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4084 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4085 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4087 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4088 (rotate:GPR (match_dup 1)
4090 "<MODE>mode == Pmode"
4092 rotl<wd>%I2. %0,%1,%<hH>2
4094 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4096 (rotate:GPR (match_dup 1)
4099 (compare:CC (match_dup 0)
4102 [(set_attr "type" "shift")
4103 (set_attr "maybe_var_shift" "yes")
4104 (set_attr "dot" "yes")
4105 (set_attr "length" "4,8")])
4108 (define_insn "ashl<mode>3"
4109 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4110 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4111 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4113 "sl<wd>%I2 %0,%1,%<hH>2"
4114 [(set_attr "type" "shift")
4115 (set_attr "maybe_var_shift" "yes")])
4117 (define_insn "*ashlsi3_64"
4118 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4120 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4121 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4124 [(set_attr "type" "shift")
4125 (set_attr "maybe_var_shift" "yes")])
4127 (define_insn_and_split "*ashl<mode>3_dot"
4128 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4129 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4130 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4132 (clobber (match_scratch:GPR 0 "=r,r"))]
4133 "<MODE>mode == Pmode"
4135 sl<wd>%I2. %0,%1,%<hH>2
4137 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4139 (ashift:GPR (match_dup 1)
4142 (compare:CC (match_dup 0)
4145 [(set_attr "type" "shift")
4146 (set_attr "maybe_var_shift" "yes")
4147 (set_attr "dot" "yes")
4148 (set_attr "length" "4,8")])
4150 (define_insn_and_split "*ashl<mode>3_dot2"
4151 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4152 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4153 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4155 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4156 (ashift:GPR (match_dup 1)
4158 "<MODE>mode == Pmode"
4160 sl<wd>%I2. %0,%1,%<hH>2
4162 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4164 (ashift:GPR (match_dup 1)
4167 (compare:CC (match_dup 0)
4170 [(set_attr "type" "shift")
4171 (set_attr "maybe_var_shift" "yes")
4172 (set_attr "dot" "yes")
4173 (set_attr "length" "4,8")])
4175 ;; Pretend we have a memory form of extswsli until register allocation is done
4176 ;; so that we use LWZ to load the value from memory, instead of LWA.
4177 (define_insn_and_split "ashdi3_extswsli"
4178 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4180 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4181 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4186 "&& reload_completed && MEM_P (operands[1])"
4190 (ashift:DI (sign_extend:DI (match_dup 3))
4193 operands[3] = gen_lowpart (SImode, operands[0]);
4195 [(set_attr "type" "shift")
4196 (set_attr "maybe_var_shift" "no")])
4199 (define_insn_and_split "ashdi3_extswsli_dot"
4200 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4203 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4204 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4206 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4213 "&& reload_completed
4214 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4215 || memory_operand (operands[1], SImode))"
4218 rtx dest = operands[0];
4219 rtx src = operands[1];
4220 rtx shift = operands[2];
4221 rtx cr = operands[3];
4228 src2 = gen_lowpart (SImode, dest);
4229 emit_move_insn (src2, src);
4232 if (REGNO (cr) == CR0_REGNO)
4234 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4238 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4239 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4242 [(set_attr "type" "shift")
4243 (set_attr "maybe_var_shift" "no")
4244 (set_attr "dot" "yes")
4245 (set_attr "length" "4,8,8,12")])
4247 (define_insn_and_split "ashdi3_extswsli_dot2"
4248 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4251 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4252 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4254 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4255 (ashift:DI (sign_extend:DI (match_dup 1))
4263 "&& reload_completed
4264 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4265 || memory_operand (operands[1], SImode))"
4268 rtx dest = operands[0];
4269 rtx src = operands[1];
4270 rtx shift = operands[2];
4271 rtx cr = operands[3];
4278 src2 = gen_lowpart (SImode, dest);
4279 emit_move_insn (src2, src);
4282 if (REGNO (cr) == CR0_REGNO)
4284 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4288 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4289 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4292 [(set_attr "type" "shift")
4293 (set_attr "maybe_var_shift" "no")
4294 (set_attr "dot" "yes")
4295 (set_attr "length" "4,8,8,12")])
4297 (define_insn "lshr<mode>3"
4298 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4299 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4300 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4302 "sr<wd>%I2 %0,%1,%<hH>2"
4303 [(set_attr "type" "shift")
4304 (set_attr "maybe_var_shift" "yes")])
4306 (define_insn "*lshrsi3_64"
4307 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4309 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4310 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4313 [(set_attr "type" "shift")
4314 (set_attr "maybe_var_shift" "yes")])
4316 (define_insn_and_split "*lshr<mode>3_dot"
4317 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4318 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4319 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4321 (clobber (match_scratch:GPR 0 "=r,r"))]
4322 "<MODE>mode == Pmode"
4324 sr<wd>%I2. %0,%1,%<hH>2
4326 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4328 (lshiftrt:GPR (match_dup 1)
4331 (compare:CC (match_dup 0)
4334 [(set_attr "type" "shift")
4335 (set_attr "maybe_var_shift" "yes")
4336 (set_attr "dot" "yes")
4337 (set_attr "length" "4,8")])
4339 (define_insn_and_split "*lshr<mode>3_dot2"
4340 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4341 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4342 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4344 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4345 (lshiftrt:GPR (match_dup 1)
4347 "<MODE>mode == Pmode"
4349 sr<wd>%I2. %0,%1,%<hH>2
4351 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4353 (lshiftrt:GPR (match_dup 1)
4356 (compare:CC (match_dup 0)
4359 [(set_attr "type" "shift")
4360 (set_attr "maybe_var_shift" "yes")
4361 (set_attr "dot" "yes")
4362 (set_attr "length" "4,8")])
4365 (define_insn "ashr<mode>3"
4366 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4367 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4368 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4369 (clobber (reg:GPR CA_REGNO))]
4371 "sra<wd>%I2 %0,%1,%<hH>2"
4372 [(set_attr "type" "shift")
4373 (set_attr "maybe_var_shift" "yes")])
4375 (define_insn "*ashrsi3_64"
4376 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4378 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4379 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4380 (clobber (reg:SI CA_REGNO))]
4383 [(set_attr "type" "shift")
4384 (set_attr "maybe_var_shift" "yes")])
4386 (define_insn_and_split "*ashr<mode>3_dot"
4387 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4388 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4389 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4391 (clobber (match_scratch:GPR 0 "=r,r"))
4392 (clobber (reg:GPR CA_REGNO))]
4393 "<MODE>mode == Pmode"
4395 sra<wd>%I2. %0,%1,%<hH>2
4397 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4398 [(parallel [(set (match_dup 0)
4399 (ashiftrt:GPR (match_dup 1)
4401 (clobber (reg:GPR CA_REGNO))])
4403 (compare:CC (match_dup 0)
4406 [(set_attr "type" "shift")
4407 (set_attr "maybe_var_shift" "yes")
4408 (set_attr "dot" "yes")
4409 (set_attr "length" "4,8")])
4411 (define_insn_and_split "*ashr<mode>3_dot2"
4412 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4413 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4414 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4416 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4417 (ashiftrt:GPR (match_dup 1)
4419 (clobber (reg:GPR CA_REGNO))]
4420 "<MODE>mode == Pmode"
4422 sra<wd>%I2. %0,%1,%<hH>2
4424 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4425 [(parallel [(set (match_dup 0)
4426 (ashiftrt:GPR (match_dup 1)
4428 (clobber (reg:GPR CA_REGNO))])
4430 (compare:CC (match_dup 0)
4433 [(set_attr "type" "shift")
4434 (set_attr "maybe_var_shift" "yes")
4435 (set_attr "dot" "yes")
4436 (set_attr "length" "4,8")])
4438 ;; Builtins to replace a division to generate FRE reciprocal estimate
4439 ;; instructions and the necessary fixup instructions
4440 (define_expand "recip<mode>3"
4441 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4442 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4443 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4444 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4446 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4450 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4451 ;; hardware division. This is only done before register allocation and with
4452 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4453 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4454 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4456 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4457 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4458 (match_operand 2 "gpc_reg_operand" "")))]
4459 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4460 && can_create_pseudo_p () && flag_finite_math_only
4461 && !flag_trapping_math && flag_reciprocal_math"
4464 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4468 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4469 ;; appropriate fixup.
4470 (define_expand "rsqrt<mode>2"
4471 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4472 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4473 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4475 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4479 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4480 ;; modes here, and also add in conditional vsx/power8-vector support to access
4481 ;; values in the traditional Altivec registers if the appropriate
4482 ;; -mupper-regs-{df,sf} option is enabled.
4484 (define_expand "abs<mode>2"
4485 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4486 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4487 "TARGET_<MODE>_INSN"
4490 (define_insn "*abs<mode>2_fpr"
4491 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4492 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4497 [(set_attr "type" "fpsimple")
4498 (set_attr "fp_type" "fp_addsub_<Fs>")])
4500 (define_insn "*nabs<mode>2_fpr"
4501 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4504 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4509 [(set_attr "type" "fpsimple")
4510 (set_attr "fp_type" "fp_addsub_<Fs>")])
4512 (define_expand "neg<mode>2"
4513 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4514 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4515 "TARGET_<MODE>_INSN"
4518 (define_insn "*neg<mode>2_fpr"
4519 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4520 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4525 [(set_attr "type" "fpsimple")
4526 (set_attr "fp_type" "fp_addsub_<Fs>")])
4528 (define_expand "add<mode>3"
4529 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4530 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4531 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4532 "TARGET_<MODE>_INSN"
4535 (define_insn "*add<mode>3_fpr"
4536 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4537 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4538 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4541 fadd<Ftrad> %0,%1,%2
4542 xsadd<Fvsx> %x0,%x1,%x2"
4543 [(set_attr "type" "fp")
4544 (set_attr "fp_type" "fp_addsub_<Fs>")])
4546 (define_expand "sub<mode>3"
4547 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4548 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4549 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4550 "TARGET_<MODE>_INSN"
4553 (define_insn "*sub<mode>3_fpr"
4554 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4555 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4556 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4559 fsub<Ftrad> %0,%1,%2
4560 xssub<Fvsx> %x0,%x1,%x2"
4561 [(set_attr "type" "fp")
4562 (set_attr "fp_type" "fp_addsub_<Fs>")])
4564 (define_expand "mul<mode>3"
4565 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4566 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4567 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4568 "TARGET_<MODE>_INSN"
4571 (define_insn "*mul<mode>3_fpr"
4572 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4573 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4574 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4577 fmul<Ftrad> %0,%1,%2
4578 xsmul<Fvsx> %x0,%x1,%x2"
4579 [(set_attr "type" "dmul")
4580 (set_attr "fp_type" "fp_mul_<Fs>")])
4582 (define_expand "div<mode>3"
4583 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4584 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4585 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4586 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4588 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4589 && can_create_pseudo_p () && flag_finite_math_only
4590 && !flag_trapping_math && flag_reciprocal_math)
4592 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4597 (define_insn "*div<mode>3_fpr"
4598 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4599 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4600 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4601 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4603 fdiv<Ftrad> %0,%1,%2
4604 xsdiv<Fvsx> %x0,%x1,%x2"
4605 [(set_attr "type" "<Fs>div")
4606 (set_attr "fp_type" "fp_div_<Fs>")])
4608 (define_insn "*sqrt<mode>2_internal"
4609 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4610 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4611 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4612 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4615 xssqrt<Fvsx> %x0,%x1"
4616 [(set_attr "type" "<Fs>sqrt")
4617 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4619 (define_expand "sqrt<mode>2"
4620 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4621 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4622 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4623 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4625 if (<MODE>mode == SFmode
4626 && TARGET_RECIP_PRECISION
4627 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4628 && !optimize_function_for_size_p (cfun)
4629 && flag_finite_math_only && !flag_trapping_math
4630 && flag_unsafe_math_optimizations)
4632 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4637 ;; Floating point reciprocal approximation
4638 (define_insn "fre<Fs>"
4639 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4640 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4646 [(set_attr "type" "fp")])
4648 (define_insn "*rsqrt<mode>2"
4649 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4650 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4652 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4654 frsqrte<Ftrad> %0,%1
4655 xsrsqrte<Fvsx> %x0,%x1"
4656 [(set_attr "type" "fp")])
4658 ;; Floating point comparisons
4659 (define_insn "*cmp<mode>_fpr"
4660 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4661 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4662 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4666 xscmpudp %0,%x1,%x2"
4667 [(set_attr "type" "fpcompare")])
4669 ;; Floating point conversions
4670 (define_expand "extendsfdf2"
4671 [(set (match_operand:DF 0 "gpc_reg_operand")
4672 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4673 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4675 if (HONOR_SNANS (SFmode))
4676 operands[1] = force_reg (SFmode, operands[1]);
4679 (define_insn_and_split "*extendsfdf2_fpr"
4680 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4681 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4682 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4688 xscpsgndp %x0,%x1,%x1
4691 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4694 emit_note (NOTE_INSN_DELETED);
4697 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4699 (define_insn "*extendsfdf2_snan"
4700 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4701 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4702 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4706 [(set_attr "type" "fp")])
4708 (define_expand "truncdfsf2"
4709 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4710 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4711 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4714 (define_insn "*truncdfsf2_fpr"
4715 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4716 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4717 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4721 [(set_attr "type" "fp")])
4723 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4724 ;; builtins.c and optabs.c that are not correct for IBM long double
4725 ;; when little-endian.
4726 (define_expand "signbit<mode>2"
4728 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4730 (subreg:DI (match_dup 2) 0))
4733 (set (match_operand:SI 0 "gpc_reg_operand" "")
4736 && (!FLOAT128_IEEE_P (<MODE>mode)
4737 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4739 if (FLOAT128_IEEE_P (<MODE>mode))
4741 if (<MODE>mode == KFmode)
4742 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4743 else if (<MODE>mode == TFmode)
4744 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4749 operands[2] = gen_reg_rtx (DFmode);
4750 operands[3] = gen_reg_rtx (DImode);
4751 if (TARGET_POWERPC64)
4753 operands[4] = gen_reg_rtx (DImode);
4754 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4755 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4756 WORDS_BIG_ENDIAN ? 4 : 0);
4760 operands[4] = gen_reg_rtx (SImode);
4761 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4762 WORDS_BIG_ENDIAN ? 0 : 4);
4763 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4767 (define_expand "copysign<mode>3"
4769 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4771 (neg:SFDF (abs:SFDF (match_dup 1))))
4772 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4773 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4777 "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4778 && ((TARGET_PPC_GFXOPT
4779 && !HONOR_NANS (<MODE>mode)
4780 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4782 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4784 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4786 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4791 operands[3] = gen_reg_rtx (<MODE>mode);
4792 operands[4] = gen_reg_rtx (<MODE>mode);
4793 operands[5] = CONST0_RTX (<MODE>mode);
4796 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4798 (define_insn_and_split "signbit<mode>2_dm"
4799 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4801 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4803 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4805 "&& reload_completed"
4808 rs6000_split_signbit (operands[0], operands[1]);
4811 [(set_attr "length" "8,8,4")
4812 (set_attr "type" "mftgpr,load,integer")])
4814 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4815 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4818 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4820 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4822 "&& reload_completed"
4825 rs6000_split_signbit (operands[0], operands[1]);
4828 [(set_attr "length" "8,8,4")
4829 (set_attr "type" "mftgpr,load,integer")])
4831 ;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various
4832 ;; floating point types, which makes normal SUBREG's problematical. Instead
4833 ;; use a special pattern to avoid using a normal movdi.
4834 (define_insn "signbit<mode>2_dm2"
4835 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4836 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4839 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4841 [(set_attr "type" "mftgpr")])
4844 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4845 ;; compiler from optimizing -0.0
4846 (define_insn "copysign<mode>3_fcpsgn"
4847 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4848 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4849 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4851 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4854 xscpsgndp %x0,%x2,%x1"
4855 [(set_attr "type" "fpsimple")])
4857 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4858 ;; fsel instruction and some auxiliary computations. Then we just have a
4859 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4861 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4862 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4863 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4864 ;; define_splits to make them if made by combine. On VSX machines we have the
4865 ;; min/max instructions.
4867 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4868 ;; to allow either DF/SF to use only traditional registers.
4870 (define_expand "s<minmax><mode>3"
4871 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4872 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4873 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4874 "TARGET_MINMAX_<MODE>"
4876 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4880 (define_insn "*s<minmax><mode>3_vsx"
4881 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4882 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4883 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4884 "TARGET_VSX && TARGET_<MODE>_FPR"
4886 return (TARGET_P9_MINMAX
4887 ? "xs<minmax>cdp %x0,%x1,%x2"
4888 : "xs<minmax>dp %x0,%x1,%x2");
4890 [(set_attr "type" "fp")])
4892 ;; The conditional move instructions allow us to perform max and min operations
4893 ;; even when we don't have the appropriate max/min instruction using the FSEL
4896 (define_insn_and_split "*s<minmax><mode>3_fpr"
4897 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4898 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4899 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4900 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4905 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4909 (define_expand "mov<mode>cc"
4910 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4911 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4912 (match_operand:GPR 2 "gpc_reg_operand" "")
4913 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4917 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4923 ;; We use the BASE_REGS for the isel input operands because, if rA is
4924 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4925 ;; because we may switch the operands and rB may end up being rA.
4927 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4928 ;; leave out the mode in operand 4 and use one pattern, but reload can
4929 ;; change the mode underneath our feet and then gets confused trying
4930 ;; to reload the value.
4931 (define_insn "isel_signed_<mode>"
4932 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4934 (match_operator 1 "scc_comparison_operator"
4935 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4937 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4938 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4941 { return output_isel (operands); }"
4942 [(set_attr "type" "isel")
4943 (set_attr "length" "4")])
4945 (define_insn "isel_unsigned_<mode>"
4946 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4948 (match_operator 1 "scc_comparison_operator"
4949 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4951 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4952 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4955 { return output_isel (operands); }"
4956 [(set_attr "type" "isel")
4957 (set_attr "length" "4")])
4959 ;; These patterns can be useful for combine; they let combine know that
4960 ;; isel can handle reversed comparisons so long as the operands are
4963 (define_insn "*isel_reversed_signed_<mode>"
4964 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4966 (match_operator 1 "scc_rev_comparison_operator"
4967 [(match_operand:CC 4 "cc_reg_operand" "y")
4969 (match_operand:GPR 2 "gpc_reg_operand" "b")
4970 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4973 { return output_isel (operands); }"
4974 [(set_attr "type" "isel")
4975 (set_attr "length" "4")])
4977 (define_insn "*isel_reversed_unsigned_<mode>"
4978 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4980 (match_operator 1 "scc_rev_comparison_operator"
4981 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4983 (match_operand:GPR 2 "gpc_reg_operand" "b")
4984 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4987 { return output_isel (operands); }"
4988 [(set_attr "type" "isel")
4989 (set_attr "length" "4")])
4991 ;; Floating point conditional move
4992 (define_expand "mov<mode>cc"
4993 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4994 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4995 (match_operand:SFDF 2 "gpc_reg_operand" "")
4996 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4997 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5000 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5006 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5007 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5009 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5010 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5011 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5012 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5013 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5015 [(set_attr "type" "fp")])
5017 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5018 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5020 (match_operator:CCFP 1 "fpmask_comparison_operator"
5021 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5022 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5023 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5024 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5025 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5030 (if_then_else:V2DI (match_dup 1)
5034 (if_then_else:SFDF (ne (match_dup 6)
5039 if (GET_CODE (operands[6]) == SCRATCH)
5040 operands[6] = gen_reg_rtx (V2DImode);
5042 operands[7] = CONSTM1_RTX (V2DImode);
5043 operands[8] = CONST0_RTX (V2DImode);
5045 [(set_attr "length" "8")
5046 (set_attr "type" "vecperm")])
5048 ;; Handle inverting the fpmask comparisons.
5049 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5050 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5052 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5053 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5054 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5055 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5056 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5057 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5062 (if_then_else:V2DI (match_dup 9)
5066 (if_then_else:SFDF (ne (match_dup 6)
5071 rtx op1 = operands[1];
5072 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
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 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5082 [(set_attr "length" "8")
5083 (set_attr "type" "vecperm")])
5085 (define_insn "*fpmask<mode>"
5086 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5088 (match_operator:CCFP 1 "fpmask_comparison_operator"
5089 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5090 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5091 (match_operand:V2DI 4 "all_ones_constant" "")
5092 (match_operand:V2DI 5 "zero_constant" "")))]
5094 "xscmp%V1dp %x0,%x2,%x3"
5095 [(set_attr "type" "fpcompare")])
5097 (define_insn "*xxsel<mode>"
5098 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5099 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5100 (match_operand:V2DI 2 "zero_constant" ""))
5101 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5102 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5104 "xxsel %x0,%x4,%x3,%x1"
5105 [(set_attr "type" "vecmove")])
5108 ;; Conversions to and from floating-point.
5110 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5111 ; don't want to support putting SImode in FPR registers.
5112 (define_insn "lfiwax"
5113 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5114 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5116 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5122 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5124 ; This split must be run before register allocation because it allocates the
5125 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5126 ; it earlier to allow for the combiner to merge insns together where it might
5127 ; not be needed and also in case the insns are deleted as dead code.
5129 (define_insn_and_split "floatsi<mode>2_lfiwax"
5130 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5131 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5132 (clobber (match_scratch:DI 2 "=wi"))]
5133 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5134 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5140 rtx dest = operands[0];
5141 rtx src = operands[1];
5144 if (!MEM_P (src) && TARGET_POWERPC64
5145 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5146 tmp = convert_to_mode (DImode, src, false);
5150 if (GET_CODE (tmp) == SCRATCH)
5151 tmp = gen_reg_rtx (DImode);
5154 src = rs6000_address_for_fpconvert (src);
5155 emit_insn (gen_lfiwax (tmp, src));
5159 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5160 emit_move_insn (stack, src);
5161 emit_insn (gen_lfiwax (tmp, stack));
5164 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5167 [(set_attr "length" "12")
5168 (set_attr "type" "fpload")])
5170 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5171 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5174 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5175 (clobber (match_scratch:DI 2 "=wi"))]
5176 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5182 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5183 if (GET_CODE (operands[2]) == SCRATCH)
5184 operands[2] = gen_reg_rtx (DImode);
5185 if (TARGET_P8_VECTOR)
5186 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5188 emit_insn (gen_lfiwax (operands[2], operands[1]));
5189 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5192 [(set_attr "length" "8")
5193 (set_attr "type" "fpload")])
5195 (define_insn "lfiwzx"
5196 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5197 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5199 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5204 xxextractuw %x0,%x1,4"
5205 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5207 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5208 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5209 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5210 (clobber (match_scratch:DI 2 "=wi"))]
5211 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5217 rtx dest = operands[0];
5218 rtx src = operands[1];
5221 if (!MEM_P (src) && TARGET_POWERPC64
5222 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5223 tmp = convert_to_mode (DImode, src, true);
5227 if (GET_CODE (tmp) == SCRATCH)
5228 tmp = gen_reg_rtx (DImode);
5231 src = rs6000_address_for_fpconvert (src);
5232 emit_insn (gen_lfiwzx (tmp, src));
5236 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5237 emit_move_insn (stack, src);
5238 emit_insn (gen_lfiwzx (tmp, stack));
5241 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5244 [(set_attr "length" "12")
5245 (set_attr "type" "fpload")])
5247 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5248 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5249 (unsigned_float:SFDF
5251 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5252 (clobber (match_scratch:DI 2 "=wi"))]
5253 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5259 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5260 if (GET_CODE (operands[2]) == SCRATCH)
5261 operands[2] = gen_reg_rtx (DImode);
5262 if (TARGET_P8_VECTOR)
5263 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5265 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5266 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5269 [(set_attr "length" "8")
5270 (set_attr "type" "fpload")])
5272 ; For each of these conversions, there is a define_expand, a define_insn
5273 ; with a '#' template, and a define_split (with C code). The idea is
5274 ; to allow constant folding with the template of the define_insn,
5275 ; then to have the insns split later (between sched1 and final).
5277 (define_expand "floatsidf2"
5278 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5279 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5282 (clobber (match_dup 4))
5283 (clobber (match_dup 5))
5284 (clobber (match_dup 6))])]
5285 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5288 if (TARGET_LFIWAX && TARGET_FCFID)
5290 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5293 else if (TARGET_FCFID)
5295 rtx dreg = operands[1];
5297 dreg = force_reg (SImode, dreg);
5298 dreg = convert_to_mode (DImode, dreg, false);
5299 emit_insn (gen_floatdidf2 (operands[0], dreg));
5303 if (!REG_P (operands[1]))
5304 operands[1] = force_reg (SImode, operands[1]);
5305 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5306 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5307 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5308 operands[5] = gen_reg_rtx (DFmode);
5309 operands[6] = gen_reg_rtx (SImode);
5312 (define_insn_and_split "*floatsidf2_internal"
5313 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5314 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5315 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5316 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5317 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5318 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5319 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5320 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5326 rtx lowword, highword;
5327 gcc_assert (MEM_P (operands[4]));
5328 highword = adjust_address (operands[4], SImode, 0);
5329 lowword = adjust_address (operands[4], SImode, 4);
5330 if (! WORDS_BIG_ENDIAN)
5331 std::swap (lowword, highword);
5333 emit_insn (gen_xorsi3 (operands[6], operands[1],
5334 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5335 emit_move_insn (lowword, operands[6]);
5336 emit_move_insn (highword, operands[2]);
5337 emit_move_insn (operands[5], operands[4]);
5338 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5341 [(set_attr "length" "24")
5342 (set_attr "type" "fp")])
5344 ;; If we don't have a direct conversion to single precision, don't enable this
5345 ;; conversion for 32-bit without fast math, because we don't have the insn to
5346 ;; generate the fixup swizzle to avoid double rounding problems.
5347 (define_expand "floatunssisf2"
5348 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5349 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5350 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5351 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5352 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5353 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5356 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5358 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5363 rtx dreg = operands[1];
5365 dreg = force_reg (SImode, dreg);
5366 dreg = convert_to_mode (DImode, dreg, true);
5367 emit_insn (gen_floatdisf2 (operands[0], dreg));
5372 (define_expand "floatunssidf2"
5373 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5374 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5377 (clobber (match_dup 4))
5378 (clobber (match_dup 5))])]
5379 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5382 if (TARGET_LFIWZX && TARGET_FCFID)
5384 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5387 else if (TARGET_FCFID)
5389 rtx dreg = operands[1];
5391 dreg = force_reg (SImode, dreg);
5392 dreg = convert_to_mode (DImode, dreg, true);
5393 emit_insn (gen_floatdidf2 (operands[0], dreg));
5397 if (!REG_P (operands[1]))
5398 operands[1] = force_reg (SImode, operands[1]);
5399 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5400 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5401 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5402 operands[5] = gen_reg_rtx (DFmode);
5405 (define_insn_and_split "*floatunssidf2_internal"
5406 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5407 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5408 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5409 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5410 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5411 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5412 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5413 && !(TARGET_FCFID && TARGET_POWERPC64)"
5419 rtx lowword, highword;
5420 gcc_assert (MEM_P (operands[4]));
5421 highword = adjust_address (operands[4], SImode, 0);
5422 lowword = adjust_address (operands[4], SImode, 4);
5423 if (! WORDS_BIG_ENDIAN)
5424 std::swap (lowword, highword);
5426 emit_move_insn (lowword, operands[1]);
5427 emit_move_insn (highword, operands[2]);
5428 emit_move_insn (operands[5], operands[4]);
5429 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5432 [(set_attr "length" "20")
5433 (set_attr "type" "fp")])
5435 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5436 ;; vector registers. These insns favor doing the sign/zero extension in
5437 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5438 ;; extension and then a direct move.
5440 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5441 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5443 (match_operand:QHI 1 "input_operand")))
5444 (clobber (match_scratch:DI 2))
5445 (clobber (match_scratch:DI 3))
5446 (clobber (match_scratch:<QHI:MODE> 4))])]
5447 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5449 if (MEM_P (operands[1]))
5450 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5453 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5454 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5456 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5457 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5458 (clobber (match_scratch:DI 3 "=X,r,X"))
5459 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5460 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5462 "&& reload_completed"
5465 rtx result = operands[0];
5466 rtx input = operands[1];
5467 rtx di = operands[2];
5471 rtx tmp = operands[3];
5472 if (altivec_register_operand (input, <QHI:MODE>mode))
5473 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5474 else if (GET_CODE (tmp) == SCRATCH)
5475 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5478 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5479 emit_move_insn (di, tmp);
5484 rtx tmp = operands[4];
5485 emit_move_insn (tmp, input);
5486 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5489 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5493 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5494 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5495 (unsigned_float:FP_ISA3
5496 (match_operand:QHI 1 "input_operand" "")))
5497 (clobber (match_scratch:DI 2 ""))
5498 (clobber (match_scratch:DI 3 ""))])]
5499 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5501 if (MEM_P (operands[1]))
5502 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5505 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5506 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5507 (unsigned_float:FP_ISA3
5508 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5509 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5510 (clobber (match_scratch:DI 3 "=X,r,X"))]
5511 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5513 "&& reload_completed"
5516 rtx result = operands[0];
5517 rtx input = operands[1];
5518 rtx di = operands[2];
5520 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5521 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5524 rtx tmp = operands[3];
5525 if (GET_CODE (tmp) == SCRATCH)
5526 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5529 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5530 emit_move_insn (di, tmp);
5534 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5538 (define_expand "fix_trunc<mode>si2"
5539 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5540 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5541 "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5544 if (!TARGET_P8_VECTOR)
5546 rtx src = force_reg (<MODE>mode, operands[1]);
5549 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5552 rtx tmp = gen_reg_rtx (DImode);
5553 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5554 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5561 ; Like the convert to float patterns, this insn must be split before
5562 ; register allocation so that it can allocate the memory slot if it
5564 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5565 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5566 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5567 (clobber (match_scratch:DI 2 "=d"))]
5568 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5569 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5570 && TARGET_STFIWX && can_create_pseudo_p ()
5571 && !TARGET_P8_VECTOR"
5576 rtx dest = operands[0];
5577 rtx src = operands[1];
5578 rtx tmp = operands[2];
5580 if (GET_CODE (tmp) == SCRATCH)
5581 tmp = gen_reg_rtx (DImode);
5583 emit_insn (gen_fctiwz_<mode> (tmp, src));
5586 dest = rs6000_address_for_fpconvert (dest);
5587 emit_insn (gen_stfiwx (dest, tmp));
5590 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5592 dest = gen_lowpart (DImode, dest);
5593 emit_move_insn (dest, tmp);
5598 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5599 emit_insn (gen_stfiwx (stack, tmp));
5600 emit_move_insn (dest, stack);
5604 [(set_attr "length" "12")
5605 (set_attr "type" "fp")])
5607 (define_insn_and_split "fix_trunc<mode>si2_internal"
5608 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5609 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5610 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5611 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5612 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
5619 gcc_assert (MEM_P (operands[3]));
5620 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5622 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5623 emit_move_insn (operands[3], operands[2]);
5624 emit_move_insn (operands[0], lowword);
5627 [(set_attr "length" "16")
5628 (set_attr "type" "fp")])
5630 (define_expand "fix_trunc<mode>di2"
5631 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5632 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5633 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5636 (define_insn "*fix_trunc<mode>di2_fctidz"
5637 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5638 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5639 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5643 [(set_attr "type" "fp")])
5645 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5646 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5647 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5648 (clobber (match_scratch:DI 2))])]
5649 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5651 if (MEM_P (operands[0]))
5652 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5655 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5656 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5658 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5659 (clobber (match_scratch:DI 2 "=X,wi"))]
5660 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5662 "&& reload_completed"
5665 rtx dest = operands[0];
5666 rtx src = operands[1];
5668 if (vsx_register_operand (dest, <QHI:MODE>mode))
5670 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5671 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5675 rtx tmp = operands[2];
5676 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5678 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5679 emit_move_insn (dest, tmp2);
5684 (define_expand "fixuns_trunc<mode>si2"
5685 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5686 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5687 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5690 if (!TARGET_P8_VECTOR)
5692 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5697 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5698 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5699 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5700 (clobber (match_scratch:DI 2 "=d"))]
5701 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5702 && TARGET_STFIWX && can_create_pseudo_p ()
5703 && !TARGET_P8_VECTOR"
5708 rtx dest = operands[0];
5709 rtx src = operands[1];
5710 rtx tmp = operands[2];
5712 if (GET_CODE (tmp) == SCRATCH)
5713 tmp = gen_reg_rtx (DImode);
5715 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5718 dest = rs6000_address_for_fpconvert (dest);
5719 emit_insn (gen_stfiwx (dest, tmp));
5722 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5724 dest = gen_lowpart (DImode, dest);
5725 emit_move_insn (dest, tmp);
5730 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5731 emit_insn (gen_stfiwx (stack, tmp));
5732 emit_move_insn (dest, stack);
5736 [(set_attr "length" "12")
5737 (set_attr "type" "fp")])
5739 (define_insn "fixuns_trunc<mode>di2"
5740 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5741 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5742 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5746 [(set_attr "type" "fp")])
5748 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5749 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5750 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5751 (clobber (match_scratch:DI 2))])]
5752 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5754 if (MEM_P (operands[0]))
5755 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5758 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5759 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5761 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5762 (clobber (match_scratch:DI 2 "=X,wi"))]
5763 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5765 "&& reload_completed"
5768 rtx dest = operands[0];
5769 rtx src = operands[1];
5771 if (vsx_register_operand (dest, <QHI:MODE>mode))
5773 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5774 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5778 rtx tmp = operands[2];
5779 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5781 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5782 emit_move_insn (dest, tmp2);
5787 ;; If -mvsx-small-integer, we can represent the FIX operation directly. On
5788 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5789 ;; to another location, since SImode is not allowed in vector registers.
5790 (define_insn "*fctiw<u>z_<mode>_smallint"
5791 [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5792 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5793 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5796 xscvdp<su>xws %x0,%x1"
5797 [(set_attr "type" "fp")])
5799 ;; Combiner pattern to prevent moving the result of converting a floating point
5800 ;; value to 32-bit integer to GPR in order to save it.
5801 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5802 [(set (match_operand:SI 0 "memory_operand" "=Z")
5803 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5804 (clobber (match_scratch:SI 2 "=wa"))]
5805 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5807 "&& reload_completed"
5809 (any_fix:SI (match_dup 1)))
5813 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5814 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5815 ;; because the first makes it clear that operand 0 is not live
5816 ;; before the instruction.
5817 (define_insn "fctiwz_<mode>"
5818 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5820 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5822 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5826 [(set_attr "type" "fp")])
5828 (define_insn "fctiwuz_<mode>"
5829 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5830 (unspec:DI [(unsigned_fix:SI
5831 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5833 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5837 [(set_attr "type" "fp")])
5839 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5840 ;; since the friz instruction does not truncate the value if the floating
5841 ;; point value is < LONG_MIN or > LONG_MAX.
5842 (define_insn "*friz"
5843 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5844 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5845 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5846 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5850 [(set_attr "type" "fp")])
5852 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5853 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5854 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5855 ;; extend it, store it back on the stack from the GPR, load it back into the
5856 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5857 ;; disable using store and load to sign/zero extend the value.
5858 (define_insn_and_split "*round32<mode>2_fprs"
5859 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5861 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5862 (clobber (match_scratch:DI 2 "=d"))
5863 (clobber (match_scratch:DI 3 "=d"))]
5864 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5865 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5866 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5871 rtx dest = operands[0];
5872 rtx src = operands[1];
5873 rtx tmp1 = operands[2];
5874 rtx tmp2 = operands[3];
5875 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5877 if (GET_CODE (tmp1) == SCRATCH)
5878 tmp1 = gen_reg_rtx (DImode);
5879 if (GET_CODE (tmp2) == SCRATCH)
5880 tmp2 = gen_reg_rtx (DImode);
5882 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5883 emit_insn (gen_stfiwx (stack, tmp1));
5884 emit_insn (gen_lfiwax (tmp2, stack));
5885 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5888 [(set_attr "type" "fpload")
5889 (set_attr "length" "16")])
5891 (define_insn_and_split "*roundu32<mode>2_fprs"
5892 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5893 (unsigned_float:SFDF
5894 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5895 (clobber (match_scratch:DI 2 "=d"))
5896 (clobber (match_scratch:DI 3 "=d"))]
5897 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5898 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5899 && can_create_pseudo_p ()"
5904 rtx dest = operands[0];
5905 rtx src = operands[1];
5906 rtx tmp1 = operands[2];
5907 rtx tmp2 = operands[3];
5908 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5910 if (GET_CODE (tmp1) == SCRATCH)
5911 tmp1 = gen_reg_rtx (DImode);
5912 if (GET_CODE (tmp2) == SCRATCH)
5913 tmp2 = gen_reg_rtx (DImode);
5915 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5916 emit_insn (gen_stfiwx (stack, tmp1));
5917 emit_insn (gen_lfiwzx (tmp2, stack));
5918 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5921 [(set_attr "type" "fpload")
5922 (set_attr "length" "16")])
5924 (define_insn "lrintsfsi2"
5925 [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
5926 (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")]
5928 "TARGET_SF_FPR && TARGET_FPRND"
5930 [(set_attr "type" "fp")])
5932 ;; No VSX equivalent to fctid
5933 (define_insn "lrint<mode>di2"
5934 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5935 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5937 "TARGET_<MODE>_FPR && TARGET_FPRND"
5939 [(set_attr "type" "fp")])
5941 (define_insn "btrunc<mode>2"
5942 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5943 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5945 "TARGET_<MODE>_FPR && TARGET_FPRND"
5949 [(set_attr "type" "fp")
5950 (set_attr "fp_type" "fp_addsub_<Fs>")])
5952 (define_insn "ceil<mode>2"
5953 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5954 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5956 "TARGET_<MODE>_FPR && TARGET_FPRND"
5960 [(set_attr "type" "fp")
5961 (set_attr "fp_type" "fp_addsub_<Fs>")])
5963 (define_insn "floor<mode>2"
5964 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5965 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5967 "TARGET_<MODE>_FPR && TARGET_FPRND"
5971 [(set_attr "type" "fp")
5972 (set_attr "fp_type" "fp_addsub_<Fs>")])
5974 ;; No VSX equivalent to frin
5975 (define_insn "round<mode>2"
5976 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5977 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5979 "TARGET_<MODE>_FPR && TARGET_FPRND"
5981 [(set_attr "type" "fp")
5982 (set_attr "fp_type" "fp_addsub_<Fs>")])
5984 (define_insn "*xsrdpi<mode>2"
5985 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5986 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5988 "TARGET_<MODE>_FPR && TARGET_VSX"
5990 [(set_attr "type" "fp")
5991 (set_attr "fp_type" "fp_addsub_<Fs>")])
5993 (define_expand "lround<mode>di2"
5995 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5997 (set (match_operand:DI 0 "gpc_reg_operand" "")
5998 (unspec:DI [(match_dup 2)]
6000 "TARGET_<MODE>_FPR && TARGET_VSX"
6002 operands[2] = gen_reg_rtx (<MODE>mode);
6005 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6006 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6007 ; is only generated for Power8 or later.
6008 (define_insn "stfiwx"
6009 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6010 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6016 [(set_attr "type" "fpstore")])
6018 ;; If we don't have a direct conversion to single precision, don't enable this
6019 ;; conversion for 32-bit without fast math, because we don't have the insn to
6020 ;; generate the fixup swizzle to avoid double rounding problems.
6021 (define_expand "floatsisf2"
6022 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6023 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6024 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6025 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6026 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6027 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6030 if (TARGET_FCFIDS && TARGET_LFIWAX)
6032 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6035 else if (TARGET_FCFID && TARGET_LFIWAX)
6037 rtx dfreg = gen_reg_rtx (DFmode);
6038 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6039 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6044 rtx dreg = operands[1];
6046 dreg = force_reg (SImode, dreg);
6047 dreg = convert_to_mode (DImode, dreg, false);
6048 emit_insn (gen_floatdisf2 (operands[0], dreg));
6053 (define_insn "floatdidf2"
6054 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6055 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6056 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6060 [(set_attr "type" "fp")])
6062 ; Allow the combiner to merge source memory operands to the conversion so that
6063 ; the optimizer/register allocator doesn't try to load the value too early in a
6064 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6065 ; hit. We will split after reload to avoid the trip through the GPRs
6067 (define_insn_and_split "*floatdidf2_mem"
6068 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6069 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6070 (clobber (match_scratch:DI 2 "=d,wi"))]
6071 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6073 "&& reload_completed"
6074 [(set (match_dup 2) (match_dup 1))
6075 (set (match_dup 0) (float:DF (match_dup 2)))]
6077 [(set_attr "length" "8")
6078 (set_attr "type" "fpload")])
6080 (define_expand "floatunsdidf2"
6081 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6083 (match_operand:DI 1 "gpc_reg_operand" "")))]
6084 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6087 (define_insn "*floatunsdidf2_fcfidu"
6088 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6089 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6090 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6094 [(set_attr "type" "fp")
6095 (set_attr "length" "4")])
6097 (define_insn_and_split "*floatunsdidf2_mem"
6098 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6099 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6100 (clobber (match_scratch:DI 2 "=d,wi"))]
6101 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6103 "&& reload_completed"
6104 [(set (match_dup 2) (match_dup 1))
6105 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6107 [(set_attr "length" "8")
6108 (set_attr "type" "fpload")])
6110 (define_expand "floatdisf2"
6111 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6112 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6113 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6114 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6119 rtx val = operands[1];
6120 if (!flag_unsafe_math_optimizations)
6122 rtx label = gen_label_rtx ();
6123 val = gen_reg_rtx (DImode);
6124 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6127 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6132 (define_insn "floatdisf2_fcfids"
6133 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6134 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6135 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6136 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6140 [(set_attr "type" "fp")])
6142 (define_insn_and_split "*floatdisf2_mem"
6143 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6144 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6145 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6146 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6147 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6149 "&& reload_completed"
6153 emit_move_insn (operands[2], operands[1]);
6154 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6157 [(set_attr "length" "8")])
6159 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6160 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6161 ;; from double rounding.
6162 ;; Instead of creating a new cpu type for two FP operations, just use fp
6163 (define_insn_and_split "floatdisf2_internal1"
6164 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6165 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6166 (clobber (match_scratch:DF 2 "=d"))]
6167 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6169 "&& reload_completed"
6171 (float:DF (match_dup 1)))
6173 (float_truncate:SF (match_dup 2)))]
6175 [(set_attr "length" "8")
6176 (set_attr "type" "fp")])
6178 ;; Twiddles bits to avoid double rounding.
6179 ;; Bits that might be truncated when converting to DFmode are replaced
6180 ;; by a bit that won't be lost at that stage, but is below the SFmode
6181 ;; rounding position.
6182 (define_expand "floatdisf2_internal2"
6183 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6185 (clobber (reg:DI CA_REGNO))])
6186 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6188 (set (match_dup 3) (plus:DI (match_dup 3)
6190 (set (match_dup 0) (plus:DI (match_dup 0)
6192 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6194 (set (match_dup 0) (ior:DI (match_dup 0)
6196 (set (match_dup 0) (and:DI (match_dup 0)
6198 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6199 (label_ref (match_operand:DI 2 "" ""))
6201 (set (match_dup 0) (match_dup 1))]
6202 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6206 operands[3] = gen_reg_rtx (DImode);
6207 operands[4] = gen_reg_rtx (CCUNSmode);
6210 (define_expand "floatunsdisf2"
6211 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6212 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6213 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6214 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6217 (define_insn "floatunsdisf2_fcfidus"
6218 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6219 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6220 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6221 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6225 [(set_attr "type" "fp")])
6227 (define_insn_and_split "*floatunsdisf2_mem"
6228 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6229 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6230 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6231 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6232 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6234 "&& reload_completed"
6238 emit_move_insn (operands[2], operands[1]);
6239 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6242 [(set_attr "length" "8")
6243 (set_attr "type" "fpload")])
6245 ;; Define the TImode operations that can be done in a small number
6246 ;; of instructions. The & constraints are to prevent the register
6247 ;; allocator from allocating registers that overlap with the inputs
6248 ;; (for example, having an input in 7,8 and an output in 6,7). We
6249 ;; also allow for the output being the same as one of the inputs.
6251 (define_expand "addti3"
6252 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6253 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6254 (match_operand:TI 2 "reg_or_short_operand" "")))]
6257 rtx lo0 = gen_lowpart (DImode, operands[0]);
6258 rtx lo1 = gen_lowpart (DImode, operands[1]);
6259 rtx lo2 = gen_lowpart (DImode, operands[2]);
6260 rtx hi0 = gen_highpart (DImode, operands[0]);
6261 rtx hi1 = gen_highpart (DImode, operands[1]);
6262 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6264 if (!reg_or_short_operand (lo2, DImode))
6265 lo2 = force_reg (DImode, lo2);
6266 if (!adde_operand (hi2, DImode))
6267 hi2 = force_reg (DImode, hi2);
6269 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6270 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6274 (define_expand "subti3"
6275 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6276 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6277 (match_operand:TI 2 "gpc_reg_operand" "")))]
6280 rtx lo0 = gen_lowpart (DImode, operands[0]);
6281 rtx lo1 = gen_lowpart (DImode, operands[1]);
6282 rtx lo2 = gen_lowpart (DImode, operands[2]);
6283 rtx hi0 = gen_highpart (DImode, operands[0]);
6284 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6285 rtx hi2 = gen_highpart (DImode, operands[2]);
6287 if (!reg_or_short_operand (lo1, DImode))
6288 lo1 = force_reg (DImode, lo1);
6289 if (!adde_operand (hi1, DImode))
6290 hi1 = force_reg (DImode, hi1);
6292 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6293 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6297 ;; 128-bit logical operations expanders
6299 (define_expand "and<mode>3"
6300 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6301 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6302 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6306 (define_expand "ior<mode>3"
6307 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6308 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6309 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6313 (define_expand "xor<mode>3"
6314 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6315 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6316 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6320 (define_expand "one_cmpl<mode>2"
6321 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6322 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6326 (define_expand "nor<mode>3"
6327 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6329 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6330 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6334 (define_expand "andc<mode>3"
6335 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6337 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6338 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6342 ;; Power8 vector logical instructions.
6343 (define_expand "eqv<mode>3"
6344 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6346 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6347 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6348 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6351 ;; Rewrite nand into canonical form
6352 (define_expand "nand<mode>3"
6353 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6355 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6356 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6357 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6360 ;; The canonical form is to have the negated element first, so we need to
6361 ;; reverse arguments.
6362 (define_expand "orc<mode>3"
6363 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6365 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6366 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6367 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6370 ;; 128-bit logical operations insns and split operations
6371 (define_insn_and_split "*and<mode>3_internal"
6372 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6374 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6375 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6378 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6379 return "xxland %x0,%x1,%x2";
6381 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6382 return "vand %0,%1,%2";
6386 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6389 rs6000_split_logical (operands, AND, false, false, false);
6394 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6395 (const_string "veclogical")
6396 (const_string "integer")))
6397 (set (attr "length")
6399 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6402 (match_test "TARGET_POWERPC64")
6404 (const_string "16"))))])
6407 (define_insn_and_split "*bool<mode>3_internal"
6408 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6409 (match_operator:BOOL_128 3 "boolean_or_operator"
6410 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6411 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6414 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6415 return "xxl%q3 %x0,%x1,%x2";
6417 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6418 return "v%q3 %0,%1,%2";
6422 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6425 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6430 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6431 (const_string "veclogical")
6432 (const_string "integer")))
6433 (set (attr "length")
6435 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6438 (match_test "TARGET_POWERPC64")
6440 (const_string "16"))))])
6443 (define_insn_and_split "*boolc<mode>3_internal1"
6444 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6445 (match_operator:BOOL_128 3 "boolean_operator"
6447 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6448 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6449 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6451 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6452 return "xxl%q3 %x0,%x1,%x2";
6454 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6455 return "v%q3 %0,%1,%2";
6459 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6460 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6463 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6468 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6469 (const_string "veclogical")
6470 (const_string "integer")))
6471 (set (attr "length")
6473 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6476 (match_test "TARGET_POWERPC64")
6478 (const_string "16"))))])
6480 (define_insn_and_split "*boolc<mode>3_internal2"
6481 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6482 (match_operator:TI2 3 "boolean_operator"
6484 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6485 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6486 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6488 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6491 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6494 [(set_attr "type" "integer")
6495 (set (attr "length")
6497 (match_test "TARGET_POWERPC64")
6499 (const_string "16")))])
6502 (define_insn_and_split "*boolcc<mode>3_internal1"
6503 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6504 (match_operator:BOOL_128 3 "boolean_operator"
6506 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6508 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6509 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6511 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6512 return "xxl%q3 %x0,%x1,%x2";
6514 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6515 return "v%q3 %0,%1,%2";
6519 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6520 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6523 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6528 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6529 (const_string "veclogical")
6530 (const_string "integer")))
6531 (set (attr "length")
6533 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6536 (match_test "TARGET_POWERPC64")
6538 (const_string "16"))))])
6540 (define_insn_and_split "*boolcc<mode>3_internal2"
6541 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6542 (match_operator:TI2 3 "boolean_operator"
6544 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6546 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6547 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6549 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6552 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6555 [(set_attr "type" "integer")
6556 (set (attr "length")
6558 (match_test "TARGET_POWERPC64")
6560 (const_string "16")))])
6564 (define_insn_and_split "*eqv<mode>3_internal1"
6565 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6568 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6569 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6572 if (vsx_register_operand (operands[0], <MODE>mode))
6573 return "xxleqv %x0,%x1,%x2";
6577 "TARGET_P8_VECTOR && reload_completed
6578 && int_reg_operand (operands[0], <MODE>mode)"
6581 rs6000_split_logical (operands, XOR, true, false, false);
6586 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6587 (const_string "veclogical")
6588 (const_string "integer")))
6589 (set (attr "length")
6591 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6594 (match_test "TARGET_POWERPC64")
6596 (const_string "16"))))])
6598 (define_insn_and_split "*eqv<mode>3_internal2"
6599 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6602 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6603 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6606 "reload_completed && !TARGET_P8_VECTOR"
6609 rs6000_split_logical (operands, XOR, true, false, false);
6612 [(set_attr "type" "integer")
6613 (set (attr "length")
6615 (match_test "TARGET_POWERPC64")
6617 (const_string "16")))])
6619 ;; 128-bit one's complement
6620 (define_insn_and_split "*one_cmpl<mode>3_internal"
6621 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6623 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6626 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6627 return "xxlnor %x0,%x1,%x1";
6629 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6630 return "vnor %0,%1,%1";
6634 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6637 rs6000_split_logical (operands, NOT, false, false, false);
6642 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6643 (const_string "veclogical")
6644 (const_string "integer")))
6645 (set (attr "length")
6647 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6650 (match_test "TARGET_POWERPC64")
6652 (const_string "16"))))])
6655 ;; Now define ways of moving data around.
6657 ;; Set up a register with a value from the GOT table
6659 (define_expand "movsi_got"
6660 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6661 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6662 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6663 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6666 if (GET_CODE (operands[1]) == CONST)
6668 rtx offset = const0_rtx;
6669 HOST_WIDE_INT value;
6671 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6672 value = INTVAL (offset);
6675 rtx tmp = (!can_create_pseudo_p ()
6677 : gen_reg_rtx (Pmode));
6678 emit_insn (gen_movsi_got (tmp, operands[1]));
6679 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6684 operands[2] = rs6000_got_register (operands[1]);
6687 (define_insn "*movsi_got_internal"
6688 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6689 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6690 (match_operand:SI 2 "gpc_reg_operand" "b")]
6692 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6693 "lwz %0,%a1@got(%2)"
6694 [(set_attr "type" "load")])
6696 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6697 ;; didn't get allocated to a hard register.
6699 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6700 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6701 (match_operand:SI 2 "memory_operand" "")]
6703 "DEFAULT_ABI == ABI_V4
6705 && reload_completed"
6706 [(set (match_dup 0) (match_dup 2))
6707 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6711 ;; For SI, we special-case integers that can't be loaded in one insn. We
6712 ;; do the load 16-bits at a time. We could do this by loading from memory,
6713 ;; and this is even supposed to be faster, but it is simpler not to get
6714 ;; integers in the TOC.
6715 (define_insn "movsi_low"
6716 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6717 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6718 (match_operand 2 "" ""))))]
6719 "TARGET_MACHO && ! TARGET_64BIT"
6720 "lwz %0,lo16(%2)(%1)"
6721 [(set_attr "type" "load")
6722 (set_attr "length" "4")])
6724 ;; MR LA LWZ LFIWZX LXSIWZX
6725 ;; STW STFIWX STXSIWX LI LIS
6726 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6727 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6728 ;; MF%1 MT%0 MT%0 NOP
6729 (define_insn "*movsi_internal1"
6730 [(set (match_operand:SI 0 "nonimmediate_operand"
6731 "=r, r, r, ?*wI, ?*wH,
6733 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6734 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6737 (match_operand:SI 1 "input_operand"
6744 "!TARGET_SINGLE_FPU &&
6745 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6772 "*, *, load, fpload, fpload,
6773 store, fpstore, fpstore, *, *,
6774 *, veclogical, vecsimple, vecsimple, vecsimple,
6775 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6785 (define_insn "*movsi_internal1_single"
6786 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6787 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6788 "TARGET_SINGLE_FPU &&
6789 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6804 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6805 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6807 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6808 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6810 ;; Because SF values are actually stored as DF values within the vector
6811 ;; registers, we need to convert the value to the vector SF format when
6812 ;; we need to use the bits in a union or similar cases. We only need
6813 ;; to do this transformation when the value is a vector register. Loads,
6814 ;; stores, and transfers within GPRs are assumed to be safe.
6816 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6817 ;; no alternatives, because the call is created as part of secondary_reload,
6818 ;; and operand #2's register class is used to allocate the temporary register.
6819 ;; This function is called before reload, and it creates the temporary as
6822 ;; MR LWZ LFIWZX LXSIWZX STW
6823 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6826 (define_insn_and_split "movsi_from_sf"
6827 [(set (match_operand:SI 0 "nonimmediate_operand"
6828 "=r, r, ?*wI, ?*wH, m,
6829 m, wY, Z, r, ?*wIwH,
6832 (unspec:SI [(match_operand:SF 1 "input_operand"
6834 f, wb, wu, wIwH, wIwH,
6838 (clobber (match_scratch:V4SF 2
6843 "TARGET_NO_SF_SUBREG
6844 && (register_operand (operands[0], SImode)
6845 || register_operand (operands[1], SFmode))"
6858 "&& reload_completed
6859 && int_reg_operand (operands[0], SImode)
6860 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6863 rtx op0 = operands[0];
6864 rtx op1 = operands[1];
6865 rtx op2 = operands[2];
6866 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6867 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6869 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6870 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6874 "*, load, fpload, fpload, store,
6875 fpstore, fpstore, fpstore, mftgpr, fp,
6883 ;; movsi_from_sf with zero extension
6885 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6888 (define_insn_and_split "*movdi_from_sf_zero_ext"
6889 [(set (match_operand:DI 0 "gpc_reg_operand"
6890 "=r, r, ?*wI, ?*wH, r,
6894 (unspec:SI [(match_operand:SF 1 "input_operand"
6897 UNSPEC_SI_FROM_SF)))
6899 (clobber (match_scratch:V4SF 2
6903 "TARGET_DIRECT_MOVE_64BIT
6904 && (register_operand (operands[0], DImode)
6905 || register_operand (operands[1], SImode))"
6914 "&& reload_completed
6915 && register_operand (operands[0], DImode)
6916 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6919 rtx op0 = operands[0];
6920 rtx op1 = operands[1];
6921 rtx op2 = operands[2];
6922 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6924 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6925 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6929 "*, load, fpload, fpload, two,
6936 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6937 ;; moving it to SImode. We can do a SFmode store without having to do the
6938 ;; conversion explicitly. If we are doing a register->register conversion, use
6939 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6940 ;; input will not fit in a SFmode, and the later assumes the value has already
6942 (define_insn "*movsi_from_df"
6943 [(set (match_operand:SI 0 "nonimmediate_operand" "=wa,m,wY,Z")
6944 (unspec:SI [(float_truncate:SF
6945 (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6946 UNSPEC_SI_FROM_SF))]
6948 "TARGET_NO_SF_SUBREG"
6954 [(set_attr "type" "fp,fpstore,fpstore,fpstore")])
6956 ;; Split a load of a large constant into the appropriate two-insn
6960 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6961 (match_operand:SI 1 "const_int_operand" ""))]
6962 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6963 && (INTVAL (operands[1]) & 0xffff) != 0"
6967 (ior:SI (match_dup 0)
6971 if (rs6000_emit_set_const (operands[0], operands[1]))
6977 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6979 [(set (match_operand:DI 0 "altivec_register_operand")
6980 (match_operand:DI 1 "xxspltib_constant_split"))]
6981 "TARGET_P9_VECTOR && reload_completed"
6984 rtx op0 = operands[0];
6985 rtx op1 = operands[1];
6986 int r = REGNO (op0);
6987 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6989 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6990 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6994 (define_insn "*mov<mode>_internal2"
6995 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6996 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6998 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7004 [(set_attr "type" "cmp,logical,cmp")
7005 (set_attr "dot" "yes")
7006 (set_attr "length" "4,4,8")])
7009 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7010 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7012 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7014 [(set (match_dup 0) (match_dup 1))
7016 (compare:CC (match_dup 0)
7020 (define_expand "mov<mode>"
7021 [(set (match_operand:INT 0 "general_operand" "")
7022 (match_operand:INT 1 "any_operand" ""))]
7024 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7026 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7027 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7028 ;; MTVSRWZ MF%1 MT%1 NOP
7029 (define_insn "*mov<mode>_internal"
7030 [(set (match_operand:QHI 0 "nonimmediate_operand"
7031 "=r, r, ?*wJwK, m, Z, r,
7032 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7033 ?*wJwK, r, *c*l, *h")
7035 (match_operand:QHI 1 "input_operand"
7036 "r, m, Z, r, wJwK, i,
7037 wJwK, O, wM, wB, wS, ?*wJwK,
7040 "gpc_reg_operand (operands[0], <MODE>mode)
7041 || gpc_reg_operand (operands[1], <MODE>mode)"
7060 "*, load, fpload, store, fpstore, *,
7061 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7062 mffgpr, mfjmpr, mtjmpr, *")
7070 ;; Here is how to move condition codes around. When we store CC data in
7071 ;; an integer register or memory, we store just the high-order 4 bits.
7072 ;; This lets us not shift in the most common case of CR0.
7073 (define_expand "movcc"
7074 [(set (match_operand:CC 0 "nonimmediate_operand" "")
7075 (match_operand:CC 1 "nonimmediate_operand" ""))]
7079 (define_insn "*movcc_internal1"
7080 [(set (match_operand:CC 0 "nonimmediate_operand"
7081 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7082 (match_operand:CC 1 "general_operand"
7083 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7084 "register_operand (operands[0], CCmode)
7085 || register_operand (operands[1], CCmode)"
7089 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7092 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7100 (cond [(eq_attr "alternative" "0,3")
7101 (const_string "cr_logical")
7102 (eq_attr "alternative" "1,2")
7103 (const_string "mtcr")
7104 (eq_attr "alternative" "6,7")
7105 (const_string "integer")
7106 (eq_attr "alternative" "8")
7107 (const_string "mfjmpr")
7108 (eq_attr "alternative" "9")
7109 (const_string "mtjmpr")
7110 (eq_attr "alternative" "10")
7111 (const_string "load")
7112 (eq_attr "alternative" "11")
7113 (const_string "store")
7114 (match_test "TARGET_MFCRF")
7115 (const_string "mfcrf")
7117 (const_string "mfcr")))
7118 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7120 ;; For floating-point, we normally deal with the floating-point registers
7121 ;; unless -msoft-float is used. The sole exception is that parameter passing
7122 ;; can produce floating-point values in fixed-point registers. Unless the
7123 ;; value is a simple constant or already in memory, we deal with this by
7124 ;; allocating memory and copying the value explicitly via that memory location.
7126 ;; Move 32-bit binary/decimal floating point
7127 (define_expand "mov<mode>"
7128 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7129 (match_operand:FMOVE32 1 "any_operand" ""))]
7131 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7134 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7135 (match_operand:FMOVE32 1 "const_double_operand" ""))]
7137 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7138 || (GET_CODE (operands[0]) == SUBREG
7139 && GET_CODE (SUBREG_REG (operands[0])) == REG
7140 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7141 [(set (match_dup 2) (match_dup 3))]
7146 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7148 if (! TARGET_POWERPC64)
7149 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7151 operands[2] = gen_lowpart (SImode, operands[0]);
7153 operands[3] = gen_int_mode (l, SImode);
7156 ;; Originally, we tried to keep movsf and movsd common, but the differences
7157 ;; addressing was making it rather difficult to hide with mode attributes. In
7158 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7159 ;; before the VSX stores meant that the register allocator would tend to do a
7160 ;; direct move to the GPR (which involves conversion from scalar to
7161 ;; vector/memory formats) to save values in the traditional Altivec registers,
7162 ;; while SDmode had problems on power6 if the GPR store was not first due to
7163 ;; the power6 not having an integer store operation.
7165 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7166 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7167 ;; MR MT<x> MF<x> NOP
7169 (define_insn "movsf_hardfloat"
7170 [(set (match_operand:SF 0 "nonimmediate_operand"
7171 "=!r, f, wb, wu, m, wY,
7172 Z, m, ww, !r, f, ww,
7174 (match_operand:SF 1 "input_operand"
7175 "m, m, wY, Z, f, wb,
7178 "(register_operand (operands[0], SFmode)
7179 || register_operand (operands[1], SFmode))
7180 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7181 && (TARGET_ALLOW_SF_SUBREG
7182 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7195 xscpsgndp %x0,%x1,%x1
7201 "load, fpload, fpload, fpload, fpstore, fpstore,
7202 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7203 *, mtjmpr, mfjmpr, *")])
7205 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7206 ;; FMR MR MT%0 MF%1 NOP
7207 (define_insn "movsd_hardfloat"
7208 [(set (match_operand:SD 0 "nonimmediate_operand"
7209 "=!r, wz, m, Z, ?wh, ?r,
7210 f, !r, *c*l, !r, *h")
7211 (match_operand:SD 1 "input_operand"
7212 "m, Z, r, wx, r, wh,
7214 "(register_operand (operands[0], SDmode)
7215 || register_operand (operands[1], SDmode))
7216 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7230 "load, fpload, store, fpstore, mffgpr, mftgpr,
7231 fpsimple, *, mtjmpr, mfjmpr, *")])
7233 (define_insn "*mov<mode>_softfloat"
7234 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7235 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7236 "(gpc_reg_operand (operands[0], <MODE>mode)
7237 || gpc_reg_operand (operands[1], <MODE>mode))
7238 && TARGET_SOFT_FLOAT"
7250 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7251 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7253 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7254 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7256 ;; Because SF values are actually stored as DF values within the vector
7257 ;; registers, we need to convert the value to the vector SF format when
7258 ;; we need to use the bits in a union or similar cases. We only need
7259 ;; to do this transformation when the value is a vector register. Loads,
7260 ;; stores, and transfers within GPRs are assumed to be safe.
7262 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7263 ;; no alternatives, because the call is created as part of secondary_reload,
7264 ;; and operand #2's register class is used to allocate the temporary register.
7265 ;; This function is called before reload, and it creates the temporary as
7268 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7269 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7270 (define_insn_and_split "movsf_from_si"
7271 [(set (match_operand:SF 0 "nonimmediate_operand"
7272 "=!r, f, wb, wu, m, Z,
7275 (unspec:SF [(match_operand:SI 1 "input_operand"
7280 (clobber (match_scratch:DI 2
7284 "TARGET_NO_SF_SUBREG
7285 && (register_operand (operands[0], SFmode)
7286 || register_operand (operands[1], SImode))"
7299 "&& reload_completed
7300 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7301 && int_reg_operand_not_pseudo (operands[1], SImode)"
7304 rtx op0 = operands[0];
7305 rtx op1 = operands[1];
7306 rtx op2 = operands[2];
7307 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7309 /* Move SF value to upper 32-bits for xscvspdpn. */
7310 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7311 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7312 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7319 "load, fpload, fpload, fpload, store, fpstore,
7320 fpstore, vecfloat, mffgpr, *")])
7323 ;; Move 64-bit binary/decimal floating point
7324 (define_expand "mov<mode>"
7325 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7326 (match_operand:FMOVE64 1 "any_operand" ""))]
7328 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7331 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7332 (match_operand:FMOVE64 1 "const_int_operand" ""))]
7333 "! TARGET_POWERPC64 && reload_completed
7334 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7335 || (GET_CODE (operands[0]) == SUBREG
7336 && GET_CODE (SUBREG_REG (operands[0])) == REG
7337 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7338 [(set (match_dup 2) (match_dup 4))
7339 (set (match_dup 3) (match_dup 1))]
7342 int endian = (WORDS_BIG_ENDIAN == 0);
7343 HOST_WIDE_INT value = INTVAL (operands[1]);
7345 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7346 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7347 operands[4] = GEN_INT (value >> 32);
7348 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7352 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7353 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7354 "! TARGET_POWERPC64 && reload_completed
7355 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7356 || (GET_CODE (operands[0]) == SUBREG
7357 && GET_CODE (SUBREG_REG (operands[0])) == REG
7358 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7359 [(set (match_dup 2) (match_dup 4))
7360 (set (match_dup 3) (match_dup 5))]
7363 int endian = (WORDS_BIG_ENDIAN == 0);
7366 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7368 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7369 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7370 operands[4] = gen_int_mode (l[endian], SImode);
7371 operands[5] = gen_int_mode (l[1 - endian], SImode);
7375 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7376 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7377 "TARGET_POWERPC64 && reload_completed
7378 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7379 || (GET_CODE (operands[0]) == SUBREG
7380 && GET_CODE (SUBREG_REG (operands[0])) == REG
7381 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7382 [(set (match_dup 2) (match_dup 3))]
7385 int endian = (WORDS_BIG_ENDIAN == 0);
7389 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7391 operands[2] = gen_lowpart (DImode, operands[0]);
7392 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7393 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7394 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7396 operands[3] = gen_int_mode (val, DImode);
7399 ;; Don't have reload use general registers to load a constant. It is
7400 ;; less efficient than loading the constant into an FP register, since
7401 ;; it will probably be used there.
7403 ;; The move constraints are ordered to prefer floating point registers before
7404 ;; general purpose registers to avoid doing a store and a load to get the value
7405 ;; into a floating point register when it is needed for a floating point
7406 ;; operation. Prefer traditional floating point registers over VSX registers,
7407 ;; since the D-form version of the memory instructions does not need a GPR for
7408 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7411 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7412 ;; except for 0.0 which can be created on VSX with an xor instruction.
7414 (define_insn "*mov<mode>_hardfloat32"
7415 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7416 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7417 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7418 && (gpc_reg_operand (operands[0], <MODE>mode)
7419 || gpc_reg_operand (operands[1], <MODE>mode))"
7434 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7435 (set_attr "size" "64")
7436 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7438 (define_insn "*mov<mode>_softfloat32"
7439 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7440 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7442 && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7443 && (gpc_reg_operand (operands[0], <MODE>mode)
7444 || gpc_reg_operand (operands[1], <MODE>mode))"
7446 [(set_attr "type" "store,load,two,*,*,*")
7447 (set_attr "length" "8,8,8,8,12,16")])
7449 ; ld/std require word-aligned displacements -> 'Y' constraint.
7450 ; List Y->r and r->Y before r->r for reload.
7451 (define_insn "*mov<mode>_hardfloat64"
7452 [(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>")
7453 (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"))]
7454 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7455 && (gpc_reg_operand (operands[0], <MODE>mode)
7456 || gpc_reg_operand (operands[1], <MODE>mode))"
7478 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7479 (set_attr "size" "64")
7480 (set_attr "length" "4")])
7482 (define_insn "*mov<mode>_softfloat64"
7483 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7484 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7485 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7486 && (gpc_reg_operand (operands[0], <MODE>mode)
7487 || gpc_reg_operand (operands[1], <MODE>mode))"
7498 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7499 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7501 (define_expand "mov<mode>"
7502 [(set (match_operand:FMOVE128 0 "general_operand" "")
7503 (match_operand:FMOVE128 1 "any_operand" ""))]
7505 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7507 ;; It's important to list Y->r and r->Y before r->r because otherwise
7508 ;; reload, given m->r, will try to pick r->r and reload it, which
7509 ;; doesn't make progress.
7511 ;; We can't split little endian direct moves of TDmode, because the words are
7512 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7513 ;; problematical. Don't allow direct move for this case.
7515 (define_insn_and_split "*mov<mode>_64bit_dm"
7516 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7517 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7518 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7519 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7520 && (gpc_reg_operand (operands[0], <MODE>mode)
7521 || gpc_reg_operand (operands[1], <MODE>mode))"
7523 "&& reload_completed"
7525 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7526 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7528 (define_insn_and_split "*movtd_64bit_nodm"
7529 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7530 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7531 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7532 && (gpc_reg_operand (operands[0], TDmode)
7533 || gpc_reg_operand (operands[1], TDmode))"
7535 "&& reload_completed"
7537 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7538 [(set_attr "length" "8,8,8,12,12,8")])
7540 (define_insn_and_split "*mov<mode>_32bit"
7541 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7542 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7543 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7544 && (FLOAT128_2REG_P (<MODE>mode)
7545 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7546 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7547 && (gpc_reg_operand (operands[0], <MODE>mode)
7548 || gpc_reg_operand (operands[1], <MODE>mode))"
7550 "&& reload_completed"
7552 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7553 [(set_attr "length" "8,8,8,8,20,20,16")])
7555 (define_insn_and_split "*mov<mode>_softfloat"
7556 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7557 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7559 && (gpc_reg_operand (operands[0], <MODE>mode)
7560 || gpc_reg_operand (operands[1], <MODE>mode))"
7562 "&& reload_completed"
7564 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7565 [(set_attr "length" "20,20,16")])
7567 (define_expand "extenddf<mode>2"
7568 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7569 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7570 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7572 if (FLOAT128_IEEE_P (<MODE>mode))
7573 rs6000_expand_float128_convert (operands[0], operands[1], false);
7574 else if (TARGET_VSX)
7576 if (<MODE>mode == TFmode)
7577 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7578 else if (<MODE>mode == IFmode)
7579 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7585 rtx zero = gen_reg_rtx (DFmode);
7586 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7588 if (<MODE>mode == TFmode)
7589 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7590 else if (<MODE>mode == IFmode)
7591 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7598 ;; Allow memory operands for the source to be created by the combiner.
7599 (define_insn_and_split "extenddf<mode>2_fprs"
7600 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7601 (float_extend:IBM128
7602 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7603 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7604 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7605 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7607 "&& reload_completed"
7608 [(set (match_dup 3) (match_dup 1))
7609 (set (match_dup 4) (match_dup 2))]
7611 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7612 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7614 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7615 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7618 (define_insn_and_split "extenddf<mode>2_vsx"
7619 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7620 (float_extend:IBM128
7621 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7622 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7624 "&& reload_completed"
7625 [(set (match_dup 2) (match_dup 1))
7626 (set (match_dup 3) (match_dup 4))]
7628 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7629 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7631 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7632 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7633 operands[4] = CONST0_RTX (DFmode);
7636 (define_expand "extendsf<mode>2"
7637 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7638 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7639 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7641 if (FLOAT128_IEEE_P (<MODE>mode))
7642 rs6000_expand_float128_convert (operands[0], operands[1], false);
7645 rtx tmp = gen_reg_rtx (DFmode);
7646 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7647 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7652 (define_expand "trunc<mode>df2"
7653 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7654 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7655 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7657 if (FLOAT128_IEEE_P (<MODE>mode))
7659 rs6000_expand_float128_convert (operands[0], operands[1], false);
7664 (define_insn_and_split "trunc<mode>df2_internal1"
7665 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7667 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7668 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7669 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7673 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7676 emit_note (NOTE_INSN_DELETED);
7679 [(set_attr "type" "fpsimple")])
7681 (define_insn "trunc<mode>df2_internal2"
7682 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7683 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7684 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7685 && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7687 [(set_attr "type" "fp")
7688 (set_attr "fp_type" "fp_addsub_d")])
7690 (define_expand "trunc<mode>sf2"
7691 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7692 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7693 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7695 if (FLOAT128_IEEE_P (<MODE>mode))
7696 rs6000_expand_float128_convert (operands[0], operands[1], false);
7697 else if (<MODE>mode == TFmode)
7698 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7699 else if (<MODE>mode == IFmode)
7700 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7706 (define_insn_and_split "trunc<mode>sf2_fprs"
7707 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7708 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7709 (clobber (match_scratch:DF 2 "=d"))]
7710 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7711 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7713 "&& reload_completed"
7715 (float_truncate:DF (match_dup 1)))
7717 (float_truncate:SF (match_dup 2)))]
7720 (define_expand "floatsi<mode>2"
7721 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7722 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7723 (clobber (match_scratch:DI 2))])]
7724 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7726 rtx op0 = operands[0];
7727 rtx op1 = operands[1];
7729 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7731 else if (FLOAT128_IEEE_P (<MODE>mode))
7733 rs6000_expand_float128_convert (op0, op1, false);
7738 rtx tmp = gen_reg_rtx (DFmode);
7739 expand_float (tmp, op1, false);
7740 if (<MODE>mode == TFmode)
7741 emit_insn (gen_extenddftf2 (op0, tmp));
7742 else if (<MODE>mode == IFmode)
7743 emit_insn (gen_extenddfif2 (op0, tmp));
7750 ; fadd, but rounding towards zero.
7751 ; This is probably not the optimal code sequence.
7752 (define_insn "fix_trunc_helper<mode>"
7753 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7754 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7755 UNSPEC_FIX_TRUNC_TF))
7756 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7757 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7758 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7759 [(set_attr "type" "fp")
7760 (set_attr "length" "20")])
7762 (define_expand "fix_trunc<mode>si2"
7763 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7764 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7765 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7767 rtx op0 = operands[0];
7768 rtx op1 = operands[1];
7770 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7774 if (FLOAT128_IEEE_P (<MODE>mode))
7775 rs6000_expand_float128_convert (op0, op1, false);
7776 else if (<MODE>mode == TFmode)
7777 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7778 else if (<MODE>mode == IFmode)
7779 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7786 (define_expand "fix_trunc<mode>si2_fprs"
7787 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7788 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7789 (clobber (match_dup 2))
7790 (clobber (match_dup 3))
7791 (clobber (match_dup 4))
7792 (clobber (match_dup 5))])]
7793 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7795 operands[2] = gen_reg_rtx (DFmode);
7796 operands[3] = gen_reg_rtx (DFmode);
7797 operands[4] = gen_reg_rtx (DImode);
7798 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7801 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7802 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7803 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7804 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7805 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7806 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7807 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7808 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7814 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7817 gcc_assert (MEM_P (operands[5]));
7818 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7820 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7821 emit_move_insn (operands[5], operands[4]);
7822 emit_move_insn (operands[0], lowword);
7826 (define_expand "fix_trunc<mode>di2"
7827 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7828 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7829 "TARGET_FLOAT128_TYPE"
7831 if (!TARGET_FLOAT128_HW)
7833 rs6000_expand_float128_convert (operands[0], operands[1], false);
7838 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7839 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7840 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7841 "TARGET_FLOAT128_TYPE"
7843 rs6000_expand_float128_convert (operands[0], operands[1], true);
7847 (define_expand "floatdi<mode>2"
7848 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7849 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7850 "TARGET_FLOAT128_TYPE"
7852 if (!TARGET_FLOAT128_HW)
7854 rs6000_expand_float128_convert (operands[0], operands[1], false);
7859 (define_expand "floatunsdi<IEEE128:mode>2"
7860 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7861 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7862 "TARGET_FLOAT128_TYPE"
7864 if (!TARGET_FLOAT128_HW)
7866 rs6000_expand_float128_convert (operands[0], operands[1], true);
7871 (define_expand "floatuns<IEEE128:mode>2"
7872 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7873 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7874 "TARGET_FLOAT128_TYPE"
7876 rtx op0 = operands[0];
7877 rtx op1 = operands[1];
7879 if (TARGET_FLOAT128_HW)
7880 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7882 rs6000_expand_float128_convert (op0, op1, true);
7886 (define_expand "neg<mode>2"
7887 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7888 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7889 "FLOAT128_IEEE_P (<MODE>mode)
7890 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7893 if (FLOAT128_IEEE_P (<MODE>mode))
7895 if (TARGET_FLOAT128_HW)
7897 if (<MODE>mode == TFmode)
7898 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7899 else if (<MODE>mode == KFmode)
7900 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7904 else if (TARGET_FLOAT128_TYPE)
7906 if (<MODE>mode == TFmode)
7907 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7908 else if (<MODE>mode == KFmode)
7909 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7915 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7916 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7918 operands[1], <MODE>mode);
7920 if (target && !rtx_equal_p (target, operands[0]))
7921 emit_move_insn (operands[0], target);
7927 (define_insn "neg<mode>2_internal"
7928 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7929 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7930 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7933 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7934 return \"fneg %L0,%L1\;fneg %0,%1\";
7936 return \"fneg %0,%1\;fneg %L0,%L1\";
7938 [(set_attr "type" "fpsimple")
7939 (set_attr "length" "8")])
7941 (define_expand "abs<mode>2"
7942 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7943 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7944 "FLOAT128_IEEE_P (<MODE>mode)
7945 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7950 if (FLOAT128_IEEE_P (<MODE>mode))
7952 if (TARGET_FLOAT128_HW)
7954 if (<MODE>mode == TFmode)
7955 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7956 else if (<MODE>mode == KFmode)
7957 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7962 else if (TARGET_FLOAT128_TYPE)
7964 if (<MODE>mode == TFmode)
7965 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7966 else if (<MODE>mode == KFmode)
7967 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7976 label = gen_label_rtx ();
7977 if (<MODE>mode == TFmode)
7978 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7979 else if (<MODE>mode == TFmode)
7980 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7987 (define_expand "abs<mode>2_internal"
7988 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7989 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7990 (set (match_dup 3) (match_dup 5))
7991 (set (match_dup 5) (abs:DF (match_dup 5)))
7992 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7993 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7994 (label_ref (match_operand 2 "" ""))
7996 (set (match_dup 6) (neg:DF (match_dup 6)))]
7997 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
8000 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8001 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8002 operands[3] = gen_reg_rtx (DFmode);
8003 operands[4] = gen_reg_rtx (CCFPmode);
8004 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8005 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8009 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8012 (define_expand "ieee_128bit_negative_zero"
8013 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8014 "TARGET_FLOAT128_TYPE"
8016 rtvec v = rtvec_alloc (16);
8019 for (i = 0; i < 16; i++)
8020 RTVEC_ELT (v, i) = const0_rtx;
8022 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8023 RTVEC_ELT (v, high) = GEN_INT (0x80);
8025 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8029 ;; IEEE 128-bit negate
8031 ;; We have 2 insns here for negate and absolute value. The first uses
8032 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8033 ;; insns, and second insn after the first split pass loads up the bit to
8034 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8035 ;; neg/abs to create the constant just once.
8037 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8038 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8039 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8040 (clobber (match_scratch:V16QI 2 "=v"))]
8041 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8044 [(parallel [(set (match_dup 0)
8045 (neg:IEEE128 (match_dup 1)))
8046 (use (match_dup 2))])]
8048 if (GET_CODE (operands[2]) == SCRATCH)
8049 operands[2] = gen_reg_rtx (V16QImode);
8051 operands[3] = gen_reg_rtx (V16QImode);
8052 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8054 [(set_attr "length" "8")
8055 (set_attr "type" "vecsimple")])
8057 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8058 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8059 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8060 (use (match_operand:V16QI 2 "register_operand" "v"))]
8061 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8062 "xxlxor %x0,%x1,%x2"
8063 [(set_attr "type" "veclogical")])
8065 ;; IEEE 128-bit absolute value
8066 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8067 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8068 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8069 (clobber (match_scratch:V16QI 2 "=v"))]
8070 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8073 [(parallel [(set (match_dup 0)
8074 (abs:IEEE128 (match_dup 1)))
8075 (use (match_dup 2))])]
8077 if (GET_CODE (operands[2]) == SCRATCH)
8078 operands[2] = gen_reg_rtx (V16QImode);
8080 operands[3] = gen_reg_rtx (V16QImode);
8081 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8083 [(set_attr "length" "8")
8084 (set_attr "type" "vecsimple")])
8086 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8087 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8088 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8089 (use (match_operand:V16QI 2 "register_operand" "v"))]
8090 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8091 "xxlandc %x0,%x1,%x2"
8092 [(set_attr "type" "veclogical")])
8094 ;; IEEE 128-bit negative absolute value
8095 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8096 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8099 (match_operand:IEEE128 1 "register_operand" "wa"))))
8100 (clobber (match_scratch:V16QI 2 "=v"))]
8101 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8102 && FLOAT128_IEEE_P (<MODE>mode)"
8105 [(parallel [(set (match_dup 0)
8106 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8107 (use (match_dup 2))])]
8109 if (GET_CODE (operands[2]) == SCRATCH)
8110 operands[2] = gen_reg_rtx (V16QImode);
8112 operands[3] = gen_reg_rtx (V16QImode);
8113 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8115 [(set_attr "length" "8")
8116 (set_attr "type" "vecsimple")])
8118 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8119 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8122 (match_operand:IEEE128 1 "register_operand" "wa"))))
8123 (use (match_operand:V16QI 2 "register_operand" "v"))]
8124 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8126 [(set_attr "type" "veclogical")])
8128 ;; Float128 conversion functions. These expand to library function calls.
8129 ;; We use expand to convert from IBM double double to IEEE 128-bit
8130 ;; and trunc for the opposite.
8131 (define_expand "extendiftf2"
8132 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8133 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8134 "TARGET_FLOAT128_TYPE"
8136 rs6000_expand_float128_convert (operands[0], operands[1], false);
8140 (define_expand "extendifkf2"
8141 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8142 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8143 "TARGET_FLOAT128_TYPE"
8145 rs6000_expand_float128_convert (operands[0], operands[1], false);
8149 (define_expand "extendtfkf2"
8150 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8151 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8152 "TARGET_FLOAT128_TYPE"
8154 rs6000_expand_float128_convert (operands[0], operands[1], false);
8158 (define_expand "trunciftf2"
8159 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8160 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8161 "TARGET_FLOAT128_TYPE"
8163 rs6000_expand_float128_convert (operands[0], operands[1], false);
8167 (define_expand "truncifkf2"
8168 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8169 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8170 "TARGET_FLOAT128_TYPE"
8172 rs6000_expand_float128_convert (operands[0], operands[1], false);
8176 (define_expand "trunckftf2"
8177 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8178 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8179 "TARGET_FLOAT128_TYPE"
8181 rs6000_expand_float128_convert (operands[0], operands[1], false);
8185 (define_expand "trunctfif2"
8186 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8187 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8188 "TARGET_FLOAT128_TYPE"
8190 rs6000_expand_float128_convert (operands[0], operands[1], false);
8195 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8196 ;; must have 3 arguments, and scratch register constraint must be a single
8199 ;; Reload patterns to support gpr load/store with misaligned mem.
8200 ;; and multiple gpr load/store at offset >= 0xfffc
8201 (define_expand "reload_<mode>_store"
8202 [(parallel [(match_operand 0 "memory_operand" "=m")
8203 (match_operand 1 "gpc_reg_operand" "r")
8204 (match_operand:GPR 2 "register_operand" "=&b")])]
8207 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8211 (define_expand "reload_<mode>_load"
8212 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8213 (match_operand 1 "memory_operand" "m")
8214 (match_operand:GPR 2 "register_operand" "=b")])]
8217 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8222 ;; Reload patterns for various types using the vector registers. We may need
8223 ;; an additional base register to convert the reg+offset addressing to reg+reg
8224 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8225 ;; index register for gpr registers.
8226 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8227 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8228 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8229 (match_operand:P 2 "register_operand" "=b")])]
8232 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8236 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8237 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8238 (match_operand:RELOAD 1 "memory_operand" "m")
8239 (match_operand:P 2 "register_operand" "=b")])]
8242 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8247 ;; Reload sometimes tries to move the address to a GPR, and can generate
8248 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8249 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8251 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8252 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8253 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8254 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8256 "TARGET_ALTIVEC && reload_completed"
8258 "&& reload_completed"
8260 (plus:P (match_dup 1)
8263 (and:P (match_dup 0)
8266 ;; Power8 merge instructions to allow direct move to/from floating point
8267 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8268 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8269 ;; value, since it is allocated in reload and not all of the flow information
8270 ;; is setup for it. We have two patterns to do the two moves between gprs and
8271 ;; fprs. There isn't a dependancy between the two, but we could potentially
8272 ;; schedule other instructions between the two instructions.
8274 (define_insn "p8_fmrgow_<mode>"
8275 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8277 (match_operand:DF 1 "register_operand" "d")
8278 (match_operand:DF 2 "register_operand" "d")]
8279 UNSPEC_P8V_FMRGOW))]
8280 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8282 [(set_attr "type" "fpsimple")])
8284 (define_insn "p8_mtvsrwz"
8285 [(set (match_operand:DF 0 "register_operand" "=d")
8286 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8287 UNSPEC_P8V_MTVSRWZ))]
8288 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8290 [(set_attr "type" "mftgpr")])
8292 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8293 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8294 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8295 UNSPEC_P8V_RELOAD_FROM_GPR))
8296 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8297 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8299 "&& reload_completed"
8302 rtx dest = operands[0];
8303 rtx src = operands[1];
8304 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8305 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8306 rtx gpr_hi_reg = gen_highpart (SImode, src);
8307 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8309 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8310 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8311 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8314 [(set_attr "length" "12")
8315 (set_attr "type" "three")])
8317 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8318 (define_insn "p8_mtvsrd_df"
8319 [(set (match_operand:DF 0 "register_operand" "=wa")
8320 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8321 UNSPEC_P8V_MTVSRD))]
8322 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8324 [(set_attr "type" "mftgpr")])
8326 (define_insn "p8_xxpermdi_<mode>"
8327 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8328 (unspec:FMOVE128_GPR [
8329 (match_operand:DF 1 "register_operand" "wa")
8330 (match_operand:DF 2 "register_operand" "wa")]
8331 UNSPEC_P8V_XXPERMDI))]
8332 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8333 "xxpermdi %x0,%x1,%x2,0"
8334 [(set_attr "type" "vecperm")])
8336 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8337 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8338 (unspec:FMOVE128_GPR
8339 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8340 UNSPEC_P8V_RELOAD_FROM_GPR))
8341 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8342 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8344 "&& reload_completed"
8347 rtx dest = operands[0];
8348 rtx src = operands[1];
8349 /* You might think that we could use op0 as one temp and a DF clobber
8350 as op2, but you'd be wrong. Secondary reload move patterns don't
8351 check for overlap of the clobber and the destination. */
8352 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8353 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8354 rtx gpr_hi_reg = gen_highpart (DImode, src);
8355 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8357 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8358 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8359 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8362 [(set_attr "length" "12")
8363 (set_attr "type" "three")])
8366 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8367 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8369 && (int_reg_operand (operands[0], <MODE>mode)
8370 || int_reg_operand (operands[1], <MODE>mode))
8371 && (!TARGET_DIRECT_MOVE_128
8372 || (!vsx_register_operand (operands[0], <MODE>mode)
8373 && !vsx_register_operand (operands[1], <MODE>mode)))"
8375 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8377 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8378 ;; type is stored internally as double precision in the VSX registers, we have
8379 ;; to convert it from the vector format.
8380 (define_insn "p8_mtvsrd_sf"
8381 [(set (match_operand:SF 0 "register_operand" "=wa")
8382 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8383 UNSPEC_P8V_MTVSRD))]
8384 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8386 [(set_attr "type" "mftgpr")])
8388 (define_insn_and_split "reload_vsx_from_gprsf"
8389 [(set (match_operand:SF 0 "register_operand" "=wa")
8390 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8391 UNSPEC_P8V_RELOAD_FROM_GPR))
8392 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8393 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8395 "&& reload_completed"
8398 rtx op0 = operands[0];
8399 rtx op1 = operands[1];
8400 rtx op2 = operands[2];
8401 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8403 /* Move SF value to upper 32-bits for xscvspdpn. */
8404 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8405 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8406 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8409 [(set_attr "length" "8")
8410 (set_attr "type" "two")])
8412 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8413 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8414 ;; and then doing a move of that.
8415 (define_insn "p8_mfvsrd_3_<mode>"
8416 [(set (match_operand:DF 0 "register_operand" "=r")
8417 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8418 UNSPEC_P8V_RELOAD_FROM_VSX))]
8419 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8421 [(set_attr "type" "mftgpr")])
8423 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8424 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8425 (unspec:FMOVE128_GPR
8426 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8427 UNSPEC_P8V_RELOAD_FROM_VSX))
8428 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8429 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8431 "&& reload_completed"
8434 rtx dest = operands[0];
8435 rtx src = operands[1];
8436 rtx tmp = operands[2];
8437 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8438 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8440 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8441 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8442 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8445 [(set_attr "length" "12")
8446 (set_attr "type" "three")])
8448 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8449 ;; type is stored internally as double precision, we have to convert it to the
8452 (define_insn_and_split "reload_gpr_from_vsxsf"
8453 [(set (match_operand:SF 0 "register_operand" "=r")
8454 (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8455 UNSPEC_P8V_RELOAD_FROM_VSX))
8456 (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8457 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8459 "&& reload_completed"
8462 rtx op0 = operands[0];
8463 rtx op1 = operands[1];
8464 rtx op2 = operands[2];
8465 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8466 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8468 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8469 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8472 [(set_attr "length" "8")
8473 (set_attr "type" "two")])
8476 ;; Next come the multi-word integer load and store and the load and store
8479 ;; List r->r after r->Y, otherwise reload will try to reload a
8480 ;; non-offsettable address by using r->r which won't make progress.
8481 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8482 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8484 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8485 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8486 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8489 (define_insn "*movdi_internal32"
8490 [(set (match_operand:DI 0 "nonimmediate_operand"
8491 "=Y, r, r, ^m, ^d, ^d,
8492 r, ^wY, $Z, ^wb, $wv, ^wi,
8493 *wo, *wo, *wv, *wi, *wi, *wv,
8496 (match_operand:DI 1 "input_operand"
8498 IJKnGHF, wb, wv, wY, Z, wi,
8499 Oj, wM, OjwM, Oj, wM, wS,
8503 && (gpc_reg_operand (operands[0], DImode)
8504 || gpc_reg_operand (operands[1], DImode))"
8526 "store, load, *, fpstore, fpload, fpsimple,
8527 *, fpstore, fpstore, fpload, fpload, veclogical,
8528 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8530 (set_attr "size" "64")])
8533 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8534 (match_operand:DI 1 "const_int_operand" ""))]
8535 "! TARGET_POWERPC64 && reload_completed
8536 && gpr_or_gpr_p (operands[0], operands[1])
8537 && !direct_move_p (operands[0], operands[1])"
8538 [(set (match_dup 2) (match_dup 4))
8539 (set (match_dup 3) (match_dup 1))]
8542 HOST_WIDE_INT value = INTVAL (operands[1]);
8543 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8545 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8547 operands[4] = GEN_INT (value >> 32);
8548 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8552 [(set (match_operand:DIFD 0 "nonimmediate_operand" "")
8553 (match_operand:DIFD 1 "input_operand" ""))]
8554 "reload_completed && !TARGET_POWERPC64
8555 && gpr_or_gpr_p (operands[0], operands[1])
8556 && !direct_move_p (operands[0], operands[1])"
8558 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8560 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8561 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8562 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8563 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8564 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8565 (define_insn "*movdi_internal64"
8566 [(set (match_operand:DI 0 "nonimmediate_operand"
8568 ^m, ^d, ^d, ^wY, $Z, $wb,
8569 $wv, ^wi, *wo, *wo, *wv, *wi,
8570 *wi, *wv, *wv, r, *h, *h,
8571 ?*r, ?*wg, ?*r, ?*wj")
8573 (match_operand:DI 1 "input_operand"
8575 d, m, d, wb, wv, wY,
8576 Z, wi, Oj, wM, OjwM, Oj,
8577 wM, wS, wB, *h, r, 0,
8581 && (gpc_reg_operand (operands[0], DImode)
8582 || gpc_reg_operand (operands[1], DImode))"
8613 "store, load, *, *, *, *,
8614 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8615 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8616 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8617 mftgpr, mffgpr, mftgpr, mffgpr")
8619 (set_attr "size" "64")
8627 ; Some DImode loads are best done as a load of -1 followed by a mask
8630 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8631 (match_operand:DI 1 "const_int_operand"))]
8633 && num_insns_constant (operands[1], DImode) > 1
8634 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8635 && rs6000_is_valid_and_mask (operands[1], DImode)"
8639 (and:DI (match_dup 0)
8643 ;; Split a load of a large constant into the appropriate five-instruction
8644 ;; sequence. Handle anything in a constant number of insns.
8645 ;; When non-easy constants can go in the TOC, this should use
8646 ;; easy_fp_constant predicate.
8648 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8649 (match_operand:DI 1 "const_int_operand" ""))]
8650 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8651 [(set (match_dup 0) (match_dup 2))
8652 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8655 if (rs6000_emit_set_const (operands[0], operands[1]))
8662 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8663 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8664 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8665 [(set (match_dup 0) (match_dup 2))
8666 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8669 if (rs6000_emit_set_const (operands[0], operands[1]))
8676 [(set (match_operand:DI 0 "altivec_register_operand" "")
8677 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8678 "TARGET_VSX && reload_completed"
8681 rtx op0 = operands[0];
8682 rtx op1 = operands[1];
8683 int r = REGNO (op0);
8684 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8686 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8687 if (op1 != const0_rtx && op1 != constm1_rtx)
8689 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8690 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8695 ;; Split integer constants that can be loaded with XXSPLTIB and a
8696 ;; sign extend operation.
8698 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8699 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8700 "TARGET_P9_VECTOR && reload_completed"
8703 rtx op0 = operands[0];
8704 rtx op1 = operands[1];
8705 int r = REGNO (op0);
8706 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8708 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8709 if (<MODE>mode == DImode)
8710 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8711 else if (<MODE>mode == SImode)
8712 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8713 else if (<MODE>mode == HImode)
8715 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8716 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8722 ;; TImode/PTImode is similar, except that we usually want to compute the
8723 ;; address into a register and use lsi/stsi (the exception is during reload).
8725 (define_insn "*mov<mode>_string"
8726 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8727 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8729 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8730 && (gpc_reg_operand (operands[0], <MODE>mode)
8731 || gpc_reg_operand (operands[1], <MODE>mode))"
8734 switch (which_alternative)
8740 return \"stswi %1,%P0,16\";
8745 /* If the address is not used in the output, we can use lsi. Otherwise,
8746 fall through to generating four loads. */
8748 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8749 return \"lswi %0,%P1,16\";
8757 [(set_attr "type" "store,store,load,load,*,*")
8758 (set_attr "update" "yes")
8759 (set_attr "indexed" "yes")
8760 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8761 (const_string "always")
8762 (const_string "conditional")))])
8764 (define_insn "*mov<mode>_ppc64"
8765 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8766 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8767 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8768 && (gpc_reg_operand (operands[0], <MODE>mode)
8769 || gpc_reg_operand (operands[1], <MODE>mode)))"
8771 return rs6000_output_move_128bit (operands);
8773 [(set_attr "type" "store,store,load,load,*,*")
8774 (set_attr "length" "8")])
8777 [(set (match_operand:TI2 0 "int_reg_operand" "")
8778 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8780 && (VECTOR_MEM_NONE_P (<MODE>mode)
8781 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8782 [(set (match_dup 2) (match_dup 4))
8783 (set (match_dup 3) (match_dup 5))]
8786 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8788 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8790 if (CONST_WIDE_INT_P (operands[1]))
8792 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8793 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8795 else if (CONST_INT_P (operands[1]))
8797 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8798 operands[5] = operands[1];
8805 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8806 (match_operand:TI2 1 "input_operand" ""))]
8808 && gpr_or_gpr_p (operands[0], operands[1])
8809 && !direct_move_p (operands[0], operands[1])
8810 && !quad_load_store_p (operands[0], operands[1])"
8812 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8814 (define_expand "load_multiple"
8815 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8816 (match_operand:SI 1 "" ""))
8817 (use (match_operand:SI 2 "" ""))])]
8818 "TARGET_STRING && !TARGET_POWERPC64"
8826 /* Support only loading a constant number of fixed-point registers from
8827 memory and only bother with this if more than two; the machine
8828 doesn't support more than eight. */
8829 if (GET_CODE (operands[2]) != CONST_INT
8830 || INTVAL (operands[2]) <= 2
8831 || INTVAL (operands[2]) > 8
8832 || GET_CODE (operands[1]) != MEM
8833 || GET_CODE (operands[0]) != REG
8834 || REGNO (operands[0]) >= 32)
8837 count = INTVAL (operands[2]);
8838 regno = REGNO (operands[0]);
8840 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8841 op1 = replace_equiv_address (operands[1],
8842 force_reg (SImode, XEXP (operands[1], 0)));
8844 for (i = 0; i < count; i++)
8845 XVECEXP (operands[3], 0, i)
8846 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8847 adjust_address_nv (op1, SImode, i * 4));
8850 (define_insn "*ldmsi8"
8851 [(match_parallel 0 "load_multiple_operation"
8852 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8853 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8854 (set (match_operand:SI 3 "gpc_reg_operand" "")
8855 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8856 (set (match_operand:SI 4 "gpc_reg_operand" "")
8857 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8858 (set (match_operand:SI 5 "gpc_reg_operand" "")
8859 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8860 (set (match_operand:SI 6 "gpc_reg_operand" "")
8861 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8862 (set (match_operand:SI 7 "gpc_reg_operand" "")
8863 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8864 (set (match_operand:SI 8 "gpc_reg_operand" "")
8865 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8866 (set (match_operand:SI 9 "gpc_reg_operand" "")
8867 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8868 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8870 { return rs6000_output_load_multiple (operands); }"
8871 [(set_attr "type" "load")
8872 (set_attr "update" "yes")
8873 (set_attr "indexed" "yes")
8874 (set_attr "length" "32")])
8876 (define_insn "*ldmsi7"
8877 [(match_parallel 0 "load_multiple_operation"
8878 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8879 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8880 (set (match_operand:SI 3 "gpc_reg_operand" "")
8881 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8882 (set (match_operand:SI 4 "gpc_reg_operand" "")
8883 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8884 (set (match_operand:SI 5 "gpc_reg_operand" "")
8885 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8886 (set (match_operand:SI 6 "gpc_reg_operand" "")
8887 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8888 (set (match_operand:SI 7 "gpc_reg_operand" "")
8889 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8890 (set (match_operand:SI 8 "gpc_reg_operand" "")
8891 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8892 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8894 { return rs6000_output_load_multiple (operands); }"
8895 [(set_attr "type" "load")
8896 (set_attr "update" "yes")
8897 (set_attr "indexed" "yes")
8898 (set_attr "length" "32")])
8900 (define_insn "*ldmsi6"
8901 [(match_parallel 0 "load_multiple_operation"
8902 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8903 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8904 (set (match_operand:SI 3 "gpc_reg_operand" "")
8905 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8906 (set (match_operand:SI 4 "gpc_reg_operand" "")
8907 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8908 (set (match_operand:SI 5 "gpc_reg_operand" "")
8909 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8910 (set (match_operand:SI 6 "gpc_reg_operand" "")
8911 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8912 (set (match_operand:SI 7 "gpc_reg_operand" "")
8913 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8914 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8916 { return rs6000_output_load_multiple (operands); }"
8917 [(set_attr "type" "load")
8918 (set_attr "update" "yes")
8919 (set_attr "indexed" "yes")
8920 (set_attr "length" "32")])
8922 (define_insn "*ldmsi5"
8923 [(match_parallel 0 "load_multiple_operation"
8924 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8925 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8926 (set (match_operand:SI 3 "gpc_reg_operand" "")
8927 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8928 (set (match_operand:SI 4 "gpc_reg_operand" "")
8929 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8930 (set (match_operand:SI 5 "gpc_reg_operand" "")
8931 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8932 (set (match_operand:SI 6 "gpc_reg_operand" "")
8933 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8934 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8936 { return rs6000_output_load_multiple (operands); }"
8937 [(set_attr "type" "load")
8938 (set_attr "update" "yes")
8939 (set_attr "indexed" "yes")
8940 (set_attr "length" "32")])
8942 (define_insn "*ldmsi4"
8943 [(match_parallel 0 "load_multiple_operation"
8944 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8945 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8946 (set (match_operand:SI 3 "gpc_reg_operand" "")
8947 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8948 (set (match_operand:SI 4 "gpc_reg_operand" "")
8949 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8950 (set (match_operand:SI 5 "gpc_reg_operand" "")
8951 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8952 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8954 { return rs6000_output_load_multiple (operands); }"
8955 [(set_attr "type" "load")
8956 (set_attr "update" "yes")
8957 (set_attr "indexed" "yes")
8958 (set_attr "length" "32")])
8960 (define_insn "*ldmsi3"
8961 [(match_parallel 0 "load_multiple_operation"
8962 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8963 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8964 (set (match_operand:SI 3 "gpc_reg_operand" "")
8965 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8966 (set (match_operand:SI 4 "gpc_reg_operand" "")
8967 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8968 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8970 { return rs6000_output_load_multiple (operands); }"
8971 [(set_attr "type" "load")
8972 (set_attr "update" "yes")
8973 (set_attr "indexed" "yes")
8974 (set_attr "length" "32")])
8976 (define_expand "store_multiple"
8977 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8978 (match_operand:SI 1 "" ""))
8979 (clobber (scratch:SI))
8980 (use (match_operand:SI 2 "" ""))])]
8981 "TARGET_STRING && !TARGET_POWERPC64"
8990 /* Support only storing a constant number of fixed-point registers to
8991 memory and only bother with this if more than two; the machine
8992 doesn't support more than eight. */
8993 if (GET_CODE (operands[2]) != CONST_INT
8994 || INTVAL (operands[2]) <= 2
8995 || INTVAL (operands[2]) > 8
8996 || GET_CODE (operands[0]) != MEM
8997 || GET_CODE (operands[1]) != REG
8998 || REGNO (operands[1]) >= 32)
9001 count = INTVAL (operands[2]);
9002 regno = REGNO (operands[1]);
9004 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9005 to = force_reg (SImode, XEXP (operands[0], 0));
9006 op0 = replace_equiv_address (operands[0], to);
9008 XVECEXP (operands[3], 0, 0)
9009 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
9010 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9011 gen_rtx_SCRATCH (SImode));
9013 for (i = 1; i < count; i++)
9014 XVECEXP (operands[3], 0, i + 1)
9015 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9016 gen_rtx_REG (SImode, regno + i));
9019 (define_insn "*stmsi8"
9020 [(match_parallel 0 "store_multiple_operation"
9021 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9022 (match_operand:SI 2 "gpc_reg_operand" "r"))
9023 (clobber (match_scratch:SI 3 "=X"))
9024 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9025 (match_operand:SI 4 "gpc_reg_operand" "r"))
9026 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9027 (match_operand:SI 5 "gpc_reg_operand" "r"))
9028 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9029 (match_operand:SI 6 "gpc_reg_operand" "r"))
9030 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9031 (match_operand:SI 7 "gpc_reg_operand" "r"))
9032 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9033 (match_operand:SI 8 "gpc_reg_operand" "r"))
9034 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9035 (match_operand:SI 9 "gpc_reg_operand" "r"))
9036 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9037 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9038 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9040 [(set_attr "type" "store")
9041 (set_attr "update" "yes")
9042 (set_attr "indexed" "yes")
9043 (set_attr "cell_micro" "always")])
9045 (define_insn "*stmsi7"
9046 [(match_parallel 0 "store_multiple_operation"
9047 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9048 (match_operand:SI 2 "gpc_reg_operand" "r"))
9049 (clobber (match_scratch:SI 3 "=X"))
9050 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9051 (match_operand:SI 4 "gpc_reg_operand" "r"))
9052 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9053 (match_operand:SI 5 "gpc_reg_operand" "r"))
9054 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9055 (match_operand:SI 6 "gpc_reg_operand" "r"))
9056 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9057 (match_operand:SI 7 "gpc_reg_operand" "r"))
9058 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9059 (match_operand:SI 8 "gpc_reg_operand" "r"))
9060 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9061 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9062 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9064 [(set_attr "type" "store")
9065 (set_attr "update" "yes")
9066 (set_attr "indexed" "yes")
9067 (set_attr "cell_micro" "always")])
9069 (define_insn "*stmsi6"
9070 [(match_parallel 0 "store_multiple_operation"
9071 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9072 (match_operand:SI 2 "gpc_reg_operand" "r"))
9073 (clobber (match_scratch:SI 3 "=X"))
9074 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9075 (match_operand:SI 4 "gpc_reg_operand" "r"))
9076 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9077 (match_operand:SI 5 "gpc_reg_operand" "r"))
9078 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9079 (match_operand:SI 6 "gpc_reg_operand" "r"))
9080 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9081 (match_operand:SI 7 "gpc_reg_operand" "r"))
9082 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9083 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9084 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9086 [(set_attr "type" "store")
9087 (set_attr "update" "yes")
9088 (set_attr "indexed" "yes")
9089 (set_attr "cell_micro" "always")])
9091 (define_insn "*stmsi5"
9092 [(match_parallel 0 "store_multiple_operation"
9093 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9094 (match_operand:SI 2 "gpc_reg_operand" "r"))
9095 (clobber (match_scratch:SI 3 "=X"))
9096 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9097 (match_operand:SI 4 "gpc_reg_operand" "r"))
9098 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9099 (match_operand:SI 5 "gpc_reg_operand" "r"))
9100 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9101 (match_operand:SI 6 "gpc_reg_operand" "r"))
9102 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9103 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9104 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9106 [(set_attr "type" "store")
9107 (set_attr "update" "yes")
9108 (set_attr "indexed" "yes")
9109 (set_attr "cell_micro" "always")])
9111 (define_insn "*stmsi4"
9112 [(match_parallel 0 "store_multiple_operation"
9113 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9114 (match_operand:SI 2 "gpc_reg_operand" "r"))
9115 (clobber (match_scratch:SI 3 "=X"))
9116 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9117 (match_operand:SI 4 "gpc_reg_operand" "r"))
9118 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9119 (match_operand:SI 5 "gpc_reg_operand" "r"))
9120 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9121 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9122 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9124 [(set_attr "type" "store")
9125 (set_attr "update" "yes")
9126 (set_attr "indexed" "yes")
9127 (set_attr "cell_micro" "always")])
9129 (define_insn "*stmsi3"
9130 [(match_parallel 0 "store_multiple_operation"
9131 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9132 (match_operand:SI 2 "gpc_reg_operand" "r"))
9133 (clobber (match_scratch:SI 3 "=X"))
9134 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9135 (match_operand:SI 4 "gpc_reg_operand" "r"))
9136 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9137 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9138 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9140 [(set_attr "type" "store")
9141 (set_attr "update" "yes")
9142 (set_attr "indexed" "yes")
9143 (set_attr "cell_micro" "always")])
9145 (define_expand "setmemsi"
9146 [(parallel [(set (match_operand:BLK 0 "" "")
9147 (match_operand 2 "const_int_operand" ""))
9148 (use (match_operand:SI 1 "" ""))
9149 (use (match_operand:SI 3 "" ""))])]
9153 /* If value to set is not zero, use the library routine. */
9154 if (operands[2] != const0_rtx)
9157 if (expand_block_clear (operands))
9163 ;; String compare N insn.
9164 ;; Argument 0 is the target (result)
9165 ;; Argument 1 is the destination
9166 ;; Argument 2 is the source
9167 ;; Argument 3 is the length
9168 ;; Argument 4 is the alignment
9170 (define_expand "cmpstrnsi"
9171 [(parallel [(set (match_operand:SI 0)
9172 (compare:SI (match_operand:BLK 1)
9173 (match_operand:BLK 2)))
9174 (use (match_operand:SI 3))
9175 (use (match_operand:SI 4))])]
9176 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9178 if (optimize_insn_for_size_p ())
9181 if (expand_strn_compare (operands, 0))
9187 ;; String compare insn.
9188 ;; Argument 0 is the target (result)
9189 ;; Argument 1 is the destination
9190 ;; Argument 2 is the source
9191 ;; Argument 3 is the alignment
9193 (define_expand "cmpstrsi"
9194 [(parallel [(set (match_operand:SI 0)
9195 (compare:SI (match_operand:BLK 1)
9196 (match_operand:BLK 2)))
9197 (use (match_operand:SI 3))])]
9198 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9200 if (optimize_insn_for_size_p ())
9203 if (expand_strn_compare (operands, 1))
9209 ;; Block compare insn.
9210 ;; Argument 0 is the target (result)
9211 ;; Argument 1 is the destination
9212 ;; Argument 2 is the source
9213 ;; Argument 3 is the length
9214 ;; Argument 4 is the alignment
9216 (define_expand "cmpmemsi"
9217 [(parallel [(set (match_operand:SI 0)
9218 (compare:SI (match_operand:BLK 1)
9219 (match_operand:BLK 2)))
9220 (use (match_operand:SI 3))
9221 (use (match_operand:SI 4))])]
9224 if (expand_block_compare (operands))
9230 ;; String/block move insn.
9231 ;; Argument 0 is the destination
9232 ;; Argument 1 is the source
9233 ;; Argument 2 is the length
9234 ;; Argument 3 is the alignment
9236 (define_expand "movmemsi"
9237 [(parallel [(set (match_operand:BLK 0 "" "")
9238 (match_operand:BLK 1 "" ""))
9239 (use (match_operand:SI 2 "" ""))
9240 (use (match_operand:SI 3 "" ""))])]
9244 if (expand_block_move (operands))
9250 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
9251 ;; register allocator doesn't have a clue about allocating 8 word registers.
9252 ;; rD/rS = r5 is preferred, efficient form.
9253 (define_expand "movmemsi_8reg"
9254 [(parallel [(set (match_operand 0 "" "")
9255 (match_operand 1 "" ""))
9256 (use (match_operand 2 "" ""))
9257 (use (match_operand 3 "" ""))
9258 (clobber (reg:SI 5))
9259 (clobber (reg:SI 6))
9260 (clobber (reg:SI 7))
9261 (clobber (reg:SI 8))
9262 (clobber (reg:SI 9))
9263 (clobber (reg:SI 10))
9264 (clobber (reg:SI 11))
9265 (clobber (reg:SI 12))
9266 (clobber (match_scratch:SI 4 ""))])]
9271 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9272 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9273 (use (match_operand:SI 2 "immediate_operand" "i"))
9274 (use (match_operand:SI 3 "immediate_operand" "i"))
9275 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9276 (clobber (reg:SI 6))
9277 (clobber (reg:SI 7))
9278 (clobber (reg:SI 8))
9279 (clobber (reg:SI 9))
9280 (clobber (reg:SI 10))
9281 (clobber (reg:SI 11))
9282 (clobber (reg:SI 12))
9283 (clobber (match_scratch:SI 5 "=X"))]
9285 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9286 || INTVAL (operands[2]) == 0)
9287 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9288 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9289 && REGNO (operands[4]) == 5"
9290 "lswi %4,%1,%2\;stswi %4,%0,%2"
9291 [(set_attr "type" "store")
9292 (set_attr "update" "yes")
9293 (set_attr "indexed" "yes")
9294 (set_attr "cell_micro" "always")
9295 (set_attr "length" "8")])
9297 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
9298 ;; register allocator doesn't have a clue about allocating 6 word registers.
9299 ;; rD/rS = r5 is preferred, efficient form.
9300 (define_expand "movmemsi_6reg"
9301 [(parallel [(set (match_operand 0 "" "")
9302 (match_operand 1 "" ""))
9303 (use (match_operand 2 "" ""))
9304 (use (match_operand 3 "" ""))
9305 (clobber (reg:SI 5))
9306 (clobber (reg:SI 6))
9307 (clobber (reg:SI 7))
9308 (clobber (reg:SI 8))
9309 (clobber (reg:SI 9))
9310 (clobber (reg:SI 10))
9311 (clobber (match_scratch:SI 4 ""))])]
9316 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9317 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9318 (use (match_operand:SI 2 "immediate_operand" "i"))
9319 (use (match_operand:SI 3 "immediate_operand" "i"))
9320 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9321 (clobber (reg:SI 6))
9322 (clobber (reg:SI 7))
9323 (clobber (reg:SI 8))
9324 (clobber (reg:SI 9))
9325 (clobber (reg:SI 10))
9326 (clobber (match_scratch:SI 5 "=X"))]
9328 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9329 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9330 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9331 && REGNO (operands[4]) == 5"
9332 "lswi %4,%1,%2\;stswi %4,%0,%2"
9333 [(set_attr "type" "store")
9334 (set_attr "update" "yes")
9335 (set_attr "indexed" "yes")
9336 (set_attr "cell_micro" "always")
9337 (set_attr "length" "8")])
9339 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9340 ;; problems with TImode.
9341 ;; rD/rS = r5 is preferred, efficient form.
9342 (define_expand "movmemsi_4reg"
9343 [(parallel [(set (match_operand 0 "" "")
9344 (match_operand 1 "" ""))
9345 (use (match_operand 2 "" ""))
9346 (use (match_operand 3 "" ""))
9347 (clobber (reg:SI 5))
9348 (clobber (reg:SI 6))
9349 (clobber (reg:SI 7))
9350 (clobber (reg:SI 8))
9351 (clobber (match_scratch:SI 4 ""))])]
9356 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9357 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9358 (use (match_operand:SI 2 "immediate_operand" "i"))
9359 (use (match_operand:SI 3 "immediate_operand" "i"))
9360 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9361 (clobber (reg:SI 6))
9362 (clobber (reg:SI 7))
9363 (clobber (reg:SI 8))
9364 (clobber (match_scratch:SI 5 "=X"))]
9366 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9367 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9368 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9369 && REGNO (operands[4]) == 5"
9370 "lswi %4,%1,%2\;stswi %4,%0,%2"
9371 [(set_attr "type" "store")
9372 (set_attr "update" "yes")
9373 (set_attr "indexed" "yes")
9374 (set_attr "cell_micro" "always")
9375 (set_attr "length" "8")])
9377 ;; Move up to 8 bytes at a time.
9378 (define_expand "movmemsi_2reg"
9379 [(parallel [(set (match_operand 0 "" "")
9380 (match_operand 1 "" ""))
9381 (use (match_operand 2 "" ""))
9382 (use (match_operand 3 "" ""))
9383 (clobber (match_scratch:DI 4 ""))
9384 (clobber (match_scratch:SI 5 ""))])]
9385 "TARGET_STRING && ! TARGET_POWERPC64"
9389 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9390 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9391 (use (match_operand:SI 2 "immediate_operand" "i"))
9392 (use (match_operand:SI 3 "immediate_operand" "i"))
9393 (clobber (match_scratch:DI 4 "=&r"))
9394 (clobber (match_scratch:SI 5 "=X"))]
9395 "TARGET_STRING && ! TARGET_POWERPC64
9396 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9397 "lswi %4,%1,%2\;stswi %4,%0,%2"
9398 [(set_attr "type" "store")
9399 (set_attr "update" "yes")
9400 (set_attr "indexed" "yes")
9401 (set_attr "cell_micro" "always")
9402 (set_attr "length" "8")])
9404 ;; Move up to 4 bytes at a time.
9405 (define_expand "movmemsi_1reg"
9406 [(parallel [(set (match_operand 0 "" "")
9407 (match_operand 1 "" ""))
9408 (use (match_operand 2 "" ""))
9409 (use (match_operand 3 "" ""))
9410 (clobber (match_scratch:SI 4 ""))
9411 (clobber (match_scratch:SI 5 ""))])]
9416 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9417 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9418 (use (match_operand:SI 2 "immediate_operand" "i"))
9419 (use (match_operand:SI 3 "immediate_operand" "i"))
9420 (clobber (match_scratch:SI 4 "=&r"))
9421 (clobber (match_scratch:SI 5 "=X"))]
9422 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9423 "lswi %4,%1,%2\;stswi %4,%0,%2"
9424 [(set_attr "type" "store")
9425 (set_attr "update" "yes")
9426 (set_attr "indexed" "yes")
9427 (set_attr "cell_micro" "always")
9428 (set_attr "length" "8")])
9430 ;; Define insns that do load or store with update. Some of these we can
9431 ;; get by using pre-decrement or pre-increment, but the hardware can also
9432 ;; do cases where the increment is not the size of the object.
9434 ;; In all these cases, we use operands 0 and 1 for the register being
9435 ;; incremented because those are the operands that local-alloc will
9436 ;; tie and these are the pair most likely to be tieable (and the ones
9437 ;; that will benefit the most).
9439 (define_insn "*movdi_update1"
9440 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9441 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9442 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9443 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9444 (plus:DI (match_dup 1) (match_dup 2)))]
9445 "TARGET_POWERPC64 && TARGET_UPDATE
9446 && (!avoiding_indexed_address_p (DImode)
9447 || !gpc_reg_operand (operands[2], DImode))"
9451 [(set_attr "type" "load")
9452 (set_attr "update" "yes")
9453 (set_attr "indexed" "yes,no")])
9455 (define_insn "movdi_<mode>_update"
9456 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9457 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9458 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9459 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9460 (plus:P (match_dup 1) (match_dup 2)))]
9461 "TARGET_POWERPC64 && TARGET_UPDATE
9462 && (!avoiding_indexed_address_p (Pmode)
9463 || !gpc_reg_operand (operands[2], Pmode)
9464 || (REG_P (operands[0])
9465 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9469 [(set_attr "type" "store")
9470 (set_attr "update" "yes")
9471 (set_attr "indexed" "yes,no")])
9473 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9474 ;; needed for stack allocation, even if the user passes -mno-update.
9475 (define_insn "movdi_<mode>_update_stack"
9476 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9477 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9478 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9479 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9480 (plus:P (match_dup 1) (match_dup 2)))]
9485 [(set_attr "type" "store")
9486 (set_attr "update" "yes")
9487 (set_attr "indexed" "yes,no")])
9489 (define_insn "*movsi_update1"
9490 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9491 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9492 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9493 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9494 (plus:SI (match_dup 1) (match_dup 2)))]
9496 && (!avoiding_indexed_address_p (SImode)
9497 || !gpc_reg_operand (operands[2], SImode))"
9501 [(set_attr "type" "load")
9502 (set_attr "update" "yes")
9503 (set_attr "indexed" "yes,no")])
9505 (define_insn "*movsi_update2"
9506 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9508 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9509 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9510 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9511 (plus:DI (match_dup 1) (match_dup 2)))]
9512 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9514 [(set_attr "type" "load")
9515 (set_attr "sign_extend" "yes")
9516 (set_attr "update" "yes")
9517 (set_attr "indexed" "yes")])
9519 (define_insn "movsi_update"
9520 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9521 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9522 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9523 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9524 (plus:SI (match_dup 1) (match_dup 2)))]
9526 && (!avoiding_indexed_address_p (SImode)
9527 || !gpc_reg_operand (operands[2], SImode)
9528 || (REG_P (operands[0])
9529 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9533 [(set_attr "type" "store")
9534 (set_attr "update" "yes")
9535 (set_attr "indexed" "yes,no")])
9537 ;; This is an unconditional pattern; needed for stack allocation, even
9538 ;; if the user passes -mno-update.
9539 (define_insn "movsi_update_stack"
9540 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9541 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9542 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9543 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9544 (plus:SI (match_dup 1) (match_dup 2)))]
9549 [(set_attr "type" "store")
9550 (set_attr "update" "yes")
9551 (set_attr "indexed" "yes,no")])
9553 (define_insn "*movhi_update1"
9554 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9555 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9556 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9557 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9558 (plus:SI (match_dup 1) (match_dup 2)))]
9560 && (!avoiding_indexed_address_p (SImode)
9561 || !gpc_reg_operand (operands[2], SImode))"
9565 [(set_attr "type" "load")
9566 (set_attr "update" "yes")
9567 (set_attr "indexed" "yes,no")])
9569 (define_insn "*movhi_update2"
9570 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9572 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9573 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9574 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9575 (plus:SI (match_dup 1) (match_dup 2)))]
9577 && (!avoiding_indexed_address_p (SImode)
9578 || !gpc_reg_operand (operands[2], SImode))"
9582 [(set_attr "type" "load")
9583 (set_attr "update" "yes")
9584 (set_attr "indexed" "yes,no")])
9586 (define_insn "*movhi_update3"
9587 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9589 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9590 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9591 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9592 (plus:SI (match_dup 1) (match_dup 2)))]
9594 && !(avoiding_indexed_address_p (SImode)
9595 && gpc_reg_operand (operands[2], SImode))"
9599 [(set_attr "type" "load")
9600 (set_attr "sign_extend" "yes")
9601 (set_attr "update" "yes")
9602 (set_attr "indexed" "yes,no")])
9604 (define_insn "*movhi_update4"
9605 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9606 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9607 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9608 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9609 (plus:SI (match_dup 1) (match_dup 2)))]
9611 && (!avoiding_indexed_address_p (SImode)
9612 || !gpc_reg_operand (operands[2], SImode))"
9616 [(set_attr "type" "store")
9617 (set_attr "update" "yes")
9618 (set_attr "indexed" "yes,no")])
9620 (define_insn "*movqi_update1"
9621 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9622 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9623 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9624 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9625 (plus:SI (match_dup 1) (match_dup 2)))]
9627 && (!avoiding_indexed_address_p (SImode)
9628 || !gpc_reg_operand (operands[2], SImode))"
9632 [(set_attr "type" "load")
9633 (set_attr "update" "yes")
9634 (set_attr "indexed" "yes,no")])
9636 (define_insn "*movqi_update2"
9637 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9639 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9640 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9641 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9642 (plus:SI (match_dup 1) (match_dup 2)))]
9644 && (!avoiding_indexed_address_p (SImode)
9645 || !gpc_reg_operand (operands[2], SImode))"
9649 [(set_attr "type" "load")
9650 (set_attr "update" "yes")
9651 (set_attr "indexed" "yes,no")])
9653 (define_insn "*movqi_update3"
9654 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9655 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9656 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9657 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9658 (plus:SI (match_dup 1) (match_dup 2)))]
9660 && (!avoiding_indexed_address_p (SImode)
9661 || !gpc_reg_operand (operands[2], SImode))"
9665 [(set_attr "type" "store")
9666 (set_attr "update" "yes")
9667 (set_attr "indexed" "yes,no")])
9669 (define_insn "*movsf_update1"
9670 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9671 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9672 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9673 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9674 (plus:SI (match_dup 1) (match_dup 2)))]
9675 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9676 && (!avoiding_indexed_address_p (SImode)
9677 || !gpc_reg_operand (operands[2], SImode))"
9681 [(set_attr "type" "fpload")
9682 (set_attr "update" "yes")
9683 (set_attr "indexed" "yes,no")])
9685 (define_insn "*movsf_update2"
9686 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9687 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9688 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9689 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9690 (plus:SI (match_dup 1) (match_dup 2)))]
9691 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9692 && (!avoiding_indexed_address_p (SImode)
9693 || !gpc_reg_operand (operands[2], SImode))"
9697 [(set_attr "type" "fpstore")
9698 (set_attr "update" "yes")
9699 (set_attr "indexed" "yes,no")])
9701 (define_insn "*movsf_update3"
9702 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9703 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9704 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9705 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9706 (plus:SI (match_dup 1) (match_dup 2)))]
9707 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9708 && (!avoiding_indexed_address_p (SImode)
9709 || !gpc_reg_operand (operands[2], SImode))"
9713 [(set_attr "type" "load")
9714 (set_attr "update" "yes")
9715 (set_attr "indexed" "yes,no")])
9717 (define_insn "*movsf_update4"
9718 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9719 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9720 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9721 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9722 (plus:SI (match_dup 1) (match_dup 2)))]
9723 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9724 && (!avoiding_indexed_address_p (SImode)
9725 || !gpc_reg_operand (operands[2], SImode))"
9729 [(set_attr "type" "store")
9730 (set_attr "update" "yes")
9731 (set_attr "indexed" "yes,no")])
9733 (define_insn "*movdf_update1"
9734 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9735 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9736 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9737 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9738 (plus:SI (match_dup 1) (match_dup 2)))]
9739 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9740 && (!avoiding_indexed_address_p (SImode)
9741 || !gpc_reg_operand (operands[2], SImode))"
9745 [(set_attr "type" "fpload")
9746 (set_attr "update" "yes")
9747 (set_attr "indexed" "yes,no")
9748 (set_attr "size" "64")])
9750 (define_insn "*movdf_update2"
9751 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9752 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9753 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9754 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9755 (plus:SI (match_dup 1) (match_dup 2)))]
9756 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9757 && (!avoiding_indexed_address_p (SImode)
9758 || !gpc_reg_operand (operands[2], SImode))"
9762 [(set_attr "type" "fpstore")
9763 (set_attr "update" "yes")
9764 (set_attr "indexed" "yes,no")])
9767 ;; After inserting conditional returns we can sometimes have
9768 ;; unnecessary register moves. Unfortunately we cannot have a
9769 ;; modeless peephole here, because some single SImode sets have early
9770 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9771 ;; sequences, using get_attr_length here will smash the operands
9772 ;; array. Neither is there an early_cobbler_p predicate.
9773 ;; Also this optimization interferes with scalars going into
9774 ;; altivec registers (the code does reloading through the FPRs).
9776 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9777 (match_operand:DF 1 "any_operand" ""))
9778 (set (match_operand:DF 2 "gpc_reg_operand" "")
9781 && peep2_reg_dead_p (2, operands[0])"
9782 [(set (match_dup 2) (match_dup 1))])
9785 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9786 (match_operand:SF 1 "any_operand" ""))
9787 (set (match_operand:SF 2 "gpc_reg_operand" "")
9790 && peep2_reg_dead_p (2, operands[0])"
9791 [(set (match_dup 2) (match_dup 1))])
9796 ;; Mode attributes for different ABIs.
9797 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9798 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9799 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9800 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9802 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9803 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9804 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9805 (match_operand 4 "" "g")))
9806 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9807 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9809 (clobber (reg:SI LR_REGNO))]
9810 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9812 if (TARGET_CMODEL != CMODEL_SMALL)
9813 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9816 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9818 "&& TARGET_TLS_MARKERS"
9820 (unspec:TLSmode [(match_dup 1)
9823 (parallel [(set (match_dup 0)
9824 (call (mem:TLSmode (match_dup 3))
9826 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9827 (clobber (reg:SI LR_REGNO))])]
9829 [(set_attr "type" "two")
9830 (set (attr "length")
9831 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9835 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9836 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9837 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9838 (match_operand 4 "" "g")))
9839 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9840 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9842 (clobber (reg:SI LR_REGNO))]
9843 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9847 if (TARGET_SECURE_PLT && flag_pic == 2)
9848 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9850 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9853 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9855 "&& TARGET_TLS_MARKERS"
9857 (unspec:TLSmode [(match_dup 1)
9860 (parallel [(set (match_dup 0)
9861 (call (mem:TLSmode (match_dup 3))
9863 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9864 (clobber (reg:SI LR_REGNO))])]
9866 [(set_attr "type" "two")
9867 (set_attr "length" "8")])
9869 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9870 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9871 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9872 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9874 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9875 "addi %0,%1,%2@got@tlsgd"
9876 "&& TARGET_CMODEL != CMODEL_SMALL"
9879 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9881 (lo_sum:TLSmode (match_dup 3)
9882 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9885 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9887 [(set (attr "length")
9888 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9892 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9893 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9895 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9896 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9898 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9899 "addis %0,%1,%2@got@tlsgd@ha"
9900 [(set_attr "length" "4")])
9902 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9903 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9904 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9905 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9906 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9908 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9909 "addi %0,%1,%2@got@tlsgd@l"
9910 [(set_attr "length" "4")])
9912 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9913 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9914 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9915 (match_operand 2 "" "g")))
9916 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9918 (clobber (reg:SI LR_REGNO))]
9919 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9920 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9921 "bl %z1(%3@tlsgd)\;nop"
9922 [(set_attr "type" "branch")
9923 (set_attr "length" "8")])
9925 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9926 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9927 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9928 (match_operand 2 "" "g")))
9929 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9931 (clobber (reg:SI LR_REGNO))]
9932 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9936 if (TARGET_SECURE_PLT && flag_pic == 2)
9937 return "bl %z1+32768(%3@tlsgd)@plt";
9938 return "bl %z1(%3@tlsgd)@plt";
9940 return "bl %z1(%3@tlsgd)";
9942 [(set_attr "type" "branch")
9943 (set_attr "length" "4")])
9945 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9946 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9947 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9948 (match_operand 3 "" "g")))
9949 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9951 (clobber (reg:SI LR_REGNO))]
9952 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9954 if (TARGET_CMODEL != CMODEL_SMALL)
9955 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9958 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9960 "&& TARGET_TLS_MARKERS"
9962 (unspec:TLSmode [(match_dup 1)]
9964 (parallel [(set (match_dup 0)
9965 (call (mem:TLSmode (match_dup 2))
9967 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9968 (clobber (reg:SI LR_REGNO))])]
9970 [(set_attr "type" "two")
9971 (set (attr "length")
9972 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9976 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9977 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9978 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9979 (match_operand 3 "" "g")))
9980 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9982 (clobber (reg:SI LR_REGNO))]
9983 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9987 if (TARGET_SECURE_PLT && flag_pic == 2)
9988 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9990 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9993 return "addi %0,%1,%&@got@tlsld\;bl %z2";
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 "length" "8")])
10007 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10008 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10009 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10011 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10012 "addi %0,%1,%&@got@tlsld"
10013 "&& TARGET_CMODEL != CMODEL_SMALL"
10014 [(set (match_dup 2)
10016 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10018 (lo_sum:TLSmode (match_dup 2)
10019 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10022 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10024 [(set (attr "length")
10025 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10029 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10030 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10032 (unspec:TLSmode [(const_int 0)
10033 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10035 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10036 "addis %0,%1,%&@got@tlsld@ha"
10037 [(set_attr "length" "4")])
10039 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10040 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10041 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10042 (unspec:TLSmode [(const_int 0)
10043 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10045 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10046 "addi %0,%1,%&@got@tlsld@l"
10047 [(set_attr "length" "4")])
10049 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10050 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10051 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10052 (match_operand 2 "" "g")))
10053 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10054 (clobber (reg:SI LR_REGNO))]
10055 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10056 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10057 "bl %z1(%&@tlsld)\;nop"
10058 [(set_attr "type" "branch")
10059 (set_attr "length" "8")])
10061 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10062 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10063 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10064 (match_operand 2 "" "g")))
10065 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10066 (clobber (reg:SI LR_REGNO))]
10067 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10071 if (TARGET_SECURE_PLT && flag_pic == 2)
10072 return "bl %z1+32768(%&@tlsld)@plt";
10073 return "bl %z1(%&@tlsld)@plt";
10075 return "bl %z1(%&@tlsld)";
10077 [(set_attr "type" "branch")
10078 (set_attr "length" "4")])
10080 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10081 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10082 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10083 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10084 UNSPEC_TLSDTPREL))]
10086 "addi %0,%1,%2@dtprel")
10088 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10089 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10090 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10091 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10092 UNSPEC_TLSDTPRELHA))]
10094 "addis %0,%1,%2@dtprel@ha")
10096 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10097 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10098 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10099 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10100 UNSPEC_TLSDTPRELLO))]
10102 "addi %0,%1,%2@dtprel@l")
10104 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10105 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10106 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10107 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10108 UNSPEC_TLSGOTDTPREL))]
10110 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10111 "&& TARGET_CMODEL != CMODEL_SMALL"
10112 [(set (match_dup 3)
10114 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10116 (lo_sum:TLSmode (match_dup 3)
10117 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10120 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10122 [(set (attr "length")
10123 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10127 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10128 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10130 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10131 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10132 UNSPEC_TLSGOTDTPREL)))]
10133 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10134 "addis %0,%1,%2@got@dtprel@ha"
10135 [(set_attr "length" "4")])
10137 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10138 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10139 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10140 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10141 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10142 UNSPEC_TLSGOTDTPREL)))]
10143 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10144 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10145 [(set_attr "length" "4")])
10147 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10148 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10149 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10150 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10153 "addi %0,%1,%2@tprel")
10155 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10156 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10157 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10158 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10159 UNSPEC_TLSTPRELHA))]
10161 "addis %0,%1,%2@tprel@ha")
10163 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10164 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10165 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10166 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10167 UNSPEC_TLSTPRELLO))]
10169 "addi %0,%1,%2@tprel@l")
10171 ;; "b" output constraint here and on tls_tls input to support linker tls
10172 ;; optimization. The linker may edit the instructions emitted by a
10173 ;; tls_got_tprel/tls_tls pair to addis,addi.
10174 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10175 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10176 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10177 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10178 UNSPEC_TLSGOTTPREL))]
10180 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10181 "&& TARGET_CMODEL != CMODEL_SMALL"
10182 [(set (match_dup 3)
10184 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10186 (lo_sum:TLSmode (match_dup 3)
10187 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10190 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10192 [(set (attr "length")
10193 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10197 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10198 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10200 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10201 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10202 UNSPEC_TLSGOTTPREL)))]
10203 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10204 "addis %0,%1,%2@got@tprel@ha"
10205 [(set_attr "length" "4")])
10207 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10208 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10209 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10210 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10211 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10212 UNSPEC_TLSGOTTPREL)))]
10213 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10214 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10215 [(set_attr "length" "4")])
10217 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10218 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10219 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10220 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10222 "TARGET_ELF && HAVE_AS_TLS"
10223 "add %0,%1,%2@tls")
10225 (define_expand "tls_get_tpointer"
10226 [(set (match_operand:SI 0 "gpc_reg_operand" "")
10227 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10228 "TARGET_XCOFF && HAVE_AS_TLS"
10231 emit_insn (gen_tls_get_tpointer_internal ());
10232 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10236 (define_insn "tls_get_tpointer_internal"
10238 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10239 (clobber (reg:SI LR_REGNO))]
10240 "TARGET_XCOFF && HAVE_AS_TLS"
10241 "bla __get_tpointer")
10243 (define_expand "tls_get_addr<mode>"
10244 [(set (match_operand:P 0 "gpc_reg_operand" "")
10245 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10246 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10247 "TARGET_XCOFF && HAVE_AS_TLS"
10250 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10251 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10252 emit_insn (gen_tls_get_addr_internal<mode> ());
10253 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10257 (define_insn "tls_get_addr_internal<mode>"
10259 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10260 (clobber (reg:P 0))
10261 (clobber (reg:P 4))
10262 (clobber (reg:P 5))
10263 (clobber (reg:P 11))
10264 (clobber (reg:CC CR0_REGNO))
10265 (clobber (reg:P LR_REGNO))]
10266 "TARGET_XCOFF && HAVE_AS_TLS"
10267 "bla __tls_get_addr")
10269 ;; Next come insns related to the calling sequence.
10271 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10272 ;; We move the back-chain and decrement the stack pointer.
10274 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
10275 ;; constant alloca, using that predicate will force the generic code to put
10276 ;; the constant size into a register before calling the expander.
10278 ;; As a result the expander would not have the constant size information
10279 ;; in those cases and would have to generate less efficient code.
10281 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10282 ;; the constant size. The value is forced into a register if necessary.
10284 (define_expand "allocate_stack"
10285 [(set (match_operand 0 "gpc_reg_operand" "")
10286 (minus (reg 1) (match_operand 1 "reg_or_cint_operand" "")))
10288 (minus (reg 1) (match_dup 1)))]
10291 { rtx chain = gen_reg_rtx (Pmode);
10292 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10294 rtx insn, par, set, mem;
10296 /* By allowing reg_or_cint_operand as the predicate we can get
10297 better code for stack-clash-protection because we do not lose
10298 size information. But the rest of the code expects the operand
10299 to be reg_or_short_operand. If it isn't, then force it into
10301 rtx orig_op1 = operands[1];
10302 if (!reg_or_short_operand (operands[1], Pmode))
10303 operands[1] = force_reg (Pmode, operands[1]);
10305 emit_move_insn (chain, stack_bot);
10307 /* Check stack bounds if necessary. */
10308 if (crtl->limit_stack)
10311 available = expand_binop (Pmode, sub_optab,
10312 stack_pointer_rtx, stack_limit_rtx,
10313 NULL_RTX, 1, OPTAB_WIDEN);
10314 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10317 /* Allocate and probe if requested.
10318 This may look similar to the loop we use for prologue allocations,
10319 but it is critically different. For the former we know the loop
10320 will iterate, but do not know that generally here. The former
10321 uses that knowledge to rotate the loop. Combining them would be
10322 possible with some performance cost. */
10323 if (flag_stack_clash_protection)
10325 rtx rounded_size, last_addr, residual;
10326 HOST_WIDE_INT probe_interval;
10327 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10328 &residual, &probe_interval,
10331 /* We do occasionally get in here with constant sizes, we might
10332 as well do a reasonable job when we obviously can. */
10333 if (rounded_size != const0_rtx)
10335 rtx loop_lab, end_loop;
10336 bool rotated = CONST_INT_P (rounded_size);
10338 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10339 last_addr, rotated);
10341 if (Pmode == SImode)
10342 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10344 GEN_INT (-probe_interval),
10347 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
10349 GEN_INT (-probe_interval),
10351 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10352 last_addr, rotated);
10355 /* Now handle residuals. We just have to set operands[1] correctly
10356 and let the rest of the expander run. */
10357 operands[1] = residual;
10358 if (!CONST_INT_P (residual))
10359 operands[1] = force_reg (Pmode, operands[1]);
10362 if (GET_CODE (operands[1]) != CONST_INT
10363 || INTVAL (operands[1]) < -32767
10364 || INTVAL (operands[1]) > 32768)
10366 neg_op0 = gen_reg_rtx (Pmode);
10368 emit_insn (gen_negsi2 (neg_op0, operands[1]));
10370 emit_insn (gen_negdi2 (neg_op0, operands[1]));
10373 neg_op0 = GEN_INT (- INTVAL (operands[1]));
10375 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10376 : gen_movdi_di_update_stack))
10377 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10379 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10380 it now and set the alias set/attributes. The above gen_*_update
10381 calls will generate a PARALLEL with the MEM set being the first
10383 par = PATTERN (insn);
10384 gcc_assert (GET_CODE (par) == PARALLEL);
10385 set = XVECEXP (par, 0, 0);
10386 gcc_assert (GET_CODE (set) == SET);
10387 mem = SET_DEST (set);
10388 gcc_assert (MEM_P (mem));
10389 MEM_NOTRAP_P (mem) = 1;
10390 set_mem_alias_set (mem, get_frame_alias_set ());
10392 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10396 ;; These patterns say how to save and restore the stack pointer. We need not
10397 ;; save the stack pointer at function level since we are careful to
10398 ;; preserve the backchain. At block level, we have to restore the backchain
10399 ;; when we restore the stack pointer.
10401 ;; For nonlocal gotos, we must save both the stack pointer and its
10402 ;; backchain and restore both. Note that in the nonlocal case, the
10403 ;; save area is a memory location.
10405 (define_expand "save_stack_function"
10406 [(match_operand 0 "any_operand" "")
10407 (match_operand 1 "any_operand" "")]
10411 (define_expand "restore_stack_function"
10412 [(match_operand 0 "any_operand" "")
10413 (match_operand 1 "any_operand" "")]
10417 ;; Adjust stack pointer (op0) to a new value (op1).
10418 ;; First copy old stack backchain to new location, and ensure that the
10419 ;; scheduler won't reorder the sp assignment before the backchain write.
10420 (define_expand "restore_stack_block"
10421 [(set (match_dup 2) (match_dup 3))
10422 (set (match_dup 4) (match_dup 2))
10424 (set (match_operand 0 "register_operand" "")
10425 (match_operand 1 "register_operand" ""))]
10431 operands[1] = force_reg (Pmode, operands[1]);
10432 operands[2] = gen_reg_rtx (Pmode);
10433 operands[3] = gen_frame_mem (Pmode, operands[0]);
10434 operands[4] = gen_frame_mem (Pmode, operands[1]);
10435 p = rtvec_alloc (1);
10436 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10438 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10441 (define_expand "save_stack_nonlocal"
10442 [(set (match_dup 3) (match_dup 4))
10443 (set (match_operand 0 "memory_operand" "") (match_dup 3))
10444 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10448 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10450 /* Copy the backchain to the first word, sp to the second. */
10451 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10452 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10453 operands[3] = gen_reg_rtx (Pmode);
10454 operands[4] = gen_frame_mem (Pmode, operands[1]);
10457 (define_expand "restore_stack_nonlocal"
10458 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10459 (set (match_dup 3) (match_dup 4))
10460 (set (match_dup 5) (match_dup 2))
10462 (set (match_operand 0 "register_operand" "") (match_dup 3))]
10466 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10469 /* Restore the backchain from the first word, sp from the second. */
10470 operands[2] = gen_reg_rtx (Pmode);
10471 operands[3] = gen_reg_rtx (Pmode);
10472 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10473 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10474 operands[5] = gen_frame_mem (Pmode, operands[3]);
10475 p = rtvec_alloc (1);
10476 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10478 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10481 ;; TOC register handling.
10483 ;; Code to initialize the TOC register...
10485 (define_insn "load_toc_aix_si"
10486 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10487 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10488 (use (reg:SI 2))])]
10489 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10493 extern int need_toc_init;
10495 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10496 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10497 operands[2] = gen_rtx_REG (Pmode, 2);
10498 return \"lwz %0,%1(%2)\";
10500 [(set_attr "type" "load")
10501 (set_attr "update" "no")
10502 (set_attr "indexed" "no")])
10504 (define_insn "load_toc_aix_di"
10505 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10506 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10507 (use (reg:DI 2))])]
10508 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10512 extern int need_toc_init;
10514 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10515 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10517 strcat (buf, \"@toc\");
10518 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10519 operands[2] = gen_rtx_REG (Pmode, 2);
10520 return \"ld %0,%1(%2)\";
10522 [(set_attr "type" "load")
10523 (set_attr "update" "no")
10524 (set_attr "indexed" "no")])
10526 (define_insn "load_toc_v4_pic_si"
10527 [(set (reg:SI LR_REGNO)
10528 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10529 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10530 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10531 [(set_attr "type" "branch")
10532 (set_attr "length" "4")])
10534 (define_expand "load_toc_v4_PIC_1"
10535 [(parallel [(set (reg:SI LR_REGNO)
10536 (match_operand:SI 0 "immediate_operand" "s"))
10537 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10538 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10539 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10542 (define_insn "load_toc_v4_PIC_1_normal"
10543 [(set (reg:SI LR_REGNO)
10544 (match_operand:SI 0 "immediate_operand" "s"))
10545 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10546 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10547 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10548 "bcl 20,31,%0\\n%0:"
10549 [(set_attr "type" "branch")
10550 (set_attr "length" "4")
10551 (set_attr "cannot_copy" "yes")])
10553 (define_insn "load_toc_v4_PIC_1_476"
10554 [(set (reg:SI LR_REGNO)
10555 (match_operand:SI 0 "immediate_operand" "s"))
10556 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10557 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10558 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10562 static char templ[32];
10564 get_ppc476_thunk_name (name);
10565 sprintf (templ, \"bl %s\\n%%0:\", name);
10568 [(set_attr "type" "branch")
10569 (set_attr "length" "4")
10570 (set_attr "cannot_copy" "yes")])
10572 (define_expand "load_toc_v4_PIC_1b"
10573 [(parallel [(set (reg:SI LR_REGNO)
10574 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10575 (label_ref (match_operand 1 "" ""))]
10578 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10581 (define_insn "load_toc_v4_PIC_1b_normal"
10582 [(set (reg:SI LR_REGNO)
10583 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10584 (label_ref (match_operand 1 "" ""))]
10587 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10588 "bcl 20,31,$+8\;.long %0-$"
10589 [(set_attr "type" "branch")
10590 (set_attr "length" "8")])
10592 (define_insn "load_toc_v4_PIC_1b_476"
10593 [(set (reg:SI LR_REGNO)
10594 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10595 (label_ref (match_operand 1 "" ""))]
10598 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10602 static char templ[32];
10604 get_ppc476_thunk_name (name);
10605 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10608 [(set_attr "type" "branch")
10609 (set_attr "length" "16")])
10611 (define_insn "load_toc_v4_PIC_2"
10612 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10613 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10614 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10615 (match_operand:SI 3 "immediate_operand" "s")))))]
10616 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10618 [(set_attr "type" "load")])
10620 (define_insn "load_toc_v4_PIC_3b"
10621 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10622 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10624 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10625 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10626 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10627 "addis %0,%1,%2-%3@ha")
10629 (define_insn "load_toc_v4_PIC_3c"
10630 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10631 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10632 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10633 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10634 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10635 "addi %0,%1,%2-%3@l")
10637 ;; If the TOC is shared over a translation unit, as happens with all
10638 ;; the kinds of PIC that we support, we need to restore the TOC
10639 ;; pointer only when jumping over units of translation.
10640 ;; On Darwin, we need to reload the picbase.
10642 (define_expand "builtin_setjmp_receiver"
10643 [(use (label_ref (match_operand 0 "" "")))]
10644 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10645 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10646 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10650 if (DEFAULT_ABI == ABI_DARWIN)
10652 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10653 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10657 crtl->uses_pic_offset_table = 1;
10658 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10659 CODE_LABEL_NUMBER (operands[0]));
10660 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10662 emit_insn (gen_load_macho_picbase (tmplabrtx));
10663 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10664 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10668 rs6000_emit_load_toc_table (FALSE);
10672 ;; Largetoc support
10673 (define_insn "*largetoc_high"
10674 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10676 (unspec [(match_operand:DI 1 "" "")
10677 (match_operand:DI 2 "gpc_reg_operand" "b")]
10679 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10680 "addis %0,%2,%1@toc@ha")
10682 (define_insn "*largetoc_high_aix<mode>"
10683 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10685 (unspec [(match_operand:P 1 "" "")
10686 (match_operand:P 2 "gpc_reg_operand" "b")]
10688 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10689 "addis %0,%1@u(%2)")
10691 (define_insn "*largetoc_high_plus"
10692 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10695 (unspec [(match_operand:DI 1 "" "")
10696 (match_operand:DI 2 "gpc_reg_operand" "b")]
10698 (match_operand:DI 3 "add_cint_operand" "n"))))]
10699 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10700 "addis %0,%2,%1+%3@toc@ha")
10702 (define_insn "*largetoc_high_plus_aix<mode>"
10703 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10706 (unspec [(match_operand:P 1 "" "")
10707 (match_operand:P 2 "gpc_reg_operand" "b")]
10709 (match_operand:P 3 "add_cint_operand" "n"))))]
10710 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10711 "addis %0,%1+%3@u(%2)")
10713 (define_insn "*largetoc_low"
10714 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10715 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10716 (match_operand:DI 2 "" "")))]
10717 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10720 (define_insn "*largetoc_low_aix<mode>"
10721 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10722 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10723 (match_operand:P 2 "" "")))]
10724 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10727 (define_insn_and_split "*tocref<mode>"
10728 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10729 (match_operand:P 1 "small_toc_ref" "R"))]
10732 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10733 [(set (match_dup 0) (high:P (match_dup 1)))
10734 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10736 ;; Elf specific ways of loading addresses for non-PIC code.
10737 ;; The output of this could be r0, but we make a very strong
10738 ;; preference for a base register because it will usually
10739 ;; be needed there.
10740 (define_insn "elf_high"
10741 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10742 (high:SI (match_operand 1 "" "")))]
10743 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10746 (define_insn "elf_low"
10747 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10748 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10749 (match_operand 2 "" "")))]
10750 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10753 ;; Call and call_value insns
10754 (define_expand "call"
10755 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10756 (match_operand 1 "" ""))
10757 (use (match_operand 2 "" ""))
10758 (clobber (reg:SI LR_REGNO))])]
10763 if (MACHOPIC_INDIRECT)
10764 operands[0] = machopic_indirect_call_target (operands[0]);
10767 gcc_assert (GET_CODE (operands[0]) == MEM);
10768 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10770 operands[0] = XEXP (operands[0], 0);
10772 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10774 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10778 if (GET_CODE (operands[0]) != SYMBOL_REF
10779 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10781 if (INTVAL (operands[2]) & CALL_LONG)
10782 operands[0] = rs6000_longcall_ref (operands[0]);
10784 switch (DEFAULT_ABI)
10788 operands[0] = force_reg (Pmode, operands[0]);
10792 gcc_unreachable ();
10797 (define_expand "call_value"
10798 [(parallel [(set (match_operand 0 "" "")
10799 (call (mem:SI (match_operand 1 "address_operand" ""))
10800 (match_operand 2 "" "")))
10801 (use (match_operand 3 "" ""))
10802 (clobber (reg:SI LR_REGNO))])]
10807 if (MACHOPIC_INDIRECT)
10808 operands[1] = machopic_indirect_call_target (operands[1]);
10811 gcc_assert (GET_CODE (operands[1]) == MEM);
10812 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10814 operands[1] = XEXP (operands[1], 0);
10816 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10818 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10822 if (GET_CODE (operands[1]) != SYMBOL_REF
10823 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10825 if (INTVAL (operands[3]) & CALL_LONG)
10826 operands[1] = rs6000_longcall_ref (operands[1]);
10828 switch (DEFAULT_ABI)
10832 operands[1] = force_reg (Pmode, operands[1]);
10836 gcc_unreachable ();
10841 ;; Call to function in current module. No TOC pointer reload needed.
10842 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10843 ;; either the function was not prototyped, or it was prototyped as a
10844 ;; variable argument function. It is > 0 if FP registers were passed
10845 ;; and < 0 if they were not.
10847 (define_insn "*call_local32"
10848 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10849 (match_operand 1 "" "g,g"))
10850 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10851 (clobber (reg:SI LR_REGNO))]
10852 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10855 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10856 output_asm_insn (\"crxor 6,6,6\", operands);
10858 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10859 output_asm_insn (\"creqv 6,6,6\", operands);
10861 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10863 [(set_attr "type" "branch")
10864 (set_attr "length" "4,8")])
10866 (define_insn "*call_local64"
10867 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10868 (match_operand 1 "" "g,g"))
10869 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10870 (clobber (reg:SI LR_REGNO))]
10871 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10874 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10875 output_asm_insn (\"crxor 6,6,6\", operands);
10877 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10878 output_asm_insn (\"creqv 6,6,6\", operands);
10880 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10882 [(set_attr "type" "branch")
10883 (set_attr "length" "4,8")])
10885 (define_insn "*call_value_local32"
10886 [(set (match_operand 0 "" "")
10887 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10888 (match_operand 2 "" "g,g")))
10889 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10890 (clobber (reg:SI LR_REGNO))]
10891 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10894 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10895 output_asm_insn (\"crxor 6,6,6\", operands);
10897 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10898 output_asm_insn (\"creqv 6,6,6\", operands);
10900 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10902 [(set_attr "type" "branch")
10903 (set_attr "length" "4,8")])
10906 (define_insn "*call_value_local64"
10907 [(set (match_operand 0 "" "")
10908 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10909 (match_operand 2 "" "g,g")))
10910 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10911 (clobber (reg:SI LR_REGNO))]
10912 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10915 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10916 output_asm_insn (\"crxor 6,6,6\", operands);
10918 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10919 output_asm_insn (\"creqv 6,6,6\", operands);
10921 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10923 [(set_attr "type" "branch")
10924 (set_attr "length" "4,8")])
10927 ;; A function pointer under System V is just a normal pointer
10928 ;; operands[0] is the function pointer
10929 ;; operands[1] is the stack size to clean up
10930 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10931 ;; which indicates how to set cr1
10933 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10934 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10935 (match_operand 1 "" "g,g,g,g"))
10936 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10937 (clobber (reg:SI LR_REGNO))]
10938 "DEFAULT_ABI == ABI_V4
10939 || DEFAULT_ABI == ABI_DARWIN"
10941 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10942 output_asm_insn ("crxor 6,6,6", operands);
10944 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10945 output_asm_insn ("creqv 6,6,6", operands);
10949 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10950 (set_attr "length" "4,4,8,8")])
10952 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10953 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10954 (match_operand 1 "" "g,g"))
10955 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10956 (clobber (reg:SI LR_REGNO))]
10957 "(DEFAULT_ABI == ABI_DARWIN
10958 || (DEFAULT_ABI == ABI_V4
10959 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10961 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10962 output_asm_insn ("crxor 6,6,6", operands);
10964 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10965 output_asm_insn ("creqv 6,6,6", operands);
10968 return output_call(insn, operands, 0, 2);
10970 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10972 gcc_assert (!TARGET_SECURE_PLT);
10973 return "bl %z0@plt";
10979 "DEFAULT_ABI == ABI_V4
10980 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10981 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10982 [(parallel [(call (mem:SI (match_dup 0))
10984 (use (match_dup 2))
10985 (use (match_dup 3))
10986 (clobber (reg:SI LR_REGNO))])]
10988 operands[3] = pic_offset_table_rtx;
10990 [(set_attr "type" "branch,branch")
10991 (set_attr "length" "4,8")])
10993 (define_insn "*call_nonlocal_sysv_secure<mode>"
10994 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10995 (match_operand 1 "" "g,g"))
10996 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10997 (use (match_operand:SI 3 "register_operand" "r,r"))
10998 (clobber (reg:SI LR_REGNO))]
10999 "(DEFAULT_ABI == ABI_V4
11000 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11001 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11003 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11004 output_asm_insn ("crxor 6,6,6", operands);
11006 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11007 output_asm_insn ("creqv 6,6,6", operands);
11010 /* The magic 32768 offset here and in the other sysv call insns
11011 corresponds to the offset of r30 in .got2, as given by LCTOC1.
11012 See sysv4.h:toc_section. */
11013 return "bl %z0+32768@plt";
11015 return "bl %z0@plt";
11017 [(set_attr "type" "branch,branch")
11018 (set_attr "length" "4,8")])
11020 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11021 [(set (match_operand 0 "" "")
11022 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11023 (match_operand 2 "" "g,g,g,g")))
11024 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11025 (clobber (reg:SI LR_REGNO))]
11026 "DEFAULT_ABI == ABI_V4
11027 || DEFAULT_ABI == ABI_DARWIN"
11029 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11030 output_asm_insn ("crxor 6,6,6", operands);
11032 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11033 output_asm_insn ("creqv 6,6,6", operands);
11037 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11038 (set_attr "length" "4,4,8,8")])
11040 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11041 [(set (match_operand 0 "" "")
11042 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11043 (match_operand 2 "" "g,g")))
11044 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11045 (clobber (reg:SI LR_REGNO))]
11046 "(DEFAULT_ABI == ABI_DARWIN
11047 || (DEFAULT_ABI == ABI_V4
11048 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11050 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11051 output_asm_insn ("crxor 6,6,6", operands);
11053 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11054 output_asm_insn ("creqv 6,6,6", operands);
11057 return output_call(insn, operands, 1, 3);
11059 if (DEFAULT_ABI == ABI_V4 && flag_pic)
11061 gcc_assert (!TARGET_SECURE_PLT);
11062 return "bl %z1@plt";
11068 "DEFAULT_ABI == ABI_V4
11069 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11070 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11071 [(parallel [(set (match_dup 0)
11072 (call (mem:SI (match_dup 1))
11074 (use (match_dup 3))
11075 (use (match_dup 4))
11076 (clobber (reg:SI LR_REGNO))])]
11078 operands[4] = pic_offset_table_rtx;
11080 [(set_attr "type" "branch,branch")
11081 (set_attr "length" "4,8")])
11083 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11084 [(set (match_operand 0 "" "")
11085 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11086 (match_operand 2 "" "g,g")))
11087 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11088 (use (match_operand:SI 4 "register_operand" "r,r"))
11089 (clobber (reg:SI LR_REGNO))]
11090 "(DEFAULT_ABI == ABI_V4
11091 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11092 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11094 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11095 output_asm_insn ("crxor 6,6,6", operands);
11097 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11098 output_asm_insn ("creqv 6,6,6", operands);
11101 return "bl %z1+32768@plt";
11103 return "bl %z1@plt";
11105 [(set_attr "type" "branch,branch")
11106 (set_attr "length" "4,8")])
11109 ;; Call to AIX abi function in the same module.
11111 (define_insn "*call_local_aix<mode>"
11112 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11113 (match_operand 1 "" "g"))
11114 (clobber (reg:P LR_REGNO))]
11115 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11117 [(set_attr "type" "branch")
11118 (set_attr "length" "4")])
11120 (define_insn "*call_value_local_aix<mode>"
11121 [(set (match_operand 0 "" "")
11122 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11123 (match_operand 2 "" "g")))
11124 (clobber (reg:P LR_REGNO))]
11125 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11127 [(set_attr "type" "branch")
11128 (set_attr "length" "4")])
11130 ;; Call to AIX abi function which may be in another module.
11131 ;; Restore the TOC pointer (r2) after the call.
11133 (define_insn "*call_nonlocal_aix<mode>"
11134 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11135 (match_operand 1 "" "g"))
11136 (clobber (reg:P LR_REGNO))]
11137 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11139 [(set_attr "type" "branch")
11140 (set_attr "length" "8")])
11142 (define_insn "*call_value_nonlocal_aix<mode>"
11143 [(set (match_operand 0 "" "")
11144 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11145 (match_operand 2 "" "g")))
11146 (clobber (reg:P LR_REGNO))]
11147 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11149 [(set_attr "type" "branch")
11150 (set_attr "length" "8")])
11152 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11153 ;; Operand0 is the addresss of the function to call
11154 ;; Operand2 is the location in the function descriptor to load r2 from
11155 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11157 (define_insn "*call_indirect_aix<mode>"
11158 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11159 (match_operand 1 "" "g,g"))
11160 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11161 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11162 (clobber (reg:P LR_REGNO))]
11163 "DEFAULT_ABI == ABI_AIX"
11164 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11165 [(set_attr "type" "jmpreg")
11166 (set_attr "length" "12")])
11168 (define_insn "*call_value_indirect_aix<mode>"
11169 [(set (match_operand 0 "" "")
11170 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11171 (match_operand 2 "" "g,g")))
11172 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11173 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11174 (clobber (reg:P LR_REGNO))]
11175 "DEFAULT_ABI == ABI_AIX"
11176 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11177 [(set_attr "type" "jmpreg")
11178 (set_attr "length" "12")])
11180 ;; Call to indirect functions with the ELFv2 ABI.
11181 ;; Operand0 is the addresss of the function to call
11182 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11184 (define_insn "*call_indirect_elfv2<mode>"
11185 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11186 (match_operand 1 "" "g,g"))
11187 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11188 (clobber (reg:P LR_REGNO))]
11189 "DEFAULT_ABI == ABI_ELFv2"
11190 "b%T0l\;<ptrload> 2,%2(1)"
11191 [(set_attr "type" "jmpreg")
11192 (set_attr "length" "8")])
11194 (define_insn "*call_value_indirect_elfv2<mode>"
11195 [(set (match_operand 0 "" "")
11196 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11197 (match_operand 2 "" "g,g")))
11198 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11199 (clobber (reg:P LR_REGNO))]
11200 "DEFAULT_ABI == ABI_ELFv2"
11201 "b%T1l\;<ptrload> 2,%3(1)"
11202 [(set_attr "type" "jmpreg")
11203 (set_attr "length" "8")])
11206 ;; Call subroutine returning any type.
11207 (define_expand "untyped_call"
11208 [(parallel [(call (match_operand 0 "" "")
11210 (match_operand 1 "" "")
11211 (match_operand 2 "" "")])]
11217 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11219 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11221 rtx set = XVECEXP (operands[2], 0, i);
11222 emit_move_insn (SET_DEST (set), SET_SRC (set));
11225 /* The optimizer does not know that the call sets the function value
11226 registers we stored in the result block. We avoid problems by
11227 claiming that all hard registers are used and clobbered at this
11229 emit_insn (gen_blockage ());
11234 ;; sibling call patterns
11235 (define_expand "sibcall"
11236 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11237 (match_operand 1 "" ""))
11238 (use (match_operand 2 "" ""))
11244 if (MACHOPIC_INDIRECT)
11245 operands[0] = machopic_indirect_call_target (operands[0]);
11248 gcc_assert (GET_CODE (operands[0]) == MEM);
11249 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11251 operands[0] = XEXP (operands[0], 0);
11253 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11255 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11260 (define_expand "sibcall_value"
11261 [(parallel [(set (match_operand 0 "register_operand" "")
11262 (call (mem:SI (match_operand 1 "address_operand" ""))
11263 (match_operand 2 "" "")))
11264 (use (match_operand 3 "" ""))
11270 if (MACHOPIC_INDIRECT)
11271 operands[1] = machopic_indirect_call_target (operands[1]);
11274 gcc_assert (GET_CODE (operands[1]) == MEM);
11275 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11277 operands[1] = XEXP (operands[1], 0);
11279 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11281 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11286 (define_insn "*sibcall_local32"
11287 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11288 (match_operand 1 "" "g,g"))
11289 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11291 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11294 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11295 output_asm_insn (\"crxor 6,6,6\", operands);
11297 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11298 output_asm_insn (\"creqv 6,6,6\", operands);
11300 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11302 [(set_attr "type" "branch")
11303 (set_attr "length" "4,8")])
11305 (define_insn "*sibcall_local64"
11306 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11307 (match_operand 1 "" "g,g"))
11308 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11310 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11313 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11314 output_asm_insn (\"crxor 6,6,6\", operands);
11316 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11317 output_asm_insn (\"creqv 6,6,6\", operands);
11319 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11321 [(set_attr "type" "branch")
11322 (set_attr "length" "4,8")])
11324 (define_insn "*sibcall_value_local32"
11325 [(set (match_operand 0 "" "")
11326 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11327 (match_operand 2 "" "g,g")))
11328 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11330 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11333 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11334 output_asm_insn (\"crxor 6,6,6\", operands);
11336 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11337 output_asm_insn (\"creqv 6,6,6\", operands);
11339 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11341 [(set_attr "type" "branch")
11342 (set_attr "length" "4,8")])
11344 (define_insn "*sibcall_value_local64"
11345 [(set (match_operand 0 "" "")
11346 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11347 (match_operand 2 "" "g,g")))
11348 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11350 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11353 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11354 output_asm_insn (\"crxor 6,6,6\", operands);
11356 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11357 output_asm_insn (\"creqv 6,6,6\", operands);
11359 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11361 [(set_attr "type" "branch")
11362 (set_attr "length" "4,8")])
11364 (define_insn "*sibcall_nonlocal_sysv<mode>"
11365 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11366 (match_operand 1 "" ""))
11367 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11369 "(DEFAULT_ABI == ABI_DARWIN
11370 || DEFAULT_ABI == ABI_V4)
11371 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11374 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11375 output_asm_insn (\"crxor 6,6,6\", operands);
11377 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11378 output_asm_insn (\"creqv 6,6,6\", operands);
11380 if (which_alternative >= 2)
11382 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11384 gcc_assert (!TARGET_SECURE_PLT);
11385 return \"b %z0@plt\";
11390 [(set_attr "type" "branch")
11391 (set_attr "length" "4,8,4,8")])
11393 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11394 [(set (match_operand 0 "" "")
11395 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11396 (match_operand 2 "" "")))
11397 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11399 "(DEFAULT_ABI == ABI_DARWIN
11400 || DEFAULT_ABI == ABI_V4)
11401 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11404 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11405 output_asm_insn (\"crxor 6,6,6\", operands);
11407 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11408 output_asm_insn (\"creqv 6,6,6\", operands);
11410 if (which_alternative >= 2)
11412 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11414 gcc_assert (!TARGET_SECURE_PLT);
11415 return \"b %z1@plt\";
11420 [(set_attr "type" "branch")
11421 (set_attr "length" "4,8,4,8")])
11423 ;; AIX ABI sibling call patterns.
11425 (define_insn "*sibcall_aix<mode>"
11426 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11427 (match_operand 1 "" "g,g"))
11429 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11433 [(set_attr "type" "branch")
11434 (set_attr "length" "4")])
11436 (define_insn "*sibcall_value_aix<mode>"
11437 [(set (match_operand 0 "" "")
11438 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11439 (match_operand 2 "" "g,g")))
11441 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11445 [(set_attr "type" "branch")
11446 (set_attr "length" "4")])
11448 (define_expand "sibcall_epilogue"
11449 [(use (const_int 0))]
11452 if (!TARGET_SCHED_PROLOG)
11453 emit_insn (gen_blockage ());
11454 rs6000_emit_epilogue (TRUE);
11458 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11459 ;; all of memory. This blocks insns from being moved across this point.
11461 (define_insn "blockage"
11462 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11466 (define_expand "probe_stack_address"
11467 [(use (match_operand 0 "address_operand"))]
11470 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11471 MEM_VOLATILE_P (operands[0]) = 1;
11474 emit_insn (gen_probe_stack_di (operands[0]));
11476 emit_insn (gen_probe_stack_si (operands[0]));
11480 (define_insn "probe_stack_<mode>"
11481 [(set (match_operand:P 0 "memory_operand" "=m")
11482 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11485 operands[1] = gen_rtx_REG (Pmode, 0);
11486 return "st<wd>%U0%X0 %1,%0";
11488 [(set_attr "type" "store")
11489 (set (attr "update")
11490 (if_then_else (match_operand 0 "update_address_mem")
11491 (const_string "yes")
11492 (const_string "no")))
11493 (set (attr "indexed")
11494 (if_then_else (match_operand 0 "indexed_address_mem")
11495 (const_string "yes")
11496 (const_string "no")))
11497 (set_attr "length" "4")])
11499 (define_insn "probe_stack_range<P:mode>"
11500 [(set (match_operand:P 0 "register_operand" "=&r")
11501 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11502 (match_operand:P 2 "register_operand" "r")
11503 (match_operand:P 3 "register_operand" "r")]
11504 UNSPECV_PROBE_STACK_RANGE))]
11506 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11507 [(set_attr "type" "three")])
11509 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11510 ;; signed & unsigned, and one type of branch.
11512 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11513 ;; insns, and branches.
11515 (define_expand "cbranch<mode>4"
11516 [(use (match_operator 0 "comparison_operator"
11517 [(match_operand:GPR 1 "gpc_reg_operand" "")
11518 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11519 (use (match_operand 3 ""))]
11523 /* Take care of the possibility that operands[2] might be negative but
11524 this might be a logical operation. That insn doesn't exist. */
11525 if (GET_CODE (operands[2]) == CONST_INT
11526 && INTVAL (operands[2]) < 0)
11528 operands[2] = force_reg (<MODE>mode, operands[2]);
11529 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11530 GET_MODE (operands[0]),
11531 operands[1], operands[2]);
11534 rs6000_emit_cbranch (<MODE>mode, operands);
11538 (define_expand "cbranch<mode>4"
11539 [(use (match_operator 0 "comparison_operator"
11540 [(match_operand:FP 1 "gpc_reg_operand" "")
11541 (match_operand:FP 2 "gpc_reg_operand" "")]))
11542 (use (match_operand 3 ""))]
11546 rs6000_emit_cbranch (<MODE>mode, operands);
11550 (define_expand "cstore<mode>4_signed"
11551 [(use (match_operator 1 "signed_comparison_operator"
11552 [(match_operand:P 2 "gpc_reg_operand")
11553 (match_operand:P 3 "gpc_reg_operand")]))
11554 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11557 enum rtx_code cond_code = GET_CODE (operands[1]);
11559 rtx op0 = operands[0];
11560 rtx op1 = operands[2];
11561 rtx op2 = operands[3];
11563 if (cond_code == GE || cond_code == LT)
11565 cond_code = swap_condition (cond_code);
11566 std::swap (op1, op2);
11569 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11570 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11571 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11573 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11574 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11575 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11577 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11579 if (cond_code == LE)
11580 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11583 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11584 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11585 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11591 (define_expand "cstore<mode>4_unsigned"
11592 [(use (match_operator 1 "unsigned_comparison_operator"
11593 [(match_operand:P 2 "gpc_reg_operand")
11594 (match_operand:P 3 "reg_or_short_operand")]))
11595 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11598 enum rtx_code cond_code = GET_CODE (operands[1]);
11600 rtx op0 = operands[0];
11601 rtx op1 = operands[2];
11602 rtx op2 = operands[3];
11604 if (cond_code == GEU || cond_code == LTU)
11606 cond_code = swap_condition (cond_code);
11607 std::swap (op1, op2);
11610 if (!gpc_reg_operand (op1, <MODE>mode))
11611 op1 = force_reg (<MODE>mode, op1);
11612 if (!reg_or_short_operand (op2, <MODE>mode))
11613 op2 = force_reg (<MODE>mode, op2);
11615 rtx tmp = gen_reg_rtx (<MODE>mode);
11616 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11618 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11619 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11621 if (cond_code == LEU)
11622 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11624 emit_insn (gen_neg<mode>2 (op0, tmp2));
11629 (define_expand "cstore_si_as_di"
11630 [(use (match_operator 1 "unsigned_comparison_operator"
11631 [(match_operand:SI 2 "gpc_reg_operand")
11632 (match_operand:SI 3 "reg_or_short_operand")]))
11633 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11636 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11637 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11639 operands[2] = force_reg (SImode, operands[2]);
11640 operands[3] = force_reg (SImode, operands[3]);
11641 rtx op1 = gen_reg_rtx (DImode);
11642 rtx op2 = gen_reg_rtx (DImode);
11643 convert_move (op1, operands[2], uns_flag);
11644 convert_move (op2, operands[3], uns_flag);
11646 if (cond_code == GT || cond_code == LE)
11648 cond_code = swap_condition (cond_code);
11649 std::swap (op1, op2);
11652 rtx tmp = gen_reg_rtx (DImode);
11653 rtx tmp2 = gen_reg_rtx (DImode);
11654 emit_insn (gen_subdi3 (tmp, op1, op2));
11655 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11661 gcc_unreachable ();
11666 tmp3 = gen_reg_rtx (DImode);
11667 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11671 convert_move (operands[0], tmp3, 1);
11676 (define_expand "cstore<mode>4_signed_imm"
11677 [(use (match_operator 1 "signed_comparison_operator"
11678 [(match_operand:GPR 2 "gpc_reg_operand")
11679 (match_operand:GPR 3 "immediate_operand")]))
11680 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11683 bool invert = false;
11685 enum rtx_code cond_code = GET_CODE (operands[1]);
11687 rtx op0 = operands[0];
11688 rtx op1 = operands[2];
11689 HOST_WIDE_INT val = INTVAL (operands[3]);
11691 if (cond_code == GE || cond_code == GT)
11693 cond_code = reverse_condition (cond_code);
11697 if (cond_code == LE)
11700 rtx tmp = gen_reg_rtx (<MODE>mode);
11701 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11702 rtx x = gen_reg_rtx (<MODE>mode);
11704 emit_insn (gen_and<mode>3 (x, op1, tmp));
11706 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11710 rtx tmp = gen_reg_rtx (<MODE>mode);
11711 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11715 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11716 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11721 (define_expand "cstore<mode>4_unsigned_imm"
11722 [(use (match_operator 1 "unsigned_comparison_operator"
11723 [(match_operand:GPR 2 "gpc_reg_operand")
11724 (match_operand:GPR 3 "immediate_operand")]))
11725 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11728 bool invert = false;
11730 enum rtx_code cond_code = GET_CODE (operands[1]);
11732 rtx op0 = operands[0];
11733 rtx op1 = operands[2];
11734 HOST_WIDE_INT val = INTVAL (operands[3]);
11736 if (cond_code == GEU || cond_code == GTU)
11738 cond_code = reverse_condition (cond_code);
11742 if (cond_code == LEU)
11745 rtx tmp = gen_reg_rtx (<MODE>mode);
11746 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11747 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11748 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11749 rtx x = gen_reg_rtx (<MODE>mode);
11751 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11753 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11757 rtx tmp = gen_reg_rtx (<MODE>mode);
11758 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11762 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11763 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11768 (define_expand "cstore<mode>4"
11769 [(use (match_operator 1 "comparison_operator"
11770 [(match_operand:GPR 2 "gpc_reg_operand")
11771 (match_operand:GPR 3 "reg_or_short_operand")]))
11772 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11775 /* Use ISEL if the user asked for it. */
11777 rs6000_emit_sISEL (<MODE>mode, operands);
11779 /* Expanding EQ and NE directly to some machine instructions does not help
11780 but does hurt combine. So don't. */
11781 else if (GET_CODE (operands[1]) == EQ)
11782 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11783 else if (<MODE>mode == Pmode
11784 && GET_CODE (operands[1]) == NE)
11785 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11786 else if (GET_CODE (operands[1]) == NE)
11788 rtx tmp = gen_reg_rtx (<MODE>mode);
11789 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11790 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11793 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11794 etc. combinations magically work out just right. */
11795 else if (<MODE>mode == Pmode
11796 && unsigned_comparison_operator (operands[1], VOIDmode))
11797 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11798 operands[2], operands[3]));
11800 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11801 else if (<MODE>mode == SImode && Pmode == DImode)
11802 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11803 operands[2], operands[3]));
11805 /* For signed comparisons against a constant, we can do some simple
11807 else if (signed_comparison_operator (operands[1], VOIDmode)
11808 && CONST_INT_P (operands[3]))
11809 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11810 operands[2], operands[3]));
11812 /* And similarly for unsigned comparisons. */
11813 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11814 && CONST_INT_P (operands[3]))
11815 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11816 operands[2], operands[3]));
11818 /* We also do not want to use mfcr for signed comparisons. */
11819 else if (<MODE>mode == Pmode
11820 && signed_comparison_operator (operands[1], VOIDmode))
11821 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11822 operands[2], operands[3]));
11824 /* Everything else, use the mfcr brute force. */
11826 rs6000_emit_sCOND (<MODE>mode, operands);
11831 (define_expand "cstore<mode>4"
11832 [(use (match_operator 1 "comparison_operator"
11833 [(match_operand:FP 2 "gpc_reg_operand")
11834 (match_operand:FP 3 "gpc_reg_operand")]))
11835 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11838 rs6000_emit_sCOND (<MODE>mode, operands);
11843 (define_expand "stack_protect_set"
11844 [(match_operand 0 "memory_operand")
11845 (match_operand 1 "memory_operand")]
11848 if (rs6000_stack_protector_guard == SSP_TLS)
11850 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11851 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11852 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11853 operands[1] = gen_rtx_MEM (Pmode, addr);
11857 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11859 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11864 (define_insn "stack_protect_setsi"
11865 [(set (match_operand:SI 0 "memory_operand" "=m")
11866 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11867 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11869 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11870 [(set_attr "type" "three")
11871 (set_attr "length" "12")])
11873 (define_insn "stack_protect_setdi"
11874 [(set (match_operand:DI 0 "memory_operand" "=Y")
11875 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11876 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11878 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11879 [(set_attr "type" "three")
11880 (set_attr "length" "12")])
11882 (define_expand "stack_protect_test"
11883 [(match_operand 0 "memory_operand")
11884 (match_operand 1 "memory_operand")
11885 (match_operand 2 "")]
11888 rtx guard = operands[1];
11890 if (rs6000_stack_protector_guard == SSP_TLS)
11892 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11893 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11894 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11895 guard = gen_rtx_MEM (Pmode, addr);
11898 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11899 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11900 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11901 emit_jump_insn (jump);
11906 (define_insn "stack_protect_testsi"
11907 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11908 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11909 (match_operand:SI 2 "memory_operand" "m,m")]
11911 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11912 (clobber (match_scratch:SI 3 "=&r,&r"))]
11915 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11916 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11917 [(set_attr "length" "16,20")])
11919 (define_insn "stack_protect_testdi"
11920 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11921 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11922 (match_operand:DI 2 "memory_operand" "Y,Y")]
11924 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11925 (clobber (match_scratch:DI 3 "=&r,&r"))]
11928 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11929 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11930 [(set_attr "length" "16,20")])
11933 ;; Here are the actual compare insns.
11934 (define_insn "*cmp<mode>_signed"
11935 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11936 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11937 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11939 "cmp<wd>%I2 %0,%1,%2"
11940 [(set_attr "type" "cmp")])
11942 (define_insn "*cmp<mode>_unsigned"
11943 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11944 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11945 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11947 "cmpl<wd>%I2 %0,%1,%2"
11948 [(set_attr "type" "cmp")])
11950 ;; If we are comparing a register for equality with a large constant,
11951 ;; we can do this with an XOR followed by a compare. But this is profitable
11952 ;; only if the large constant is only used for the comparison (and in this
11953 ;; case we already have a register to reuse as scratch).
11955 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11956 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11959 [(set (match_operand:SI 0 "register_operand")
11960 (match_operand:SI 1 "logical_const_operand" ""))
11961 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11963 (match_operand:SI 2 "logical_const_operand" "")]))
11964 (set (match_operand:CC 4 "cc_reg_operand" "")
11965 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11968 (if_then_else (match_operator 6 "equality_operator"
11969 [(match_dup 4) (const_int 0)])
11970 (match_operand 7 "" "")
11971 (match_operand 8 "" "")))]
11972 "peep2_reg_dead_p (3, operands[0])
11973 && peep2_reg_dead_p (4, operands[4])
11974 && REGNO (operands[0]) != REGNO (operands[5])"
11975 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11976 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11977 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11980 /* Get the constant we are comparing against, and see what it looks like
11981 when sign-extended from 16 to 32 bits. Then see what constant we could
11982 XOR with SEXTC to get the sign-extended value. */
11983 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11985 operands[1], operands[2]);
11986 HOST_WIDE_INT c = INTVAL (cnst);
11987 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11988 HOST_WIDE_INT xorv = c ^ sextc;
11990 operands[9] = GEN_INT (xorv);
11991 operands[10] = GEN_INT (sextc);
11994 ;; The following two insns don't exist as single insns, but if we provide
11995 ;; them, we can swap an add and compare, which will enable us to overlap more
11996 ;; of the required delay between a compare and branch. We generate code for
11997 ;; them by splitting.
12000 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12001 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
12002 (match_operand:SI 2 "short_cint_operand" "i")))
12003 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12004 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12007 [(set_attr "length" "8")])
12010 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
12011 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
12012 (match_operand:SI 2 "u_short_cint_operand" "i")))
12013 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12014 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12017 [(set_attr "length" "8")])
12020 [(set (match_operand:CC 3 "cc_reg_operand" "")
12021 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
12022 (match_operand:SI 2 "short_cint_operand" "")))
12023 (set (match_operand:SI 0 "gpc_reg_operand" "")
12024 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12026 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
12027 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12030 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
12031 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
12032 (match_operand:SI 2 "u_short_cint_operand" "")))
12033 (set (match_operand:SI 0 "gpc_reg_operand" "")
12034 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12036 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
12037 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12039 ;; Only need to compare second words if first words equal
12040 (define_insn "*cmp<mode>_internal1"
12041 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12042 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12043 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12044 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12045 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12046 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12047 [(set_attr "type" "fpcompare")
12048 (set_attr "length" "12")])
12050 (define_insn_and_split "*cmp<mode>_internal2"
12051 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12052 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12053 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12054 (clobber (match_scratch:DF 3 "=d"))
12055 (clobber (match_scratch:DF 4 "=d"))
12056 (clobber (match_scratch:DF 5 "=d"))
12057 (clobber (match_scratch:DF 6 "=d"))
12058 (clobber (match_scratch:DF 7 "=d"))
12059 (clobber (match_scratch:DF 8 "=d"))
12060 (clobber (match_scratch:DF 9 "=d"))
12061 (clobber (match_scratch:DF 10 "=d"))
12062 (clobber (match_scratch:GPR 11 "=b"))]
12063 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12064 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12066 "&& reload_completed"
12067 [(set (match_dup 3) (match_dup 14))
12068 (set (match_dup 4) (match_dup 15))
12069 (set (match_dup 9) (abs:DF (match_dup 5)))
12070 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12071 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12072 (label_ref (match_dup 12))
12074 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12075 (set (pc) (label_ref (match_dup 13)))
12077 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12078 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12079 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12080 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12083 REAL_VALUE_TYPE rv;
12084 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12085 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12087 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12088 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12089 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12090 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12091 operands[12] = gen_label_rtx ();
12092 operands[13] = gen_label_rtx ();
12094 operands[14] = force_const_mem (DFmode,
12095 const_double_from_real_value (rv, DFmode));
12096 operands[15] = force_const_mem (DFmode,
12097 const_double_from_real_value (dconst0,
12102 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12103 operands[14] = gen_const_mem (DFmode, tocref);
12104 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12105 operands[15] = gen_const_mem (DFmode, tocref);
12106 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12107 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12111 ;; Now we have the scc insns. We can do some combinations because of the
12112 ;; way the machine works.
12114 ;; Note that this is probably faster if we can put an insn between the
12115 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12116 ;; cases the insns below which don't use an intermediate CR field will
12117 ;; be used instead.
12119 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12120 (match_operator:SI 1 "scc_comparison_operator"
12121 [(match_operand 2 "cc_reg_operand" "y")
12124 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12125 [(set (attr "type")
12126 (cond [(match_test "TARGET_MFCRF")
12127 (const_string "mfcrf")
12129 (const_string "mfcr")))
12130 (set_attr "length" "8")])
12132 ;; Same as above, but get the OV/ORDERED bit.
12133 (define_insn "move_from_CR_ov_bit"
12134 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12135 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12138 "mfcr %0\;rlwinm %0,%0,%t1,1"
12139 [(set_attr "type" "mfcr")
12140 (set_attr "length" "8")])
12143 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12144 (match_operator:DI 1 "scc_comparison_operator"
12145 [(match_operand 2 "cc_reg_operand" "y")
12148 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12149 [(set (attr "type")
12150 (cond [(match_test "TARGET_MFCRF")
12151 (const_string "mfcrf")
12153 (const_string "mfcr")))
12154 (set_attr "length" "8")])
12157 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12158 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12159 [(match_operand 2 "cc_reg_operand" "y,y")
12162 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12163 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12166 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12168 [(set_attr "type" "shift")
12169 (set_attr "dot" "yes")
12170 (set_attr "length" "8,16")])
12173 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12174 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12175 [(match_operand 2 "cc_reg_operand" "")
12178 (set (match_operand:SI 3 "gpc_reg_operand" "")
12179 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12180 "TARGET_32BIT && reload_completed"
12181 [(set (match_dup 3)
12182 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12184 (compare:CC (match_dup 3)
12189 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12190 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12191 [(match_operand 2 "cc_reg_operand" "y")
12193 (match_operand:SI 3 "const_int_operand" "n")))]
12197 int is_bit = ccr_bit (operands[1], 1);
12198 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12201 if (is_bit >= put_bit)
12202 count = is_bit - put_bit;
12204 count = 32 - (put_bit - is_bit);
12206 operands[4] = GEN_INT (count);
12207 operands[5] = GEN_INT (put_bit);
12209 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12211 [(set (attr "type")
12212 (cond [(match_test "TARGET_MFCRF")
12213 (const_string "mfcrf")
12215 (const_string "mfcr")))
12216 (set_attr "length" "8")])
12219 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12221 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12222 [(match_operand 2 "cc_reg_operand" "y,y")
12224 (match_operand:SI 3 "const_int_operand" "n,n"))
12226 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12227 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12232 int is_bit = ccr_bit (operands[1], 1);
12233 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12236 /* Force split for non-cc0 compare. */
12237 if (which_alternative == 1)
12240 if (is_bit >= put_bit)
12241 count = is_bit - put_bit;
12243 count = 32 - (put_bit - is_bit);
12245 operands[5] = GEN_INT (count);
12246 operands[6] = GEN_INT (put_bit);
12248 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12250 [(set_attr "type" "shift")
12251 (set_attr "dot" "yes")
12252 (set_attr "length" "8,16")])
12255 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
12257 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12258 [(match_operand 2 "cc_reg_operand")
12260 (match_operand:SI 3 "const_int_operand"))
12262 (set (match_operand:SI 4 "gpc_reg_operand")
12263 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12266 [(set (match_dup 4)
12267 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12270 (compare:CC (match_dup 4)
12275 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12278 (define_insn_and_split "eq<mode>3"
12279 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12280 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12281 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12282 (clobber (match_scratch:GPR 3 "=r"))
12283 (clobber (match_scratch:GPR 4 "=r"))]
12287 [(set (match_dup 4)
12288 (clz:GPR (match_dup 3)))
12290 (lshiftrt:GPR (match_dup 4)
12293 operands[3] = rs6000_emit_eqne (<MODE>mode,
12294 operands[1], operands[2], operands[3]);
12296 if (GET_CODE (operands[4]) == SCRATCH)
12297 operands[4] = gen_reg_rtx (<MODE>mode);
12299 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12301 [(set (attr "length")
12302 (if_then_else (match_test "operands[2] == const0_rtx")
12304 (const_string "12")))])
12306 (define_insn_and_split "ne<mode>3"
12307 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12308 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12309 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12310 (clobber (match_scratch:P 3 "=r"))
12311 (clobber (match_scratch:P 4 "=r"))
12312 (clobber (reg:P CA_REGNO))]
12316 [(parallel [(set (match_dup 4)
12317 (plus:P (match_dup 3)
12319 (set (reg:P CA_REGNO)
12320 (ne:P (match_dup 3)
12322 (parallel [(set (match_dup 0)
12323 (plus:P (plus:P (not:P (match_dup 4))
12326 (clobber (reg:P CA_REGNO))])]
12328 operands[3] = rs6000_emit_eqne (<MODE>mode,
12329 operands[1], operands[2], operands[3]);
12331 if (GET_CODE (operands[4]) == SCRATCH)
12332 operands[4] = gen_reg_rtx (<MODE>mode);
12334 [(set (attr "length")
12335 (if_then_else (match_test "operands[2] == const0_rtx")
12337 (const_string "12")))])
12339 (define_insn_and_split "*neg_eq_<mode>"
12340 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12341 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12342 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12343 (clobber (match_scratch:P 3 "=r"))
12344 (clobber (match_scratch:P 4 "=r"))
12345 (clobber (reg:P CA_REGNO))]
12349 [(parallel [(set (match_dup 4)
12350 (plus:P (match_dup 3)
12352 (set (reg:P CA_REGNO)
12353 (ne:P (match_dup 3)
12355 (parallel [(set (match_dup 0)
12356 (plus:P (reg:P CA_REGNO)
12358 (clobber (reg:P CA_REGNO))])]
12360 operands[3] = rs6000_emit_eqne (<MODE>mode,
12361 operands[1], operands[2], operands[3]);
12363 if (GET_CODE (operands[4]) == SCRATCH)
12364 operands[4] = gen_reg_rtx (<MODE>mode);
12366 [(set (attr "length")
12367 (if_then_else (match_test "operands[2] == const0_rtx")
12369 (const_string "12")))])
12371 (define_insn_and_split "*neg_ne_<mode>"
12372 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12373 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12374 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12375 (clobber (match_scratch:P 3 "=r"))
12376 (clobber (match_scratch:P 4 "=r"))
12377 (clobber (reg:P CA_REGNO))]
12381 [(parallel [(set (match_dup 4)
12382 (neg:P (match_dup 3)))
12383 (set (reg:P CA_REGNO)
12384 (eq:P (match_dup 3)
12386 (parallel [(set (match_dup 0)
12387 (plus:P (reg:P CA_REGNO)
12389 (clobber (reg:P CA_REGNO))])]
12391 operands[3] = rs6000_emit_eqne (<MODE>mode,
12392 operands[1], operands[2], operands[3]);
12394 if (GET_CODE (operands[4]) == SCRATCH)
12395 operands[4] = gen_reg_rtx (<MODE>mode);
12397 [(set (attr "length")
12398 (if_then_else (match_test "operands[2] == const0_rtx")
12400 (const_string "12")))])
12402 (define_insn_and_split "*plus_eq_<mode>"
12403 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12404 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12405 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12406 (match_operand:P 3 "gpc_reg_operand" "r")))
12407 (clobber (match_scratch:P 4 "=r"))
12408 (clobber (match_scratch:P 5 "=r"))
12409 (clobber (reg:P CA_REGNO))]
12413 [(parallel [(set (match_dup 5)
12414 (neg:P (match_dup 4)))
12415 (set (reg:P CA_REGNO)
12416 (eq:P (match_dup 4)
12418 (parallel [(set (match_dup 0)
12419 (plus:P (match_dup 3)
12421 (clobber (reg:P CA_REGNO))])]
12423 operands[4] = rs6000_emit_eqne (<MODE>mode,
12424 operands[1], operands[2], operands[4]);
12426 if (GET_CODE (operands[5]) == SCRATCH)
12427 operands[5] = gen_reg_rtx (<MODE>mode);
12429 [(set (attr "length")
12430 (if_then_else (match_test "operands[2] == const0_rtx")
12432 (const_string "12")))])
12434 (define_insn_and_split "*plus_ne_<mode>"
12435 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12436 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12437 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12438 (match_operand:P 3 "gpc_reg_operand" "r")))
12439 (clobber (match_scratch:P 4 "=r"))
12440 (clobber (match_scratch:P 5 "=r"))
12441 (clobber (reg:P CA_REGNO))]
12445 [(parallel [(set (match_dup 5)
12446 (plus:P (match_dup 4)
12448 (set (reg:P CA_REGNO)
12449 (ne:P (match_dup 4)
12451 (parallel [(set (match_dup 0)
12452 (plus:P (match_dup 3)
12454 (clobber (reg:P CA_REGNO))])]
12456 operands[4] = rs6000_emit_eqne (<MODE>mode,
12457 operands[1], operands[2], operands[4]);
12459 if (GET_CODE (operands[5]) == SCRATCH)
12460 operands[5] = gen_reg_rtx (<MODE>mode);
12462 [(set (attr "length")
12463 (if_then_else (match_test "operands[2] == const0_rtx")
12465 (const_string "12")))])
12467 (define_insn_and_split "*minus_eq_<mode>"
12468 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12469 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12470 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12471 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12472 (clobber (match_scratch:P 4 "=r"))
12473 (clobber (match_scratch:P 5 "=r"))
12474 (clobber (reg:P CA_REGNO))]
12478 [(parallel [(set (match_dup 5)
12479 (plus:P (match_dup 4)
12481 (set (reg:P CA_REGNO)
12482 (ne:P (match_dup 4)
12484 (parallel [(set (match_dup 0)
12485 (plus:P (plus:P (match_dup 3)
12488 (clobber (reg:P CA_REGNO))])]
12490 operands[4] = rs6000_emit_eqne (<MODE>mode,
12491 operands[1], operands[2], operands[4]);
12493 if (GET_CODE (operands[5]) == SCRATCH)
12494 operands[5] = gen_reg_rtx (<MODE>mode);
12496 [(set (attr "length")
12497 (if_then_else (match_test "operands[2] == const0_rtx")
12499 (const_string "12")))])
12501 (define_insn_and_split "*minus_ne_<mode>"
12502 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12503 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12504 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12505 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12506 (clobber (match_scratch:P 4 "=r"))
12507 (clobber (match_scratch:P 5 "=r"))
12508 (clobber (reg:P CA_REGNO))]
12512 [(parallel [(set (match_dup 5)
12513 (neg:P (match_dup 4)))
12514 (set (reg:P CA_REGNO)
12515 (eq:P (match_dup 4)
12517 (parallel [(set (match_dup 0)
12518 (plus:P (plus:P (match_dup 3)
12521 (clobber (reg:P CA_REGNO))])]
12523 operands[4] = rs6000_emit_eqne (<MODE>mode,
12524 operands[1], operands[2], operands[4]);
12526 if (GET_CODE (operands[5]) == SCRATCH)
12527 operands[5] = gen_reg_rtx (<MODE>mode);
12529 [(set (attr "length")
12530 (if_then_else (match_test "operands[2] == const0_rtx")
12532 (const_string "12")))])
12534 (define_insn_and_split "*eqsi3_ext<mode>"
12535 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12536 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12537 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12538 (clobber (match_scratch:SI 3 "=r"))
12539 (clobber (match_scratch:SI 4 "=r"))]
12543 [(set (match_dup 4)
12544 (clz:SI (match_dup 3)))
12547 (lshiftrt:SI (match_dup 4)
12550 operands[3] = rs6000_emit_eqne (SImode,
12551 operands[1], operands[2], operands[3]);
12553 if (GET_CODE (operands[4]) == SCRATCH)
12554 operands[4] = gen_reg_rtx (SImode);
12556 [(set (attr "length")
12557 (if_then_else (match_test "operands[2] == const0_rtx")
12559 (const_string "12")))])
12561 (define_insn_and_split "*nesi3_ext<mode>"
12562 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12563 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12564 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12565 (clobber (match_scratch:SI 3 "=r"))
12566 (clobber (match_scratch:SI 4 "=r"))
12567 (clobber (match_scratch:EXTSI 5 "=r"))]
12571 [(set (match_dup 4)
12572 (clz:SI (match_dup 3)))
12575 (lshiftrt:SI (match_dup 4)
12578 (xor:EXTSI (match_dup 5)
12581 operands[3] = rs6000_emit_eqne (SImode,
12582 operands[1], operands[2], operands[3]);
12584 if (GET_CODE (operands[4]) == SCRATCH)
12585 operands[4] = gen_reg_rtx (SImode);
12586 if (GET_CODE (operands[5]) == SCRATCH)
12587 operands[5] = gen_reg_rtx (<MODE>mode);
12589 [(set (attr "length")
12590 (if_then_else (match_test "operands[2] == const0_rtx")
12591 (const_string "12")
12592 (const_string "16")))])
12594 ;; Define both directions of branch and return. If we need a reload
12595 ;; register, we'd rather use CR0 since it is much easier to copy a
12596 ;; register CC value to there.
12600 (if_then_else (match_operator 1 "branch_comparison_operator"
12602 "cc_reg_operand" "y")
12604 (label_ref (match_operand 0 "" ""))
12609 return output_cbranch (operands[1], \"%l0\", 0, insn);
12611 [(set_attr "type" "branch")])
12615 (if_then_else (match_operator 0 "branch_comparison_operator"
12617 "cc_reg_operand" "y")
12624 return output_cbranch (operands[0], NULL, 0, insn);
12626 [(set_attr "type" "jmpreg")
12627 (set_attr "length" "4")])
12631 (if_then_else (match_operator 1 "branch_comparison_operator"
12633 "cc_reg_operand" "y")
12636 (label_ref (match_operand 0 "" ""))))]
12640 return output_cbranch (operands[1], \"%l0\", 1, insn);
12642 [(set_attr "type" "branch")])
12646 (if_then_else (match_operator 0 "branch_comparison_operator"
12648 "cc_reg_operand" "y")
12655 return output_cbranch (operands[0], NULL, 1, insn);
12657 [(set_attr "type" "jmpreg")
12658 (set_attr "length" "4")])
12660 ;; Logic on condition register values.
12662 ; This pattern matches things like
12663 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12664 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12666 ; which are generated by the branch logic.
12667 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12669 (define_insn "*cceq_ior_compare"
12670 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12671 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12672 [(match_operator:SI 2
12673 "branch_positive_comparison_operator"
12675 "cc_reg_operand" "y,y")
12677 (match_operator:SI 4
12678 "branch_positive_comparison_operator"
12680 "cc_reg_operand" "0,y")
12684 "cr%q1 %E0,%j2,%j4"
12685 [(set_attr "type" "cr_logical,delayed_cr")])
12687 ; Why is the constant -1 here, but 1 in the previous pattern?
12688 ; Because ~1 has all but the low bit set.
12690 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12691 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12692 [(not:SI (match_operator:SI 2
12693 "branch_positive_comparison_operator"
12695 "cc_reg_operand" "y,y")
12697 (match_operator:SI 4
12698 "branch_positive_comparison_operator"
12700 "cc_reg_operand" "0,y")
12704 "cr%q1 %E0,%j2,%j4"
12705 [(set_attr "type" "cr_logical,delayed_cr")])
12707 (define_insn "*cceq_rev_compare"
12708 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12709 (compare:CCEQ (match_operator:SI 1
12710 "branch_positive_comparison_operator"
12712 "cc_reg_operand" "0,y")
12717 [(set_attr "type" "cr_logical,delayed_cr")])
12719 ;; If we are comparing the result of two comparisons, this can be done
12720 ;; using creqv or crxor.
12722 (define_insn_and_split ""
12723 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12724 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12725 [(match_operand 2 "cc_reg_operand" "y")
12727 (match_operator 3 "branch_comparison_operator"
12728 [(match_operand 4 "cc_reg_operand" "y")
12733 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12737 int positive_1, positive_2;
12739 positive_1 = branch_positive_comparison_operator (operands[1],
12740 GET_MODE (operands[1]));
12741 positive_2 = branch_positive_comparison_operator (operands[3],
12742 GET_MODE (operands[3]));
12745 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12746 GET_CODE (operands[1])),
12748 operands[2], const0_rtx);
12749 else if (GET_MODE (operands[1]) != SImode)
12750 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12751 operands[2], const0_rtx);
12754 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12755 GET_CODE (operands[3])),
12757 operands[4], const0_rtx);
12758 else if (GET_MODE (operands[3]) != SImode)
12759 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12760 operands[4], const0_rtx);
12762 if (positive_1 == positive_2)
12764 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12765 operands[5] = constm1_rtx;
12769 operands[5] = const1_rtx;
12773 ;; Unconditional branch and return.
12775 (define_insn "jump"
12777 (label_ref (match_operand 0 "" "")))]
12780 [(set_attr "type" "branch")])
12782 (define_insn "<return_str>return"
12786 [(set_attr "type" "jmpreg")])
12788 (define_expand "indirect_jump"
12789 [(set (pc) (match_operand 0 "register_operand" ""))])
12791 (define_insn "*indirect_jump<mode>"
12792 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12797 [(set_attr "type" "jmpreg")])
12799 ;; Table jump for switch statements:
12800 (define_expand "tablejump"
12801 [(use (match_operand 0 "" ""))
12802 (use (label_ref (match_operand 1 "" "")))]
12807 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12809 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12813 (define_expand "tablejumpsi"
12814 [(set (match_dup 3)
12815 (plus:SI (match_operand:SI 0 "" "")
12817 (parallel [(set (pc) (match_dup 3))
12818 (use (label_ref (match_operand 1 "" "")))])]
12821 { operands[0] = force_reg (SImode, operands[0]);
12822 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12823 operands[3] = gen_reg_rtx (SImode);
12826 (define_expand "tablejumpdi"
12827 [(set (match_dup 4)
12828 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12830 (plus:DI (match_dup 4)
12832 (parallel [(set (pc) (match_dup 3))
12833 (use (label_ref (match_operand 1 "" "")))])]
12836 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12837 operands[3] = gen_reg_rtx (DImode);
12838 operands[4] = gen_reg_rtx (DImode);
12841 (define_insn "*tablejump<mode>_internal1"
12843 (match_operand:P 0 "register_operand" "c,*l"))
12844 (use (label_ref (match_operand 1 "" "")))]
12849 [(set_attr "type" "jmpreg")])
12852 [(unspec [(const_int 0)] UNSPEC_NOP)]
12856 (define_insn "group_ending_nop"
12857 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12861 if (rs6000_cpu_attr == CPU_POWER6)
12862 return \"ori 1,1,0\";
12863 return \"ori 2,2,0\";
12866 ;; Define the subtract-one-and-jump insns, starting with the template
12867 ;; so loop.c knows what to generate.
12869 (define_expand "doloop_end"
12870 [(use (match_operand 0 "" "")) ; loop pseudo
12871 (use (match_operand 1 "" ""))] ; label
12877 if (GET_MODE (operands[0]) != DImode)
12879 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12883 if (GET_MODE (operands[0]) != SImode)
12885 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12890 (define_expand "ctr<mode>"
12891 [(parallel [(set (pc)
12892 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12894 (label_ref (match_operand 1 "" ""))
12897 (plus:P (match_dup 0)
12899 (clobber (match_scratch:CC 2 ""))
12900 (clobber (match_scratch:P 3 ""))])]
12904 ;; We need to be able to do this for any operand, including MEM, or we
12905 ;; will cause reload to blow up since we don't allow output reloads on
12907 ;; For the length attribute to be calculated correctly, the
12908 ;; label MUST be operand 0.
12909 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12910 ;; the ctr<mode> insns.
12912 (define_insn "ctr<mode>_internal1"
12914 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12916 (label_ref (match_operand 0 "" ""))
12918 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12919 (plus:P (match_dup 1)
12921 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12922 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12926 if (which_alternative != 0)
12928 else if (get_attr_length (insn) == 4)
12929 return \"bdnz %l0\";
12931 return \"bdz $+8\;b %l0\";
12933 [(set_attr "type" "branch")
12934 (set_attr "length" "*,16,20,20")])
12936 (define_insn "ctr<mode>_internal2"
12938 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12941 (label_ref (match_operand 0 "" ""))))
12942 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12943 (plus:P (match_dup 1)
12945 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12946 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12950 if (which_alternative != 0)
12952 else if (get_attr_length (insn) == 4)
12953 return \"bdz %l0\";
12955 return \"bdnz $+8\;b %l0\";
12957 [(set_attr "type" "branch")
12958 (set_attr "length" "*,16,20,20")])
12960 ;; Similar but use EQ
12962 (define_insn "ctr<mode>_internal3"
12964 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12966 (label_ref (match_operand 0 "" ""))
12968 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12969 (plus:P (match_dup 1)
12971 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12972 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12976 if (which_alternative != 0)
12978 else if (get_attr_length (insn) == 4)
12979 return \"bdz %l0\";
12981 return \"bdnz $+8\;b %l0\";
12983 [(set_attr "type" "branch")
12984 (set_attr "length" "*,16,20,20")])
12986 (define_insn "ctr<mode>_internal4"
12988 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12991 (label_ref (match_operand 0 "" ""))))
12992 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12993 (plus:P (match_dup 1)
12995 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12996 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13000 if (which_alternative != 0)
13002 else if (get_attr_length (insn) == 4)
13003 return \"bdnz %l0\";
13005 return \"bdz $+8\;b %l0\";
13007 [(set_attr "type" "branch")
13008 (set_attr "length" "*,16,20,20")])
13010 ;; Now the splitters if we could not allocate the CTR register
13014 (if_then_else (match_operator 2 "comparison_operator"
13015 [(match_operand:P 1 "gpc_reg_operand" "")
13017 (match_operand 5 "" "")
13018 (match_operand 6 "" "")))
13019 (set (match_operand:P 0 "int_reg_operand" "")
13020 (plus:P (match_dup 1) (const_int -1)))
13021 (clobber (match_scratch:CC 3 ""))
13022 (clobber (match_scratch:P 4 ""))]
13024 [(set (match_dup 3)
13025 (compare:CC (match_dup 1)
13028 (plus:P (match_dup 1)
13030 (set (pc) (if_then_else (match_dup 7)
13034 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13035 operands[3], const0_rtx); }")
13039 (if_then_else (match_operator 2 "comparison_operator"
13040 [(match_operand:P 1 "gpc_reg_operand" "")
13042 (match_operand 5 "" "")
13043 (match_operand 6 "" "")))
13044 (set (match_operand:P 0 "nonimmediate_operand" "")
13045 (plus:P (match_dup 1) (const_int -1)))
13046 (clobber (match_scratch:CC 3 ""))
13047 (clobber (match_scratch:P 4 ""))]
13048 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
13049 [(set (match_dup 3)
13050 (compare:CC (match_dup 1)
13053 (plus:P (match_dup 1)
13057 (set (pc) (if_then_else (match_dup 7)
13061 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13062 operands[3], const0_rtx); }")
13064 (define_insn "trap"
13065 [(trap_if (const_int 1) (const_int 0))]
13068 [(set_attr "type" "trap")])
13070 (define_expand "ctrap<mode>4"
13071 [(trap_if (match_operator 0 "ordered_comparison_operator"
13072 [(match_operand:GPR 1 "register_operand")
13073 (match_operand:GPR 2 "reg_or_short_operand")])
13074 (match_operand 3 "zero_constant" ""))]
13079 [(trap_if (match_operator 0 "ordered_comparison_operator"
13080 [(match_operand:GPR 1 "register_operand" "r")
13081 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13084 "t<wd>%V0%I2 %1,%2"
13085 [(set_attr "type" "trap")])
13087 ;; Insns related to generating the function prologue and epilogue.
13089 (define_expand "prologue"
13090 [(use (const_int 0))]
13093 rs6000_emit_prologue ();
13094 if (!TARGET_SCHED_PROLOG)
13095 emit_insn (gen_blockage ());
13099 (define_insn "*movesi_from_cr_one"
13100 [(match_parallel 0 "mfcr_operation"
13101 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13102 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13103 (match_operand 3 "immediate_operand" "n")]
13104 UNSPEC_MOVESI_FROM_CR))])]
13110 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13112 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13113 operands[4] = GEN_INT (mask);
13114 output_asm_insn (\"mfcr %1,%4\", operands);
13118 [(set_attr "type" "mfcrf")])
13120 ;; Don't include the volatile CRs since their values are not used wrt CR save
13121 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13122 ;; prologue past an insn (early exit test) that defines a register used in the
13124 (define_insn "prologue_movesi_from_cr"
13125 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13126 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13127 (reg:CC CR4_REGNO)]
13128 UNSPEC_MOVESI_FROM_CR))]
13131 [(set_attr "type" "mfcr")])
13133 (define_insn "*crsave"
13134 [(match_parallel 0 "crsave_operation"
13135 [(set (match_operand:SI 1 "memory_operand" "=m")
13136 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13139 [(set_attr "type" "store")])
13141 (define_insn "*stmw"
13142 [(match_parallel 0 "stmw_operation"
13143 [(set (match_operand:SI 1 "memory_operand" "=m")
13144 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13147 [(set_attr "type" "store")
13148 (set_attr "update" "yes")
13149 (set_attr "indexed" "yes")])
13151 ; The following comment applies to:
13155 ; return_and_restore_gpregs*
13156 ; return_and_restore_fpregs*
13157 ; return_and_restore_fpregs_aix*
13159 ; The out-of-line save / restore functions expects one input argument.
13160 ; Since those are not standard call_insn's, we must avoid using
13161 ; MATCH_OPERAND for that argument. That way the register rename
13162 ; optimization will not try to rename this register.
13163 ; Each pattern is repeated for each possible register number used in
13164 ; various ABIs (r11, r1, and for some functions r12)
13166 (define_insn "*save_gpregs_<mode>_r11"
13167 [(match_parallel 0 "any_parallel_operand"
13168 [(clobber (reg:P LR_REGNO))
13169 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13171 (set (match_operand:P 2 "memory_operand" "=m")
13172 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13175 [(set_attr "type" "branch")
13176 (set_attr "length" "4")])
13178 (define_insn "*save_gpregs_<mode>_r12"
13179 [(match_parallel 0 "any_parallel_operand"
13180 [(clobber (reg:P LR_REGNO))
13181 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13183 (set (match_operand:P 2 "memory_operand" "=m")
13184 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13187 [(set_attr "type" "branch")
13188 (set_attr "length" "4")])
13190 (define_insn "*save_gpregs_<mode>_r1"
13191 [(match_parallel 0 "any_parallel_operand"
13192 [(clobber (reg:P LR_REGNO))
13193 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13195 (set (match_operand:P 2 "memory_operand" "=m")
13196 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13199 [(set_attr "type" "branch")
13200 (set_attr "length" "4")])
13202 (define_insn "*save_fpregs_<mode>_r11"
13203 [(match_parallel 0 "any_parallel_operand"
13204 [(clobber (reg:P LR_REGNO))
13205 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13207 (set (match_operand:DF 2 "memory_operand" "=m")
13208 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13211 [(set_attr "type" "branch")
13212 (set_attr "length" "4")])
13214 (define_insn "*save_fpregs_<mode>_r12"
13215 [(match_parallel 0 "any_parallel_operand"
13216 [(clobber (reg:P LR_REGNO))
13217 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13219 (set (match_operand:DF 2 "memory_operand" "=m")
13220 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13223 [(set_attr "type" "branch")
13224 (set_attr "length" "4")])
13226 (define_insn "*save_fpregs_<mode>_r1"
13227 [(match_parallel 0 "any_parallel_operand"
13228 [(clobber (reg:P LR_REGNO))
13229 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13231 (set (match_operand:DF 2 "memory_operand" "=m")
13232 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13235 [(set_attr "type" "branch")
13236 (set_attr "length" "4")])
13238 ; This is to explain that changes to the stack pointer should
13239 ; not be moved over loads from or stores to stack memory.
13240 (define_insn "stack_tie"
13241 [(match_parallel 0 "tie_operand"
13242 [(set (mem:BLK (reg 1)) (const_int 0))])]
13245 [(set_attr "length" "0")])
13247 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13248 ; stay behind all restores from the stack, it cannot be reordered to before
13249 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13250 (define_insn "stack_restore_tie"
13251 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13252 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13253 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13254 (set (mem:BLK (scratch)) (const_int 0))]
13259 [(set_attr "type" "*,add")])
13261 (define_expand "epilogue"
13262 [(use (const_int 0))]
13265 if (!TARGET_SCHED_PROLOG)
13266 emit_insn (gen_blockage ());
13267 rs6000_emit_epilogue (FALSE);
13271 ; On some processors, doing the mtcrf one CC register at a time is
13272 ; faster (like on the 604e). On others, doing them all at once is
13273 ; faster; for instance, on the 601 and 750.
13275 (define_expand "movsi_to_cr_one"
13276 [(set (match_operand:CC 0 "cc_reg_operand" "")
13277 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13278 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13280 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13282 (define_insn "*movsi_to_cr"
13283 [(match_parallel 0 "mtcrf_operation"
13284 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13285 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13286 (match_operand 3 "immediate_operand" "n")]
13287 UNSPEC_MOVESI_TO_CR))])]
13293 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13294 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13295 operands[4] = GEN_INT (mask);
13296 return \"mtcrf %4,%2\";
13298 [(set_attr "type" "mtcr")])
13300 (define_insn "*mtcrfsi"
13301 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13302 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13303 (match_operand 2 "immediate_operand" "n")]
13304 UNSPEC_MOVESI_TO_CR))]
13305 "GET_CODE (operands[0]) == REG
13306 && CR_REGNO_P (REGNO (operands[0]))
13307 && GET_CODE (operands[2]) == CONST_INT
13308 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13310 [(set_attr "type" "mtcr")])
13312 ; The load-multiple instructions have similar properties.
13313 ; Note that "load_multiple" is a name known to the machine-independent
13314 ; code that actually corresponds to the PowerPC load-string.
13316 (define_insn "*lmw"
13317 [(match_parallel 0 "lmw_operation"
13318 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13319 (match_operand:SI 2 "memory_operand" "m"))])]
13322 [(set_attr "type" "load")
13323 (set_attr "update" "yes")
13324 (set_attr "indexed" "yes")
13325 (set_attr "cell_micro" "always")])
13327 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13328 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13330 ; The following comment applies to:
13334 ; return_and_restore_gpregs*
13335 ; return_and_restore_fpregs*
13336 ; return_and_restore_fpregs_aix*
13338 ; The out-of-line save / restore functions expects one input argument.
13339 ; Since those are not standard call_insn's, we must avoid using
13340 ; MATCH_OPERAND for that argument. That way the register rename
13341 ; optimization will not try to rename this register.
13342 ; Each pattern is repeated for each possible register number used in
13343 ; various ABIs (r11, r1, and for some functions r12)
13345 (define_insn "*restore_gpregs_<mode>_r11"
13346 [(match_parallel 0 "any_parallel_operand"
13347 [(clobber (reg:P LR_REGNO))
13348 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13350 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13351 (match_operand:P 3 "memory_operand" "m"))])]
13354 [(set_attr "type" "branch")
13355 (set_attr "length" "4")])
13357 (define_insn "*restore_gpregs_<mode>_r12"
13358 [(match_parallel 0 "any_parallel_operand"
13359 [(clobber (reg:P LR_REGNO))
13360 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13362 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13363 (match_operand:P 3 "memory_operand" "m"))])]
13366 [(set_attr "type" "branch")
13367 (set_attr "length" "4")])
13369 (define_insn "*restore_gpregs_<mode>_r1"
13370 [(match_parallel 0 "any_parallel_operand"
13371 [(clobber (reg:P LR_REGNO))
13372 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13374 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13375 (match_operand:P 3 "memory_operand" "m"))])]
13378 [(set_attr "type" "branch")
13379 (set_attr "length" "4")])
13381 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13382 [(match_parallel 0 "any_parallel_operand"
13384 (clobber (reg:P LR_REGNO))
13385 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13387 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13388 (match_operand:P 3 "memory_operand" "m"))])]
13391 [(set_attr "type" "branch")
13392 (set_attr "length" "4")])
13394 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13395 [(match_parallel 0 "any_parallel_operand"
13397 (clobber (reg:P LR_REGNO))
13398 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13400 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13401 (match_operand:P 3 "memory_operand" "m"))])]
13404 [(set_attr "type" "branch")
13405 (set_attr "length" "4")])
13407 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13408 [(match_parallel 0 "any_parallel_operand"
13410 (clobber (reg:P LR_REGNO))
13411 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13413 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13414 (match_operand:P 3 "memory_operand" "m"))])]
13417 [(set_attr "type" "branch")
13418 (set_attr "length" "4")])
13420 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13421 [(match_parallel 0 "any_parallel_operand"
13423 (clobber (reg:P LR_REGNO))
13424 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13426 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13427 (match_operand:DF 3 "memory_operand" "m"))])]
13430 [(set_attr "type" "branch")
13431 (set_attr "length" "4")])
13433 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13434 [(match_parallel 0 "any_parallel_operand"
13436 (clobber (reg:P LR_REGNO))
13437 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13439 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13440 (match_operand:DF 3 "memory_operand" "m"))])]
13443 [(set_attr "type" "branch")
13444 (set_attr "length" "4")])
13446 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13447 [(match_parallel 0 "any_parallel_operand"
13449 (clobber (reg:P LR_REGNO))
13450 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13452 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13453 (match_operand:DF 3 "memory_operand" "m"))])]
13456 [(set_attr "type" "branch")
13457 (set_attr "length" "4")])
13459 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13460 [(match_parallel 0 "any_parallel_operand"
13462 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13464 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13465 (match_operand:DF 3 "memory_operand" "m"))])]
13468 [(set_attr "type" "branch")
13469 (set_attr "length" "4")])
13471 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13472 [(match_parallel 0 "any_parallel_operand"
13474 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13476 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13477 (match_operand:DF 3 "memory_operand" "m"))])]
13480 [(set_attr "type" "branch")
13481 (set_attr "length" "4")])
13483 ; This is used in compiling the unwind routines.
13484 (define_expand "eh_return"
13485 [(use (match_operand 0 "general_operand" ""))]
13490 emit_insn (gen_eh_set_lr_si (operands[0]));
13492 emit_insn (gen_eh_set_lr_di (operands[0]));
13496 ; We can't expand this before we know where the link register is stored.
13497 (define_insn "eh_set_lr_<mode>"
13498 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13500 (clobber (match_scratch:P 1 "=&b"))]
13505 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13506 (clobber (match_scratch 1 ""))]
13511 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13515 (define_insn "prefetch"
13516 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13517 (match_operand:SI 1 "const_int_operand" "n")
13518 (match_operand:SI 2 "const_int_operand" "n"))]
13522 if (GET_CODE (operands[0]) == REG)
13523 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13524 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13526 [(set_attr "type" "load")])
13528 ;; Handle -fsplit-stack.
13530 (define_expand "split_stack_prologue"
13534 rs6000_expand_split_stack_prologue ();
13538 (define_expand "load_split_stack_limit"
13539 [(set (match_operand 0)
13540 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13543 emit_insn (gen_rtx_SET (operands[0],
13544 gen_rtx_UNSPEC (Pmode,
13545 gen_rtvec (1, const0_rtx),
13546 UNSPEC_STACK_CHECK)));
13550 (define_insn "load_split_stack_limit_di"
13551 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13552 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13554 "ld %0,-0x7040(13)"
13555 [(set_attr "type" "load")
13556 (set_attr "update" "no")
13557 (set_attr "indexed" "no")])
13559 (define_insn "load_split_stack_limit_si"
13560 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13561 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13563 "lwz %0,-0x7020(2)"
13564 [(set_attr "type" "load")
13565 (set_attr "update" "no")
13566 (set_attr "indexed" "no")])
13568 ;; A return instruction which the middle-end doesn't see.
13569 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13570 ;; after the call to __morestack.
13571 (define_insn "split_stack_return"
13572 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13575 [(set_attr "type" "jmpreg")])
13577 ;; If there are operand 0 bytes available on the stack, jump to
13579 (define_expand "split_stack_space_check"
13580 [(set (match_dup 2)
13581 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13583 (minus (reg STACK_POINTER_REGNUM)
13584 (match_operand 0)))
13585 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13586 (set (pc) (if_then_else
13587 (geu (match_dup 4) (const_int 0))
13588 (label_ref (match_operand 1))
13592 rs6000_split_stack_space_check (operands[0], operands[1]);
13596 (define_insn "bpermd_<mode>"
13597 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13598 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13599 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13602 [(set_attr "type" "popcnt")])
13605 ;; Builtin fma support. Handle
13606 ;; Note that the conditions for expansion are in the FMA_F iterator.
13608 (define_expand "fma<mode>4"
13609 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13611 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13612 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13613 (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13617 (define_insn "*fma<mode>4_fpr"
13618 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13620 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13621 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13622 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13623 "TARGET_<MODE>_FPR"
13625 fmadd<Ftrad> %0,%1,%2,%3
13626 xsmadda<Fvsx> %x0,%x1,%x2
13627 xsmaddm<Fvsx> %x0,%x1,%x3"
13628 [(set_attr "type" "fp")
13629 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13631 ; Altivec only has fma and nfms.
13632 (define_expand "fms<mode>4"
13633 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13635 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13636 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13637 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13638 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13641 (define_insn "*fms<mode>4_fpr"
13642 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13644 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13645 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13646 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13647 "TARGET_<MODE>_FPR"
13649 fmsub<Ftrad> %0,%1,%2,%3
13650 xsmsuba<Fvsx> %x0,%x1,%x2
13651 xsmsubm<Fvsx> %x0,%x1,%x3"
13652 [(set_attr "type" "fp")
13653 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13655 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13656 (define_expand "fnma<mode>4"
13657 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13660 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13661 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13662 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13663 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13666 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13667 (define_expand "fnms<mode>4"
13668 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13671 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13672 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13673 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13674 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13677 ; Not an official optab name, but used from builtins.
13678 (define_expand "nfma<mode>4"
13679 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13682 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13683 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13684 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13685 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13688 (define_insn "*nfma<mode>4_fpr"
13689 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13692 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13693 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13694 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13695 "TARGET_<MODE>_FPR"
13697 fnmadd<Ftrad> %0,%1,%2,%3
13698 xsnmadda<Fvsx> %x0,%x1,%x2
13699 xsnmaddm<Fvsx> %x0,%x1,%x3"
13700 [(set_attr "type" "fp")
13701 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13703 ; Not an official optab name, but used from builtins.
13704 (define_expand "nfms<mode>4"
13705 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13708 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13709 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13710 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13714 (define_insn "*nfmssf4_fpr"
13715 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13718 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13719 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13721 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13722 "TARGET_<MODE>_FPR"
13724 fnmsub<Ftrad> %0,%1,%2,%3
13725 xsnmsuba<Fvsx> %x0,%x1,%x2
13726 xsnmsubm<Fvsx> %x0,%x1,%x3"
13727 [(set_attr "type" "fp")
13728 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13731 (define_expand "rs6000_get_timebase"
13732 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13735 if (TARGET_POWERPC64)
13736 emit_insn (gen_rs6000_mftb_di (operands[0]));
13738 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13742 (define_insn "rs6000_get_timebase_ppc32"
13743 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13744 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13745 (clobber (match_scratch:SI 1 "=r"))
13746 (clobber (match_scratch:CC 2 "=y"))]
13747 "!TARGET_POWERPC64"
13749 if (WORDS_BIG_ENDIAN)
13752 return "mfspr %0,269\;"
13760 return "mftbu %0\;"
13769 return "mfspr %L0,269\;"
13777 return "mftbu %L0\;"
13784 [(set_attr "length" "20")])
13786 (define_insn "rs6000_mftb_<mode>"
13787 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13788 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13792 return "mfspr %0,268";
13798 (define_insn "rs6000_mffs"
13799 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13800 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13801 "TARGET_HARD_FLOAT"
13804 (define_insn "rs6000_mtfsf"
13805 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13806 (match_operand:DF 1 "gpc_reg_operand" "d")]
13808 "TARGET_HARD_FLOAT"
13812 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13813 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13814 ;; register that is being loaded. The fused ops must be physically adjacent.
13816 ;; There are two parts to addis fusion. The support for fused TOCs occur
13817 ;; before register allocation, and is meant to reduce the lifetime for the
13818 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13819 ;; to use the register that is being load. The peephole2 then gathers any
13820 ;; other fused possibilities that it can find after register allocation. If
13821 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13823 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13824 ;; before register allocation, so that we can avoid allocating a temporary base
13825 ;; register that won't be used, and that we try to load into base registers,
13826 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13827 ;; (addis followed by load) even on power8.
13830 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13831 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13832 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13833 [(parallel [(set (match_dup 0) (match_dup 2))
13834 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13835 (use (match_dup 3))
13836 (clobber (scratch:DI))])]
13838 operands[2] = fusion_wrap_memory_address (operands[1]);
13839 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13842 (define_insn "*toc_fusionload_<mode>"
13843 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13844 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13845 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13846 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13847 (clobber (match_scratch:DI 3 "=X,&b"))]
13848 "TARGET_TOC_FUSION_INT"
13850 if (base_reg_operand (operands[0], <MODE>mode))
13851 return emit_fusion_gpr_load (operands[0], operands[1]);
13853 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13855 [(set_attr "type" "load")
13856 (set_attr "length" "8")])
13858 (define_insn "*toc_fusionload_di"
13859 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13860 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13861 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13862 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13863 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13864 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13865 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13867 if (base_reg_operand (operands[0], DImode))
13868 return emit_fusion_gpr_load (operands[0], operands[1]);
13870 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13872 [(set_attr "type" "load")
13873 (set_attr "length" "8")])
13876 ;; Find cases where the addis that feeds into a load instruction is either used
13877 ;; once or is the same as the target register, and replace it with the fusion
13881 [(set (match_operand:P 0 "base_reg_operand" "")
13882 (match_operand:P 1 "fusion_gpr_addis" ""))
13883 (set (match_operand:INT1 2 "base_reg_operand" "")
13884 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13886 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13890 expand_fusion_gpr_load (operands);
13894 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13897 (define_insn "fusion_gpr_load_<mode>"
13898 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13899 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13900 UNSPEC_FUSION_GPR))]
13903 return emit_fusion_gpr_load (operands[0], operands[1]);
13905 [(set_attr "type" "load")
13906 (set_attr "length" "8")])
13909 ;; ISA 3.0 (power9) fusion support
13910 ;; Merge addis with floating load/store to FPRs (or GPRs).
13912 [(set (match_operand:P 0 "base_reg_operand" "")
13913 (match_operand:P 1 "fusion_gpr_addis" ""))
13914 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13915 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13916 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13917 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13920 expand_fusion_p9_load (operands);
13925 [(set (match_operand:P 0 "base_reg_operand" "")
13926 (match_operand:P 1 "fusion_gpr_addis" ""))
13927 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13928 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13929 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13930 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13931 && !rtx_equal_p (operands[0], operands[3])"
13934 expand_fusion_p9_store (operands);
13939 [(set (match_operand:SDI 0 "int_reg_operand" "")
13940 (match_operand:SDI 1 "upper16_cint_operand" ""))
13942 (ior:SDI (match_dup 0)
13943 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13945 [(set (match_dup 0)
13946 (unspec:SDI [(match_dup 1)
13947 (match_dup 2)] UNSPEC_FUSION_P9))])
13950 [(set (match_operand:SDI 0 "int_reg_operand" "")
13951 (match_operand:SDI 1 "upper16_cint_operand" ""))
13952 (set (match_operand:SDI 2 "int_reg_operand" "")
13953 (ior:SDI (match_dup 0)
13954 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13956 && !rtx_equal_p (operands[0], operands[2])
13957 && peep2_reg_dead_p (2, operands[0])"
13958 [(set (match_dup 2)
13959 (unspec:SDI [(match_dup 1)
13960 (match_dup 3)] UNSPEC_FUSION_P9))])
13962 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13963 ;; reload). Because we want to eventually have secondary_reload generate
13964 ;; these, they have to have a single alternative that gives the register
13965 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13966 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13967 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13969 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13971 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13974 /* This insn is a secondary reload insn, which cannot have alternatives.
13975 If we are not loading up register 0, use the power8 fusion instead. */
13976 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13977 return emit_fusion_gpr_load (operands[0], operands[1]);
13979 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13981 [(set_attr "type" "load")
13982 (set_attr "length" "8")])
13984 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13985 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13987 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13989 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13992 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13994 [(set_attr "type" "store")
13995 (set_attr "length" "8")])
13997 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13998 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
14000 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14002 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14005 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14007 [(set_attr "type" "fpload")
14008 (set_attr "length" "8")])
14010 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
14011 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14013 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
14015 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14018 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14020 [(set_attr "type" "fpstore")
14021 (set_attr "length" "8")])
14023 (define_insn "*fusion_p9_<mode>_constant"
14024 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
14025 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
14026 (match_operand:SDI 2 "u_short_cint_operand" "K")]
14027 UNSPEC_FUSION_P9))]
14030 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
14031 return "ori %0,%0,%2";
14033 [(set_attr "type" "two")
14034 (set_attr "length" "8")])
14037 ;; Optimize cases where we want to do a D-form load (register+offset) on
14038 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14043 ;; and we change this to:
14048 [(match_scratch:P 0 "b")
14049 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14050 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14051 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14053 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14054 [(set (match_dup 0)
14059 rtx tmp_reg = operands[0];
14060 rtx mem = operands[2];
14061 rtx addr = XEXP (mem, 0);
14062 rtx add_op0, add_op1, new_addr;
14064 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14065 add_op0 = XEXP (addr, 0);
14066 add_op1 = XEXP (addr, 1);
14067 gcc_assert (REG_P (add_op0));
14068 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14070 operands[4] = add_op1;
14071 operands[5] = change_address (mem, <MODE>mode, new_addr);
14074 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14075 ;; Altivec register, and the register allocator has generated:
14079 ;; and we change this to:
14084 [(match_scratch:P 0 "b")
14085 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14086 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14087 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14089 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14090 [(set (match_dup 0)
14095 rtx tmp_reg = operands[0];
14096 rtx mem = operands[3];
14097 rtx addr = XEXP (mem, 0);
14098 rtx add_op0, add_op1, new_addr;
14100 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14101 add_op0 = XEXP (addr, 0);
14102 add_op1 = XEXP (addr, 1);
14103 gcc_assert (REG_P (add_op0));
14104 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14106 operands[4] = add_op1;
14107 operands[5] = change_address (mem, <MODE>mode, new_addr);
14111 ;; Miscellaneous ISA 2.06 (power7) instructions
14112 (define_insn "addg6s"
14113 [(set (match_operand:SI 0 "register_operand" "=r")
14114 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14115 (match_operand:SI 2 "register_operand" "r")]
14119 [(set_attr "type" "integer")
14120 (set_attr "length" "4")])
14122 (define_insn "cdtbcd"
14123 [(set (match_operand:SI 0 "register_operand" "=r")
14124 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14128 [(set_attr "type" "integer")
14129 (set_attr "length" "4")])
14131 (define_insn "cbcdtd"
14132 [(set (match_operand:SI 0 "register_operand" "=r")
14133 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14137 [(set_attr "type" "integer")
14138 (set_attr "length" "4")])
14140 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14145 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14146 (UNSPEC_DIVEO "eo")
14147 (UNSPEC_DIVEU "eu")
14148 (UNSPEC_DIVEUO "euo")])
14150 (define_insn "div<div_extend>_<mode>"
14151 [(set (match_operand:GPR 0 "register_operand" "=r")
14152 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14153 (match_operand:GPR 2 "register_operand" "r")]
14154 UNSPEC_DIV_EXTEND))]
14156 "div<wd><div_extend> %0,%1,%2"
14157 [(set_attr "type" "div")
14158 (set_attr "size" "<bits>")])
14161 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14163 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14164 (define_mode_attr FP128_64 [(TF "DF")
14169 (define_expand "unpack<mode>"
14170 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14172 [(match_operand:FMOVE128 1 "register_operand" "")
14173 (match_operand:QI 2 "const_0_to_1_operand" "")]
14174 UNSPEC_UNPACK_128BIT))]
14175 "FLOAT128_2REG_P (<MODE>mode)"
14178 (define_insn_and_split "unpack<mode>_dm"
14179 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14181 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14182 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14183 UNSPEC_UNPACK_128BIT))]
14184 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14186 "&& reload_completed"
14187 [(set (match_dup 0) (match_dup 3))]
14189 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14191 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14193 emit_note (NOTE_INSN_DELETED);
14197 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14199 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14200 (set_attr "length" "4")])
14202 (define_insn_and_split "unpack<mode>_nodm"
14203 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14205 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14206 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14207 UNSPEC_UNPACK_128BIT))]
14208 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14210 "&& reload_completed"
14211 [(set (match_dup 0) (match_dup 3))]
14213 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14215 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14217 emit_note (NOTE_INSN_DELETED);
14221 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14223 [(set_attr "type" "fp,fpstore")
14224 (set_attr "length" "4")])
14226 (define_insn_and_split "pack<mode>"
14227 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14229 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14230 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14231 UNSPEC_PACK_128BIT))]
14232 "FLOAT128_2REG_P (<MODE>mode)"
14236 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14237 [(set (match_dup 3) (match_dup 1))
14238 (set (match_dup 4) (match_dup 2))]
14240 unsigned dest_hi = REGNO (operands[0]);
14241 unsigned dest_lo = dest_hi + 1;
14243 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14244 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14246 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14247 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14249 [(set_attr "type" "fpsimple,fp")
14250 (set_attr "length" "4,8")])
14252 (define_insn "unpack<mode>"
14253 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14254 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14255 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14256 UNSPEC_UNPACK_128BIT))]
14257 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14259 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14260 return ASM_COMMENT_START " xxpermdi to same register";
14262 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14263 return "xxpermdi %x0,%x1,%x1,%3";
14265 [(set_attr "type" "vecperm")])
14267 (define_insn "pack<mode>"
14268 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14269 (unspec:FMOVE128_VSX
14270 [(match_operand:DI 1 "register_operand" "wa")
14271 (match_operand:DI 2 "register_operand" "wa")]
14272 UNSPEC_PACK_128BIT))]
14274 "xxpermdi %x0,%x1,%x2,0"
14275 [(set_attr "type" "vecperm")])
14279 ;; ISA 2.08 IEEE 128-bit floating point support.
14281 (define_insn "add<mode>3"
14282 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14284 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14285 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14286 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14288 [(set_attr "type" "vecfloat")
14289 (set_attr "size" "128")])
14291 (define_insn "sub<mode>3"
14292 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14294 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14295 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14296 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14298 [(set_attr "type" "vecfloat")
14299 (set_attr "size" "128")])
14301 (define_insn "mul<mode>3"
14302 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14304 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14305 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14306 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14308 [(set_attr "type" "vecfloat")
14309 (set_attr "size" "128")])
14311 (define_insn "div<mode>3"
14312 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14314 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14315 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14316 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14318 [(set_attr "type" "vecdiv")
14319 (set_attr "size" "128")])
14321 (define_insn "sqrt<mode>2"
14322 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14324 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14325 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14327 [(set_attr "type" "vecdiv")
14328 (set_attr "size" "128")])
14330 (define_expand "copysign<mode>3"
14331 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14332 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14333 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14334 "FLOAT128_IEEE_P (<MODE>mode)"
14336 if (TARGET_FLOAT128_HW)
14337 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14341 rtx tmp = gen_reg_rtx (<MODE>mode);
14342 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14343 operands[2], tmp));
14348 (define_insn "copysign<mode>3_hard"
14349 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14351 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14352 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14354 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14355 "xscpsgnqp %0,%2,%1"
14356 [(set_attr "type" "vecmove")
14357 (set_attr "size" "128")])
14359 (define_insn "copysign<mode>3_soft"
14360 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14362 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14363 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14364 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14366 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14367 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14368 [(set_attr "type" "veccomplex")
14369 (set_attr "length" "8")])
14371 (define_insn "neg<mode>2_hw"
14372 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14374 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14375 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14377 [(set_attr "type" "vecmove")
14378 (set_attr "size" "128")])
14381 (define_insn "abs<mode>2_hw"
14382 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14384 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14385 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14387 [(set_attr "type" "vecmove")
14388 (set_attr "size" "128")])
14391 (define_insn "*nabs<mode>2_hw"
14392 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14395 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14396 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14398 [(set_attr "type" "vecmove")
14399 (set_attr "size" "128")])
14401 ;; Initially don't worry about doing fusion
14402 (define_insn "fma<mode>4_hw"
14403 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14405 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14406 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14407 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14408 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14409 "xsmaddqp %0,%1,%2"
14410 [(set_attr "type" "vecfloat")
14411 (set_attr "size" "128")])
14413 (define_insn "*fms<mode>4_hw"
14414 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14416 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14417 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14419 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14420 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14421 "xsmsubqp %0,%1,%2"
14422 [(set_attr "type" "vecfloat")
14423 (set_attr "size" "128")])
14425 (define_insn "*nfma<mode>4_hw"
14426 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14429 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14430 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14431 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14432 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14433 "xsnmaddqp %0,%1,%2"
14434 [(set_attr "type" "vecfloat")
14435 (set_attr "size" "128")])
14437 (define_insn "*nfms<mode>4_hw"
14438 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14441 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14442 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14444 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14445 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14446 "xsnmsubqp %0,%1,%2"
14447 [(set_attr "type" "vecfloat")
14448 (set_attr "size" "128")])
14450 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14451 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14452 (float_extend:IEEE128
14453 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14454 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14456 [(set_attr "type" "vecfloat")
14457 (set_attr "size" "128")])
14459 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14460 ;; point is a simple copy.
14461 (define_insn_and_split "extendkftf2"
14462 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14463 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14464 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14468 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14471 emit_note (NOTE_INSN_DELETED);
14474 [(set_attr "type" "*,veclogical")
14475 (set_attr "length" "0,4")])
14477 (define_insn_and_split "trunctfkf2"
14478 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14479 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14480 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14484 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14487 emit_note (NOTE_INSN_DELETED);
14490 [(set_attr "type" "*,veclogical")
14491 (set_attr "length" "0,4")])
14493 (define_insn "trunc<mode>df2_hw"
14494 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14496 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14497 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14499 [(set_attr "type" "vecfloat")
14500 (set_attr "size" "128")])
14502 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14503 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14505 (define_insn_and_split "trunc<mode>sf2_hw"
14506 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14508 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14509 (clobber (match_scratch:DF 2 "=v"))]
14510 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14513 [(set (match_dup 2)
14514 (unspec:DF [(match_dup 1)]
14515 UNSPEC_TRUNC_ROUND_TO_ODD))
14517 (float_truncate:SF (match_dup 2)))]
14519 if (GET_CODE (operands[2]) == SCRATCH)
14520 operands[2] = gen_reg_rtx (DFmode);
14522 [(set_attr "type" "vecfloat")
14523 (set_attr "length" "8")])
14525 ;; Conversion between IEEE 128-bit and integer types
14526 (define_insn "fix_<mode>di2_hw"
14527 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14528 (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14529 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14531 [(set_attr "type" "vecfloat")
14532 (set_attr "size" "128")])
14534 (define_insn "fixuns_<mode>di2_hw"
14535 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14536 (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14537 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14539 [(set_attr "type" "vecfloat")
14540 (set_attr "size" "128")])
14542 (define_insn "fix_<mode>si2_hw"
14543 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14544 (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14545 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14547 [(set_attr "type" "vecfloat")
14548 (set_attr "size" "128")])
14550 (define_insn "fixuns_<mode>si2_hw"
14551 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14552 (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14553 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14555 [(set_attr "type" "vecfloat")
14556 (set_attr "size" "128")])
14558 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14559 ;; floating point value to 32-bit integer to GPR in order to save it.
14560 (define_insn_and_split "*fix<uns>_<mode>_mem"
14561 [(set (match_operand:SI 0 "memory_operand" "=Z")
14562 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14563 (clobber (match_scratch:SI 2 "=v"))]
14564 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14566 "&& reload_completed"
14567 [(set (match_dup 2)
14568 (any_fix:SI (match_dup 1)))
14572 (define_insn "float_<mode>di2_hw"
14573 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14574 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14575 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14577 [(set_attr "type" "vecfloat")
14578 (set_attr "size" "128")])
14580 (define_insn_and_split "float_<mode>si2_hw"
14581 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14582 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14583 (clobber (match_scratch:DI 2 "=v"))]
14584 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14587 [(set (match_dup 2)
14588 (sign_extend:DI (match_dup 1)))
14590 (float:IEEE128 (match_dup 2)))]
14592 if (GET_CODE (operands[2]) == SCRATCH)
14593 operands[2] = gen_reg_rtx (DImode);
14596 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14597 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14598 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14599 (clobber (match_scratch:DI 2 "=X,r,X"))]
14600 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14602 "&& reload_completed"
14605 rtx dest = operands[0];
14606 rtx src = operands[1];
14607 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14609 if (altivec_register_operand (src, <QHI:MODE>mode))
14610 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14611 else if (int_reg_operand (src, <QHI:MODE>mode))
14613 rtx ext_di = operands[2];
14614 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14615 emit_move_insn (dest_di, ext_di);
14617 else if (MEM_P (src))
14619 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14620 emit_move_insn (dest_qhi, src);
14621 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14624 gcc_unreachable ();
14626 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14629 [(set_attr "length" "8,12,12")
14630 (set_attr "type" "vecfloat")
14631 (set_attr "size" "128")])
14633 (define_insn "floatuns_<mode>di2_hw"
14634 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14635 (unsigned_float:IEEE128
14636 (match_operand:DI 1 "altivec_register_operand" "v")))]
14637 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14639 [(set_attr "type" "vecfloat")
14640 (set_attr "size" "128")])
14642 (define_insn_and_split "floatuns_<mode>si2_hw"
14643 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14644 (unsigned_float:IEEE128
14645 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14646 (clobber (match_scratch:DI 2 "=v"))]
14647 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14650 [(set (match_dup 2)
14651 (zero_extend:DI (match_dup 1)))
14653 (float:IEEE128 (match_dup 2)))]
14655 if (GET_CODE (operands[2]) == SCRATCH)
14656 operands[2] = gen_reg_rtx (DImode);
14659 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14660 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14661 (unsigned_float:IEEE128
14662 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14663 (clobber (match_scratch:DI 2 "=X,r,X"))]
14664 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14666 "&& reload_completed"
14669 rtx dest = operands[0];
14670 rtx src = operands[1];
14671 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14673 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14674 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14675 else if (int_reg_operand (src, <QHI:MODE>mode))
14677 rtx ext_di = operands[2];
14678 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14679 emit_move_insn (dest_di, ext_di);
14682 gcc_unreachable ();
14684 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14687 [(set_attr "length" "8,12,8")
14688 (set_attr "type" "vecfloat")
14689 (set_attr "size" "128")])
14691 ;; IEEE 128-bit instructions with round to odd semantics
14692 (define_insn "add<mode>3_odd"
14693 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14695 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14696 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14697 UNSPEC_ADD_ROUND_TO_ODD))]
14698 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14699 "xsaddqpo %0,%1,%2"
14700 [(set_attr "type" "vecfloat")
14701 (set_attr "size" "128")])
14703 (define_insn "sub<mode>3_odd"
14704 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14706 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14707 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14708 UNSPEC_SUB_ROUND_TO_ODD))]
14709 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14710 "xssubqpo %0,%1,%2"
14711 [(set_attr "type" "vecfloat")
14712 (set_attr "size" "128")])
14714 (define_insn "mul<mode>3_odd"
14715 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14717 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14718 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14719 UNSPEC_MUL_ROUND_TO_ODD))]
14720 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14721 "xsmulqpo %0,%1,%2"
14722 [(set_attr "type" "vecfloat")
14723 (set_attr "size" "128")])
14725 (define_insn "div<mode>3_odd"
14726 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14728 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14729 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14730 UNSPEC_DIV_ROUND_TO_ODD))]
14731 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14732 "xsdivqpo %0,%1,%2"
14733 [(set_attr "type" "vecdiv")
14734 (set_attr "size" "128")])
14736 (define_insn "sqrt<mode>2_odd"
14737 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14739 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14740 UNSPEC_SQRT_ROUND_TO_ODD))]
14741 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14743 [(set_attr "type" "vecdiv")
14744 (set_attr "size" "128")])
14746 (define_insn "fma<mode>4_odd"
14747 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14749 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14750 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14751 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14752 UNSPEC_FMA_ROUND_TO_ODD))]
14753 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14754 "xsmaddqpo %0,%1,%2"
14755 [(set_attr "type" "vecfloat")
14756 (set_attr "size" "128")])
14758 (define_insn "*fms<mode>4_odd"
14759 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14761 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14762 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14764 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14765 UNSPEC_FMA_ROUND_TO_ODD))]
14766 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14767 "xsmsubqpo %0,%1,%2"
14768 [(set_attr "type" "vecfloat")
14769 (set_attr "size" "128")])
14771 (define_insn "*nfma<mode>4_odd"
14772 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14775 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14776 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14777 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14778 UNSPEC_FMA_ROUND_TO_ODD)))]
14779 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14780 "xsnmaddqpo %0,%1,%2"
14781 [(set_attr "type" "vecfloat")
14782 (set_attr "size" "128")])
14784 (define_insn "*nfms<mode>4_odd"
14785 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14788 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14789 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14791 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14792 UNSPEC_FMA_ROUND_TO_ODD)))]
14793 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14794 "xsnmsubqpo %0,%1,%2"
14795 [(set_attr "type" "vecfloat")
14796 (set_attr "size" "128")])
14798 (define_insn "trunc<mode>df2_odd"
14799 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14800 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14801 UNSPEC_TRUNC_ROUND_TO_ODD))]
14802 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14804 [(set_attr "type" "vecfloat")
14805 (set_attr "size" "128")])
14807 ;; IEEE 128-bit comparisons
14808 (define_insn "*cmp<mode>_hw"
14809 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14810 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14811 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14812 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14813 "xscmpuqp %0,%1,%2"
14814 [(set_attr "type" "veccmp")
14815 (set_attr "size" "128")])
14819 (include "sync.md")
14820 (include "vector.md")
14822 (include "altivec.md")
14824 (include "paired.md")
14825 (include "crypto.md")