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)
55 (FRAME_POINTER_REGNUM 113)
59 (FIRST_SPE_HIGH_REGNO 117)
60 (LAST_SPE_HIGH_REGNO 148)
67 (define_c_enum "unspec"
68 [UNSPEC_FRSP ; frsp for POWER machines
69 UNSPEC_PROBE_STACK ; probe stack memory reference
70 UNSPEC_TOCPTR ; address of a word pointing to the TOC
71 UNSPEC_TOC ; address of the TOC (more-or-less)
72 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
74 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
81 UNSPEC_LD_MPIC ; load_macho_picbase
82 UNSPEC_RELD_MPIC ; re-load_macho_picbase
83 UNSPEC_MPIC_CORRECT ; macho_correct_pic
97 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
98 UNSPEC_MV_CR_GT ; move_from_CR_gt_bit
116 UNSPEC_MACHOPIC_OFFSET
130 UNSPEC_P8V_RELOAD_FROM_GPR
133 UNSPEC_P8V_RELOAD_FROM_VSX
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
160 UNSPECV_LL ; load-locked
161 UNSPECV_SC ; store-conditional
162 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
163 UNSPECV_EH_RR ; eh_reg_restore
164 UNSPECV_ISYNC ; isync instruction
165 UNSPECV_MFTB ; move from time base
166 UNSPECV_NLGR ; non-local goto receiver
167 UNSPECV_MFFS ; Move from FPSCR
168 UNSPECV_MTFSF ; Move to FPSCR Fields
169 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
173 ;; Define an insn type attribute. This is used in function unit delay
177 add,logical,shift,insert,
179 exts,cntlz,popcnt,isel,
180 load,store,fpload,fpstore,vecload,vecstore,
182 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
184 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
376 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
377 (DF "TARGET_HARD_FLOAT
378 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
379 (TF "TARGET_HARD_FLOAT
380 && (TARGET_FPRS || TARGET_E500_DOUBLE)
381 && TARGET_LONG_DOUBLE_128")
382 (IF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")
383 (KF "TARGET_FLOAT128_TYPE")
387 ; Any fma capable floating-point mode.
388 (define_mode_iterator FMA_F [
389 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
390 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
391 || VECTOR_UNIT_VSX_P (DFmode)")
392 (V2SF "TARGET_PAIRED_FLOAT")
393 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
394 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
395 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
396 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
399 ; Floating point move iterators to combine binary and decimal moves
400 (define_mode_iterator FMOVE32 [SF SD])
401 (define_mode_iterator FMOVE64 [DF DD])
402 (define_mode_iterator FMOVE64X [DI DF DD])
403 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
404 (IF "FLOAT128_IBM_P (IFmode)")
405 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
407 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
408 (IF "FLOAT128_2REG_P (IFmode)")
409 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
411 ; Iterators for 128 bit types for direct move
412 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
420 (KF "FLOAT128_VECTOR_P (KFmode)")
421 (TF "FLOAT128_VECTOR_P (TFmode)")])
423 ; Iterator for 128-bit VSX types for pack/unpack
424 (define_mode_iterator FMOVE128_VSX [V1TI KF])
426 ; Whether a floating point move is ok, don't allow SD without hardware FP
427 (define_mode_attr fmove_ok [(SF "")
429 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
432 ; Convert REAL_VALUE to the appropriate bits
433 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
434 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
435 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
436 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
438 ; Whether 0.0 has an all-zero bit pattern
439 (define_mode_attr zero_fp [(SF "j")
448 ; Definitions for 64-bit VSX
449 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
451 ; Definitions for 64-bit direct move
452 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
454 ; Definitions for 64-bit use of altivec registers
455 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
457 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
458 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
460 ; These modes do not fit in integer registers in 32-bit mode.
461 ; but on e500v2, the gpr are 64 bit registers
462 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
464 ; Iterator for reciprocal estimate instructions
465 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
467 ; Iterator for just SF/DF
468 (define_mode_iterator SFDF [SF DF])
470 ; Like SFDF, but a different name to match conditional move where the
471 ; comparison operands may be a different mode than the input operands.
472 (define_mode_iterator SFDF2 [SF DF])
474 ; Iterator for 128-bit floating point that uses the IBM double-double format
475 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
476 (TF "FLOAT128_IBM_P (TFmode)")])
478 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
479 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
480 (TF "FLOAT128_IEEE_P (TFmode)")])
482 ; Iterator for 128-bit floating point
483 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
484 (IF "TARGET_FLOAT128_TYPE")
485 (TF "TARGET_LONG_DOUBLE_128")])
487 ; Iterator for signbit on 64-bit machines with direct move
488 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
489 (TF "FLOAT128_VECTOR_P (TFmode)")])
491 ; Iterator for ISA 3.0 supported floating point types
492 (define_mode_iterator FP_ISA3 [SF DF])
494 ; SF/DF suffix for traditional floating instructions
495 (define_mode_attr Ftrad [(SF "s") (DF "")])
497 ; SF/DF suffix for VSX instructions
498 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
500 ; SF/DF constraint for arithmetic on traditional floating point registers
501 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
503 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
504 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
505 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
507 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
509 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
510 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
511 ; instructions added in ISA 2.07 (power8)
512 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
514 ; SF/DF constraint for arithmetic on altivec registers
515 (define_mode_attr Fa [(SF "wu") (DF "wv")])
517 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
518 (define_mode_attr Fs [(SF "s") (DF "d")])
521 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
522 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
524 ; Conditional returns.
525 (define_code_iterator any_return [return simple_return])
526 (define_code_attr return_pred [(return "direct_return ()")
527 (simple_return "1")])
528 (define_code_attr return_str [(return "") (simple_return "simple_")])
531 (define_code_iterator iorxor [ior xor])
532 (define_code_iterator and_ior_xor [and ior xor])
534 ; Signed/unsigned variants of ops.
535 (define_code_iterator any_extend [sign_extend zero_extend])
536 (define_code_iterator any_fix [fix unsigned_fix])
537 (define_code_iterator any_float [float unsigned_float])
539 (define_code_attr u [(sign_extend "")
544 (define_code_attr su [(sign_extend "s")
549 (unsigned_float "u")])
551 (define_code_attr az [(sign_extend "a")
556 (unsigned_float "z")])
558 (define_code_attr uns [(fix "")
561 (unsigned_float "uns")])
563 ; Various instructions that come in SI and DI forms.
564 ; A generic w/d attribute, for things like cmpw/cmpd.
565 (define_mode_attr wd [(QI "b")
576 ;; How many bits in this mode?
577 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
580 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
582 ;; ISEL/ISEL64 target selection
583 (define_mode_attr sel [(SI "") (DI "64")])
585 ;; Bitmask for shift instructions
586 (define_mode_attr hH [(SI "h") (DI "H")])
588 ;; A mode twice the size of the given mode
589 (define_mode_attr dmode [(SI "di") (DI "ti")])
590 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
592 ;; Suffix for reload patterns
593 (define_mode_attr ptrsize [(SI "32bit")
596 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
597 (DI "TARGET_64BIT")])
599 (define_mode_attr mptrsize [(SI "si")
602 (define_mode_attr ptrload [(SI "lwz")
605 (define_mode_attr ptrm [(SI "m")
608 (define_mode_attr rreg [(SF "f")
615 (define_mode_attr rreg2 [(SF "f")
618 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
619 (DF "TARGET_FCFID")])
621 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
622 (DF "TARGET_E500_DOUBLE")])
624 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
625 (DF "TARGET_DOUBLE_FLOAT")])
627 ;; Mode iterator for logical operations on 128-bit types
628 (define_mode_iterator BOOL_128 [TI
630 (V16QI "TARGET_ALTIVEC")
631 (V8HI "TARGET_ALTIVEC")
632 (V4SI "TARGET_ALTIVEC")
633 (V4SF "TARGET_ALTIVEC")
634 (V2DI "TARGET_ALTIVEC")
635 (V2DF "TARGET_ALTIVEC")
636 (V1TI "TARGET_ALTIVEC")])
638 ;; For the GPRs we use 3 constraints for register outputs, two that are the
639 ;; same as the output register, and a third where the output register is an
640 ;; early clobber, so we don't have to deal with register overlaps. For the
641 ;; vector types, we prefer to use the vector registers. For TI mode, allow
644 ;; Mode attribute for boolean operation register constraints for output
645 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
647 (V16QI "wa,v,&?r,?r,?r")
648 (V8HI "wa,v,&?r,?r,?r")
649 (V4SI "wa,v,&?r,?r,?r")
650 (V4SF "wa,v,&?r,?r,?r")
651 (V2DI "wa,v,&?r,?r,?r")
652 (V2DF "wa,v,&?r,?r,?r")
653 (V1TI "wa,v,&?r,?r,?r")])
655 ;; Mode attribute for boolean operation register constraints for operand1
656 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
664 (V1TI "wa,v,r,0,r")])
666 ;; Mode attribute for boolean operation register constraints for operand2
667 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
675 (V1TI "wa,v,r,r,0")])
677 ;; Mode attribute for boolean operation register constraints for operand1
678 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
679 ;; is used for operand1 or operand2
680 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
688 (V1TI "wa,v,r,0,0")])
690 ;; Reload iterator for creating the function to allocate a base register to
691 ;; supplement addressing modes.
692 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
693 SF SD SI DF DD DI TI PTI KF IF TF])
695 ;; Iterate over smin, smax
696 (define_code_iterator fp_minmax [smin smax])
698 (define_code_attr minmax [(smin "min")
701 (define_code_attr SMINMAX [(smin "SMIN")
704 ;; Iterator to optimize the following cases:
705 ;; D-form load to FPR register & move to Altivec register
706 ;; Move Altivec register to FPR register and store
707 (define_mode_iterator ALTIVEC_DFORM [DI DF SF])
710 ;; Start with fixed-point load and store insns. Here we put only the more
711 ;; complex forms. Basic data transfer is done later.
713 (define_insn "zero_extendqi<mode>2"
714 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
715 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
722 [(set_attr "type" "load,shift,fpload,vecperm")])
724 (define_insn_and_split "*zero_extendqi<mode>2_dot"
725 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
726 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
728 (clobber (match_scratch:EXTQI 0 "=r,r"))]
729 "rs6000_gen_cell_microcode"
733 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
735 (zero_extend:EXTQI (match_dup 1)))
737 (compare:CC (match_dup 0)
740 [(set_attr "type" "logical")
741 (set_attr "dot" "yes")
742 (set_attr "length" "4,8")])
744 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
745 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
746 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
748 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
749 (zero_extend:EXTQI (match_dup 1)))]
750 "rs6000_gen_cell_microcode"
754 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
756 (zero_extend:EXTQI (match_dup 1)))
758 (compare:CC (match_dup 0)
761 [(set_attr "type" "logical")
762 (set_attr "dot" "yes")
763 (set_attr "length" "4,8")])
766 (define_insn "zero_extendhi<mode>2"
767 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
768 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
772 rlwinm %0,%1,0,0xffff
775 [(set_attr "type" "load,shift,fpload,vecperm")])
777 (define_insn_and_split "*zero_extendhi<mode>2_dot"
778 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
779 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
781 (clobber (match_scratch:EXTHI 0 "=r,r"))]
782 "rs6000_gen_cell_microcode"
786 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
788 (zero_extend:EXTHI (match_dup 1)))
790 (compare:CC (match_dup 0)
793 [(set_attr "type" "logical")
794 (set_attr "dot" "yes")
795 (set_attr "length" "4,8")])
797 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
798 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
799 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
801 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
802 (zero_extend:EXTHI (match_dup 1)))]
803 "rs6000_gen_cell_microcode"
807 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
809 (zero_extend:EXTHI (match_dup 1)))
811 (compare:CC (match_dup 0)
814 [(set_attr "type" "logical")
815 (set_attr "dot" "yes")
816 (set_attr "length" "4,8")])
819 (define_insn "zero_extendsi<mode>2"
820 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
821 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
830 xxextractuw %x0,%x1,4"
831 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
833 (define_insn_and_split "*zero_extendsi<mode>2_dot"
834 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
835 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
837 (clobber (match_scratch:EXTSI 0 "=r,r"))]
838 "rs6000_gen_cell_microcode"
842 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
844 (zero_extend:DI (match_dup 1)))
846 (compare:CC (match_dup 0)
849 [(set_attr "type" "shift")
850 (set_attr "dot" "yes")
851 (set_attr "length" "4,8")])
853 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
854 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
855 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
857 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
858 (zero_extend:EXTSI (match_dup 1)))]
859 "rs6000_gen_cell_microcode"
863 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
865 (zero_extend:EXTSI (match_dup 1)))
867 (compare:CC (match_dup 0)
870 [(set_attr "type" "shift")
871 (set_attr "dot" "yes")
872 (set_attr "length" "4,8")])
875 (define_insn "extendqi<mode>2"
876 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
877 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
882 [(set_attr "type" "exts,vecperm")])
884 (define_insn_and_split "*extendqi<mode>2_dot"
885 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
886 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
888 (clobber (match_scratch:EXTQI 0 "=r,r"))]
889 "rs6000_gen_cell_microcode"
893 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
895 (sign_extend:EXTQI (match_dup 1)))
897 (compare:CC (match_dup 0)
900 [(set_attr "type" "exts")
901 (set_attr "dot" "yes")
902 (set_attr "length" "4,8")])
904 (define_insn_and_split "*extendqi<mode>2_dot2"
905 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
906 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
908 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
909 (sign_extend:EXTQI (match_dup 1)))]
910 "rs6000_gen_cell_microcode"
914 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
916 (sign_extend:EXTQI (match_dup 1)))
918 (compare:CC (match_dup 0)
921 [(set_attr "type" "exts")
922 (set_attr "dot" "yes")
923 (set_attr "length" "4,8")])
926 (define_expand "extendhi<mode>2"
927 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
928 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
932 (define_insn "*extendhi<mode>2"
933 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
934 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
935 "rs6000_gen_cell_microcode || TARGET_VSX_SMALL_INTEGER"
941 [(set_attr "type" "load,exts,fpload,vecperm")
942 (set_attr "sign_extend" "yes")
943 (set_attr "length" "4,4,8,4")])
946 [(set (match_operand:EXTHI 0 "altivec_register_operand")
948 (match_operand:HI 1 "indexed_or_indirect_operand")))]
949 "TARGET_P9_VECTOR && reload_completed"
953 (sign_extend:EXTHI (match_dup 2)))]
955 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
958 (define_insn "*extendhi<mode>2_noload"
959 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
960 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
961 "!rs6000_gen_cell_microcode"
963 [(set_attr "type" "exts")])
965 (define_insn_and_split "*extendhi<mode>2_dot"
966 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
967 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
969 (clobber (match_scratch:EXTHI 0 "=r,r"))]
970 "rs6000_gen_cell_microcode"
974 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
976 (sign_extend:EXTHI (match_dup 1)))
978 (compare:CC (match_dup 0)
981 [(set_attr "type" "exts")
982 (set_attr "dot" "yes")
983 (set_attr "length" "4,8")])
985 (define_insn_and_split "*extendhi<mode>2_dot2"
986 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
987 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
989 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
990 (sign_extend:EXTHI (match_dup 1)))]
991 "rs6000_gen_cell_microcode"
995 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
997 (sign_extend:EXTHI (match_dup 1)))
999 (compare:CC (match_dup 0)
1002 [(set_attr "type" "exts")
1003 (set_attr "dot" "yes")
1004 (set_attr "length" "4,8")])
1007 (define_insn "extendsi<mode>2"
1008 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK,wH")
1009 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK,wH")))]
1019 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm")
1020 (set_attr "sign_extend" "yes")
1021 (set_attr "length" "4,4,4,4,4,4,8")])
1024 [(set (match_operand:DI 0 "altivec_register_operand")
1025 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1026 "TARGET_VSX_SMALL_INTEGER && TARGET_P8_VECTOR && !TARGET_P9_VECTOR
1027 && reload_completed"
1030 rtx dest = operands[0];
1031 rtx src = operands[1];
1032 int dest_regno = REGNO (dest);
1033 int src_regno = REGNO (src);
1034 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1035 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1037 if (VECTOR_ELT_ORDER_BIG)
1039 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1040 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1044 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1045 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1050 (define_insn_and_split "*extendsi<mode>2_dot"
1051 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1052 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1054 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1055 "rs6000_gen_cell_microcode"
1059 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1061 (sign_extend:EXTSI (match_dup 1)))
1063 (compare:CC (match_dup 0)
1066 [(set_attr "type" "exts")
1067 (set_attr "dot" "yes")
1068 (set_attr "length" "4,8")])
1070 (define_insn_and_split "*extendsi<mode>2_dot2"
1071 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1072 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1074 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1075 (sign_extend:EXTSI (match_dup 1)))]
1076 "rs6000_gen_cell_microcode"
1080 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1082 (sign_extend:EXTSI (match_dup 1)))
1084 (compare:CC (match_dup 0)
1087 [(set_attr "type" "exts")
1088 (set_attr "dot" "yes")
1089 (set_attr "length" "4,8")])
1091 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1093 (define_insn "*macchwc"
1094 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1095 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1096 (match_operand:SI 2 "gpc_reg_operand" "r")
1099 (match_operand:HI 1 "gpc_reg_operand" "r")))
1100 (match_operand:SI 4 "gpc_reg_operand" "0"))
1102 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1103 (plus:SI (mult:SI (ashiftrt:SI
1111 [(set_attr "type" "halfmul")])
1113 (define_insn "*macchw"
1114 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1115 (plus:SI (mult:SI (ashiftrt:SI
1116 (match_operand:SI 2 "gpc_reg_operand" "r")
1119 (match_operand:HI 1 "gpc_reg_operand" "r")))
1120 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1123 [(set_attr "type" "halfmul")])
1125 (define_insn "*macchwuc"
1126 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1127 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1128 (match_operand:SI 2 "gpc_reg_operand" "r")
1131 (match_operand:HI 1 "gpc_reg_operand" "r")))
1132 (match_operand:SI 4 "gpc_reg_operand" "0"))
1134 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1135 (plus:SI (mult:SI (lshiftrt:SI
1143 [(set_attr "type" "halfmul")])
1145 (define_insn "*macchwu"
1146 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1147 (plus:SI (mult:SI (lshiftrt:SI
1148 (match_operand:SI 2 "gpc_reg_operand" "r")
1151 (match_operand:HI 1 "gpc_reg_operand" "r")))
1152 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1155 [(set_attr "type" "halfmul")])
1157 (define_insn "*machhwc"
1158 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1159 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1160 (match_operand:SI 1 "gpc_reg_operand" "%r")
1163 (match_operand:SI 2 "gpc_reg_operand" "r")
1165 (match_operand:SI 4 "gpc_reg_operand" "0"))
1167 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1168 (plus:SI (mult:SI (ashiftrt:SI
1177 [(set_attr "type" "halfmul")])
1179 (define_insn "*machhw"
1180 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1181 (plus:SI (mult:SI (ashiftrt:SI
1182 (match_operand:SI 1 "gpc_reg_operand" "%r")
1185 (match_operand:SI 2 "gpc_reg_operand" "r")
1187 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1190 [(set_attr "type" "halfmul")])
1192 (define_insn "*machhwuc"
1193 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1194 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1195 (match_operand:SI 1 "gpc_reg_operand" "%r")
1198 (match_operand:SI 2 "gpc_reg_operand" "r")
1200 (match_operand:SI 4 "gpc_reg_operand" "0"))
1202 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1203 (plus:SI (mult:SI (lshiftrt:SI
1212 [(set_attr "type" "halfmul")])
1214 (define_insn "*machhwu"
1215 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1216 (plus:SI (mult:SI (lshiftrt:SI
1217 (match_operand:SI 1 "gpc_reg_operand" "%r")
1220 (match_operand:SI 2 "gpc_reg_operand" "r")
1222 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1225 [(set_attr "type" "halfmul")])
1227 (define_insn "*maclhwc"
1228 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1229 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1230 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1232 (match_operand:HI 2 "gpc_reg_operand" "r")))
1233 (match_operand:SI 4 "gpc_reg_operand" "0"))
1235 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1236 (plus:SI (mult:SI (sign_extend:SI
1243 [(set_attr "type" "halfmul")])
1245 (define_insn "*maclhw"
1246 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1247 (plus:SI (mult:SI (sign_extend:SI
1248 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1250 (match_operand:HI 2 "gpc_reg_operand" "r")))
1251 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1254 [(set_attr "type" "halfmul")])
1256 (define_insn "*maclhwuc"
1257 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1258 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1259 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1261 (match_operand:HI 2 "gpc_reg_operand" "r")))
1262 (match_operand:SI 4 "gpc_reg_operand" "0"))
1264 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265 (plus:SI (mult:SI (zero_extend:SI
1272 [(set_attr "type" "halfmul")])
1274 (define_insn "*maclhwu"
1275 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1276 (plus:SI (mult:SI (zero_extend:SI
1277 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1279 (match_operand:HI 2 "gpc_reg_operand" "r")))
1280 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1283 [(set_attr "type" "halfmul")])
1285 (define_insn "*nmacchwc"
1286 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1287 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1288 (mult:SI (ashiftrt:SI
1289 (match_operand:SI 2 "gpc_reg_operand" "r")
1292 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1294 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1295 (minus:SI (match_dup 4)
1296 (mult:SI (ashiftrt:SI
1303 [(set_attr "type" "halfmul")])
1305 (define_insn "*nmacchw"
1306 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1307 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1308 (mult:SI (ashiftrt:SI
1309 (match_operand:SI 2 "gpc_reg_operand" "r")
1312 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1315 [(set_attr "type" "halfmul")])
1317 (define_insn "*nmachhwc"
1318 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1319 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1320 (mult:SI (ashiftrt:SI
1321 (match_operand:SI 1 "gpc_reg_operand" "%r")
1324 (match_operand:SI 2 "gpc_reg_operand" "r")
1327 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1328 (minus:SI (match_dup 4)
1329 (mult:SI (ashiftrt:SI
1337 [(set_attr "type" "halfmul")])
1339 (define_insn "*nmachhw"
1340 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1342 (mult:SI (ashiftrt:SI
1343 (match_operand:SI 1 "gpc_reg_operand" "%r")
1346 (match_operand:SI 2 "gpc_reg_operand" "r")
1350 [(set_attr "type" "halfmul")])
1352 (define_insn "*nmaclhwc"
1353 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1354 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1355 (mult:SI (sign_extend:SI
1356 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1358 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1360 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1361 (minus:SI (match_dup 4)
1362 (mult:SI (sign_extend:SI
1368 [(set_attr "type" "halfmul")])
1370 (define_insn "*nmaclhw"
1371 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1372 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1373 (mult:SI (sign_extend:SI
1374 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1376 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1379 [(set_attr "type" "halfmul")])
1381 (define_insn "*mulchwc"
1382 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1383 (compare:CC (mult:SI (ashiftrt:SI
1384 (match_operand:SI 2 "gpc_reg_operand" "r")
1387 (match_operand:HI 1 "gpc_reg_operand" "r")))
1389 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390 (mult:SI (ashiftrt:SI
1397 [(set_attr "type" "halfmul")])
1399 (define_insn "*mulchw"
1400 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1401 (mult:SI (ashiftrt:SI
1402 (match_operand:SI 2 "gpc_reg_operand" "r")
1405 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1408 [(set_attr "type" "halfmul")])
1410 (define_insn "*mulchwuc"
1411 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1412 (compare:CC (mult:SI (lshiftrt:SI
1413 (match_operand:SI 2 "gpc_reg_operand" "r")
1416 (match_operand:HI 1 "gpc_reg_operand" "r")))
1418 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1419 (mult:SI (lshiftrt:SI
1426 [(set_attr "type" "halfmul")])
1428 (define_insn "*mulchwu"
1429 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1430 (mult:SI (lshiftrt:SI
1431 (match_operand:SI 2 "gpc_reg_operand" "r")
1434 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1437 [(set_attr "type" "halfmul")])
1439 (define_insn "*mulhhwc"
1440 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1441 (compare:CC (mult:SI (ashiftrt:SI
1442 (match_operand:SI 1 "gpc_reg_operand" "%r")
1445 (match_operand:SI 2 "gpc_reg_operand" "r")
1448 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1449 (mult:SI (ashiftrt:SI
1457 [(set_attr "type" "halfmul")])
1459 (define_insn "*mulhhw"
1460 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1461 (mult:SI (ashiftrt:SI
1462 (match_operand:SI 1 "gpc_reg_operand" "%r")
1465 (match_operand:SI 2 "gpc_reg_operand" "r")
1469 [(set_attr "type" "halfmul")])
1471 (define_insn "*mulhhwuc"
1472 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1473 (compare:CC (mult:SI (lshiftrt:SI
1474 (match_operand:SI 1 "gpc_reg_operand" "%r")
1477 (match_operand:SI 2 "gpc_reg_operand" "r")
1480 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1481 (mult:SI (lshiftrt:SI
1489 [(set_attr "type" "halfmul")])
1491 (define_insn "*mulhhwu"
1492 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1493 (mult:SI (lshiftrt:SI
1494 (match_operand:SI 1 "gpc_reg_operand" "%r")
1497 (match_operand:SI 2 "gpc_reg_operand" "r")
1501 [(set_attr "type" "halfmul")])
1503 (define_insn "*mullhwc"
1504 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1505 (compare:CC (mult:SI (sign_extend:SI
1506 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1508 (match_operand:HI 2 "gpc_reg_operand" "r")))
1510 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1511 (mult:SI (sign_extend:SI
1517 [(set_attr "type" "halfmul")])
1519 (define_insn "*mullhw"
1520 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1521 (mult:SI (sign_extend:SI
1522 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1524 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1527 [(set_attr "type" "halfmul")])
1529 (define_insn "*mullhwuc"
1530 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1531 (compare:CC (mult:SI (zero_extend:SI
1532 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1534 (match_operand:HI 2 "gpc_reg_operand" "r")))
1536 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1537 (mult:SI (zero_extend:SI
1543 [(set_attr "type" "halfmul")])
1545 (define_insn "*mullhwu"
1546 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1547 (mult:SI (zero_extend:SI
1548 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1550 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1553 [(set_attr "type" "halfmul")])
1555 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1556 (define_insn "dlmzb"
1557 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1558 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1559 (match_operand:SI 2 "gpc_reg_operand" "r")]
1561 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1562 (unspec:SI [(match_dup 1)
1568 (define_expand "strlensi"
1569 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1570 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1571 (match_operand:QI 2 "const_int_operand" "")
1572 (match_operand 3 "const_int_operand" "")]
1573 UNSPEC_DLMZB_STRLEN))
1574 (clobber (match_scratch:CC 4 "=x"))]
1575 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1577 rtx result = operands[0];
1578 rtx src = operands[1];
1579 rtx search_char = operands[2];
1580 rtx align = operands[3];
1581 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1582 rtx loop_label, end_label, mem, cr0, cond;
1583 if (search_char != const0_rtx
1584 || GET_CODE (align) != CONST_INT
1585 || INTVAL (align) < 8)
1587 word1 = gen_reg_rtx (SImode);
1588 word2 = gen_reg_rtx (SImode);
1589 scratch_dlmzb = gen_reg_rtx (SImode);
1590 scratch_string = gen_reg_rtx (Pmode);
1591 loop_label = gen_label_rtx ();
1592 end_label = gen_label_rtx ();
1593 addr = force_reg (Pmode, XEXP (src, 0));
1594 emit_move_insn (scratch_string, addr);
1595 emit_label (loop_label);
1596 mem = change_address (src, SImode, scratch_string);
1597 emit_move_insn (word1, mem);
1598 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1599 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1600 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1601 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1602 emit_jump_insn (gen_rtx_SET (pc_rtx,
1603 gen_rtx_IF_THEN_ELSE (VOIDmode,
1609 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1610 emit_jump_insn (gen_rtx_SET (pc_rtx,
1611 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1613 emit_label (end_label);
1614 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1615 emit_insn (gen_subsi3 (result, scratch_string, addr));
1616 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1620 ;; Fixed-point arithmetic insns.
1622 (define_expand "add<mode>3"
1623 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1624 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1625 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1628 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1630 rtx lo0 = gen_lowpart (SImode, operands[0]);
1631 rtx lo1 = gen_lowpart (SImode, operands[1]);
1632 rtx lo2 = gen_lowpart (SImode, operands[2]);
1633 rtx hi0 = gen_highpart (SImode, operands[0]);
1634 rtx hi1 = gen_highpart (SImode, operands[1]);
1635 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1637 if (!reg_or_short_operand (lo2, SImode))
1638 lo2 = force_reg (SImode, lo2);
1639 if (!adde_operand (hi2, SImode))
1640 hi2 = force_reg (SImode, hi2);
1642 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1643 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1647 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1649 rtx tmp = ((!can_create_pseudo_p ()
1650 || rtx_equal_p (operands[0], operands[1]))
1651 ? operands[0] : gen_reg_rtx (<MODE>mode));
1653 HOST_WIDE_INT val = INTVAL (operands[2]);
1654 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1655 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1657 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1660 /* The ordering here is important for the prolog expander.
1661 When space is allocated from the stack, adding 'low' first may
1662 produce a temporary deallocation (which would be bad). */
1663 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1664 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1669 (define_insn "*add<mode>3"
1670 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1671 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1672 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1678 [(set_attr "type" "add")])
1680 (define_insn "addsi3_high"
1681 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1682 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1683 (high:SI (match_operand 2 "" ""))))]
1684 "TARGET_MACHO && !TARGET_64BIT"
1685 "addis %0,%1,ha16(%2)"
1686 [(set_attr "type" "add")])
1688 (define_insn_and_split "*add<mode>3_dot"
1689 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1690 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1691 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1693 (clobber (match_scratch:GPR 0 "=r,r"))]
1694 "<MODE>mode == Pmode"
1698 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1700 (plus:GPR (match_dup 1)
1703 (compare:CC (match_dup 0)
1706 [(set_attr "type" "add")
1707 (set_attr "dot" "yes")
1708 (set_attr "length" "4,8")])
1710 (define_insn_and_split "*add<mode>3_dot2"
1711 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1712 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1713 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1715 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1716 (plus:GPR (match_dup 1)
1718 "<MODE>mode == Pmode"
1722 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1724 (plus:GPR (match_dup 1)
1727 (compare:CC (match_dup 0)
1730 [(set_attr "type" "add")
1731 (set_attr "dot" "yes")
1732 (set_attr "length" "4,8")])
1734 (define_insn_and_split "*add<mode>3_imm_dot"
1735 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1736 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1737 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1739 (clobber (match_scratch:GPR 0 "=r,r"))
1740 (clobber (reg:GPR CA_REGNO))]
1741 "<MODE>mode == Pmode"
1745 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1747 (plus:GPR (match_dup 1)
1750 (compare:CC (match_dup 0)
1753 [(set_attr "type" "add")
1754 (set_attr "dot" "yes")
1755 (set_attr "length" "4,8")])
1757 (define_insn_and_split "*add<mode>3_imm_dot2"
1758 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1759 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1760 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1762 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1763 (plus:GPR (match_dup 1)
1765 (clobber (reg:GPR CA_REGNO))]
1766 "<MODE>mode == Pmode"
1770 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1772 (plus:GPR (match_dup 1)
1775 (compare:CC (match_dup 0)
1778 [(set_attr "type" "add")
1779 (set_attr "dot" "yes")
1780 (set_attr "length" "4,8")])
1782 ;; Split an add that we can't do in one insn into two insns, each of which
1783 ;; does one 16-bit part. This is used by combine. Note that the low-order
1784 ;; add should be last in case the result gets used in an address.
1787 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1788 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1789 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1791 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1792 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1794 HOST_WIDE_INT val = INTVAL (operands[2]);
1795 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1796 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1798 operands[4] = GEN_INT (low);
1799 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1800 operands[3] = GEN_INT (rest);
1801 else if (can_create_pseudo_p ())
1803 operands[3] = gen_reg_rtx (DImode);
1804 emit_move_insn (operands[3], operands[2]);
1805 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1813 (define_insn "add<mode>3_carry"
1814 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1815 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1816 (match_operand:P 2 "reg_or_short_operand" "rI")))
1817 (set (reg:P CA_REGNO)
1818 (ltu:P (plus:P (match_dup 1)
1823 [(set_attr "type" "add")])
1825 (define_insn "*add<mode>3_imm_carry_pos"
1826 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1827 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1828 (match_operand:P 2 "short_cint_operand" "n")))
1829 (set (reg:P CA_REGNO)
1830 (geu:P (match_dup 1)
1831 (match_operand:P 3 "const_int_operand" "n")))]
1832 "INTVAL (operands[2]) > 0
1833 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1835 [(set_attr "type" "add")])
1837 (define_insn "*add<mode>3_imm_carry_0"
1838 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1839 (match_operand:P 1 "gpc_reg_operand" "r"))
1840 (set (reg:P CA_REGNO)
1844 [(set_attr "type" "add")])
1846 (define_insn "*add<mode>3_imm_carry_m1"
1847 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1848 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1850 (set (reg:P CA_REGNO)
1855 [(set_attr "type" "add")])
1857 (define_insn "*add<mode>3_imm_carry_neg"
1858 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1859 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1860 (match_operand:P 2 "short_cint_operand" "n")))
1861 (set (reg:P CA_REGNO)
1862 (gtu:P (match_dup 1)
1863 (match_operand:P 3 "const_int_operand" "n")))]
1864 "INTVAL (operands[2]) < 0
1865 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1867 [(set_attr "type" "add")])
1870 (define_expand "add<mode>3_carry_in"
1872 (set (match_operand:GPR 0 "gpc_reg_operand")
1873 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1874 (match_operand:GPR 2 "adde_operand"))
1875 (reg:GPR CA_REGNO)))
1876 (clobber (reg:GPR CA_REGNO))])]
1879 if (operands[2] == const0_rtx)
1881 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1884 if (operands[2] == constm1_rtx)
1886 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1891 (define_insn "*add<mode>3_carry_in_internal"
1892 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1893 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1894 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1895 (reg:GPR CA_REGNO)))
1896 (clobber (reg:GPR CA_REGNO))]
1899 [(set_attr "type" "add")])
1901 (define_insn "add<mode>3_carry_in_0"
1902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1904 (reg:GPR CA_REGNO)))
1905 (clobber (reg:GPR CA_REGNO))]
1908 [(set_attr "type" "add")])
1910 (define_insn "add<mode>3_carry_in_m1"
1911 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1912 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1915 (clobber (reg:GPR CA_REGNO))]
1918 [(set_attr "type" "add")])
1921 (define_expand "one_cmpl<mode>2"
1922 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1923 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1926 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1928 rs6000_split_logical (operands, NOT, false, false, false);
1933 (define_insn "*one_cmpl<mode>2"
1934 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1935 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1939 (define_insn_and_split "*one_cmpl<mode>2_dot"
1940 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1941 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1943 (clobber (match_scratch:GPR 0 "=r,r"))]
1944 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1948 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1950 (not:GPR (match_dup 1)))
1952 (compare:CC (match_dup 0)
1955 [(set_attr "type" "logical")
1956 (set_attr "dot" "yes")
1957 (set_attr "length" "4,8")])
1959 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1960 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1961 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1963 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1964 (not:GPR (match_dup 1)))]
1965 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1969 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1971 (not:GPR (match_dup 1)))
1973 (compare:CC (match_dup 0)
1976 [(set_attr "type" "logical")
1977 (set_attr "dot" "yes")
1978 (set_attr "length" "4,8")])
1981 (define_expand "sub<mode>3"
1982 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1983 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1984 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1987 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1989 rtx lo0 = gen_lowpart (SImode, operands[0]);
1990 rtx lo1 = gen_lowpart (SImode, operands[1]);
1991 rtx lo2 = gen_lowpart (SImode, operands[2]);
1992 rtx hi0 = gen_highpart (SImode, operands[0]);
1993 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1994 rtx hi2 = gen_highpart (SImode, operands[2]);
1996 if (!reg_or_short_operand (lo1, SImode))
1997 lo1 = force_reg (SImode, lo1);
1998 if (!adde_operand (hi1, SImode))
1999 hi1 = force_reg (SImode, hi1);
2001 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2002 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2006 if (short_cint_operand (operands[1], <MODE>mode))
2008 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2013 (define_insn "*subf<mode>3"
2014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2015 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2016 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2019 [(set_attr "type" "add")])
2021 (define_insn_and_split "*subf<mode>3_dot"
2022 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2023 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2024 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2026 (clobber (match_scratch:GPR 0 "=r,r"))]
2027 "<MODE>mode == Pmode"
2031 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2033 (minus:GPR (match_dup 2)
2036 (compare:CC (match_dup 0)
2039 [(set_attr "type" "add")
2040 (set_attr "dot" "yes")
2041 (set_attr "length" "4,8")])
2043 (define_insn_and_split "*subf<mode>3_dot2"
2044 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2045 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2046 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2048 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2049 (minus:GPR (match_dup 2)
2051 "<MODE>mode == Pmode"
2055 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2057 (minus:GPR (match_dup 2)
2060 (compare:CC (match_dup 0)
2063 [(set_attr "type" "add")
2064 (set_attr "dot" "yes")
2065 (set_attr "length" "4,8")])
2067 (define_insn "subf<mode>3_imm"
2068 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2069 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2070 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2071 (clobber (reg:GPR CA_REGNO))]
2074 [(set_attr "type" "add")])
2076 (define_insn_and_split "subf<mode>3_carry_dot2"
2077 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2078 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2079 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2081 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2082 (minus:P (match_dup 2)
2084 (set (reg:P CA_REGNO)
2085 (leu:P (match_dup 1)
2087 "<MODE>mode == Pmode"
2091 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2092 [(parallel [(set (match_dup 0)
2093 (minus:P (match_dup 2)
2095 (set (reg:P CA_REGNO)
2096 (leu:P (match_dup 1)
2099 (compare:CC (match_dup 0)
2102 [(set_attr "type" "add")
2103 (set_attr "dot" "yes")
2104 (set_attr "length" "4,8")])
2106 (define_insn "subf<mode>3_carry"
2107 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2108 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2109 (match_operand:P 1 "gpc_reg_operand" "r")))
2110 (set (reg:P CA_REGNO)
2111 (leu:P (match_dup 1)
2115 [(set_attr "type" "add")])
2117 (define_insn "*subf<mode>3_imm_carry_0"
2118 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2119 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2120 (set (reg:P CA_REGNO)
2125 [(set_attr "type" "add")])
2127 (define_insn "*subf<mode>3_imm_carry_m1"
2128 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2129 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2130 (set (reg:P CA_REGNO)
2134 [(set_attr "type" "add")])
2137 (define_expand "subf<mode>3_carry_in"
2139 (set (match_operand:GPR 0 "gpc_reg_operand")
2140 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2142 (match_operand:GPR 2 "adde_operand")))
2143 (clobber (reg:GPR CA_REGNO))])]
2146 if (operands[2] == const0_rtx)
2148 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2151 if (operands[2] == constm1_rtx)
2153 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2158 (define_insn "*subf<mode>3_carry_in_internal"
2159 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2160 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2162 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2163 (clobber (reg:GPR CA_REGNO))]
2166 [(set_attr "type" "add")])
2168 (define_insn "subf<mode>3_carry_in_0"
2169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2170 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2171 (reg:GPR CA_REGNO)))
2172 (clobber (reg:GPR CA_REGNO))]
2175 [(set_attr "type" "add")])
2177 (define_insn "subf<mode>3_carry_in_m1"
2178 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2179 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2180 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2182 (clobber (reg:GPR CA_REGNO))]
2185 [(set_attr "type" "add")])
2187 (define_insn "subf<mode>3_carry_in_xx"
2188 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189 (plus:GPR (reg:GPR CA_REGNO)
2191 (clobber (reg:GPR CA_REGNO))]
2194 [(set_attr "type" "add")])
2197 (define_insn "neg<mode>2"
2198 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2202 [(set_attr "type" "add")])
2204 (define_insn_and_split "*neg<mode>2_dot"
2205 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2206 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2208 (clobber (match_scratch:GPR 0 "=r,r"))]
2209 "<MODE>mode == Pmode"
2213 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2215 (neg:GPR (match_dup 1)))
2217 (compare:CC (match_dup 0)
2220 [(set_attr "type" "add")
2221 (set_attr "dot" "yes")
2222 (set_attr "length" "4,8")])
2224 (define_insn_and_split "*neg<mode>2_dot2"
2225 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2226 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2228 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2229 (neg:GPR (match_dup 1)))]
2230 "<MODE>mode == Pmode"
2234 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2236 (neg:GPR (match_dup 1)))
2238 (compare:CC (match_dup 0)
2241 [(set_attr "type" "add")
2242 (set_attr "dot" "yes")
2243 (set_attr "length" "4,8")])
2246 (define_insn "clz<mode>2"
2247 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2248 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2251 [(set_attr "type" "cntlz")])
2253 (define_expand "ctz<mode>2"
2254 [(set (match_operand:GPR 0 "gpc_reg_operand")
2255 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2260 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2264 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2265 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2266 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2270 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2271 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2272 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2273 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2277 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2278 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2279 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2280 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2286 (define_insn "ctz<mode>2_hw"
2287 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2288 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2291 [(set_attr "type" "cntlz")])
2293 (define_expand "ffs<mode>2"
2294 [(set (match_operand:GPR 0 "gpc_reg_operand")
2295 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2298 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2299 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2300 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2301 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2302 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2303 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2304 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2309 (define_expand "popcount<mode>2"
2310 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2311 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2312 "TARGET_POPCNTB || TARGET_POPCNTD"
2314 rs6000_emit_popcount (operands[0], operands[1]);
2318 (define_insn "popcntb<mode>2"
2319 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2320 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2324 [(set_attr "type" "popcnt")])
2326 (define_insn "popcntd<mode>2"
2327 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2328 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2331 [(set_attr "type" "popcnt")])
2334 (define_expand "parity<mode>2"
2335 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2336 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2339 rs6000_emit_parity (operands[0], operands[1]);
2343 (define_insn "parity<mode>2_cmpb"
2344 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2345 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2346 "TARGET_CMPB && TARGET_POPCNTB"
2348 [(set_attr "type" "popcnt")])
2350 (define_insn "cmpb<mode>3"
2351 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2352 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2353 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2356 [(set_attr "type" "cmp")])
2358 ;; Since the hardware zeros the upper part of the register, save generating the
2359 ;; AND immediate if we are converting to unsigned
2360 (define_insn "*bswap<mode>2_extenddi"
2361 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2363 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2366 [(set_attr "length" "4")
2367 (set_attr "type" "load")])
2369 (define_insn "*bswaphi2_extendsi"
2370 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2372 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2375 [(set_attr "length" "4")
2376 (set_attr "type" "load")])
2378 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2379 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2380 ;; load with byte swap, which can be slower than doing it in the registers. It
2381 ;; also prevents certain failures with the RELOAD register allocator.
2383 (define_expand "bswap<mode>2"
2384 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2385 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2388 rtx dest = operands[0];
2389 rtx src = operands[1];
2391 if (!REG_P (dest) && !REG_P (src))
2392 src = force_reg (<MODE>mode, src);
2395 emit_insn (gen_bswap<mode>2_load (dest, src));
2396 else if (MEM_P (dest))
2397 emit_insn (gen_bswap<mode>2_store (dest, src));
2399 emit_insn (gen_bswap<mode>2_reg (dest, src));
2403 (define_insn "bswap<mode>2_load"
2404 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2405 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2408 [(set_attr "type" "load")])
2410 (define_insn "bswap<mode>2_store"
2411 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2412 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2415 [(set_attr "type" "store")])
2417 (define_insn_and_split "bswaphi2_reg"
2418 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
2420 (match_operand:HI 1 "gpc_reg_operand" "r")))
2421 (clobber (match_scratch:SI 2 "=&r"))]
2426 (and:SI (lshiftrt:SI (match_dup 4)
2430 (and:SI (ashift:SI (match_dup 4)
2432 (const_int 65280))) ;; 0xff00
2434 (ior:SI (match_dup 3)
2437 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2438 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2440 [(set_attr "length" "12")
2441 (set_attr "type" "*")])
2443 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2444 ;; zero_extract insns do not change for -mlittle.
2445 (define_insn_and_split "bswapsi2_reg"
2446 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
2448 (match_operand:SI 1 "gpc_reg_operand" "r")))]
2452 [(set (match_dup 0) ; DABC
2453 (rotate:SI (match_dup 1)
2455 (set (match_dup 0) ; DCBC
2456 (ior:SI (and:SI (ashift:SI (match_dup 1)
2458 (const_int 16711680))
2459 (and:SI (match_dup 0)
2460 (const_int -16711681))))
2461 (set (match_dup 0) ; DCBA
2462 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2465 (and:SI (match_dup 0)
2466 (const_int -256))))]
2469 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2470 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2473 (define_expand "bswapdi2"
2474 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2476 (match_operand:DI 1 "reg_or_mem_operand" "")))
2477 (clobber (match_scratch:DI 2 ""))
2478 (clobber (match_scratch:DI 3 ""))])]
2481 rtx dest = operands[0];
2482 rtx src = operands[1];
2484 if (!REG_P (dest) && !REG_P (src))
2485 operands[1] = src = force_reg (DImode, src);
2487 if (TARGET_POWERPC64 && TARGET_LDBRX)
2490 emit_insn (gen_bswapdi2_load (dest, src));
2491 else if (MEM_P (dest))
2492 emit_insn (gen_bswapdi2_store (dest, src));
2494 emit_insn (gen_bswapdi2_reg (dest, src));
2498 if (!TARGET_POWERPC64)
2500 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2501 that uses 64-bit registers needs the same scratch registers as 64-bit
2503 emit_insn (gen_bswapdi2_32bit (dest, src));
2508 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2509 (define_insn "bswapdi2_load"
2510 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2511 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2512 "TARGET_POWERPC64 && TARGET_LDBRX"
2514 [(set_attr "type" "load")])
2516 (define_insn "bswapdi2_store"
2517 [(set (match_operand:DI 0 "memory_operand" "=Z")
2518 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2519 "TARGET_POWERPC64 && TARGET_LDBRX"
2521 [(set_attr "type" "store")])
2523 (define_insn "bswapdi2_reg"
2524 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2525 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2526 (clobber (match_scratch:DI 2 "=&r"))
2527 (clobber (match_scratch:DI 3 "=&r"))]
2528 "TARGET_POWERPC64 && TARGET_LDBRX"
2530 [(set_attr "length" "36")])
2532 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2533 (define_insn "*bswapdi2_64bit"
2534 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2535 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2536 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2537 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2538 "TARGET_POWERPC64 && !TARGET_LDBRX
2539 && (REG_P (operands[0]) || REG_P (operands[1]))
2540 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2541 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2543 [(set_attr "length" "16,12,36")])
2546 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2547 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2548 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2549 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2550 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2554 rtx dest = operands[0];
2555 rtx src = operands[1];
2556 rtx op2 = operands[2];
2557 rtx op3 = operands[3];
2558 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2559 BYTES_BIG_ENDIAN ? 4 : 0);
2560 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2561 BYTES_BIG_ENDIAN ? 4 : 0);
2567 addr1 = XEXP (src, 0);
2568 if (GET_CODE (addr1) == PLUS)
2570 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2571 if (TARGET_AVOID_XFORM)
2573 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2577 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2579 else if (TARGET_AVOID_XFORM)
2581 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2586 emit_move_insn (op2, GEN_INT (4));
2587 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2590 word1 = change_address (src, SImode, addr1);
2591 word2 = change_address (src, SImode, addr2);
2593 if (BYTES_BIG_ENDIAN)
2595 emit_insn (gen_bswapsi2 (op3_32, word2));
2596 emit_insn (gen_bswapsi2 (dest_32, word1));
2600 emit_insn (gen_bswapsi2 (op3_32, word1));
2601 emit_insn (gen_bswapsi2 (dest_32, word2));
2604 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2605 emit_insn (gen_iordi3 (dest, dest, op3));
2610 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2611 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2612 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2613 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2614 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2618 rtx dest = operands[0];
2619 rtx src = operands[1];
2620 rtx op2 = operands[2];
2621 rtx op3 = operands[3];
2622 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2623 BYTES_BIG_ENDIAN ? 4 : 0);
2624 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2625 BYTES_BIG_ENDIAN ? 4 : 0);
2631 addr1 = XEXP (dest, 0);
2632 if (GET_CODE (addr1) == PLUS)
2634 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2635 if (TARGET_AVOID_XFORM)
2637 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2641 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2643 else if (TARGET_AVOID_XFORM)
2645 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2650 emit_move_insn (op2, GEN_INT (4));
2651 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2654 word1 = change_address (dest, SImode, addr1);
2655 word2 = change_address (dest, SImode, addr2);
2657 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2659 if (BYTES_BIG_ENDIAN)
2661 emit_insn (gen_bswapsi2 (word1, src_si));
2662 emit_insn (gen_bswapsi2 (word2, op3_si));
2666 emit_insn (gen_bswapsi2 (word2, src_si));
2667 emit_insn (gen_bswapsi2 (word1, op3_si));
2673 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2674 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2675 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2676 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2677 "TARGET_POWERPC64 && reload_completed"
2681 rtx dest = operands[0];
2682 rtx src = operands[1];
2683 rtx op2 = operands[2];
2684 rtx op3 = operands[3];
2685 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2686 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2687 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2688 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2689 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2691 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2692 emit_insn (gen_bswapsi2 (dest_si, src_si));
2693 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2694 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2695 emit_insn (gen_iordi3 (dest, dest, op3));
2699 (define_insn "bswapdi2_32bit"
2700 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2701 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2702 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2703 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2705 [(set_attr "length" "16,12,36")])
2708 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2709 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2710 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2711 "!TARGET_POWERPC64 && reload_completed"
2715 rtx dest = operands[0];
2716 rtx src = operands[1];
2717 rtx op2 = operands[2];
2718 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2719 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2725 addr1 = XEXP (src, 0);
2726 if (GET_CODE (addr1) == PLUS)
2728 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2729 if (TARGET_AVOID_XFORM
2730 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2732 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2736 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2738 else if (TARGET_AVOID_XFORM
2739 || REGNO (addr1) == REGNO (dest2))
2741 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2746 emit_move_insn (op2, GEN_INT (4));
2747 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2750 word1 = change_address (src, SImode, addr1);
2751 word2 = change_address (src, SImode, addr2);
2753 emit_insn (gen_bswapsi2 (dest2, word1));
2754 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2755 thus allowing us to omit an early clobber on the output. */
2756 emit_insn (gen_bswapsi2 (dest1, word2));
2761 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2762 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2763 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2764 "!TARGET_POWERPC64 && reload_completed"
2768 rtx dest = operands[0];
2769 rtx src = operands[1];
2770 rtx op2 = operands[2];
2771 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2772 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2778 addr1 = XEXP (dest, 0);
2779 if (GET_CODE (addr1) == PLUS)
2781 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2782 if (TARGET_AVOID_XFORM)
2784 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2788 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2790 else if (TARGET_AVOID_XFORM)
2792 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2797 emit_move_insn (op2, GEN_INT (4));
2798 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2801 word1 = change_address (dest, SImode, addr1);
2802 word2 = change_address (dest, SImode, addr2);
2804 emit_insn (gen_bswapsi2 (word2, src1));
2805 emit_insn (gen_bswapsi2 (word1, src2));
2810 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2811 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2812 (clobber (match_operand:SI 2 "" ""))]
2813 "!TARGET_POWERPC64 && reload_completed"
2817 rtx dest = operands[0];
2818 rtx src = operands[1];
2819 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2820 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2821 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2822 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2824 emit_insn (gen_bswapsi2 (dest1, src2));
2825 emit_insn (gen_bswapsi2 (dest2, src1));
2830 (define_insn "mul<mode>3"
2831 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2832 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2833 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2838 [(set_attr "type" "mul")
2840 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2842 (match_operand:GPR 2 "short_cint_operand" "")
2843 (const_string "16")]
2844 (const_string "<bits>")))])
2846 (define_insn_and_split "*mul<mode>3_dot"
2847 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2848 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2849 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2851 (clobber (match_scratch:GPR 0 "=r,r"))]
2852 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2856 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2858 (mult:GPR (match_dup 1)
2861 (compare:CC (match_dup 0)
2864 [(set_attr "type" "mul")
2865 (set_attr "size" "<bits>")
2866 (set_attr "dot" "yes")
2867 (set_attr "length" "4,8")])
2869 (define_insn_and_split "*mul<mode>3_dot2"
2870 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2871 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2872 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2874 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2875 (mult:GPR (match_dup 1)
2877 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2881 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2883 (mult:GPR (match_dup 1)
2886 (compare:CC (match_dup 0)
2889 [(set_attr "type" "mul")
2890 (set_attr "size" "<bits>")
2891 (set_attr "dot" "yes")
2892 (set_attr "length" "4,8")])
2895 (define_expand "<su>mul<mode>3_highpart"
2896 [(set (match_operand:GPR 0 "gpc_reg_operand")
2898 (mult:<DMODE> (any_extend:<DMODE>
2899 (match_operand:GPR 1 "gpc_reg_operand"))
2901 (match_operand:GPR 2 "gpc_reg_operand")))
2905 if (<MODE>mode == SImode && TARGET_POWERPC64)
2907 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2912 if (!WORDS_BIG_ENDIAN)
2914 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2920 (define_insn "*<su>mul<mode>3_highpart"
2921 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2923 (mult:<DMODE> (any_extend:<DMODE>
2924 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2926 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2928 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2929 "mulh<wd><u> %0,%1,%2"
2930 [(set_attr "type" "mul")
2931 (set_attr "size" "<bits>")])
2933 (define_insn "<su>mulsi3_highpart_le"
2934 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2936 (mult:DI (any_extend:DI
2937 (match_operand:SI 1 "gpc_reg_operand" "r"))
2939 (match_operand:SI 2 "gpc_reg_operand" "r")))
2941 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2943 [(set_attr "type" "mul")])
2945 (define_insn "<su>muldi3_highpart_le"
2946 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2948 (mult:TI (any_extend:TI
2949 (match_operand:DI 1 "gpc_reg_operand" "r"))
2951 (match_operand:DI 2 "gpc_reg_operand" "r")))
2953 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2955 [(set_attr "type" "mul")
2956 (set_attr "size" "64")])
2958 (define_insn "<su>mulsi3_highpart_64"
2959 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2962 (mult:DI (any_extend:DI
2963 (match_operand:SI 1 "gpc_reg_operand" "r"))
2965 (match_operand:SI 2 "gpc_reg_operand" "r")))
2969 [(set_attr "type" "mul")])
2971 (define_expand "<u>mul<mode><dmode>3"
2972 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2973 (mult:<DMODE> (any_extend:<DMODE>
2974 (match_operand:GPR 1 "gpc_reg_operand"))
2976 (match_operand:GPR 2 "gpc_reg_operand"))))]
2977 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2979 rtx l = gen_reg_rtx (<MODE>mode);
2980 rtx h = gen_reg_rtx (<MODE>mode);
2981 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2982 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2983 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2984 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2988 (define_insn "*maddld4"
2989 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2990 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2991 (match_operand:DI 2 "gpc_reg_operand" "r"))
2992 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2994 "maddld %0,%1,%2,%3"
2995 [(set_attr "type" "mul")])
2997 (define_insn "udiv<mode>3"
2998 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2999 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3000 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3003 [(set_attr "type" "div")
3004 (set_attr "size" "<bits>")])
3007 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3008 ;; modulus. If it isn't a power of two, force operands into register and do
3010 (define_expand "div<mode>3"
3011 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3012 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3013 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3016 if (CONST_INT_P (operands[2])
3017 && INTVAL (operands[2]) > 0
3018 && exact_log2 (INTVAL (operands[2])) >= 0)
3020 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3024 operands[2] = force_reg (<MODE>mode, operands[2]);
3027 (define_insn "*div<mode>3"
3028 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3029 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3030 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3033 [(set_attr "type" "div")
3034 (set_attr "size" "<bits>")])
3036 (define_insn "div<mode>3_sra"
3037 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3038 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3039 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3040 (clobber (reg:GPR CA_REGNO))]
3042 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3043 [(set_attr "type" "two")
3044 (set_attr "length" "8")])
3046 (define_insn_and_split "*div<mode>3_sra_dot"
3047 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3048 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3049 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3051 (clobber (match_scratch:GPR 0 "=r,r"))
3052 (clobber (reg:GPR CA_REGNO))]
3053 "<MODE>mode == Pmode"
3055 sra<wd>i %0,%1,%p2\;addze. %0,%0
3057 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3058 [(parallel [(set (match_dup 0)
3059 (div:GPR (match_dup 1)
3061 (clobber (reg:GPR CA_REGNO))])
3063 (compare:CC (match_dup 0)
3066 [(set_attr "type" "two")
3067 (set_attr "length" "8,12")
3068 (set_attr "cell_micro" "not")])
3070 (define_insn_and_split "*div<mode>3_sra_dot2"
3071 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3072 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3073 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3075 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3076 (div:GPR (match_dup 1)
3078 (clobber (reg:GPR CA_REGNO))]
3079 "<MODE>mode == Pmode"
3081 sra<wd>i %0,%1,%p2\;addze. %0,%0
3083 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3084 [(parallel [(set (match_dup 0)
3085 (div:GPR (match_dup 1)
3087 (clobber (reg:GPR CA_REGNO))])
3089 (compare:CC (match_dup 0)
3092 [(set_attr "type" "two")
3093 (set_attr "length" "8,12")
3094 (set_attr "cell_micro" "not")])
3096 (define_expand "mod<mode>3"
3097 [(set (match_operand:GPR 0 "gpc_reg_operand")
3098 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3099 (match_operand:GPR 2 "reg_or_cint_operand")))]
3106 if (GET_CODE (operands[2]) != CONST_INT
3107 || INTVAL (operands[2]) <= 0
3108 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3113 operands[2] = force_reg (<MODE>mode, operands[2]);
3117 temp1 = gen_reg_rtx (<MODE>mode);
3118 temp2 = gen_reg_rtx (<MODE>mode);
3120 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3121 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3122 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3127 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3128 ;; mod, prefer putting the result of mod into a different register
3129 (define_insn "*mod<mode>3"
3130 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3131 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3132 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3135 [(set_attr "type" "div")
3136 (set_attr "size" "<bits>")])
3139 (define_insn "umod<mode>3"
3140 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3141 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3142 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3145 [(set_attr "type" "div")
3146 (set_attr "size" "<bits>")])
3148 ;; On machines with modulo support, do a combined div/mod the old fashioned
3149 ;; method, since the multiply/subtract is faster than doing the mod instruction
3153 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3154 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3155 (match_operand:GPR 2 "gpc_reg_operand" "")))
3156 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3157 (mod:GPR (match_dup 1)
3160 && ! reg_mentioned_p (operands[0], operands[1])
3161 && ! reg_mentioned_p (operands[0], operands[2])
3162 && ! reg_mentioned_p (operands[3], operands[1])
3163 && ! reg_mentioned_p (operands[3], operands[2])"
3165 (div:GPR (match_dup 1)
3168 (mult:GPR (match_dup 0)
3171 (minus:GPR (match_dup 1)
3175 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3176 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3177 (match_operand:GPR 2 "gpc_reg_operand" "")))
3178 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3179 (umod:GPR (match_dup 1)
3182 && ! reg_mentioned_p (operands[0], operands[1])
3183 && ! reg_mentioned_p (operands[0], operands[2])
3184 && ! reg_mentioned_p (operands[3], operands[1])
3185 && ! reg_mentioned_p (operands[3], operands[2])"
3187 (udiv:GPR (match_dup 1)
3190 (mult:GPR (match_dup 0)
3193 (minus:GPR (match_dup 1)
3197 ;; Logical instructions
3198 ;; The logical instructions are mostly combined by using match_operator,
3199 ;; but the plain AND insns are somewhat different because there is no
3200 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3201 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3203 (define_expand "and<mode>3"
3204 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3205 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3206 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3209 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3211 rs6000_split_logical (operands, AND, false, false, false);
3215 if (CONST_INT_P (operands[2]))
3217 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3219 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3223 if (logical_const_operand (operands[2], <MODE>mode)
3224 && rs6000_gen_cell_microcode)
3226 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3230 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3232 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3236 operands[2] = force_reg (<MODE>mode, operands[2]);
3241 (define_insn "and<mode>3_imm"
3242 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3243 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3244 (match_operand:GPR 2 "logical_const_operand" "n")))
3245 (clobber (match_scratch:CC 3 "=x"))]
3246 "rs6000_gen_cell_microcode
3247 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3248 "andi%e2. %0,%1,%u2"
3249 [(set_attr "type" "logical")
3250 (set_attr "dot" "yes")])
3252 (define_insn_and_split "*and<mode>3_imm_dot"
3253 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3254 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3255 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3257 (clobber (match_scratch:GPR 0 "=r,r"))
3258 (clobber (match_scratch:CC 4 "=X,x"))]
3259 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3260 && rs6000_gen_cell_microcode
3261 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3265 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3266 [(parallel [(set (match_dup 0)
3267 (and:GPR (match_dup 1)
3269 (clobber (match_dup 4))])
3271 (compare:CC (match_dup 0)
3274 [(set_attr "type" "logical")
3275 (set_attr "dot" "yes")
3276 (set_attr "length" "4,8")])
3278 (define_insn_and_split "*and<mode>3_imm_dot2"
3279 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3280 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3281 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3283 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3284 (and:GPR (match_dup 1)
3286 (clobber (match_scratch:CC 4 "=X,x"))]
3287 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3288 && rs6000_gen_cell_microcode
3289 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3293 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3294 [(parallel [(set (match_dup 0)
3295 (and:GPR (match_dup 1)
3297 (clobber (match_dup 4))])
3299 (compare:CC (match_dup 0)
3302 [(set_attr "type" "logical")
3303 (set_attr "dot" "yes")
3304 (set_attr "length" "4,8")])
3306 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3307 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3308 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3309 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3311 (clobber (match_scratch:GPR 0 "=r,r"))]
3312 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3313 && rs6000_gen_cell_microcode
3314 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3318 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3320 (and:GPR (match_dup 1)
3323 (compare:CC (match_dup 0)
3326 [(set_attr "type" "logical")
3327 (set_attr "dot" "yes")
3328 (set_attr "length" "4,8")])
3330 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3331 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3332 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3333 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3335 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3336 (and:GPR (match_dup 1)
3338 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3339 && rs6000_gen_cell_microcode
3340 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3344 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3346 (and:GPR (match_dup 1)
3349 (compare:CC (match_dup 0)
3352 [(set_attr "type" "logical")
3353 (set_attr "dot" "yes")
3354 (set_attr "length" "4,8")])
3356 (define_insn "*and<mode>3_imm_dot_shifted"
3357 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3360 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3361 (match_operand:SI 4 "const_int_operand" "n"))
3362 (match_operand:GPR 2 "const_int_operand" "n"))
3364 (clobber (match_scratch:GPR 0 "=r"))]
3365 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3366 << INTVAL (operands[4])),
3368 && (<MODE>mode == Pmode
3369 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3370 && rs6000_gen_cell_microcode"
3372 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3373 return "andi%e2. %0,%1,%u2";
3375 [(set_attr "type" "logical")
3376 (set_attr "dot" "yes")])
3379 (define_insn "and<mode>3_mask"
3380 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3381 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3382 (match_operand:GPR 2 "const_int_operand" "n")))]
3383 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3385 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3387 [(set_attr "type" "shift")])
3389 (define_insn_and_split "*and<mode>3_mask_dot"
3390 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3391 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3392 (match_operand:GPR 2 "const_int_operand" "n,n"))
3394 (clobber (match_scratch:GPR 0 "=r,r"))]
3395 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3396 && rs6000_gen_cell_microcode
3397 && !logical_const_operand (operands[2], <MODE>mode)
3398 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3400 if (which_alternative == 0)
3401 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3405 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3407 (and:GPR (match_dup 1)
3410 (compare:CC (match_dup 0)
3413 [(set_attr "type" "shift")
3414 (set_attr "dot" "yes")
3415 (set_attr "length" "4,8")])
3417 (define_insn_and_split "*and<mode>3_mask_dot2"
3418 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3419 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3420 (match_operand:GPR 2 "const_int_operand" "n,n"))
3422 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3423 (and:GPR (match_dup 1)
3425 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3426 && rs6000_gen_cell_microcode
3427 && !logical_const_operand (operands[2], <MODE>mode)
3428 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3430 if (which_alternative == 0)
3431 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3435 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3437 (and:GPR (match_dup 1)
3440 (compare:CC (match_dup 0)
3443 [(set_attr "type" "shift")
3444 (set_attr "dot" "yes")
3445 (set_attr "length" "4,8")])
3448 (define_insn_and_split "*and<mode>3_2insn"
3449 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3450 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3451 (match_operand:GPR 2 "const_int_operand" "n")))]
3452 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3453 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3454 || (logical_const_operand (operands[2], <MODE>mode)
3455 && rs6000_gen_cell_microcode))"
3460 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3463 [(set_attr "type" "shift")
3464 (set_attr "length" "8")])
3466 (define_insn_and_split "*and<mode>3_2insn_dot"
3467 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3468 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3469 (match_operand:GPR 2 "const_int_operand" "n,n"))
3471 (clobber (match_scratch:GPR 0 "=r,r"))]
3472 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3473 && rs6000_gen_cell_microcode
3474 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3475 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3476 || (logical_const_operand (operands[2], <MODE>mode)
3477 && rs6000_gen_cell_microcode))"
3479 "&& reload_completed"
3482 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3485 [(set_attr "type" "shift")
3486 (set_attr "dot" "yes")
3487 (set_attr "length" "8,12")])
3489 (define_insn_and_split "*and<mode>3_2insn_dot2"
3490 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3491 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3492 (match_operand:GPR 2 "const_int_operand" "n,n"))
3494 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3495 (and:GPR (match_dup 1)
3497 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3498 && rs6000_gen_cell_microcode
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)
3502 && rs6000_gen_cell_microcode))"
3504 "&& reload_completed"
3507 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3510 [(set_attr "type" "shift")
3511 (set_attr "dot" "yes")
3512 (set_attr "length" "8,12")])
3515 (define_expand "<code><mode>3"
3516 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3517 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3518 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3521 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3523 rs6000_split_logical (operands, <CODE>, false, false, false);
3527 if (non_logical_cint_operand (operands[2], <MODE>mode))
3529 rtx tmp = ((!can_create_pseudo_p ()
3530 || rtx_equal_p (operands[0], operands[1]))
3531 ? operands[0] : gen_reg_rtx (<MODE>mode));
3533 HOST_WIDE_INT value = INTVAL (operands[2]);
3534 HOST_WIDE_INT lo = value & 0xffff;
3535 HOST_WIDE_INT hi = value - lo;
3537 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3538 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3542 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3543 operands[2] = force_reg (<MODE>mode, operands[2]);
3547 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3548 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3549 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3552 (iorxor:GPR (match_dup 1)
3555 (iorxor:GPR (match_dup 3)
3558 operands[3] = ((!can_create_pseudo_p ()
3559 || rtx_equal_p (operands[0], operands[1]))
3560 ? operands[0] : gen_reg_rtx (<MODE>mode));
3562 HOST_WIDE_INT value = INTVAL (operands[2]);
3563 HOST_WIDE_INT lo = value & 0xffff;
3564 HOST_WIDE_INT hi = value - lo;
3566 operands[4] = GEN_INT (hi);
3567 operands[5] = GEN_INT (lo);
3570 (define_insn "*bool<mode>3_imm"
3571 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3572 (match_operator:GPR 3 "boolean_or_operator"
3573 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3574 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3577 [(set_attr "type" "logical")])
3579 (define_insn "*bool<mode>3"
3580 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3581 (match_operator:GPR 3 "boolean_operator"
3582 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3583 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3586 [(set_attr "type" "logical")])
3588 (define_insn_and_split "*bool<mode>3_dot"
3589 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3590 (compare:CC (match_operator:GPR 3 "boolean_operator"
3591 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3592 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3594 (clobber (match_scratch:GPR 0 "=r,r"))]
3595 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3599 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3603 (compare:CC (match_dup 0)
3606 [(set_attr "type" "logical")
3607 (set_attr "dot" "yes")
3608 (set_attr "length" "4,8")])
3610 (define_insn_and_split "*bool<mode>3_dot2"
3611 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3612 (compare:CC (match_operator:GPR 3 "boolean_operator"
3613 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3614 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3616 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3618 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3622 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3626 (compare:CC (match_dup 0)
3629 [(set_attr "type" "logical")
3630 (set_attr "dot" "yes")
3631 (set_attr "length" "4,8")])
3634 (define_insn "*boolc<mode>3"
3635 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3636 (match_operator:GPR 3 "boolean_operator"
3637 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3638 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3641 [(set_attr "type" "logical")])
3643 (define_insn_and_split "*boolc<mode>3_dot"
3644 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3645 (compare:CC (match_operator:GPR 3 "boolean_operator"
3646 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3647 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3649 (clobber (match_scratch:GPR 0 "=r,r"))]
3650 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3654 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3658 (compare:CC (match_dup 0)
3661 [(set_attr "type" "logical")
3662 (set_attr "dot" "yes")
3663 (set_attr "length" "4,8")])
3665 (define_insn_and_split "*boolc<mode>3_dot2"
3666 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3667 (compare:CC (match_operator:GPR 3 "boolean_operator"
3668 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3669 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3671 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3673 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3677 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3681 (compare:CC (match_dup 0)
3684 [(set_attr "type" "logical")
3685 (set_attr "dot" "yes")
3686 (set_attr "length" "4,8")])
3689 (define_insn "*boolcc<mode>3"
3690 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3691 (match_operator:GPR 3 "boolean_operator"
3692 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3693 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3696 [(set_attr "type" "logical")])
3698 (define_insn_and_split "*boolcc<mode>3_dot"
3699 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3700 (compare:CC (match_operator:GPR 3 "boolean_operator"
3701 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3702 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3704 (clobber (match_scratch:GPR 0 "=r,r"))]
3705 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3709 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3713 (compare:CC (match_dup 0)
3716 [(set_attr "type" "logical")
3717 (set_attr "dot" "yes")
3718 (set_attr "length" "4,8")])
3720 (define_insn_and_split "*boolcc<mode>3_dot2"
3721 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3722 (compare:CC (match_operator:GPR 3 "boolean_operator"
3723 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3724 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3726 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3728 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3732 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3736 (compare:CC (match_dup 0)
3739 [(set_attr "type" "logical")
3740 (set_attr "dot" "yes")
3741 (set_attr "length" "4,8")])
3744 ;; TODO: Should have dots of this as well.
3745 (define_insn "*eqv<mode>3"
3746 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3747 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3748 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3751 [(set_attr "type" "logical")])
3753 ;; Rotate-and-mask and insert.
3755 (define_insn "*rotl<mode>3_mask"
3756 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3757 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3758 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3759 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3760 (match_operand:GPR 3 "const_int_operand" "n")))]
3761 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3763 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3765 [(set_attr "type" "shift")
3766 (set_attr "maybe_var_shift" "yes")])
3768 (define_insn_and_split "*rotl<mode>3_mask_dot"
3769 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3771 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3772 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3773 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3774 (match_operand:GPR 3 "const_int_operand" "n,n"))
3776 (clobber (match_scratch:GPR 0 "=r,r"))]
3777 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3778 && rs6000_gen_cell_microcode
3779 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3781 if (which_alternative == 0)
3782 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3786 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3788 (and:GPR (match_dup 4)
3791 (compare:CC (match_dup 0)
3794 [(set_attr "type" "shift")
3795 (set_attr "maybe_var_shift" "yes")
3796 (set_attr "dot" "yes")
3797 (set_attr "length" "4,8")])
3799 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3800 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3802 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3803 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3804 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3805 (match_operand:GPR 3 "const_int_operand" "n,n"))
3807 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3808 (and:GPR (match_dup 4)
3810 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3811 && rs6000_gen_cell_microcode
3812 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3814 if (which_alternative == 0)
3815 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3819 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3821 (and:GPR (match_dup 4)
3824 (compare:CC (match_dup 0)
3827 [(set_attr "type" "shift")
3828 (set_attr "maybe_var_shift" "yes")
3829 (set_attr "dot" "yes")
3830 (set_attr "length" "4,8")])
3832 ; Special case for less-than-0. We can do it with just one machine
3833 ; instruction, but the generic optimizers do not realise it is cheap.
3834 (define_insn "*lt0_disi"
3835 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3836 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3839 "rlwinm %0,%1,1,31,31"
3840 [(set_attr "type" "shift")])
3844 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3845 ; both are an AND so are the same precedence).
3846 (define_insn "*rotl<mode>3_insert"
3847 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3848 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3849 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3850 (match_operand:SI 2 "const_int_operand" "n")])
3851 (match_operand:GPR 3 "const_int_operand" "n"))
3852 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3853 (match_operand:GPR 6 "const_int_operand" "n"))))]
3854 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3855 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3857 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3859 [(set_attr "type" "insert")])
3860 ; FIXME: this needs an attr "size", so that the scheduler can see the
3861 ; difference between rlwimi and rldimi. We also might want dot forms,
3862 ; but not for rlwimi on POWER4 and similar processors.
3864 (define_insn "*rotl<mode>3_insert_2"
3865 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3867 (match_operand:GPR 6 "const_int_operand" "n"))
3868 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3869 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3870 (match_operand:SI 2 "const_int_operand" "n")])
3871 (match_operand:GPR 3 "const_int_operand" "n"))))]
3872 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3873 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3875 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3877 [(set_attr "type" "insert")])
3879 ; There are also some forms without one of the ANDs.
3880 (define_insn "*rotl<mode>3_insert_3"
3881 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3882 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3883 (match_operand:GPR 4 "const_int_operand" "n"))
3884 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3885 (match_operand:SI 2 "const_int_operand" "n"))))]
3886 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3888 if (<MODE>mode == SImode)
3889 return "rlwimi %0,%1,%h2,0,31-%h2";
3891 return "rldimi %0,%1,%H2,0";
3893 [(set_attr "type" "insert")])
3895 (define_insn "*rotl<mode>3_insert_4"
3896 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3897 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3898 (match_operand:GPR 4 "const_int_operand" "n"))
3899 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3900 (match_operand:SI 2 "const_int_operand" "n"))))]
3901 "<MODE>mode == SImode &&
3902 GET_MODE_PRECISION (<MODE>mode)
3903 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3905 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3906 - INTVAL (operands[2]));
3907 if (<MODE>mode == SImode)
3908 return "rlwimi %0,%1,%h2,32-%h2,31";
3910 return "rldimi %0,%1,%H2,64-%H2";
3912 [(set_attr "type" "insert")])
3914 (define_insn "*rotlsi3_insert_5"
3915 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3916 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3917 (match_operand:SI 2 "const_int_operand" "n,n"))
3918 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3919 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3920 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3921 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3922 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3926 [(set_attr "type" "insert")])
3928 (define_insn "*rotldi3_insert_6"
3929 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3930 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3931 (match_operand:DI 2 "const_int_operand" "n"))
3932 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3933 (match_operand:DI 4 "const_int_operand" "n"))))]
3934 "exact_log2 (-UINTVAL (operands[2])) > 0
3935 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3937 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3938 return "rldimi %0,%3,0,%5";
3940 [(set_attr "type" "insert")
3941 (set_attr "size" "64")])
3943 (define_insn "*rotldi3_insert_7"
3944 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3945 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3946 (match_operand:DI 4 "const_int_operand" "n"))
3947 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3948 (match_operand:DI 2 "const_int_operand" "n"))))]
3949 "exact_log2 (-UINTVAL (operands[2])) > 0
3950 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3952 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3953 return "rldimi %0,%3,0,%5";
3955 [(set_attr "type" "insert")
3956 (set_attr "size" "64")])
3959 ; This handles the important case of multiple-precision shifts. There is
3960 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3962 [(set (match_operand:GPR 0 "gpc_reg_operand")
3963 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3964 (match_operand:SI 3 "const_int_operand"))
3965 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3966 (match_operand:SI 4 "const_int_operand"))))]
3967 "can_create_pseudo_p ()
3968 && INTVAL (operands[3]) + INTVAL (operands[4])
3969 >= GET_MODE_PRECISION (<MODE>mode)"
3971 (lshiftrt:GPR (match_dup 2)
3974 (ior:GPR (and:GPR (match_dup 5)
3976 (ashift:GPR (match_dup 1)
3979 unsigned HOST_WIDE_INT mask = 1;
3980 mask = (mask << INTVAL (operands[3])) - 1;
3981 operands[5] = gen_reg_rtx (<MODE>mode);
3982 operands[6] = GEN_INT (mask);
3986 [(set (match_operand:GPR 0 "gpc_reg_operand")
3987 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3988 (match_operand:SI 4 "const_int_operand"))
3989 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3990 (match_operand:SI 3 "const_int_operand"))))]
3991 "can_create_pseudo_p ()
3992 && INTVAL (operands[3]) + INTVAL (operands[4])
3993 >= GET_MODE_PRECISION (<MODE>mode)"
3995 (lshiftrt:GPR (match_dup 2)
3998 (ior:GPR (and:GPR (match_dup 5)
4000 (ashift:GPR (match_dup 1)
4003 unsigned HOST_WIDE_INT mask = 1;
4004 mask = (mask << INTVAL (operands[3])) - 1;
4005 operands[5] = gen_reg_rtx (<MODE>mode);
4006 operands[6] = GEN_INT (mask);
4010 ; Another important case is setting some bits to 1; we can do that with
4011 ; an insert instruction, in many cases.
4012 (define_insn_and_split "*ior<mode>_mask"
4013 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4014 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4015 (match_operand:GPR 2 "const_int_operand" "n")))
4016 (clobber (match_scratch:GPR 3 "=r"))]
4017 "!logical_const_operand (operands[2], <MODE>mode)
4018 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4024 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4027 (and:GPR (match_dup 1)
4031 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4032 if (GET_CODE (operands[3]) == SCRATCH)
4033 operands[3] = gen_reg_rtx (<MODE>mode);
4034 operands[4] = GEN_INT (ne);
4035 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4037 [(set_attr "type" "two")
4038 (set_attr "length" "8")])
4041 ;; Now the simple shifts.
4043 (define_insn "rotl<mode>3"
4044 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4045 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4046 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4048 "rotl<wd>%I2 %0,%1,%<hH>2"
4049 [(set_attr "type" "shift")
4050 (set_attr "maybe_var_shift" "yes")])
4052 (define_insn "*rotlsi3_64"
4053 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4055 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4056 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4058 "rotlw%I2 %0,%1,%h2"
4059 [(set_attr "type" "shift")
4060 (set_attr "maybe_var_shift" "yes")])
4062 (define_insn_and_split "*rotl<mode>3_dot"
4063 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4064 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4065 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4067 (clobber (match_scratch:GPR 0 "=r,r"))]
4068 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4070 rotl<wd>%I2. %0,%1,%<hH>2
4072 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4074 (rotate:GPR (match_dup 1)
4077 (compare:CC (match_dup 0)
4080 [(set_attr "type" "shift")
4081 (set_attr "maybe_var_shift" "yes")
4082 (set_attr "dot" "yes")
4083 (set_attr "length" "4,8")])
4085 (define_insn_and_split "*rotl<mode>3_dot2"
4086 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4087 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4088 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4090 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4091 (rotate:GPR (match_dup 1)
4093 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4095 rotl<wd>%I2. %0,%1,%<hH>2
4097 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4099 (rotate:GPR (match_dup 1)
4102 (compare:CC (match_dup 0)
4105 [(set_attr "type" "shift")
4106 (set_attr "maybe_var_shift" "yes")
4107 (set_attr "dot" "yes")
4108 (set_attr "length" "4,8")])
4111 (define_insn "ashl<mode>3"
4112 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4113 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4114 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4116 "sl<wd>%I2 %0,%1,%<hH>2"
4117 [(set_attr "type" "shift")
4118 (set_attr "maybe_var_shift" "yes")])
4120 (define_insn "*ashlsi3_64"
4121 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4123 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4124 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4127 [(set_attr "type" "shift")
4128 (set_attr "maybe_var_shift" "yes")])
4130 (define_insn_and_split "*ashl<mode>3_dot"
4131 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4132 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4133 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4135 (clobber (match_scratch:GPR 0 "=r,r"))]
4136 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4138 sl<wd>%I2. %0,%1,%<hH>2
4140 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4142 (ashift:GPR (match_dup 1)
4145 (compare:CC (match_dup 0)
4148 [(set_attr "type" "shift")
4149 (set_attr "maybe_var_shift" "yes")
4150 (set_attr "dot" "yes")
4151 (set_attr "length" "4,8")])
4153 (define_insn_and_split "*ashl<mode>3_dot2"
4154 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4155 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4156 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4158 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4159 (ashift:GPR (match_dup 1)
4161 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4163 sl<wd>%I2. %0,%1,%<hH>2
4165 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4167 (ashift:GPR (match_dup 1)
4170 (compare:CC (match_dup 0)
4173 [(set_attr "type" "shift")
4174 (set_attr "maybe_var_shift" "yes")
4175 (set_attr "dot" "yes")
4176 (set_attr "length" "4,8")])
4178 ;; Pretend we have a memory form of extswsli until register allocation is done
4179 ;; so that we use LWZ to load the value from memory, instead of LWA.
4180 (define_insn_and_split "ashdi3_extswsli"
4181 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4183 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4184 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4189 "&& reload_completed && MEM_P (operands[1])"
4193 (ashift:DI (sign_extend:DI (match_dup 3))
4196 operands[3] = gen_lowpart (SImode, operands[0]);
4198 [(set_attr "type" "shift")
4199 (set_attr "maybe_var_shift" "no")])
4202 (define_insn_and_split "ashdi3_extswsli_dot"
4203 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4206 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4207 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4209 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4216 "&& reload_completed
4217 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4218 || memory_operand (operands[1], SImode))"
4221 rtx dest = operands[0];
4222 rtx src = operands[1];
4223 rtx shift = operands[2];
4224 rtx cr = operands[3];
4231 src2 = gen_lowpart (SImode, dest);
4232 emit_move_insn (src2, src);
4235 if (REGNO (cr) == CR0_REGNO)
4237 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4241 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4242 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4245 [(set_attr "type" "shift")
4246 (set_attr "maybe_var_shift" "no")
4247 (set_attr "dot" "yes")
4248 (set_attr "length" "4,8,8,12")])
4250 (define_insn_and_split "ashdi3_extswsli_dot2"
4251 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4254 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4255 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4257 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4258 (ashift:DI (sign_extend:DI (match_dup 1))
4266 "&& reload_completed
4267 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4268 || memory_operand (operands[1], SImode))"
4271 rtx dest = operands[0];
4272 rtx src = operands[1];
4273 rtx shift = operands[2];
4274 rtx cr = operands[3];
4281 src2 = gen_lowpart (SImode, dest);
4282 emit_move_insn (src2, src);
4285 if (REGNO (cr) == CR0_REGNO)
4287 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4291 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4292 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4295 [(set_attr "type" "shift")
4296 (set_attr "maybe_var_shift" "no")
4297 (set_attr "dot" "yes")
4298 (set_attr "length" "4,8,8,12")])
4300 (define_insn "lshr<mode>3"
4301 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4302 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4303 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4305 "sr<wd>%I2 %0,%1,%<hH>2"
4306 [(set_attr "type" "shift")
4307 (set_attr "maybe_var_shift" "yes")])
4309 (define_insn "*lshrsi3_64"
4310 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4312 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4313 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4316 [(set_attr "type" "shift")
4317 (set_attr "maybe_var_shift" "yes")])
4319 (define_insn_and_split "*lshr<mode>3_dot"
4320 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4321 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4322 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4324 (clobber (match_scratch:GPR 0 "=r,r"))]
4325 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4327 sr<wd>%I2. %0,%1,%<hH>2
4329 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4331 (lshiftrt:GPR (match_dup 1)
4334 (compare:CC (match_dup 0)
4337 [(set_attr "type" "shift")
4338 (set_attr "maybe_var_shift" "yes")
4339 (set_attr "dot" "yes")
4340 (set_attr "length" "4,8")])
4342 (define_insn_and_split "*lshr<mode>3_dot2"
4343 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4344 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4345 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4347 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4348 (lshiftrt:GPR (match_dup 1)
4350 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4352 sr<wd>%I2. %0,%1,%<hH>2
4354 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4356 (lshiftrt:GPR (match_dup 1)
4359 (compare:CC (match_dup 0)
4362 [(set_attr "type" "shift")
4363 (set_attr "maybe_var_shift" "yes")
4364 (set_attr "dot" "yes")
4365 (set_attr "length" "4,8")])
4368 (define_insn "ashr<mode>3"
4369 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4370 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4371 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4372 (clobber (reg:GPR CA_REGNO))]
4374 "sra<wd>%I2 %0,%1,%<hH>2"
4375 [(set_attr "type" "shift")
4376 (set_attr "maybe_var_shift" "yes")])
4378 (define_insn "*ashrsi3_64"
4379 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4381 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4382 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4383 (clobber (reg:SI CA_REGNO))]
4386 [(set_attr "type" "shift")
4387 (set_attr "maybe_var_shift" "yes")])
4389 (define_insn_and_split "*ashr<mode>3_dot"
4390 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4391 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4392 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4394 (clobber (match_scratch:GPR 0 "=r,r"))
4395 (clobber (reg:GPR CA_REGNO))]
4396 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4398 sra<wd>%I2. %0,%1,%<hH>2
4400 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4401 [(parallel [(set (match_dup 0)
4402 (ashiftrt:GPR (match_dup 1)
4404 (clobber (reg:GPR CA_REGNO))])
4406 (compare:CC (match_dup 0)
4409 [(set_attr "type" "shift")
4410 (set_attr "maybe_var_shift" "yes")
4411 (set_attr "dot" "yes")
4412 (set_attr "length" "4,8")])
4414 (define_insn_and_split "*ashr<mode>3_dot2"
4415 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4416 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4417 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4419 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4420 (ashiftrt:GPR (match_dup 1)
4422 (clobber (reg:GPR CA_REGNO))]
4423 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4425 sra<wd>%I2. %0,%1,%<hH>2
4427 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4428 [(parallel [(set (match_dup 0)
4429 (ashiftrt:GPR (match_dup 1)
4431 (clobber (reg:GPR CA_REGNO))])
4433 (compare:CC (match_dup 0)
4436 [(set_attr "type" "shift")
4437 (set_attr "maybe_var_shift" "yes")
4438 (set_attr "dot" "yes")
4439 (set_attr "length" "4,8")])
4441 ;; Builtins to replace a division to generate FRE reciprocal estimate
4442 ;; instructions and the necessary fixup instructions
4443 (define_expand "recip<mode>3"
4444 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4445 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4446 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4447 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4449 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4453 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4454 ;; hardware division. This is only done before register allocation and with
4455 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4456 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4457 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4459 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4460 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4461 (match_operand 2 "gpc_reg_operand" "")))]
4462 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4463 && can_create_pseudo_p () && flag_finite_math_only
4464 && !flag_trapping_math && flag_reciprocal_math"
4467 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4471 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4472 ;; appropriate fixup.
4473 (define_expand "rsqrt<mode>2"
4474 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4475 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4476 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4478 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4482 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4483 ;; modes here, and also add in conditional vsx/power8-vector support to access
4484 ;; values in the traditional Altivec registers if the appropriate
4485 ;; -mupper-regs-{df,sf} option is enabled.
4487 (define_expand "abs<mode>2"
4488 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4489 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4490 "TARGET_<MODE>_INSN"
4493 (define_insn "*abs<mode>2_fpr"
4494 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4495 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4500 [(set_attr "type" "fpsimple")
4501 (set_attr "fp_type" "fp_addsub_<Fs>")])
4503 (define_insn "*nabs<mode>2_fpr"
4504 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4507 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4512 [(set_attr "type" "fpsimple")
4513 (set_attr "fp_type" "fp_addsub_<Fs>")])
4515 (define_expand "neg<mode>2"
4516 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4517 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4518 "TARGET_<MODE>_INSN"
4521 (define_insn "*neg<mode>2_fpr"
4522 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4523 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4528 [(set_attr "type" "fpsimple")
4529 (set_attr "fp_type" "fp_addsub_<Fs>")])
4531 (define_expand "add<mode>3"
4532 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4533 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4534 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4535 "TARGET_<MODE>_INSN"
4538 (define_insn "*add<mode>3_fpr"
4539 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4540 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4541 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4544 fadd<Ftrad> %0,%1,%2
4545 xsadd<Fvsx> %x0,%x1,%x2"
4546 [(set_attr "type" "fp")
4547 (set_attr "fp_type" "fp_addsub_<Fs>")])
4549 (define_expand "sub<mode>3"
4550 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4551 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4552 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4553 "TARGET_<MODE>_INSN"
4556 (define_insn "*sub<mode>3_fpr"
4557 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4558 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4559 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4562 fsub<Ftrad> %0,%1,%2
4563 xssub<Fvsx> %x0,%x1,%x2"
4564 [(set_attr "type" "fp")
4565 (set_attr "fp_type" "fp_addsub_<Fs>")])
4567 (define_expand "mul<mode>3"
4568 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4569 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4570 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4571 "TARGET_<MODE>_INSN"
4574 (define_insn "*mul<mode>3_fpr"
4575 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4576 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4577 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4580 fmul<Ftrad> %0,%1,%2
4581 xsmul<Fvsx> %x0,%x1,%x2"
4582 [(set_attr "type" "dmul")
4583 (set_attr "fp_type" "fp_mul_<Fs>")])
4585 (define_expand "div<mode>3"
4586 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4587 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4588 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4589 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4591 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4592 && can_create_pseudo_p () && flag_finite_math_only
4593 && !flag_trapping_math && flag_reciprocal_math)
4595 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4600 (define_insn "*div<mode>3_fpr"
4601 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4602 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4603 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4604 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4606 fdiv<Ftrad> %0,%1,%2
4607 xsdiv<Fvsx> %x0,%x1,%x2"
4608 [(set_attr "type" "<Fs>div")
4609 (set_attr "fp_type" "fp_div_<Fs>")])
4611 (define_insn "*sqrt<mode>2_internal"
4612 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4613 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4614 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4615 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4618 xssqrt<Fvsx> %x0,%x1"
4619 [(set_attr "type" "<Fs>sqrt")
4620 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4622 (define_expand "sqrt<mode>2"
4623 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4624 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4625 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4626 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4628 if (<MODE>mode == SFmode
4629 && TARGET_RECIP_PRECISION
4630 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4631 && !optimize_function_for_size_p (cfun)
4632 && flag_finite_math_only && !flag_trapping_math
4633 && flag_unsafe_math_optimizations)
4635 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4640 ;; Floating point reciprocal approximation
4641 (define_insn "fre<Fs>"
4642 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4643 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4649 [(set_attr "type" "fp")])
4651 (define_insn "*rsqrt<mode>2"
4652 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4653 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4655 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4657 frsqrte<Ftrad> %0,%1
4658 xsrsqrte<Fvsx> %x0,%x1"
4659 [(set_attr "type" "fp")])
4661 ;; Floating point comparisons
4662 (define_insn "*cmp<mode>_fpr"
4663 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4664 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4665 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4669 xscmpudp %0,%x1,%x2"
4670 [(set_attr "type" "fpcompare")])
4672 ;; Floating point conversions
4673 (define_expand "extendsfdf2"
4674 [(set (match_operand:DF 0 "gpc_reg_operand")
4675 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand")))]
4676 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4678 if (HONOR_SNANS (SFmode))
4679 operands[1] = force_reg (SFmode, operands[1]);
4682 (define_insn_and_split "*extendsfdf2_fpr"
4683 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4684 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4685 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4686 && !HONOR_SNANS (SFmode)"
4692 xscpsgndp %x0,%x1,%x1
4695 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4698 emit_note (NOTE_INSN_DELETED);
4701 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4703 (define_insn "*extendsfdf2_snan"
4704 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4705 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4706 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4707 && HONOR_SNANS (SFmode)"
4711 [(set_attr "type" "fp")])
4713 (define_expand "truncdfsf2"
4714 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4715 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4716 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4719 (define_insn "*truncdfsf2_fpr"
4720 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4721 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4722 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4726 [(set_attr "type" "fp")])
4728 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4729 ;; builtins.c and optabs.c that are not correct for IBM long double
4730 ;; when little-endian.
4731 (define_expand "signbit<mode>2"
4733 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4735 (subreg:DI (match_dup 2) 0))
4738 (set (match_operand:SI 0 "gpc_reg_operand" "")
4741 && (TARGET_FPRS || TARGET_E500_DOUBLE)
4742 && (!FLOAT128_IEEE_P (<MODE>mode)
4743 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4745 if (FLOAT128_IEEE_P (<MODE>mode))
4747 if (<MODE>mode == KFmode)
4748 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4749 else if (<MODE>mode == TFmode)
4750 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4755 operands[2] = gen_reg_rtx (DFmode);
4756 operands[3] = gen_reg_rtx (DImode);
4757 if (TARGET_POWERPC64)
4759 operands[4] = gen_reg_rtx (DImode);
4760 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4761 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4762 WORDS_BIG_ENDIAN ? 4 : 0);
4766 operands[4] = gen_reg_rtx (SImode);
4767 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4768 WORDS_BIG_ENDIAN ? 0 : 4);
4769 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4773 (define_expand "copysign<mode>3"
4775 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4777 (neg:SFDF (abs:SFDF (match_dup 1))))
4778 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4779 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4783 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4784 && ((TARGET_PPC_GFXOPT
4785 && !HONOR_NANS (<MODE>mode)
4786 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4788 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4790 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4792 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4797 operands[3] = gen_reg_rtx (<MODE>mode);
4798 operands[4] = gen_reg_rtx (<MODE>mode);
4799 operands[5] = CONST0_RTX (<MODE>mode);
4802 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4804 (define_insn_and_split "signbit<mode>2_dm"
4805 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4807 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4809 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4811 "&& reload_completed"
4814 rs6000_split_signbit (operands[0], operands[1]);
4817 [(set_attr "length" "8,8,4")
4818 (set_attr "type" "mftgpr,load,integer")])
4820 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4821 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4824 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4826 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4828 "&& reload_completed"
4831 rs6000_split_signbit (operands[0], operands[1]);
4834 [(set_attr "length" "8,8,4")
4835 (set_attr "type" "mftgpr,load,integer")])
4837 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4838 ;; point types, which makes normal SUBREG's problematical. Instead use a
4839 ;; special pattern to avoid using a normal movdi.
4840 (define_insn "signbit<mode>2_dm2"
4841 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4842 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4845 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4847 [(set_attr "type" "mftgpr")])
4850 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4851 ;; compiler from optimizing -0.0
4852 (define_insn "copysign<mode>3_fcpsgn"
4853 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4854 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4855 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4857 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4860 xscpsgndp %x0,%x2,%x1"
4861 [(set_attr "type" "fpsimple")])
4863 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4864 ;; fsel instruction and some auxiliary computations. Then we just have a
4865 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4867 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4868 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4869 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4870 ;; define_splits to make them if made by combine. On VSX machines we have the
4871 ;; min/max instructions.
4873 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4874 ;; to allow either DF/SF to use only traditional registers.
4876 (define_expand "s<minmax><mode>3"
4877 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4878 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4879 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4880 "TARGET_MINMAX_<MODE>"
4882 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4886 (define_insn "*s<minmax><mode>3_vsx"
4887 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4888 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4889 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4890 "TARGET_VSX && TARGET_<MODE>_FPR"
4892 return (TARGET_P9_MINMAX
4893 ? "xs<minmax>cdp %x0,%x1,%x2"
4894 : "xs<minmax>dp %x0,%x1,%x2");
4896 [(set_attr "type" "fp")])
4898 ;; The conditional move instructions allow us to perform max and min operations
4899 ;; even when we don't have the appropriate max/min instruction using the FSEL
4902 (define_insn_and_split "*s<minmax><mode>3_fpr"
4903 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4904 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4905 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4906 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4911 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4915 (define_expand "mov<mode>cc"
4916 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4917 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4918 (match_operand:GPR 2 "gpc_reg_operand" "")
4919 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4923 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4929 ;; We use the BASE_REGS for the isel input operands because, if rA is
4930 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4931 ;; because we may switch the operands and rB may end up being rA.
4933 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4934 ;; leave out the mode in operand 4 and use one pattern, but reload can
4935 ;; change the mode underneath our feet and then gets confused trying
4936 ;; to reload the value.
4937 (define_insn "isel_signed_<mode>"
4938 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4940 (match_operator 1 "scc_comparison_operator"
4941 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4943 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4944 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4947 { return output_isel (operands); }"
4948 [(set_attr "type" "isel")
4949 (set_attr "length" "4")])
4951 (define_insn "isel_unsigned_<mode>"
4952 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4954 (match_operator 1 "scc_comparison_operator"
4955 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4957 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4958 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4961 { return output_isel (operands); }"
4962 [(set_attr "type" "isel")
4963 (set_attr "length" "4")])
4965 ;; These patterns can be useful for combine; they let combine know that
4966 ;; isel can handle reversed comparisons so long as the operands are
4969 (define_insn "*isel_reversed_signed_<mode>"
4970 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4972 (match_operator 1 "scc_rev_comparison_operator"
4973 [(match_operand:CC 4 "cc_reg_operand" "y")
4975 (match_operand:GPR 2 "gpc_reg_operand" "b")
4976 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4979 { return output_isel (operands); }"
4980 [(set_attr "type" "isel")
4981 (set_attr "length" "4")])
4983 (define_insn "*isel_reversed_unsigned_<mode>"
4984 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4986 (match_operator 1 "scc_rev_comparison_operator"
4987 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4989 (match_operand:GPR 2 "gpc_reg_operand" "b")
4990 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4993 { return output_isel (operands); }"
4994 [(set_attr "type" "isel")
4995 (set_attr "length" "4")])
4997 ;; Floating point conditional move
4998 (define_expand "mov<mode>cc"
4999 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5000 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
5001 (match_operand:SFDF 2 "gpc_reg_operand" "")
5002 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
5003 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5006 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5012 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5013 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5015 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5016 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5017 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5018 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5019 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5021 [(set_attr "type" "fp")])
5023 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5024 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5026 (match_operator:CCFP 1 "fpmask_comparison_operator"
5027 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5028 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5029 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5030 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5031 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5036 (if_then_else:V2DI (match_dup 1)
5040 (if_then_else:SFDF (ne (match_dup 6)
5045 if (GET_CODE (operands[6]) == SCRATCH)
5046 operands[6] = gen_reg_rtx (V2DImode);
5048 operands[7] = CONSTM1_RTX (V2DImode);
5049 operands[8] = CONST0_RTX (V2DImode);
5051 [(set_attr "length" "8")
5052 (set_attr "type" "vecperm")])
5054 ;; Handle inverting the fpmask comparisons.
5055 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5056 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5058 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5059 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5060 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5061 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5062 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5063 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5068 (if_then_else:V2DI (match_dup 9)
5072 (if_then_else:SFDF (ne (match_dup 6)
5077 rtx op1 = operands[1];
5078 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5080 if (GET_CODE (operands[6]) == SCRATCH)
5081 operands[6] = gen_reg_rtx (V2DImode);
5083 operands[7] = CONSTM1_RTX (V2DImode);
5084 operands[8] = CONST0_RTX (V2DImode);
5086 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5088 [(set_attr "length" "8")
5089 (set_attr "type" "vecperm")])
5091 (define_insn "*fpmask<mode>"
5092 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5094 (match_operator:CCFP 1 "fpmask_comparison_operator"
5095 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5096 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5097 (match_operand:V2DI 4 "all_ones_constant" "")
5098 (match_operand:V2DI 5 "zero_constant" "")))]
5100 "xscmp%V1dp %x0,%x2,%x3"
5101 [(set_attr "type" "fpcompare")])
5103 (define_insn "*xxsel<mode>"
5104 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5105 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5106 (match_operand:V2DI 2 "zero_constant" ""))
5107 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5108 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5110 "xxsel %x0,%x4,%x3,%x1"
5111 [(set_attr "type" "vecmove")])
5114 ;; Conversions to and from floating-point.
5116 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5117 ; don't want to support putting SImode in FPR registers.
5118 (define_insn "lfiwax"
5119 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5120 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5122 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5128 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5130 ; This split must be run before register allocation because it allocates the
5131 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5132 ; it earlier to allow for the combiner to merge insns together where it might
5133 ; not be needed and also in case the insns are deleted as dead code.
5135 (define_insn_and_split "floatsi<mode>2_lfiwax"
5136 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5137 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5138 (clobber (match_scratch:DI 2 "=wi"))]
5139 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5140 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5146 rtx dest = operands[0];
5147 rtx src = operands[1];
5150 if (!MEM_P (src) && TARGET_POWERPC64
5151 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5152 tmp = convert_to_mode (DImode, src, false);
5156 if (GET_CODE (tmp) == SCRATCH)
5157 tmp = gen_reg_rtx (DImode);
5160 src = rs6000_address_for_fpconvert (src);
5161 emit_insn (gen_lfiwax (tmp, src));
5165 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5166 emit_move_insn (stack, src);
5167 emit_insn (gen_lfiwax (tmp, stack));
5170 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5173 [(set_attr "length" "12")
5174 (set_attr "type" "fpload")])
5176 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5177 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5180 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5181 (clobber (match_scratch:DI 2 "=wi"))]
5182 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5189 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5190 if (GET_CODE (operands[2]) == SCRATCH)
5191 operands[2] = gen_reg_rtx (DImode);
5192 if (TARGET_VSX_SMALL_INTEGER)
5193 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5195 emit_insn (gen_lfiwax (operands[2], operands[1]));
5196 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5199 [(set_attr "length" "8")
5200 (set_attr "type" "fpload")])
5202 (define_insn "lfiwzx"
5203 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5204 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5206 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5211 xxextractuw %x0,%x1,4"
5212 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5214 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5215 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5216 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5217 (clobber (match_scratch:DI 2 "=wi"))]
5218 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5225 rtx dest = operands[0];
5226 rtx src = operands[1];
5229 if (!MEM_P (src) && TARGET_POWERPC64
5230 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5231 tmp = convert_to_mode (DImode, src, true);
5235 if (GET_CODE (tmp) == SCRATCH)
5236 tmp = gen_reg_rtx (DImode);
5239 src = rs6000_address_for_fpconvert (src);
5240 emit_insn (gen_lfiwzx (tmp, src));
5244 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5245 emit_move_insn (stack, src);
5246 emit_insn (gen_lfiwzx (tmp, stack));
5249 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5252 [(set_attr "length" "12")
5253 (set_attr "type" "fpload")])
5255 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5256 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5257 (unsigned_float:SFDF
5259 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5260 (clobber (match_scratch:DI 2 "=wi"))]
5261 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5268 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5269 if (GET_CODE (operands[2]) == SCRATCH)
5270 operands[2] = gen_reg_rtx (DImode);
5271 if (TARGET_VSX_SMALL_INTEGER)
5272 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5274 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5275 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5278 [(set_attr "length" "8")
5279 (set_attr "type" "fpload")])
5281 ; For each of these conversions, there is a define_expand, a define_insn
5282 ; with a '#' template, and a define_split (with C code). The idea is
5283 ; to allow constant folding with the template of the define_insn,
5284 ; then to have the insns split later (between sched1 and final).
5286 (define_expand "floatsidf2"
5287 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5288 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5291 (clobber (match_dup 4))
5292 (clobber (match_dup 5))
5293 (clobber (match_dup 6))])]
5295 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5298 if (TARGET_E500_DOUBLE)
5300 if (!REG_P (operands[1]))
5301 operands[1] = force_reg (SImode, operands[1]);
5302 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5305 else if (TARGET_LFIWAX && TARGET_FCFID)
5307 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5310 else if (TARGET_FCFID)
5312 rtx dreg = operands[1];
5314 dreg = force_reg (SImode, dreg);
5315 dreg = convert_to_mode (DImode, dreg, false);
5316 emit_insn (gen_floatdidf2 (operands[0], dreg));
5320 if (!REG_P (operands[1]))
5321 operands[1] = force_reg (SImode, operands[1]);
5322 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5323 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5324 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5325 operands[5] = gen_reg_rtx (DFmode);
5326 operands[6] = gen_reg_rtx (SImode);
5329 (define_insn_and_split "*floatsidf2_internal"
5330 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5331 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5332 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5333 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5334 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5335 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5336 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5337 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5343 rtx lowword, highword;
5344 gcc_assert (MEM_P (operands[4]));
5345 highword = adjust_address (operands[4], SImode, 0);
5346 lowword = adjust_address (operands[4], SImode, 4);
5347 if (! WORDS_BIG_ENDIAN)
5348 std::swap (lowword, highword);
5350 emit_insn (gen_xorsi3 (operands[6], operands[1],
5351 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5352 emit_move_insn (lowword, operands[6]);
5353 emit_move_insn (highword, operands[2]);
5354 emit_move_insn (operands[5], operands[4]);
5355 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5358 [(set_attr "length" "24")
5359 (set_attr "type" "fp")])
5361 ;; If we don't have a direct conversion to single precision, don't enable this
5362 ;; conversion for 32-bit without fast math, because we don't have the insn to
5363 ;; generate the fixup swizzle to avoid double rounding problems.
5364 (define_expand "floatunssisf2"
5365 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5366 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5367 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5370 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5371 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5372 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5377 if (!REG_P (operands[1]))
5378 operands[1] = force_reg (SImode, operands[1]);
5380 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5382 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5387 rtx dreg = operands[1];
5389 dreg = force_reg (SImode, dreg);
5390 dreg = convert_to_mode (DImode, dreg, true);
5391 emit_insn (gen_floatdisf2 (operands[0], dreg));
5396 (define_expand "floatunssidf2"
5397 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5398 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5401 (clobber (match_dup 4))
5402 (clobber (match_dup 5))])]
5404 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5407 if (TARGET_E500_DOUBLE)
5409 if (!REG_P (operands[1]))
5410 operands[1] = force_reg (SImode, operands[1]);
5411 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5414 else if (TARGET_LFIWZX && TARGET_FCFID)
5416 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5419 else if (TARGET_FCFID)
5421 rtx dreg = operands[1];
5423 dreg = force_reg (SImode, dreg);
5424 dreg = convert_to_mode (DImode, dreg, true);
5425 emit_insn (gen_floatdidf2 (operands[0], dreg));
5429 if (!REG_P (operands[1]))
5430 operands[1] = force_reg (SImode, operands[1]);
5431 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5432 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5433 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5434 operands[5] = gen_reg_rtx (DFmode);
5437 (define_insn_and_split "*floatunssidf2_internal"
5438 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5439 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5440 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5441 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5442 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5443 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5444 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5445 && !(TARGET_FCFID && TARGET_POWERPC64)"
5451 rtx lowword, highword;
5452 gcc_assert (MEM_P (operands[4]));
5453 highword = adjust_address (operands[4], SImode, 0);
5454 lowword = adjust_address (operands[4], SImode, 4);
5455 if (! WORDS_BIG_ENDIAN)
5456 std::swap (lowword, highword);
5458 emit_move_insn (lowword, operands[1]);
5459 emit_move_insn (highword, operands[2]);
5460 emit_move_insn (operands[5], operands[4]);
5461 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5464 [(set_attr "length" "20")
5465 (set_attr "type" "fp")])
5467 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5468 ;; vector registers. These insns favor doing the sign/zero extension in
5469 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5470 ;; extension and then a direct move.
5472 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5473 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5475 (match_operand:QHI 1 "input_operand")))
5476 (clobber (match_scratch:DI 2))
5477 (clobber (match_scratch:DI 3))
5478 (clobber (match_scratch:<QHI:MODE> 4))])]
5479 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5480 && TARGET_VSX_SMALL_INTEGER"
5482 if (MEM_P (operands[1]))
5483 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5486 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5487 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5489 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5490 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5491 (clobber (match_scratch:DI 3 "=X,r,X"))
5492 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5493 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5494 && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5496 "&& reload_completed"
5499 rtx result = operands[0];
5500 rtx input = operands[1];
5501 rtx di = operands[2];
5505 rtx tmp = operands[3];
5506 if (altivec_register_operand (input, <QHI:MODE>mode))
5507 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5508 else if (GET_CODE (tmp) == SCRATCH)
5509 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5512 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5513 emit_move_insn (di, tmp);
5518 rtx tmp = operands[4];
5519 emit_move_insn (tmp, input);
5520 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5523 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5527 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5528 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5529 (unsigned_float:FP_ISA3
5530 (match_operand:QHI 1 "input_operand" "")))
5531 (clobber (match_scratch:DI 2 ""))
5532 (clobber (match_scratch:DI 3 ""))])]
5533 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5534 && TARGET_VSX_SMALL_INTEGER"
5536 if (MEM_P (operands[1]))
5537 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5540 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5541 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5542 (unsigned_float:FP_ISA3
5543 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5544 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5545 (clobber (match_scratch:DI 3 "=X,r,X"))]
5546 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5547 && TARGET_VSX_SMALL_INTEGER"
5549 "&& reload_completed"
5552 rtx result = operands[0];
5553 rtx input = operands[1];
5554 rtx di = operands[2];
5556 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5557 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5560 rtx tmp = operands[3];
5561 if (GET_CODE (tmp) == SCRATCH)
5562 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5565 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5566 emit_move_insn (di, tmp);
5570 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5574 (define_expand "fix_trunc<mode>si2"
5575 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5576 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5577 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5580 if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
5582 rtx src = force_reg (<MODE>mode, operands[1]);
5585 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5588 rtx tmp = gen_reg_rtx (DImode);
5589 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5590 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5597 ; Like the convert to float patterns, this insn must be split before
5598 ; register allocation so that it can allocate the memory slot if it
5600 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5601 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5602 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5603 (clobber (match_scratch:DI 2 "=d"))]
5604 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5605 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5606 && TARGET_STFIWX && can_create_pseudo_p ()
5607 && !TARGET_VSX_SMALL_INTEGER"
5612 rtx dest = operands[0];
5613 rtx src = operands[1];
5614 rtx tmp = operands[2];
5616 if (GET_CODE (tmp) == SCRATCH)
5617 tmp = gen_reg_rtx (DImode);
5619 emit_insn (gen_fctiwz_<mode> (tmp, src));
5622 dest = rs6000_address_for_fpconvert (dest);
5623 emit_insn (gen_stfiwx (dest, tmp));
5626 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5628 dest = gen_lowpart (DImode, dest);
5629 emit_move_insn (dest, tmp);
5634 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5635 emit_insn (gen_stfiwx (stack, tmp));
5636 emit_move_insn (dest, stack);
5640 [(set_attr "length" "12")
5641 (set_attr "type" "fp")])
5643 (define_insn_and_split "fix_trunc<mode>si2_internal"
5644 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5645 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5646 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5647 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5648 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5649 && !TARGET_VSX_SMALL_INTEGER"
5656 gcc_assert (MEM_P (operands[3]));
5657 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5659 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5660 emit_move_insn (operands[3], operands[2]);
5661 emit_move_insn (operands[0], lowword);
5664 [(set_attr "length" "16")
5665 (set_attr "type" "fp")])
5667 (define_expand "fix_trunc<mode>di2"
5668 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5669 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5670 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5674 (define_insn "*fix_trunc<mode>di2_fctidz"
5675 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5676 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5677 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5682 [(set_attr "type" "fp")])
5684 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5685 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5686 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5687 (clobber (match_scratch:DI 2))])]
5688 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5689 && TARGET_VSX_SMALL_INTEGER"
5691 if (MEM_P (operands[0]))
5692 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5695 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5696 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5698 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5699 (clobber (match_scratch:DI 2 "=X,wi"))]
5700 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5701 && TARGET_VSX_SMALL_INTEGER"
5703 "&& reload_completed"
5706 rtx dest = operands[0];
5707 rtx src = operands[1];
5709 if (vsx_register_operand (dest, <QHI:MODE>mode))
5711 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5712 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5716 rtx tmp = operands[2];
5717 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5719 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5720 emit_move_insn (dest, tmp2);
5725 (define_expand "fixuns_trunc<mode>si2"
5726 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5727 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5729 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5733 if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
5735 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5740 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5741 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5742 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5743 (clobber (match_scratch:DI 2 "=d"))]
5744 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5745 && TARGET_STFIWX && can_create_pseudo_p ()
5746 && !TARGET_VSX_SMALL_INTEGER"
5751 rtx dest = operands[0];
5752 rtx src = operands[1];
5753 rtx tmp = operands[2];
5755 if (GET_CODE (tmp) == SCRATCH)
5756 tmp = gen_reg_rtx (DImode);
5758 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5761 dest = rs6000_address_for_fpconvert (dest);
5762 emit_insn (gen_stfiwx (dest, tmp));
5765 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5767 dest = gen_lowpart (DImode, dest);
5768 emit_move_insn (dest, tmp);
5773 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5774 emit_insn (gen_stfiwx (stack, tmp));
5775 emit_move_insn (dest, stack);
5779 [(set_attr "length" "12")
5780 (set_attr "type" "fp")])
5782 (define_insn "fixuns_trunc<mode>di2"
5783 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5784 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5785 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ"
5789 [(set_attr "type" "fp")])
5791 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5792 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5793 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5794 (clobber (match_scratch:DI 2))])]
5795 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5796 && TARGET_VSX_SMALL_INTEGER"
5798 if (MEM_P (operands[0]))
5799 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5802 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5803 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5805 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5806 (clobber (match_scratch:DI 2 "=X,wi"))]
5807 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5808 && TARGET_VSX_SMALL_INTEGER"
5810 "&& reload_completed"
5813 rtx dest = operands[0];
5814 rtx src = operands[1];
5816 if (vsx_register_operand (dest, <QHI:MODE>mode))
5818 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5819 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5823 rtx tmp = operands[2];
5824 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5826 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5827 emit_move_insn (dest, tmp2);
5832 ;; If -mvsx-small-integer, we can represent the FIX operation directly. On
5833 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5834 ;; to another location, since SImode is not allowed in vector registers.
5835 (define_insn "*fctiw<u>z_<mode>_smallint"
5836 [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5837 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5838 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5839 && TARGET_VSX_SMALL_INTEGER"
5842 xscvdp<su>xws %x0,%x1"
5843 [(set_attr "type" "fp")])
5845 ;; Combiner pattern to prevent moving the result of converting a floating point
5846 ;; value to 32-bit integer to GPR in order to save it.
5847 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5848 [(set (match_operand:SI 0 "memory_operand" "=Z")
5849 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5850 (clobber (match_scratch:SI 2 "=wa"))]
5851 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5852 && TARGET_VSX_SMALL_INTEGER"
5854 "&& reload_completed"
5856 (any_fix:SI (match_dup 1)))
5860 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5861 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5862 ;; because the first makes it clear that operand 0 is not live
5863 ;; before the instruction.
5864 (define_insn "fctiwz_<mode>"
5865 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5867 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5869 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5873 [(set_attr "type" "fp")])
5875 (define_insn "fctiwuz_<mode>"
5876 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5877 (unspec:DI [(unsigned_fix:SI
5878 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5880 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5884 [(set_attr "type" "fp")])
5886 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5887 ;; since the friz instruction does not truncate the value if the floating
5888 ;; point value is < LONG_MIN or > LONG_MAX.
5889 (define_insn "*friz"
5890 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5891 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5892 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5893 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5897 [(set_attr "type" "fp")])
5899 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5900 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5901 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5902 ;; extend it, store it back on the stack from the GPR, load it back into the
5903 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5904 ;; disable using store and load to sign/zero extend the value.
5905 (define_insn_and_split "*round32<mode>2_fprs"
5906 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5908 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5909 (clobber (match_scratch:DI 2 "=d"))
5910 (clobber (match_scratch:DI 3 "=d"))]
5911 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5912 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5913 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5918 rtx dest = operands[0];
5919 rtx src = operands[1];
5920 rtx tmp1 = operands[2];
5921 rtx tmp2 = operands[3];
5922 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5924 if (GET_CODE (tmp1) == SCRATCH)
5925 tmp1 = gen_reg_rtx (DImode);
5926 if (GET_CODE (tmp2) == SCRATCH)
5927 tmp2 = gen_reg_rtx (DImode);
5929 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5930 emit_insn (gen_stfiwx (stack, tmp1));
5931 emit_insn (gen_lfiwax (tmp2, stack));
5932 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5935 [(set_attr "type" "fpload")
5936 (set_attr "length" "16")])
5938 (define_insn_and_split "*roundu32<mode>2_fprs"
5939 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5940 (unsigned_float:SFDF
5941 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5942 (clobber (match_scratch:DI 2 "=d"))
5943 (clobber (match_scratch:DI 3 "=d"))]
5944 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5945 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5946 && can_create_pseudo_p ()"
5951 rtx dest = operands[0];
5952 rtx src = operands[1];
5953 rtx tmp1 = operands[2];
5954 rtx tmp2 = operands[3];
5955 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5957 if (GET_CODE (tmp1) == SCRATCH)
5958 tmp1 = gen_reg_rtx (DImode);
5959 if (GET_CODE (tmp2) == SCRATCH)
5960 tmp2 = gen_reg_rtx (DImode);
5962 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5963 emit_insn (gen_stfiwx (stack, tmp1));
5964 emit_insn (gen_lfiwzx (tmp2, stack));
5965 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5968 [(set_attr "type" "fpload")
5969 (set_attr "length" "16")])
5971 ;; No VSX equivalent to fctid
5972 (define_insn "lrint<mode>di2"
5973 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5974 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5976 "TARGET_<MODE>_FPR && TARGET_FPRND"
5978 [(set_attr "type" "fp")])
5980 (define_insn "btrunc<mode>2"
5981 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5982 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5984 "TARGET_<MODE>_FPR && TARGET_FPRND"
5988 [(set_attr "type" "fp")
5989 (set_attr "fp_type" "fp_addsub_<Fs>")])
5991 (define_insn "ceil<mode>2"
5992 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5993 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5995 "TARGET_<MODE>_FPR && TARGET_FPRND"
5999 [(set_attr "type" "fp")
6000 (set_attr "fp_type" "fp_addsub_<Fs>")])
6002 (define_insn "floor<mode>2"
6003 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6004 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6006 "TARGET_<MODE>_FPR && TARGET_FPRND"
6010 [(set_attr "type" "fp")
6011 (set_attr "fp_type" "fp_addsub_<Fs>")])
6013 ;; No VSX equivalent to frin
6014 (define_insn "round<mode>2"
6015 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6016 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6018 "TARGET_<MODE>_FPR && TARGET_FPRND"
6020 [(set_attr "type" "fp")
6021 (set_attr "fp_type" "fp_addsub_<Fs>")])
6023 (define_insn "*xsrdpi<mode>2"
6024 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6025 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6027 "TARGET_<MODE>_FPR && TARGET_VSX"
6029 [(set_attr "type" "fp")
6030 (set_attr "fp_type" "fp_addsub_<Fs>")])
6032 (define_expand "lround<mode>di2"
6034 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6036 (set (match_operand:DI 0 "gpc_reg_operand" "")
6037 (unspec:DI [(match_dup 2)]
6039 "TARGET_<MODE>_FPR && TARGET_VSX"
6041 operands[2] = gen_reg_rtx (<MODE>mode);
6044 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6045 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6046 ; is only generated for Power8 or later.
6047 (define_insn "stfiwx"
6048 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6049 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6055 [(set_attr "type" "fpstore")])
6057 ;; If we don't have a direct conversion to single precision, don't enable this
6058 ;; conversion for 32-bit without fast math, because we don't have the insn to
6059 ;; generate the fixup swizzle to avoid double rounding problems.
6060 (define_expand "floatsisf2"
6061 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6062 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6063 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6066 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6067 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6068 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
6073 if (!REG_P (operands[1]))
6074 operands[1] = force_reg (SImode, operands[1]);
6076 else if (TARGET_FCFIDS && TARGET_LFIWAX)
6078 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6081 else if (TARGET_FCFID && TARGET_LFIWAX)
6083 rtx dfreg = gen_reg_rtx (DFmode);
6084 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6085 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6090 rtx dreg = operands[1];
6092 dreg = force_reg (SImode, dreg);
6093 dreg = convert_to_mode (DImode, dreg, false);
6094 emit_insn (gen_floatdisf2 (operands[0], dreg));
6099 (define_expand "floatdidf2"
6100 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6101 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6102 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6105 (define_insn "*floatdidf2_fpr"
6106 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6107 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6108 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6112 [(set_attr "type" "fp")])
6114 ; Allow the combiner to merge source memory operands to the conversion so that
6115 ; the optimizer/register allocator doesn't try to load the value too early in a
6116 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6117 ; hit. We will split after reload to avoid the trip through the GPRs
6119 (define_insn_and_split "*floatdidf2_mem"
6120 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6121 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6122 (clobber (match_scratch:DI 2 "=d,wi"))]
6123 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6125 "&& reload_completed"
6126 [(set (match_dup 2) (match_dup 1))
6127 (set (match_dup 0) (float:DF (match_dup 2)))]
6129 [(set_attr "length" "8")
6130 (set_attr "type" "fpload")])
6132 (define_expand "floatunsdidf2"
6133 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6135 (match_operand:DI 1 "gpc_reg_operand" "")))]
6136 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6139 (define_insn "*floatunsdidf2_fcfidu"
6140 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6141 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6142 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6146 [(set_attr "type" "fp")
6147 (set_attr "length" "4")])
6149 (define_insn_and_split "*floatunsdidf2_mem"
6150 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6151 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6152 (clobber (match_scratch:DI 2 "=d,wi"))]
6153 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6155 "&& reload_completed"
6156 [(set (match_dup 2) (match_dup 1))
6157 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6159 [(set_attr "length" "8")
6160 (set_attr "type" "fpload")])
6162 (define_expand "floatdisf2"
6163 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6164 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6165 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6166 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6171 rtx val = operands[1];
6172 if (!flag_unsafe_math_optimizations)
6174 rtx label = gen_label_rtx ();
6175 val = gen_reg_rtx (DImode);
6176 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6179 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6184 (define_insn "floatdisf2_fcfids"
6185 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6186 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6187 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6188 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6192 [(set_attr "type" "fp")])
6194 (define_insn_and_split "*floatdisf2_mem"
6195 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6196 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6197 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6198 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6199 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6201 "&& reload_completed"
6205 emit_move_insn (operands[2], operands[1]);
6206 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6209 [(set_attr "length" "8")])
6211 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6212 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6213 ;; from double rounding.
6214 ;; Instead of creating a new cpu type for two FP operations, just use fp
6215 (define_insn_and_split "floatdisf2_internal1"
6216 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6217 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6218 (clobber (match_scratch:DF 2 "=d"))]
6219 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6222 "&& reload_completed"
6224 (float:DF (match_dup 1)))
6226 (float_truncate:SF (match_dup 2)))]
6228 [(set_attr "length" "8")
6229 (set_attr "type" "fp")])
6231 ;; Twiddles bits to avoid double rounding.
6232 ;; Bits that might be truncated when converting to DFmode are replaced
6233 ;; by a bit that won't be lost at that stage, but is below the SFmode
6234 ;; rounding position.
6235 (define_expand "floatdisf2_internal2"
6236 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6238 (clobber (reg:DI CA_REGNO))])
6239 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6241 (set (match_dup 3) (plus:DI (match_dup 3)
6243 (set (match_dup 0) (plus:DI (match_dup 0)
6245 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6247 (set (match_dup 0) (ior:DI (match_dup 0)
6249 (set (match_dup 0) (and:DI (match_dup 0)
6251 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6252 (label_ref (match_operand:DI 2 "" ""))
6254 (set (match_dup 0) (match_dup 1))]
6255 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6259 operands[3] = gen_reg_rtx (DImode);
6260 operands[4] = gen_reg_rtx (CCUNSmode);
6263 (define_expand "floatunsdisf2"
6264 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6265 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6266 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6267 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6270 (define_insn "floatunsdisf2_fcfidus"
6271 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6272 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6273 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6274 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6278 [(set_attr "type" "fp")])
6280 (define_insn_and_split "*floatunsdisf2_mem"
6281 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6282 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6283 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6284 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6285 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6287 "&& reload_completed"
6291 emit_move_insn (operands[2], operands[1]);
6292 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6295 [(set_attr "length" "8")
6296 (set_attr "type" "fpload")])
6298 ;; Define the TImode operations that can be done in a small number
6299 ;; of instructions. The & constraints are to prevent the register
6300 ;; allocator from allocating registers that overlap with the inputs
6301 ;; (for example, having an input in 7,8 and an output in 6,7). We
6302 ;; also allow for the output being the same as one of the inputs.
6304 (define_expand "addti3"
6305 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6306 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6307 (match_operand:TI 2 "reg_or_short_operand" "")))]
6310 rtx lo0 = gen_lowpart (DImode, operands[0]);
6311 rtx lo1 = gen_lowpart (DImode, operands[1]);
6312 rtx lo2 = gen_lowpart (DImode, operands[2]);
6313 rtx hi0 = gen_highpart (DImode, operands[0]);
6314 rtx hi1 = gen_highpart (DImode, operands[1]);
6315 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6317 if (!reg_or_short_operand (lo2, DImode))
6318 lo2 = force_reg (DImode, lo2);
6319 if (!adde_operand (hi2, DImode))
6320 hi2 = force_reg (DImode, hi2);
6322 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6323 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6327 (define_expand "subti3"
6328 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6329 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6330 (match_operand:TI 2 "gpc_reg_operand" "")))]
6333 rtx lo0 = gen_lowpart (DImode, operands[0]);
6334 rtx lo1 = gen_lowpart (DImode, operands[1]);
6335 rtx lo2 = gen_lowpart (DImode, operands[2]);
6336 rtx hi0 = gen_highpart (DImode, operands[0]);
6337 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6338 rtx hi2 = gen_highpart (DImode, operands[2]);
6340 if (!reg_or_short_operand (lo1, DImode))
6341 lo1 = force_reg (DImode, lo1);
6342 if (!adde_operand (hi1, DImode))
6343 hi1 = force_reg (DImode, hi1);
6345 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6346 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6350 ;; 128-bit logical operations expanders
6352 (define_expand "and<mode>3"
6353 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6354 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6355 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6359 (define_expand "ior<mode>3"
6360 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6361 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6362 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6366 (define_expand "xor<mode>3"
6367 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6368 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6369 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6373 (define_expand "one_cmpl<mode>2"
6374 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6375 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6379 (define_expand "nor<mode>3"
6380 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6382 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6383 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6387 (define_expand "andc<mode>3"
6388 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6390 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6391 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6395 ;; Power8 vector logical instructions.
6396 (define_expand "eqv<mode>3"
6397 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6399 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6400 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6401 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6404 ;; Rewrite nand into canonical form
6405 (define_expand "nand<mode>3"
6406 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6408 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6409 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6410 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6413 ;; The canonical form is to have the negated element first, so we need to
6414 ;; reverse arguments.
6415 (define_expand "orc<mode>3"
6416 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6418 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6419 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6420 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6423 ;; 128-bit logical operations insns and split operations
6424 (define_insn_and_split "*and<mode>3_internal"
6425 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6427 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6428 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6431 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6432 return "xxland %x0,%x1,%x2";
6434 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6435 return "vand %0,%1,%2";
6439 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6442 rs6000_split_logical (operands, AND, false, false, false);
6447 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6448 (const_string "veclogical")
6449 (const_string "integer")))
6450 (set (attr "length")
6452 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6455 (match_test "TARGET_POWERPC64")
6457 (const_string "16"))))])
6460 (define_insn_and_split "*bool<mode>3_internal"
6461 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6462 (match_operator:BOOL_128 3 "boolean_or_operator"
6463 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6464 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6467 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6468 return "xxl%q3 %x0,%x1,%x2";
6470 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6471 return "v%q3 %0,%1,%2";
6475 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6478 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6483 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6484 (const_string "veclogical")
6485 (const_string "integer")))
6486 (set (attr "length")
6488 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6491 (match_test "TARGET_POWERPC64")
6493 (const_string "16"))))])
6496 (define_insn_and_split "*boolc<mode>3_internal1"
6497 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6498 (match_operator:BOOL_128 3 "boolean_operator"
6500 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6501 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6502 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6504 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6505 return "xxl%q3 %x0,%x1,%x2";
6507 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6508 return "v%q3 %0,%1,%2";
6512 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6513 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6516 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6521 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6522 (const_string "veclogical")
6523 (const_string "integer")))
6524 (set (attr "length")
6526 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6529 (match_test "TARGET_POWERPC64")
6531 (const_string "16"))))])
6533 (define_insn_and_split "*boolc<mode>3_internal2"
6534 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6535 (match_operator:TI2 3 "boolean_operator"
6537 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6538 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6539 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6541 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6544 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6547 [(set_attr "type" "integer")
6548 (set (attr "length")
6550 (match_test "TARGET_POWERPC64")
6552 (const_string "16")))])
6555 (define_insn_and_split "*boolcc<mode>3_internal1"
6556 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6557 (match_operator:BOOL_128 3 "boolean_operator"
6559 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6561 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6562 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6564 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6565 return "xxl%q3 %x0,%x1,%x2";
6567 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6568 return "v%q3 %0,%1,%2";
6572 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6573 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6576 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6581 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6582 (const_string "veclogical")
6583 (const_string "integer")))
6584 (set (attr "length")
6586 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6589 (match_test "TARGET_POWERPC64")
6591 (const_string "16"))))])
6593 (define_insn_and_split "*boolcc<mode>3_internal2"
6594 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6595 (match_operator:TI2 3 "boolean_operator"
6597 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6599 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6600 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6602 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6605 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6608 [(set_attr "type" "integer")
6609 (set (attr "length")
6611 (match_test "TARGET_POWERPC64")
6613 (const_string "16")))])
6617 (define_insn_and_split "*eqv<mode>3_internal1"
6618 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6621 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6622 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6625 if (vsx_register_operand (operands[0], <MODE>mode))
6626 return "xxleqv %x0,%x1,%x2";
6630 "TARGET_P8_VECTOR && reload_completed
6631 && int_reg_operand (operands[0], <MODE>mode)"
6634 rs6000_split_logical (operands, XOR, true, false, false);
6639 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6640 (const_string "veclogical")
6641 (const_string "integer")))
6642 (set (attr "length")
6644 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6647 (match_test "TARGET_POWERPC64")
6649 (const_string "16"))))])
6651 (define_insn_and_split "*eqv<mode>3_internal2"
6652 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6655 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6656 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6659 "reload_completed && !TARGET_P8_VECTOR"
6662 rs6000_split_logical (operands, XOR, true, false, false);
6665 [(set_attr "type" "integer")
6666 (set (attr "length")
6668 (match_test "TARGET_POWERPC64")
6670 (const_string "16")))])
6672 ;; 128-bit one's complement
6673 (define_insn_and_split "*one_cmpl<mode>3_internal"
6674 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6676 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6679 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6680 return "xxlnor %x0,%x1,%x1";
6682 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6683 return "vnor %0,%1,%1";
6687 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6690 rs6000_split_logical (operands, NOT, false, false, false);
6695 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6696 (const_string "veclogical")
6697 (const_string "integer")))
6698 (set (attr "length")
6700 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6703 (match_test "TARGET_POWERPC64")
6705 (const_string "16"))))])
6708 ;; Now define ways of moving data around.
6710 ;; Set up a register with a value from the GOT table
6712 (define_expand "movsi_got"
6713 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6714 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6715 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6716 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6719 if (GET_CODE (operands[1]) == CONST)
6721 rtx offset = const0_rtx;
6722 HOST_WIDE_INT value;
6724 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6725 value = INTVAL (offset);
6728 rtx tmp = (!can_create_pseudo_p ()
6730 : gen_reg_rtx (Pmode));
6731 emit_insn (gen_movsi_got (tmp, operands[1]));
6732 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6737 operands[2] = rs6000_got_register (operands[1]);
6740 (define_insn "*movsi_got_internal"
6741 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6742 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6743 (match_operand:SI 2 "gpc_reg_operand" "b")]
6745 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6746 "lwz %0,%a1@got(%2)"
6747 [(set_attr "type" "load")])
6749 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6750 ;; didn't get allocated to a hard register.
6752 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6753 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6754 (match_operand:SI 2 "memory_operand" "")]
6756 "DEFAULT_ABI == ABI_V4
6758 && (reload_in_progress || reload_completed)"
6759 [(set (match_dup 0) (match_dup 2))
6760 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6764 ;; For SI, we special-case integers that can't be loaded in one insn. We
6765 ;; do the load 16-bits at a time. We could do this by loading from memory,
6766 ;; and this is even supposed to be faster, but it is simpler not to get
6767 ;; integers in the TOC.
6768 (define_insn "movsi_low"
6769 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6770 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6771 (match_operand 2 "" ""))))]
6772 "TARGET_MACHO && ! TARGET_64BIT"
6773 "lwz %0,lo16(%2)(%1)"
6774 [(set_attr "type" "load")
6775 (set_attr "length" "4")])
6777 ;; MR LA LWZ LFIWZX LXSIWZX
6778 ;; STW STFIWX STXSIWX LI LIS
6779 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6780 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6781 ;; MF%1 MT%0 MT%0 NOP
6782 (define_insn "*movsi_internal1"
6783 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6784 "=r, r, r, ?*wI, ?*wH,
6786 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6787 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6790 (match_operand:SI 1 "input_operand"
6797 "!TARGET_SINGLE_FPU &&
6798 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6825 "*, *, load, fpload, fpload,
6826 store, fpstore, fpstore, *, *,
6827 *, veclogical, vecsimple, vecsimple, vecsimple,
6828 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6838 (define_insn "*movsi_internal1_single"
6839 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6840 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6841 "TARGET_SINGLE_FPU &&
6842 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6857 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6858 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6860 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6861 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6863 ;; Because SF values are actually stored as DF values within the vector
6864 ;; registers, we need to convert the value to the vector SF format when
6865 ;; we need to use the bits in a union or similar cases. We only need
6866 ;; to do this transformation when the value is a vector register. Loads,
6867 ;; stores, and transfers within GPRs are assumed to be safe.
6869 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6870 ;; no alternatives, because the call is created as part of secondary_reload,
6871 ;; and operand #2's register class is used to allocate the temporary register.
6872 ;; This function is called before reload, and it creates the temporary as
6875 ;; MR LWZ LFIWZX LXSIWZX STW
6876 ;; STFS STXSSP STXSSPX VSX->GPR MTVSRWZ
6879 (define_insn_and_split "movsi_from_sf"
6880 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6881 "=r, r, ?*wI, ?*wH, m,
6885 (unspec:SI [(match_operand:SF 1 "input_operand"
6891 (clobber (match_scratch:V4SF 2
6896 "TARGET_NO_SF_SUBREG
6897 && (register_operand (operands[0], SImode)
6898 || register_operand (operands[1], SFmode))"
6911 "&& reload_completed
6912 && register_operand (operands[0], SImode)
6913 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6916 rtx op0 = operands[0];
6917 rtx op1 = operands[1];
6918 rtx op2 = operands[2];
6919 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6921 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6923 if (int_reg_operand (op0, SImode))
6925 emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6926 emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6930 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6931 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6932 emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6938 "*, load, fpload, fpload, store,
6939 fpstore, fpstore, fpstore, mftgpr, mffgpr,
6947 ;; movsi_from_sf with zero extension
6949 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6952 (define_insn_and_split "*movdi_from_sf_zero_ext"
6953 [(set (match_operand:DI 0 "gpc_reg_operand"
6954 "=r, r, ?*wI, ?*wH, r,
6958 (unspec:SI [(match_operand:SF 1 "input_operand"
6961 UNSPEC_SI_FROM_SF)))
6963 (clobber (match_scratch:V4SF 2
6967 "TARGET_DIRECT_MOVE_64BIT
6968 && (register_operand (operands[0], DImode)
6969 || register_operand (operands[1], SImode))"
6978 "&& reload_completed
6979 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6982 rtx op0 = operands[0];
6983 rtx op1 = operands[1];
6984 rtx op2 = operands[2];
6986 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6988 if (int_reg_operand (op0, DImode))
6990 emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6991 emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6995 rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6996 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6997 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6998 emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
7004 "*, load, fpload, fpload, mftgpr,
7005 mffgpr, veclogical")
7011 ;; Split a load of a large constant into the appropriate two-insn
7015 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7016 (match_operand:SI 1 "const_int_operand" ""))]
7017 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7018 && (INTVAL (operands[1]) & 0xffff) != 0"
7022 (ior:SI (match_dup 0)
7026 if (rs6000_emit_set_const (operands[0], operands[1]))
7032 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7034 [(set (match_operand:DI 0 "altivec_register_operand")
7035 (match_operand:DI 1 "xxspltib_constant_split"))]
7036 "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
7039 rtx op0 = operands[0];
7040 rtx op1 = operands[1];
7041 int r = REGNO (op0);
7042 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7044 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7045 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7049 (define_insn "*mov<mode>_internal2"
7050 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7051 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7053 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7059 [(set_attr "type" "cmp,logical,cmp")
7060 (set_attr "dot" "yes")
7061 (set_attr "length" "4,4,8")])
7064 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
7065 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
7067 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
7069 [(set (match_dup 0) (match_dup 1))
7071 (compare:CC (match_dup 0)
7075 (define_expand "mov<mode>"
7076 [(set (match_operand:INT 0 "general_operand" "")
7077 (match_operand:INT 1 "any_operand" ""))]
7079 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7081 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7082 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7083 ;; MTVSRWZ MF%1 MT%1 NOP
7084 (define_insn "*mov<mode>_internal"
7085 [(set (match_operand:QHI 0 "nonimmediate_operand"
7086 "=r, r, ?*wJwK, m, Z, r,
7087 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7088 ?*wJwK, r, *c*l, *h")
7090 (match_operand:QHI 1 "input_operand"
7091 "r, m, Z, r, wJwK, i,
7092 wJwK, O, wM, wB, wS, ?*wJwK,
7095 "gpc_reg_operand (operands[0], <MODE>mode)
7096 || gpc_reg_operand (operands[1], <MODE>mode)"
7115 "*, load, fpload, store, fpstore, *,
7116 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7117 mffgpr, mfjmpr, mtjmpr, *")
7125 ;; Here is how to move condition codes around. When we store CC data in
7126 ;; an integer register or memory, we store just the high-order 4 bits.
7127 ;; This lets us not shift in the most common case of CR0.
7128 (define_expand "movcc"
7129 [(set (match_operand:CC 0 "nonimmediate_operand" "")
7130 (match_operand:CC 1 "nonimmediate_operand" ""))]
7134 (define_insn "*movcc_internal1"
7135 [(set (match_operand:CC 0 "nonimmediate_operand"
7136 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7137 (match_operand:CC 1 "general_operand"
7138 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7139 "register_operand (operands[0], CCmode)
7140 || register_operand (operands[1], CCmode)"
7144 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7147 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7155 (cond [(eq_attr "alternative" "0,3")
7156 (const_string "cr_logical")
7157 (eq_attr "alternative" "1,2")
7158 (const_string "mtcr")
7159 (eq_attr "alternative" "6,7")
7160 (const_string "integer")
7161 (eq_attr "alternative" "8")
7162 (const_string "mfjmpr")
7163 (eq_attr "alternative" "9")
7164 (const_string "mtjmpr")
7165 (eq_attr "alternative" "10")
7166 (const_string "load")
7167 (eq_attr "alternative" "11")
7168 (const_string "store")
7169 (match_test "TARGET_MFCRF")
7170 (const_string "mfcrf")
7172 (const_string "mfcr")))
7173 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7175 ;; For floating-point, we normally deal with the floating-point registers
7176 ;; unless -msoft-float is used. The sole exception is that parameter passing
7177 ;; can produce floating-point values in fixed-point registers. Unless the
7178 ;; value is a simple constant or already in memory, we deal with this by
7179 ;; allocating memory and copying the value explicitly via that memory location.
7181 ;; Move 32-bit binary/decimal floating point
7182 (define_expand "mov<mode>"
7183 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7184 (match_operand:FMOVE32 1 "any_operand" ""))]
7186 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7189 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7190 (match_operand:FMOVE32 1 "const_double_operand" ""))]
7192 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7193 || (GET_CODE (operands[0]) == SUBREG
7194 && GET_CODE (SUBREG_REG (operands[0])) == REG
7195 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7196 [(set (match_dup 2) (match_dup 3))]
7201 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7203 if (! TARGET_POWERPC64)
7204 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7206 operands[2] = gen_lowpart (SImode, operands[0]);
7208 operands[3] = gen_int_mode (l, SImode);
7211 ;; Originally, we tried to keep movsf and movsd common, but the differences
7212 ;; addressing was making it rather difficult to hide with mode attributes. In
7213 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7214 ;; before the VSX stores meant that the register allocator would tend to do a
7215 ;; direct move to the GPR (which involves conversion from scalar to
7216 ;; vector/memory formats) to save values in the traditional Altivec registers,
7217 ;; while SDmode had problems on power6 if the GPR store was not first due to
7218 ;; the power6 not having an integer store operation.
7220 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7221 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7222 ;; MR MT<x> MF<x> NOP
7224 (define_insn "movsf_hardfloat"
7225 [(set (match_operand:SF 0 "nonimmediate_operand"
7226 "=!r, f, wb, wu, m, wY,
7227 Z, m, ww, !r, f, ww,
7229 (match_operand:SF 1 "input_operand"
7230 "m, m, wY, Z, f, wb,
7233 "(register_operand (operands[0], SFmode)
7234 || register_operand (operands[1], SFmode))
7235 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7236 && (TARGET_ALLOW_SF_SUBREG
7237 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7250 xscpsgndp %x0,%x1,%x1
7256 "load, fpload, fpload, fpload, fpstore, fpstore,
7257 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7258 *, mtjmpr, mfjmpr, *")])
7260 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7261 ;; FMR MR MT%0 MF%1 NOP
7262 (define_insn "movsd_hardfloat"
7263 [(set (match_operand:SD 0 "nonimmediate_operand"
7264 "=!r, wz, m, Z, ?wh, ?r,
7265 f, !r, *c*l, !r, *h")
7266 (match_operand:SD 1 "input_operand"
7267 "m, Z, r, wx, r, wh,
7269 "(register_operand (operands[0], SDmode)
7270 || register_operand (operands[1], SDmode))
7271 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
7285 "load, fpload, store, fpstore, mffgpr, mftgpr,
7286 fpsimple, *, mtjmpr, mfjmpr, *")])
7288 (define_insn "*mov<mode>_softfloat"
7289 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7290 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7291 "(gpc_reg_operand (operands[0], <MODE>mode)
7292 || gpc_reg_operand (operands[1], <MODE>mode))
7293 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7305 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7306 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7308 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7309 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7311 ;; Because SF values are actually stored as DF values within the vector
7312 ;; registers, we need to convert the value to the vector SF format when
7313 ;; we need to use the bits in a union or similar cases. We only need
7314 ;; to do this transformation when the value is a vector register. Loads,
7315 ;; stores, and transfers within GPRs are assumed to be safe.
7317 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7318 ;; no alternatives, because the call is created as part of secondary_reload,
7319 ;; and operand #2's register class is used to allocate the temporary register.
7320 ;; This function is called before reload, and it creates the temporary as
7323 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7324 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7325 (define_insn_and_split "movsf_from_si"
7326 [(set (match_operand:SF 0 "rs6000_nonimmediate_operand"
7327 "=!r, f, wb, wu, m, Z,
7330 (unspec:SF [(match_operand:SI 1 "input_operand"
7335 (clobber (match_scratch:DI 2
7339 "TARGET_NO_SF_SUBREG
7340 && (register_operand (operands[0], SFmode)
7341 || register_operand (operands[1], SImode))"
7354 "&& reload_completed
7355 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7356 && int_reg_operand_not_pseudo (operands[1], SImode)"
7359 rtx op0 = operands[0];
7360 rtx op1 = operands[1];
7361 rtx op2 = operands[2];
7362 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7364 /* Move SF value to upper 32-bits for xscvspdpn. */
7365 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7366 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7367 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7374 "load, fpload, fpload, fpload, store, fpstore,
7375 fpstore, vecfloat, mffgpr, *")])
7378 ;; Move 64-bit binary/decimal floating point
7379 (define_expand "mov<mode>"
7380 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7381 (match_operand:FMOVE64 1 "any_operand" ""))]
7383 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7386 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7387 (match_operand:FMOVE64 1 "const_int_operand" ""))]
7388 "! TARGET_POWERPC64 && reload_completed
7389 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7390 || (GET_CODE (operands[0]) == SUBREG
7391 && GET_CODE (SUBREG_REG (operands[0])) == REG
7392 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7393 [(set (match_dup 2) (match_dup 4))
7394 (set (match_dup 3) (match_dup 1))]
7397 int endian = (WORDS_BIG_ENDIAN == 0);
7398 HOST_WIDE_INT value = INTVAL (operands[1]);
7400 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7401 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7402 operands[4] = GEN_INT (value >> 32);
7403 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7407 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7408 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7409 "! TARGET_POWERPC64 && reload_completed
7410 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7411 || (GET_CODE (operands[0]) == SUBREG
7412 && GET_CODE (SUBREG_REG (operands[0])) == REG
7413 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7414 [(set (match_dup 2) (match_dup 4))
7415 (set (match_dup 3) (match_dup 5))]
7418 int endian = (WORDS_BIG_ENDIAN == 0);
7421 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7423 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7424 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7425 operands[4] = gen_int_mode (l[endian], SImode);
7426 operands[5] = gen_int_mode (l[1 - endian], SImode);
7430 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7431 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7432 "TARGET_POWERPC64 && reload_completed
7433 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7434 || (GET_CODE (operands[0]) == SUBREG
7435 && GET_CODE (SUBREG_REG (operands[0])) == REG
7436 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7437 [(set (match_dup 2) (match_dup 3))]
7440 int endian = (WORDS_BIG_ENDIAN == 0);
7444 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7446 operands[2] = gen_lowpart (DImode, operands[0]);
7447 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7448 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7449 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7451 operands[3] = gen_int_mode (val, DImode);
7454 ;; Don't have reload use general registers to load a constant. It is
7455 ;; less efficient than loading the constant into an FP register, since
7456 ;; it will probably be used there.
7458 ;; The move constraints are ordered to prefer floating point registers before
7459 ;; general purpose registers to avoid doing a store and a load to get the value
7460 ;; into a floating point register when it is needed for a floating point
7461 ;; operation. Prefer traditional floating point registers over VSX registers,
7462 ;; since the D-form version of the memory instructions does not need a GPR for
7463 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7466 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7467 ;; except for 0.0 which can be created on VSX with an xor instruction.
7469 (define_insn "*mov<mode>_hardfloat32"
7470 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7471 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7472 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7473 && (gpc_reg_operand (operands[0], <MODE>mode)
7474 || gpc_reg_operand (operands[1], <MODE>mode))"
7489 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7490 (set_attr "size" "64")
7491 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7493 (define_insn "*mov<mode>_softfloat32"
7494 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7495 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7497 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
7498 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7499 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7500 && (gpc_reg_operand (operands[0], <MODE>mode)
7501 || gpc_reg_operand (operands[1], <MODE>mode))"
7503 [(set_attr "type" "store,load,two,*,*,*")
7504 (set_attr "length" "8,8,8,8,12,16")])
7506 ; ld/std require word-aligned displacements -> 'Y' constraint.
7507 ; List Y->r and r->Y before r->r for reload.
7508 (define_insn "*mov<mode>_hardfloat64"
7509 [(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>")
7510 (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"))]
7511 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7512 && (gpc_reg_operand (operands[0], <MODE>mode)
7513 || gpc_reg_operand (operands[1], <MODE>mode))"
7535 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7536 (set_attr "size" "64")
7537 (set_attr "length" "4")])
7539 (define_insn "*mov<mode>_softfloat64"
7540 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7541 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7542 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7543 && (gpc_reg_operand (operands[0], <MODE>mode)
7544 || gpc_reg_operand (operands[1], <MODE>mode))"
7555 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7556 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7558 (define_expand "mov<mode>"
7559 [(set (match_operand:FMOVE128 0 "general_operand" "")
7560 (match_operand:FMOVE128 1 "any_operand" ""))]
7562 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7564 ;; It's important to list Y->r and r->Y before r->r because otherwise
7565 ;; reload, given m->r, will try to pick r->r and reload it, which
7566 ;; doesn't make progress.
7568 ;; We can't split little endian direct moves of TDmode, because the words are
7569 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7570 ;; problematical. Don't allow direct move for this case.
7572 (define_insn_and_split "*mov<mode>_64bit_dm"
7573 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7574 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7575 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7576 && FLOAT128_2REG_P (<MODE>mode)
7577 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7578 && (gpc_reg_operand (operands[0], <MODE>mode)
7579 || gpc_reg_operand (operands[1], <MODE>mode))"
7581 "&& reload_completed"
7583 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7584 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7586 (define_insn_and_split "*movtd_64bit_nodm"
7587 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7588 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7589 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7590 && (gpc_reg_operand (operands[0], TDmode)
7591 || gpc_reg_operand (operands[1], TDmode))"
7593 "&& reload_completed"
7595 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7596 [(set_attr "length" "8,8,8,12,12,8")])
7598 (define_insn_and_split "*mov<mode>_32bit"
7599 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7600 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7601 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7602 && (FLOAT128_2REG_P (<MODE>mode)
7603 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7604 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7605 && (gpc_reg_operand (operands[0], <MODE>mode)
7606 || gpc_reg_operand (operands[1], <MODE>mode))"
7608 "&& reload_completed"
7610 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7611 [(set_attr "length" "8,8,8,8,20,20,16")])
7613 (define_insn_and_split "*mov<mode>_softfloat"
7614 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7615 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7616 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7617 && (gpc_reg_operand (operands[0], <MODE>mode)
7618 || gpc_reg_operand (operands[1], <MODE>mode))"
7620 "&& reload_completed"
7622 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7623 [(set_attr "length" "20,20,16")])
7625 (define_expand "extenddf<mode>2"
7626 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7627 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7628 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7629 && TARGET_LONG_DOUBLE_128"
7631 if (FLOAT128_IEEE_P (<MODE>mode))
7632 rs6000_expand_float128_convert (operands[0], operands[1], false);
7633 else if (TARGET_E500_DOUBLE)
7635 gcc_assert (<MODE>mode == TFmode);
7636 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7638 else if (TARGET_VSX)
7640 if (<MODE>mode == TFmode)
7641 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7642 else if (<MODE>mode == IFmode)
7643 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7649 rtx zero = gen_reg_rtx (DFmode);
7650 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7652 if (<MODE>mode == TFmode)
7653 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7654 else if (<MODE>mode == IFmode)
7655 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7662 ;; Allow memory operands for the source to be created by the combiner.
7663 (define_insn_and_split "extenddf<mode>2_fprs"
7664 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7665 (float_extend:IBM128
7666 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7667 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7668 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7669 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7671 "&& reload_completed"
7672 [(set (match_dup 3) (match_dup 1))
7673 (set (match_dup 4) (match_dup 2))]
7675 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7676 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7678 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7679 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7682 (define_insn_and_split "extenddf<mode>2_vsx"
7683 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7684 (float_extend:IBM128
7685 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7686 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7688 "&& reload_completed"
7689 [(set (match_dup 2) (match_dup 1))
7690 (set (match_dup 3) (match_dup 4))]
7692 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7693 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7695 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7696 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7697 operands[4] = CONST0_RTX (DFmode);
7700 (define_expand "extendsf<mode>2"
7701 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7702 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7704 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7705 && TARGET_LONG_DOUBLE_128"
7707 if (FLOAT128_IEEE_P (<MODE>mode))
7708 rs6000_expand_float128_convert (operands[0], operands[1], false);
7711 rtx tmp = gen_reg_rtx (DFmode);
7712 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7713 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7718 (define_expand "trunc<mode>df2"
7719 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7720 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7722 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7723 && TARGET_LONG_DOUBLE_128"
7725 if (FLOAT128_IEEE_P (<MODE>mode))
7727 rs6000_expand_float128_convert (operands[0], operands[1], false);
7732 (define_insn_and_split "trunc<mode>df2_internal1"
7733 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7735 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7736 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7737 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7741 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7744 emit_note (NOTE_INSN_DELETED);
7747 [(set_attr "type" "fpsimple")])
7749 (define_insn "trunc<mode>df2_internal2"
7750 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7751 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7752 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7753 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7755 [(set_attr "type" "fp")
7756 (set_attr "fp_type" "fp_addsub_d")])
7758 (define_expand "trunc<mode>sf2"
7759 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7760 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7762 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7763 && TARGET_LONG_DOUBLE_128"
7765 if (FLOAT128_IEEE_P (<MODE>mode))
7766 rs6000_expand_float128_convert (operands[0], operands[1], false);
7767 else if (TARGET_E500_DOUBLE)
7769 gcc_assert (<MODE>mode == TFmode);
7770 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7772 else if (<MODE>mode == TFmode)
7773 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7774 else if (<MODE>mode == IFmode)
7775 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7781 (define_insn_and_split "trunc<mode>sf2_fprs"
7782 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7783 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7784 (clobber (match_scratch:DF 2 "=d"))]
7785 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7786 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7788 "&& reload_completed"
7790 (float_truncate:DF (match_dup 1)))
7792 (float_truncate:SF (match_dup 2)))]
7795 (define_expand "floatsi<mode>2"
7796 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7797 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7798 (clobber (match_scratch:DI 2))])]
7800 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7801 && TARGET_LONG_DOUBLE_128"
7803 rtx op0 = operands[0];
7804 rtx op1 = operands[1];
7806 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7808 else if (FLOAT128_IEEE_P (<MODE>mode))
7810 rs6000_expand_float128_convert (op0, op1, false);
7815 rtx tmp = gen_reg_rtx (DFmode);
7816 expand_float (tmp, op1, false);
7817 if (<MODE>mode == TFmode)
7818 emit_insn (gen_extenddftf2 (op0, tmp));
7819 else if (<MODE>mode == IFmode)
7820 emit_insn (gen_extenddfif2 (op0, tmp));
7827 ; fadd, but rounding towards zero.
7828 ; This is probably not the optimal code sequence.
7829 (define_insn "fix_trunc_helper<mode>"
7830 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7831 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7832 UNSPEC_FIX_TRUNC_TF))
7833 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7834 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7835 && FLOAT128_IBM_P (<MODE>mode)"
7836 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7837 [(set_attr "type" "fp")
7838 (set_attr "length" "20")])
7840 (define_expand "fix_trunc<mode>si2"
7841 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7842 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7844 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7846 rtx op0 = operands[0];
7847 rtx op1 = operands[1];
7849 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7853 if (FLOAT128_IEEE_P (<MODE>mode))
7854 rs6000_expand_float128_convert (op0, op1, false);
7855 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7856 emit_insn (gen_spe_fix_trunctfsi2 (op0, op1));
7857 else if (<MODE>mode == TFmode)
7858 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7859 else if (<MODE>mode == IFmode)
7860 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7867 (define_expand "fix_trunc<mode>si2_fprs"
7868 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7869 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7870 (clobber (match_dup 2))
7871 (clobber (match_dup 3))
7872 (clobber (match_dup 4))
7873 (clobber (match_dup 5))])]
7874 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7876 operands[2] = gen_reg_rtx (DFmode);
7877 operands[3] = gen_reg_rtx (DFmode);
7878 operands[4] = gen_reg_rtx (DImode);
7879 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7882 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7883 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7884 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7885 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7886 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7887 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7888 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7889 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7895 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7898 gcc_assert (MEM_P (operands[5]));
7899 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7901 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7902 emit_move_insn (operands[5], operands[4]);
7903 emit_move_insn (operands[0], lowword);
7907 (define_expand "fix_trunc<mode>di2"
7908 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7909 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7910 "TARGET_FLOAT128_TYPE"
7912 if (!TARGET_FLOAT128_HW)
7914 rs6000_expand_float128_convert (operands[0], operands[1], false);
7919 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7920 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7921 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7922 "TARGET_FLOAT128_TYPE"
7924 rs6000_expand_float128_convert (operands[0], operands[1], true);
7928 (define_expand "floatdi<mode>2"
7929 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7930 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7931 "TARGET_FLOAT128_TYPE"
7933 if (!TARGET_FLOAT128_HW)
7935 rs6000_expand_float128_convert (operands[0], operands[1], false);
7940 (define_expand "floatunsdi<IEEE128:mode>2"
7941 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7942 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7943 "TARGET_FLOAT128_TYPE"
7945 if (!TARGET_FLOAT128_HW)
7947 rs6000_expand_float128_convert (operands[0], operands[1], true);
7952 (define_expand "floatuns<IEEE128:mode>2"
7953 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7954 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7955 "TARGET_FLOAT128_TYPE"
7957 rtx op0 = operands[0];
7958 rtx op1 = operands[1];
7960 if (TARGET_FLOAT128_HW)
7961 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7963 rs6000_expand_float128_convert (op0, op1, true);
7967 (define_expand "neg<mode>2"
7968 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7969 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7970 "FLOAT128_IEEE_P (<MODE>mode)
7971 || (FLOAT128_IBM_P (<MODE>mode)
7972 && TARGET_HARD_FLOAT
7973 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7976 if (FLOAT128_IEEE_P (<MODE>mode))
7978 if (TARGET_FLOAT128_HW)
7980 if (<MODE>mode == TFmode)
7981 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7982 else if (<MODE>mode == KFmode)
7983 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7987 else if (TARGET_FLOAT128_TYPE)
7989 if (<MODE>mode == TFmode)
7990 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7991 else if (<MODE>mode == KFmode)
7992 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7998 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7999 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8001 operands[1], <MODE>mode);
8003 if (target && !rtx_equal_p (target, operands[0]))
8004 emit_move_insn (operands[0], target);
8010 (define_insn "neg<mode>2_internal"
8011 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8012 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8013 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
8016 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8017 return \"fneg %L0,%L1\;fneg %0,%1\";
8019 return \"fneg %0,%1\;fneg %L0,%L1\";
8021 [(set_attr "type" "fpsimple")
8022 (set_attr "length" "8")])
8024 (define_expand "abs<mode>2"
8025 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
8026 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
8027 "FLOAT128_IEEE_P (<MODE>mode)
8028 || (FLOAT128_IBM_P (<MODE>mode)
8029 && TARGET_HARD_FLOAT
8030 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
8035 if (FLOAT128_IEEE_P (<MODE>mode))
8037 if (TARGET_FLOAT128_HW)
8039 if (<MODE>mode == TFmode)
8040 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8041 else if (<MODE>mode == KFmode)
8042 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8047 else if (TARGET_FLOAT128_TYPE)
8049 if (<MODE>mode == TFmode)
8050 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8051 else if (<MODE>mode == KFmode)
8052 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8061 label = gen_label_rtx ();
8062 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
8064 if (flag_finite_math_only && !flag_trapping_math)
8065 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
8067 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
8069 else if (<MODE>mode == TFmode)
8070 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8071 else if (<MODE>mode == TFmode)
8072 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8079 (define_expand "abs<mode>2_internal"
8080 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
8081 (match_operand:IBM128 1 "gpc_reg_operand" ""))
8082 (set (match_dup 3) (match_dup 5))
8083 (set (match_dup 5) (abs:DF (match_dup 5)))
8084 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8085 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8086 (label_ref (match_operand 2 "" ""))
8088 (set (match_dup 6) (neg:DF (match_dup 6)))]
8089 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8090 && TARGET_LONG_DOUBLE_128"
8093 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8094 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8095 operands[3] = gen_reg_rtx (DFmode);
8096 operands[4] = gen_reg_rtx (CCFPmode);
8097 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8098 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8102 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8105 (define_expand "ieee_128bit_negative_zero"
8106 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8107 "TARGET_FLOAT128_TYPE"
8109 rtvec v = rtvec_alloc (16);
8112 for (i = 0; i < 16; i++)
8113 RTVEC_ELT (v, i) = const0_rtx;
8115 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8116 RTVEC_ELT (v, high) = GEN_INT (0x80);
8118 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8122 ;; IEEE 128-bit negate
8124 ;; We have 2 insns here for negate and absolute value. The first uses
8125 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8126 ;; insns, and second insn after the first split pass loads up the bit to
8127 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8128 ;; neg/abs to create the constant just once.
8130 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8131 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8132 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8133 (clobber (match_scratch:V16QI 2 "=v"))]
8134 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8137 [(parallel [(set (match_dup 0)
8138 (neg:IEEE128 (match_dup 1)))
8139 (use (match_dup 2))])]
8141 if (GET_CODE (operands[2]) == SCRATCH)
8142 operands[2] = gen_reg_rtx (V16QImode);
8144 operands[3] = gen_reg_rtx (V16QImode);
8145 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8147 [(set_attr "length" "8")
8148 (set_attr "type" "vecsimple")])
8150 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8151 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8152 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8153 (use (match_operand:V16QI 2 "register_operand" "v"))]
8154 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8155 "xxlxor %x0,%x1,%x2"
8156 [(set_attr "type" "veclogical")])
8158 ;; IEEE 128-bit absolute value
8159 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8160 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8161 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8162 (clobber (match_scratch:V16QI 2 "=v"))]
8163 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8166 [(parallel [(set (match_dup 0)
8167 (abs:IEEE128 (match_dup 1)))
8168 (use (match_dup 2))])]
8170 if (GET_CODE (operands[2]) == SCRATCH)
8171 operands[2] = gen_reg_rtx (V16QImode);
8173 operands[3] = gen_reg_rtx (V16QImode);
8174 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8176 [(set_attr "length" "8")
8177 (set_attr "type" "vecsimple")])
8179 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8180 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8181 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8182 (use (match_operand:V16QI 2 "register_operand" "v"))]
8183 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8184 "xxlandc %x0,%x1,%x2"
8185 [(set_attr "type" "veclogical")])
8187 ;; IEEE 128-bit negative absolute value
8188 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8189 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8192 (match_operand:IEEE128 1 "register_operand" "wa"))))
8193 (clobber (match_scratch:V16QI 2 "=v"))]
8194 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8195 && FLOAT128_IEEE_P (<MODE>mode)"
8198 [(parallel [(set (match_dup 0)
8199 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8200 (use (match_dup 2))])]
8202 if (GET_CODE (operands[2]) == SCRATCH)
8203 operands[2] = gen_reg_rtx (V16QImode);
8205 operands[3] = gen_reg_rtx (V16QImode);
8206 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8208 [(set_attr "length" "8")
8209 (set_attr "type" "vecsimple")])
8211 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8212 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8215 (match_operand:IEEE128 1 "register_operand" "wa"))))
8216 (use (match_operand:V16QI 2 "register_operand" "v"))]
8217 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8219 [(set_attr "type" "veclogical")])
8221 ;; Float128 conversion functions. These expand to library function calls.
8222 ;; We use expand to convert from IBM double double to IEEE 128-bit
8223 ;; and trunc for the opposite.
8224 (define_expand "extendiftf2"
8225 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8226 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8227 "TARGET_FLOAT128_TYPE"
8229 rs6000_expand_float128_convert (operands[0], operands[1], false);
8233 (define_expand "extendifkf2"
8234 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8235 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8236 "TARGET_FLOAT128_TYPE"
8238 rs6000_expand_float128_convert (operands[0], operands[1], false);
8242 (define_expand "extendtfkf2"
8243 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8244 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8245 "TARGET_FLOAT128_TYPE"
8247 rs6000_expand_float128_convert (operands[0], operands[1], false);
8251 (define_expand "trunciftf2"
8252 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8253 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8254 "TARGET_FLOAT128_TYPE"
8256 rs6000_expand_float128_convert (operands[0], operands[1], false);
8260 (define_expand "truncifkf2"
8261 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8262 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8263 "TARGET_FLOAT128_TYPE"
8265 rs6000_expand_float128_convert (operands[0], operands[1], false);
8269 (define_expand "trunckftf2"
8270 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8271 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8272 "TARGET_FLOAT128_TYPE"
8274 rs6000_expand_float128_convert (operands[0], operands[1], false);
8278 (define_expand "trunctfif2"
8279 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8280 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8281 "TARGET_FLOAT128_TYPE"
8283 rs6000_expand_float128_convert (operands[0], operands[1], false);
8288 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8289 ;; must have 3 arguments, and scratch register constraint must be a single
8292 ;; Reload patterns to support gpr load/store with misaligned mem.
8293 ;; and multiple gpr load/store at offset >= 0xfffc
8294 (define_expand "reload_<mode>_store"
8295 [(parallel [(match_operand 0 "memory_operand" "=m")
8296 (match_operand 1 "gpc_reg_operand" "r")
8297 (match_operand:GPR 2 "register_operand" "=&b")])]
8300 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8304 (define_expand "reload_<mode>_load"
8305 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8306 (match_operand 1 "memory_operand" "m")
8307 (match_operand:GPR 2 "register_operand" "=b")])]
8310 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8315 ;; Reload patterns for various types using the vector registers. We may need
8316 ;; an additional base register to convert the reg+offset addressing to reg+reg
8317 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8318 ;; index register for gpr registers.
8319 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8320 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8321 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8322 (match_operand:P 2 "register_operand" "=b")])]
8325 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8329 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8330 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8331 (match_operand:RELOAD 1 "memory_operand" "m")
8332 (match_operand:P 2 "register_operand" "=b")])]
8335 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8340 ;; Reload sometimes tries to move the address to a GPR, and can generate
8341 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8342 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8344 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8345 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8346 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8347 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8349 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
8351 "&& reload_completed"
8353 (plus:P (match_dup 1)
8356 (and:P (match_dup 0)
8359 ;; Power8 merge instructions to allow direct move to/from floating point
8360 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8361 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8362 ;; value, since it is allocated in reload and not all of the flow information
8363 ;; is setup for it. We have two patterns to do the two moves between gprs and
8364 ;; fprs. There isn't a dependancy between the two, but we could potentially
8365 ;; schedule other instructions between the two instructions.
8367 (define_insn "p8_fmrgow_<mode>"
8368 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8370 (match_operand:DF 1 "register_operand" "d")
8371 (match_operand:DF 2 "register_operand" "d")]
8372 UNSPEC_P8V_FMRGOW))]
8373 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8375 [(set_attr "type" "fpsimple")])
8377 (define_insn "p8_mtvsrwz"
8378 [(set (match_operand:DF 0 "register_operand" "=d")
8379 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8380 UNSPEC_P8V_MTVSRWZ))]
8381 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8383 [(set_attr "type" "mftgpr")])
8385 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8386 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8387 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8388 UNSPEC_P8V_RELOAD_FROM_GPR))
8389 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8390 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8392 "&& reload_completed"
8395 rtx dest = operands[0];
8396 rtx src = operands[1];
8397 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8398 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8399 rtx gpr_hi_reg = gen_highpart (SImode, src);
8400 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8402 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8403 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8404 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8407 [(set_attr "length" "12")
8408 (set_attr "type" "three")])
8410 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8411 (define_insn "p8_mtvsrd_df"
8412 [(set (match_operand:DF 0 "register_operand" "=wa")
8413 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8414 UNSPEC_P8V_MTVSRD))]
8415 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8417 [(set_attr "type" "mftgpr")])
8419 (define_insn "p8_xxpermdi_<mode>"
8420 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8421 (unspec:FMOVE128_GPR [
8422 (match_operand:DF 1 "register_operand" "wa")
8423 (match_operand:DF 2 "register_operand" "wa")]
8424 UNSPEC_P8V_XXPERMDI))]
8425 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8426 "xxpermdi %x0,%x1,%x2,0"
8427 [(set_attr "type" "vecperm")])
8429 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8430 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8431 (unspec:FMOVE128_GPR
8432 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8433 UNSPEC_P8V_RELOAD_FROM_GPR))
8434 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8435 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8437 "&& reload_completed"
8440 rtx dest = operands[0];
8441 rtx src = operands[1];
8442 /* You might think that we could use op0 as one temp and a DF clobber
8443 as op2, but you'd be wrong. Secondary reload move patterns don't
8444 check for overlap of the clobber and the destination. */
8445 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8446 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8447 rtx gpr_hi_reg = gen_highpart (DImode, src);
8448 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8450 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8451 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8452 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8455 [(set_attr "length" "12")
8456 (set_attr "type" "three")])
8459 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8460 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8462 && (int_reg_operand (operands[0], <MODE>mode)
8463 || int_reg_operand (operands[1], <MODE>mode))
8464 && (!TARGET_DIRECT_MOVE_128
8465 || (!vsx_register_operand (operands[0], <MODE>mode)
8466 && !vsx_register_operand (operands[1], <MODE>mode)))"
8468 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8470 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8471 ;; type is stored internally as double precision in the VSX registers, we have
8472 ;; to convert it from the vector format.
8473 (define_insn "p8_mtvsrd_sf"
8474 [(set (match_operand:SF 0 "register_operand" "=wa")
8475 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8476 UNSPEC_P8V_MTVSRD))]
8477 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8479 [(set_attr "type" "mftgpr")])
8481 (define_insn_and_split "reload_vsx_from_gprsf"
8482 [(set (match_operand:SF 0 "register_operand" "=wa")
8483 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8484 UNSPEC_P8V_RELOAD_FROM_GPR))
8485 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8486 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8488 "&& reload_completed"
8491 rtx op0 = operands[0];
8492 rtx op1 = operands[1];
8493 rtx op2 = operands[2];
8494 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8496 /* Move SF value to upper 32-bits for xscvspdpn. */
8497 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8498 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8499 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8502 [(set_attr "length" "8")
8503 (set_attr "type" "two")])
8505 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8506 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8507 ;; and then doing a move of that.
8508 (define_insn "p8_mfvsrd_3_<mode>"
8509 [(set (match_operand:DF 0 "register_operand" "=r")
8510 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8511 UNSPEC_P8V_RELOAD_FROM_VSX))]
8512 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8514 [(set_attr "type" "mftgpr")])
8516 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8517 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8518 (unspec:FMOVE128_GPR
8519 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8520 UNSPEC_P8V_RELOAD_FROM_VSX))
8521 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8522 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8524 "&& reload_completed"
8527 rtx dest = operands[0];
8528 rtx src = operands[1];
8529 rtx tmp = operands[2];
8530 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8531 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8533 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8534 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8535 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8538 [(set_attr "length" "12")
8539 (set_attr "type" "three")])
8541 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8542 ;; type is stored internally as double precision, we have to convert it to the
8545 (define_insn_and_split "reload_gpr_from_vsxsf"
8546 [(set (match_operand:SF 0 "register_operand" "=r")
8547 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8548 UNSPEC_P8V_RELOAD_FROM_VSX))
8549 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8550 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8552 "&& reload_completed"
8555 rtx op0 = operands[0];
8556 rtx op1 = operands[1];
8557 rtx op2 = operands[2];
8558 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8560 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8561 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8562 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8565 [(set_attr "length" "12")
8566 (set_attr "type" "three")])
8568 (define_insn "p8_mfvsrd_4_disf"
8569 [(set (match_operand:DI 0 "register_operand" "=r")
8570 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8571 UNSPEC_P8V_RELOAD_FROM_VSX))]
8572 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8574 [(set_attr "type" "mftgpr")])
8577 ;; Next come the multi-word integer load and store and the load and store
8580 ;; List r->r after r->Y, otherwise reload will try to reload a
8581 ;; non-offsettable address by using r->r which won't make progress.
8582 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8583 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8585 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8586 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8587 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8590 (define_insn "*movdi_internal32"
8591 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8592 "=Y, r, r, ^m, ^d, ^d,
8593 r, ^wY, $Z, ^wb, $wv, ^wi,
8594 *wo, *wo, *wv, *wi, *wi, *wv,
8597 (match_operand:DI 1 "input_operand"
8599 IJKnGHF, wb, wv, wY, Z, wi,
8600 Oj, wM, OjwM, Oj, wM, wS,
8604 && (gpc_reg_operand (operands[0], DImode)
8605 || gpc_reg_operand (operands[1], DImode))"
8627 "store, load, *, fpstore, fpload, fpsimple,
8628 *, fpstore, fpstore, fpload, fpload, veclogical,
8629 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8631 (set_attr "size" "64")])
8634 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8635 (match_operand:DI 1 "const_int_operand" ""))]
8636 "! TARGET_POWERPC64 && reload_completed
8637 && gpr_or_gpr_p (operands[0], operands[1])
8638 && !direct_move_p (operands[0], operands[1])"
8639 [(set (match_dup 2) (match_dup 4))
8640 (set (match_dup 3) (match_dup 1))]
8643 HOST_WIDE_INT value = INTVAL (operands[1]);
8644 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8646 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8648 operands[4] = GEN_INT (value >> 32);
8649 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8653 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8654 (match_operand:DIFD 1 "input_operand" ""))]
8655 "reload_completed && !TARGET_POWERPC64
8656 && gpr_or_gpr_p (operands[0], operands[1])
8657 && !direct_move_p (operands[0], operands[1])"
8659 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8661 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8662 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8663 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8664 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8665 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8666 (define_insn "*movdi_internal64"
8667 [(set (match_operand:DI 0 "nonimmediate_operand"
8669 ^m, ^d, ^d, ^wY, $Z, $wb,
8670 $wv, ^wi, *wo, *wo, *wv, *wi,
8671 *wi, *wv, *wv, r, *h, *h,
8672 ?*r, ?*wg, ?*r, ?*wj")
8674 (match_operand:DI 1 "input_operand"
8676 d, m, d, wb, wv, wY,
8677 Z, wi, Oj, wM, OjwM, Oj,
8678 wM, wS, wB, *h, r, 0,
8682 && (gpc_reg_operand (operands[0], DImode)
8683 || gpc_reg_operand (operands[1], DImode))"
8714 "store, load, *, *, *, *,
8715 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8716 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8717 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8718 mftgpr, mffgpr, mftgpr, mffgpr")
8720 (set_attr "size" "64")
8728 ; Some DImode loads are best done as a load of -1 followed by a mask
8731 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8732 (match_operand:DI 1 "const_int_operand"))]
8734 && num_insns_constant (operands[1], DImode) > 1
8735 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8736 && rs6000_is_valid_and_mask (operands[1], DImode)"
8740 (and:DI (match_dup 0)
8744 ;; Split a load of a large constant into the appropriate five-instruction
8745 ;; sequence. Handle anything in a constant number of insns.
8746 ;; When non-easy constants can go in the TOC, this should use
8747 ;; easy_fp_constant predicate.
8749 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8750 (match_operand:DI 1 "const_int_operand" ""))]
8751 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8752 [(set (match_dup 0) (match_dup 2))
8753 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8756 if (rs6000_emit_set_const (operands[0], operands[1]))
8763 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8764 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8765 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8766 [(set (match_dup 0) (match_dup 2))
8767 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8770 if (rs6000_emit_set_const (operands[0], operands[1]))
8777 [(set (match_operand:DI 0 "altivec_register_operand" "")
8778 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8779 "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8782 rtx op0 = operands[0];
8783 rtx op1 = operands[1];
8784 int r = REGNO (op0);
8785 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8787 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8788 if (op1 != const0_rtx && op1 != constm1_rtx)
8790 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8791 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8796 ;; Split integer constants that can be loaded with XXSPLTIB and a
8797 ;; sign extend operation.
8799 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8800 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8801 "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8804 rtx op0 = operands[0];
8805 rtx op1 = operands[1];
8806 int r = REGNO (op0);
8807 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8809 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8810 if (<MODE>mode == DImode)
8811 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8812 else if (<MODE>mode == SImode)
8813 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8814 else if (<MODE>mode == HImode)
8816 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8817 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8823 ;; TImode/PTImode is similar, except that we usually want to compute the
8824 ;; address into a register and use lsi/stsi (the exception is during reload).
8826 (define_insn "*mov<mode>_string"
8827 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8828 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8830 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8831 && (gpc_reg_operand (operands[0], <MODE>mode)
8832 || gpc_reg_operand (operands[1], <MODE>mode))"
8835 switch (which_alternative)
8841 return \"stswi %1,%P0,16\";
8846 /* If the address is not used in the output, we can use lsi. Otherwise,
8847 fall through to generating four loads. */
8849 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8850 return \"lswi %0,%P1,16\";
8858 [(set_attr "type" "store,store,load,load,*,*")
8859 (set_attr "update" "yes")
8860 (set_attr "indexed" "yes")
8861 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8862 (const_string "always")
8863 (const_string "conditional")))])
8865 (define_insn "*mov<mode>_ppc64"
8866 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8867 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8868 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8869 && (gpc_reg_operand (operands[0], <MODE>mode)
8870 || gpc_reg_operand (operands[1], <MODE>mode)))"
8872 return rs6000_output_move_128bit (operands);
8874 [(set_attr "type" "store,store,load,load,*,*")
8875 (set_attr "length" "8")])
8878 [(set (match_operand:TI2 0 "int_reg_operand" "")
8879 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8881 && (VECTOR_MEM_NONE_P (<MODE>mode)
8882 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8883 [(set (match_dup 2) (match_dup 4))
8884 (set (match_dup 3) (match_dup 5))]
8887 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8889 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8891 if (CONST_WIDE_INT_P (operands[1]))
8893 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8894 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8896 else if (CONST_INT_P (operands[1]))
8898 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8899 operands[5] = operands[1];
8906 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8907 (match_operand:TI2 1 "input_operand" ""))]
8909 && gpr_or_gpr_p (operands[0], operands[1])
8910 && !direct_move_p (operands[0], operands[1])
8911 && !quad_load_store_p (operands[0], operands[1])"
8913 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8915 (define_expand "load_multiple"
8916 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8917 (match_operand:SI 1 "" ""))
8918 (use (match_operand:SI 2 "" ""))])]
8919 "TARGET_STRING && !TARGET_POWERPC64"
8927 /* Support only loading a constant number of fixed-point registers from
8928 memory and only bother with this if more than two; the machine
8929 doesn't support more than eight. */
8930 if (GET_CODE (operands[2]) != CONST_INT
8931 || INTVAL (operands[2]) <= 2
8932 || INTVAL (operands[2]) > 8
8933 || GET_CODE (operands[1]) != MEM
8934 || GET_CODE (operands[0]) != REG
8935 || REGNO (operands[0]) >= 32)
8938 count = INTVAL (operands[2]);
8939 regno = REGNO (operands[0]);
8941 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8942 op1 = replace_equiv_address (operands[1],
8943 force_reg (SImode, XEXP (operands[1], 0)));
8945 for (i = 0; i < count; i++)
8946 XVECEXP (operands[3], 0, i)
8947 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8948 adjust_address_nv (op1, SImode, i * 4));
8951 (define_insn "*ldmsi8"
8952 [(match_parallel 0 "load_multiple_operation"
8953 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8954 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8955 (set (match_operand:SI 3 "gpc_reg_operand" "")
8956 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8957 (set (match_operand:SI 4 "gpc_reg_operand" "")
8958 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8959 (set (match_operand:SI 5 "gpc_reg_operand" "")
8960 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8961 (set (match_operand:SI 6 "gpc_reg_operand" "")
8962 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8963 (set (match_operand:SI 7 "gpc_reg_operand" "")
8964 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8965 (set (match_operand:SI 8 "gpc_reg_operand" "")
8966 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8967 (set (match_operand:SI 9 "gpc_reg_operand" "")
8968 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8969 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8971 { return rs6000_output_load_multiple (operands); }"
8972 [(set_attr "type" "load")
8973 (set_attr "update" "yes")
8974 (set_attr "indexed" "yes")
8975 (set_attr "length" "32")])
8977 (define_insn "*ldmsi7"
8978 [(match_parallel 0 "load_multiple_operation"
8979 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8980 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8981 (set (match_operand:SI 3 "gpc_reg_operand" "")
8982 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8983 (set (match_operand:SI 4 "gpc_reg_operand" "")
8984 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8985 (set (match_operand:SI 5 "gpc_reg_operand" "")
8986 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8987 (set (match_operand:SI 6 "gpc_reg_operand" "")
8988 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8989 (set (match_operand:SI 7 "gpc_reg_operand" "")
8990 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8991 (set (match_operand:SI 8 "gpc_reg_operand" "")
8992 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8993 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8995 { return rs6000_output_load_multiple (operands); }"
8996 [(set_attr "type" "load")
8997 (set_attr "update" "yes")
8998 (set_attr "indexed" "yes")
8999 (set_attr "length" "32")])
9001 (define_insn "*ldmsi6"
9002 [(match_parallel 0 "load_multiple_operation"
9003 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9004 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9005 (set (match_operand:SI 3 "gpc_reg_operand" "")
9006 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9007 (set (match_operand:SI 4 "gpc_reg_operand" "")
9008 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9009 (set (match_operand:SI 5 "gpc_reg_operand" "")
9010 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9011 (set (match_operand:SI 6 "gpc_reg_operand" "")
9012 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
9013 (set (match_operand:SI 7 "gpc_reg_operand" "")
9014 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
9015 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9017 { return rs6000_output_load_multiple (operands); }"
9018 [(set_attr "type" "load")
9019 (set_attr "update" "yes")
9020 (set_attr "indexed" "yes")
9021 (set_attr "length" "32")])
9023 (define_insn "*ldmsi5"
9024 [(match_parallel 0 "load_multiple_operation"
9025 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9026 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9027 (set (match_operand:SI 3 "gpc_reg_operand" "")
9028 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9029 (set (match_operand:SI 4 "gpc_reg_operand" "")
9030 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9031 (set (match_operand:SI 5 "gpc_reg_operand" "")
9032 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9033 (set (match_operand:SI 6 "gpc_reg_operand" "")
9034 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
9035 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9037 { return rs6000_output_load_multiple (operands); }"
9038 [(set_attr "type" "load")
9039 (set_attr "update" "yes")
9040 (set_attr "indexed" "yes")
9041 (set_attr "length" "32")])
9043 (define_insn "*ldmsi4"
9044 [(match_parallel 0 "load_multiple_operation"
9045 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9046 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9047 (set (match_operand:SI 3 "gpc_reg_operand" "")
9048 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9049 (set (match_operand:SI 4 "gpc_reg_operand" "")
9050 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9051 (set (match_operand:SI 5 "gpc_reg_operand" "")
9052 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
9053 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9055 { return rs6000_output_load_multiple (operands); }"
9056 [(set_attr "type" "load")
9057 (set_attr "update" "yes")
9058 (set_attr "indexed" "yes")
9059 (set_attr "length" "32")])
9061 (define_insn "*ldmsi3"
9062 [(match_parallel 0 "load_multiple_operation"
9063 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9064 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9065 (set (match_operand:SI 3 "gpc_reg_operand" "")
9066 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9067 (set (match_operand:SI 4 "gpc_reg_operand" "")
9068 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
9069 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
9071 { return rs6000_output_load_multiple (operands); }"
9072 [(set_attr "type" "load")
9073 (set_attr "update" "yes")
9074 (set_attr "indexed" "yes")
9075 (set_attr "length" "32")])
9077 (define_expand "store_multiple"
9078 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9079 (match_operand:SI 1 "" ""))
9080 (clobber (scratch:SI))
9081 (use (match_operand:SI 2 "" ""))])]
9082 "TARGET_STRING && !TARGET_POWERPC64"
9091 /* Support only storing a constant number of fixed-point registers to
9092 memory and only bother with this if more than two; the machine
9093 doesn't support more than eight. */
9094 if (GET_CODE (operands[2]) != CONST_INT
9095 || INTVAL (operands[2]) <= 2
9096 || INTVAL (operands[2]) > 8
9097 || GET_CODE (operands[0]) != MEM
9098 || GET_CODE (operands[1]) != REG
9099 || REGNO (operands[1]) >= 32)
9102 count = INTVAL (operands[2]);
9103 regno = REGNO (operands[1]);
9105 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9106 to = force_reg (SImode, XEXP (operands[0], 0));
9107 op0 = replace_equiv_address (operands[0], to);
9109 XVECEXP (operands[3], 0, 0)
9110 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
9111 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9112 gen_rtx_SCRATCH (SImode));
9114 for (i = 1; i < count; i++)
9115 XVECEXP (operands[3], 0, i + 1)
9116 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9117 gen_rtx_REG (SImode, regno + i));
9120 (define_insn "*stmsi8"
9121 [(match_parallel 0 "store_multiple_operation"
9122 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9123 (match_operand:SI 2 "gpc_reg_operand" "r"))
9124 (clobber (match_scratch:SI 3 "=X"))
9125 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9126 (match_operand:SI 4 "gpc_reg_operand" "r"))
9127 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9128 (match_operand:SI 5 "gpc_reg_operand" "r"))
9129 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9130 (match_operand:SI 6 "gpc_reg_operand" "r"))
9131 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9132 (match_operand:SI 7 "gpc_reg_operand" "r"))
9133 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9134 (match_operand:SI 8 "gpc_reg_operand" "r"))
9135 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9136 (match_operand:SI 9 "gpc_reg_operand" "r"))
9137 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9138 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9139 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9141 [(set_attr "type" "store")
9142 (set_attr "update" "yes")
9143 (set_attr "indexed" "yes")
9144 (set_attr "cell_micro" "always")])
9146 (define_insn "*stmsi7"
9147 [(match_parallel 0 "store_multiple_operation"
9148 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9149 (match_operand:SI 2 "gpc_reg_operand" "r"))
9150 (clobber (match_scratch:SI 3 "=X"))
9151 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9152 (match_operand:SI 4 "gpc_reg_operand" "r"))
9153 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9154 (match_operand:SI 5 "gpc_reg_operand" "r"))
9155 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9156 (match_operand:SI 6 "gpc_reg_operand" "r"))
9157 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9158 (match_operand:SI 7 "gpc_reg_operand" "r"))
9159 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9160 (match_operand:SI 8 "gpc_reg_operand" "r"))
9161 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9162 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9163 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9165 [(set_attr "type" "store")
9166 (set_attr "update" "yes")
9167 (set_attr "indexed" "yes")
9168 (set_attr "cell_micro" "always")])
9170 (define_insn "*stmsi6"
9171 [(match_parallel 0 "store_multiple_operation"
9172 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9173 (match_operand:SI 2 "gpc_reg_operand" "r"))
9174 (clobber (match_scratch:SI 3 "=X"))
9175 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9176 (match_operand:SI 4 "gpc_reg_operand" "r"))
9177 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9178 (match_operand:SI 5 "gpc_reg_operand" "r"))
9179 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9180 (match_operand:SI 6 "gpc_reg_operand" "r"))
9181 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9182 (match_operand:SI 7 "gpc_reg_operand" "r"))
9183 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9184 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9185 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9187 [(set_attr "type" "store")
9188 (set_attr "update" "yes")
9189 (set_attr "indexed" "yes")
9190 (set_attr "cell_micro" "always")])
9192 (define_insn "*stmsi5"
9193 [(match_parallel 0 "store_multiple_operation"
9194 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9195 (match_operand:SI 2 "gpc_reg_operand" "r"))
9196 (clobber (match_scratch:SI 3 "=X"))
9197 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9198 (match_operand:SI 4 "gpc_reg_operand" "r"))
9199 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9200 (match_operand:SI 5 "gpc_reg_operand" "r"))
9201 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9202 (match_operand:SI 6 "gpc_reg_operand" "r"))
9203 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9204 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9205 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9207 [(set_attr "type" "store")
9208 (set_attr "update" "yes")
9209 (set_attr "indexed" "yes")
9210 (set_attr "cell_micro" "always")])
9212 (define_insn "*stmsi4"
9213 [(match_parallel 0 "store_multiple_operation"
9214 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9215 (match_operand:SI 2 "gpc_reg_operand" "r"))
9216 (clobber (match_scratch:SI 3 "=X"))
9217 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9218 (match_operand:SI 4 "gpc_reg_operand" "r"))
9219 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9220 (match_operand:SI 5 "gpc_reg_operand" "r"))
9221 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9222 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9223 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9225 [(set_attr "type" "store")
9226 (set_attr "update" "yes")
9227 (set_attr "indexed" "yes")
9228 (set_attr "cell_micro" "always")])
9230 (define_insn "*stmsi3"
9231 [(match_parallel 0 "store_multiple_operation"
9232 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9233 (match_operand:SI 2 "gpc_reg_operand" "r"))
9234 (clobber (match_scratch:SI 3 "=X"))
9235 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9236 (match_operand:SI 4 "gpc_reg_operand" "r"))
9237 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9238 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9239 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9241 [(set_attr "type" "store")
9242 (set_attr "update" "yes")
9243 (set_attr "indexed" "yes")
9244 (set_attr "cell_micro" "always")])
9246 (define_expand "setmemsi"
9247 [(parallel [(set (match_operand:BLK 0 "" "")
9248 (match_operand 2 "const_int_operand" ""))
9249 (use (match_operand:SI 1 "" ""))
9250 (use (match_operand:SI 3 "" ""))])]
9254 /* If value to set is not zero, use the library routine. */
9255 if (operands[2] != const0_rtx)
9258 if (expand_block_clear (operands))
9264 ;; String compare N insn.
9265 ;; Argument 0 is the target (result)
9266 ;; Argument 1 is the destination
9267 ;; Argument 2 is the source
9268 ;; Argument 3 is the length
9269 ;; Argument 4 is the alignment
9271 (define_expand "cmpstrnsi"
9272 [(parallel [(set (match_operand:SI 0)
9273 (compare:SI (match_operand:BLK 1)
9274 (match_operand:BLK 2)))
9275 (use (match_operand:SI 3))
9276 (use (match_operand:SI 4))])]
9277 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9279 if (optimize_insn_for_size_p ())
9282 if (expand_strn_compare (operands, 0))
9288 ;; String compare insn.
9289 ;; Argument 0 is the target (result)
9290 ;; Argument 1 is the destination
9291 ;; Argument 2 is the source
9292 ;; Argument 3 is the alignment
9294 (define_expand "cmpstrsi"
9295 [(parallel [(set (match_operand:SI 0)
9296 (compare:SI (match_operand:BLK 1)
9297 (match_operand:BLK 2)))
9298 (use (match_operand:SI 3))])]
9299 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9301 if (optimize_insn_for_size_p ())
9304 if (expand_strn_compare (operands, 1))
9310 ;; Block compare insn.
9311 ;; Argument 0 is the target (result)
9312 ;; Argument 1 is the destination
9313 ;; Argument 2 is the source
9314 ;; Argument 3 is the length
9315 ;; Argument 4 is the alignment
9317 (define_expand "cmpmemsi"
9318 [(parallel [(set (match_operand:SI 0)
9319 (compare:SI (match_operand:BLK 1)
9320 (match_operand:BLK 2)))
9321 (use (match_operand:SI 3))
9322 (use (match_operand:SI 4))])]
9325 if (expand_block_compare (operands))
9331 ;; String/block move insn.
9332 ;; Argument 0 is the destination
9333 ;; Argument 1 is the source
9334 ;; Argument 2 is the length
9335 ;; Argument 3 is the alignment
9337 (define_expand "movmemsi"
9338 [(parallel [(set (match_operand:BLK 0 "" "")
9339 (match_operand:BLK 1 "" ""))
9340 (use (match_operand:SI 2 "" ""))
9341 (use (match_operand:SI 3 "" ""))])]
9345 if (expand_block_move (operands))
9351 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
9352 ;; register allocator doesn't have a clue about allocating 8 word registers.
9353 ;; rD/rS = r5 is preferred, efficient form.
9354 (define_expand "movmemsi_8reg"
9355 [(parallel [(set (match_operand 0 "" "")
9356 (match_operand 1 "" ""))
9357 (use (match_operand 2 "" ""))
9358 (use (match_operand 3 "" ""))
9359 (clobber (reg:SI 5))
9360 (clobber (reg:SI 6))
9361 (clobber (reg:SI 7))
9362 (clobber (reg:SI 8))
9363 (clobber (reg:SI 9))
9364 (clobber (reg:SI 10))
9365 (clobber (reg:SI 11))
9366 (clobber (reg:SI 12))
9367 (clobber (match_scratch:SI 4 ""))])]
9372 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9373 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9374 (use (match_operand:SI 2 "immediate_operand" "i"))
9375 (use (match_operand:SI 3 "immediate_operand" "i"))
9376 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9377 (clobber (reg:SI 6))
9378 (clobber (reg:SI 7))
9379 (clobber (reg:SI 8))
9380 (clobber (reg:SI 9))
9381 (clobber (reg:SI 10))
9382 (clobber (reg:SI 11))
9383 (clobber (reg:SI 12))
9384 (clobber (match_scratch:SI 5 "=X"))]
9386 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9387 || INTVAL (operands[2]) == 0)
9388 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9389 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9390 && REGNO (operands[4]) == 5"
9391 "lswi %4,%1,%2\;stswi %4,%0,%2"
9392 [(set_attr "type" "store")
9393 (set_attr "update" "yes")
9394 (set_attr "indexed" "yes")
9395 (set_attr "cell_micro" "always")
9396 (set_attr "length" "8")])
9398 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
9399 ;; register allocator doesn't have a clue about allocating 6 word registers.
9400 ;; rD/rS = r5 is preferred, efficient form.
9401 (define_expand "movmemsi_6reg"
9402 [(parallel [(set (match_operand 0 "" "")
9403 (match_operand 1 "" ""))
9404 (use (match_operand 2 "" ""))
9405 (use (match_operand 3 "" ""))
9406 (clobber (reg:SI 5))
9407 (clobber (reg:SI 6))
9408 (clobber (reg:SI 7))
9409 (clobber (reg:SI 8))
9410 (clobber (reg:SI 9))
9411 (clobber (reg:SI 10))
9412 (clobber (match_scratch:SI 4 ""))])]
9417 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9418 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9419 (use (match_operand:SI 2 "immediate_operand" "i"))
9420 (use (match_operand:SI 3 "immediate_operand" "i"))
9421 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9422 (clobber (reg:SI 6))
9423 (clobber (reg:SI 7))
9424 (clobber (reg:SI 8))
9425 (clobber (reg:SI 9))
9426 (clobber (reg:SI 10))
9427 (clobber (match_scratch:SI 5 "=X"))]
9429 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9430 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9431 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9432 && REGNO (operands[4]) == 5"
9433 "lswi %4,%1,%2\;stswi %4,%0,%2"
9434 [(set_attr "type" "store")
9435 (set_attr "update" "yes")
9436 (set_attr "indexed" "yes")
9437 (set_attr "cell_micro" "always")
9438 (set_attr "length" "8")])
9440 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9441 ;; problems with TImode.
9442 ;; rD/rS = r5 is preferred, efficient form.
9443 (define_expand "movmemsi_4reg"
9444 [(parallel [(set (match_operand 0 "" "")
9445 (match_operand 1 "" ""))
9446 (use (match_operand 2 "" ""))
9447 (use (match_operand 3 "" ""))
9448 (clobber (reg:SI 5))
9449 (clobber (reg:SI 6))
9450 (clobber (reg:SI 7))
9451 (clobber (reg:SI 8))
9452 (clobber (match_scratch:SI 4 ""))])]
9457 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9458 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9459 (use (match_operand:SI 2 "immediate_operand" "i"))
9460 (use (match_operand:SI 3 "immediate_operand" "i"))
9461 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9462 (clobber (reg:SI 6))
9463 (clobber (reg:SI 7))
9464 (clobber (reg:SI 8))
9465 (clobber (match_scratch:SI 5 "=X"))]
9467 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9468 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9469 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9470 && REGNO (operands[4]) == 5"
9471 "lswi %4,%1,%2\;stswi %4,%0,%2"
9472 [(set_attr "type" "store")
9473 (set_attr "update" "yes")
9474 (set_attr "indexed" "yes")
9475 (set_attr "cell_micro" "always")
9476 (set_attr "length" "8")])
9478 ;; Move up to 8 bytes at a time.
9479 (define_expand "movmemsi_2reg"
9480 [(parallel [(set (match_operand 0 "" "")
9481 (match_operand 1 "" ""))
9482 (use (match_operand 2 "" ""))
9483 (use (match_operand 3 "" ""))
9484 (clobber (match_scratch:DI 4 ""))
9485 (clobber (match_scratch:SI 5 ""))])]
9486 "TARGET_STRING && ! TARGET_POWERPC64"
9490 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9491 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9492 (use (match_operand:SI 2 "immediate_operand" "i"))
9493 (use (match_operand:SI 3 "immediate_operand" "i"))
9494 (clobber (match_scratch:DI 4 "=&r"))
9495 (clobber (match_scratch:SI 5 "=X"))]
9496 "TARGET_STRING && ! TARGET_POWERPC64
9497 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9498 "lswi %4,%1,%2\;stswi %4,%0,%2"
9499 [(set_attr "type" "store")
9500 (set_attr "update" "yes")
9501 (set_attr "indexed" "yes")
9502 (set_attr "cell_micro" "always")
9503 (set_attr "length" "8")])
9505 ;; Move up to 4 bytes at a time.
9506 (define_expand "movmemsi_1reg"
9507 [(parallel [(set (match_operand 0 "" "")
9508 (match_operand 1 "" ""))
9509 (use (match_operand 2 "" ""))
9510 (use (match_operand 3 "" ""))
9511 (clobber (match_scratch:SI 4 ""))
9512 (clobber (match_scratch:SI 5 ""))])]
9517 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9518 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9519 (use (match_operand:SI 2 "immediate_operand" "i"))
9520 (use (match_operand:SI 3 "immediate_operand" "i"))
9521 (clobber (match_scratch:SI 4 "=&r"))
9522 (clobber (match_scratch:SI 5 "=X"))]
9523 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9524 "lswi %4,%1,%2\;stswi %4,%0,%2"
9525 [(set_attr "type" "store")
9526 (set_attr "update" "yes")
9527 (set_attr "indexed" "yes")
9528 (set_attr "cell_micro" "always")
9529 (set_attr "length" "8")])
9531 ;; Define insns that do load or store with update. Some of these we can
9532 ;; get by using pre-decrement or pre-increment, but the hardware can also
9533 ;; do cases where the increment is not the size of the object.
9535 ;; In all these cases, we use operands 0 and 1 for the register being
9536 ;; incremented because those are the operands that local-alloc will
9537 ;; tie and these are the pair most likely to be tieable (and the ones
9538 ;; that will benefit the most).
9540 (define_insn "*movdi_update1"
9541 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9542 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9543 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9544 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9545 (plus:DI (match_dup 1) (match_dup 2)))]
9546 "TARGET_POWERPC64 && TARGET_UPDATE
9547 && (!avoiding_indexed_address_p (DImode)
9548 || !gpc_reg_operand (operands[2], DImode))"
9552 [(set_attr "type" "load")
9553 (set_attr "update" "yes")
9554 (set_attr "indexed" "yes,no")])
9556 (define_insn "movdi_<mode>_update"
9557 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9558 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9559 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9560 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9561 (plus:P (match_dup 1) (match_dup 2)))]
9562 "TARGET_POWERPC64 && TARGET_UPDATE
9563 && (!avoiding_indexed_address_p (Pmode)
9564 || !gpc_reg_operand (operands[2], Pmode)
9565 || (REG_P (operands[0])
9566 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9570 [(set_attr "type" "store")
9571 (set_attr "update" "yes")
9572 (set_attr "indexed" "yes,no")])
9574 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9575 ;; needed for stack allocation, even if the user passes -mno-update.
9576 (define_insn "movdi_<mode>_update_stack"
9577 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9578 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9579 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9580 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9581 (plus:P (match_dup 1) (match_dup 2)))]
9586 [(set_attr "type" "store")
9587 (set_attr "update" "yes")
9588 (set_attr "indexed" "yes,no")])
9590 (define_insn "*movsi_update1"
9591 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9592 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9593 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9594 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9595 (plus:SI (match_dup 1) (match_dup 2)))]
9597 && (!avoiding_indexed_address_p (SImode)
9598 || !gpc_reg_operand (operands[2], SImode))"
9602 [(set_attr "type" "load")
9603 (set_attr "update" "yes")
9604 (set_attr "indexed" "yes,no")])
9606 (define_insn "*movsi_update2"
9607 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9609 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9610 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9611 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9612 (plus:DI (match_dup 1) (match_dup 2)))]
9613 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9614 && !avoiding_indexed_address_p (DImode)"
9616 [(set_attr "type" "load")
9617 (set_attr "sign_extend" "yes")
9618 (set_attr "update" "yes")
9619 (set_attr "indexed" "yes")])
9621 (define_insn "movsi_update"
9622 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9623 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9624 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9625 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9626 (plus:SI (match_dup 1) (match_dup 2)))]
9628 && (!avoiding_indexed_address_p (SImode)
9629 || !gpc_reg_operand (operands[2], SImode)
9630 || (REG_P (operands[0])
9631 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9635 [(set_attr "type" "store")
9636 (set_attr "update" "yes")
9637 (set_attr "indexed" "yes,no")])
9639 ;; This is an unconditional pattern; needed for stack allocation, even
9640 ;; if the user passes -mno-update.
9641 (define_insn "movsi_update_stack"
9642 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9643 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9644 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9645 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9646 (plus:SI (match_dup 1) (match_dup 2)))]
9651 [(set_attr "type" "store")
9652 (set_attr "update" "yes")
9653 (set_attr "indexed" "yes,no")])
9655 (define_insn "*movhi_update1"
9656 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9657 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9658 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9659 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9660 (plus:SI (match_dup 1) (match_dup 2)))]
9662 && (!avoiding_indexed_address_p (SImode)
9663 || !gpc_reg_operand (operands[2], SImode))"
9667 [(set_attr "type" "load")
9668 (set_attr "update" "yes")
9669 (set_attr "indexed" "yes,no")])
9671 (define_insn "*movhi_update2"
9672 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9674 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9675 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9676 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9677 (plus:SI (match_dup 1) (match_dup 2)))]
9679 && (!avoiding_indexed_address_p (SImode)
9680 || !gpc_reg_operand (operands[2], SImode))"
9684 [(set_attr "type" "load")
9685 (set_attr "update" "yes")
9686 (set_attr "indexed" "yes,no")])
9688 (define_insn "*movhi_update3"
9689 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9691 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9692 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9693 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9694 (plus:SI (match_dup 1) (match_dup 2)))]
9695 "TARGET_UPDATE && rs6000_gen_cell_microcode
9696 && (!avoiding_indexed_address_p (SImode)
9697 || !gpc_reg_operand (operands[2], SImode))"
9701 [(set_attr "type" "load")
9702 (set_attr "sign_extend" "yes")
9703 (set_attr "update" "yes")
9704 (set_attr "indexed" "yes,no")])
9706 (define_insn "*movhi_update4"
9707 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9708 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9709 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9710 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9711 (plus:SI (match_dup 1) (match_dup 2)))]
9713 && (!avoiding_indexed_address_p (SImode)
9714 || !gpc_reg_operand (operands[2], SImode))"
9718 [(set_attr "type" "store")
9719 (set_attr "update" "yes")
9720 (set_attr "indexed" "yes,no")])
9722 (define_insn "*movqi_update1"
9723 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9724 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9725 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9726 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9727 (plus:SI (match_dup 1) (match_dup 2)))]
9729 && (!avoiding_indexed_address_p (SImode)
9730 || !gpc_reg_operand (operands[2], SImode))"
9734 [(set_attr "type" "load")
9735 (set_attr "update" "yes")
9736 (set_attr "indexed" "yes,no")])
9738 (define_insn "*movqi_update2"
9739 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9741 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9742 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9743 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9744 (plus:SI (match_dup 1) (match_dup 2)))]
9746 && (!avoiding_indexed_address_p (SImode)
9747 || !gpc_reg_operand (operands[2], SImode))"
9751 [(set_attr "type" "load")
9752 (set_attr "update" "yes")
9753 (set_attr "indexed" "yes,no")])
9755 (define_insn "*movqi_update3"
9756 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9757 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9758 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9759 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9760 (plus:SI (match_dup 1) (match_dup 2)))]
9762 && (!avoiding_indexed_address_p (SImode)
9763 || !gpc_reg_operand (operands[2], SImode))"
9767 [(set_attr "type" "store")
9768 (set_attr "update" "yes")
9769 (set_attr "indexed" "yes,no")])
9771 (define_insn "*movsf_update1"
9772 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9773 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9774 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9775 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9776 (plus:SI (match_dup 1) (match_dup 2)))]
9777 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9778 && (!avoiding_indexed_address_p (SImode)
9779 || !gpc_reg_operand (operands[2], SImode))"
9783 [(set_attr "type" "fpload")
9784 (set_attr "update" "yes")
9785 (set_attr "indexed" "yes,no")])
9787 (define_insn "*movsf_update2"
9788 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9789 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9790 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9791 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9792 (plus:SI (match_dup 1) (match_dup 2)))]
9793 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9794 && (!avoiding_indexed_address_p (SImode)
9795 || !gpc_reg_operand (operands[2], SImode))"
9799 [(set_attr "type" "fpstore")
9800 (set_attr "update" "yes")
9801 (set_attr "indexed" "yes,no")])
9803 (define_insn "*movsf_update3"
9804 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9805 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9806 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9807 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9808 (plus:SI (match_dup 1) (match_dup 2)))]
9809 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9810 && (!avoiding_indexed_address_p (SImode)
9811 || !gpc_reg_operand (operands[2], SImode))"
9815 [(set_attr "type" "load")
9816 (set_attr "update" "yes")
9817 (set_attr "indexed" "yes,no")])
9819 (define_insn "*movsf_update4"
9820 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9821 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9822 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9823 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9824 (plus:SI (match_dup 1) (match_dup 2)))]
9825 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9826 && (!avoiding_indexed_address_p (SImode)
9827 || !gpc_reg_operand (operands[2], SImode))"
9831 [(set_attr "type" "store")
9832 (set_attr "update" "yes")
9833 (set_attr "indexed" "yes,no")])
9835 (define_insn "*movdf_update1"
9836 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9837 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9838 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9839 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9840 (plus:SI (match_dup 1) (match_dup 2)))]
9841 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9842 && (!avoiding_indexed_address_p (SImode)
9843 || !gpc_reg_operand (operands[2], SImode))"
9847 [(set_attr "type" "fpload")
9848 (set_attr "update" "yes")
9849 (set_attr "indexed" "yes,no")
9850 (set_attr "size" "64")])
9852 (define_insn "*movdf_update2"
9853 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9854 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9855 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9856 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9857 (plus:SI (match_dup 1) (match_dup 2)))]
9858 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9859 && (!avoiding_indexed_address_p (SImode)
9860 || !gpc_reg_operand (operands[2], SImode))"
9864 [(set_attr "type" "fpstore")
9865 (set_attr "update" "yes")
9866 (set_attr "indexed" "yes,no")])
9869 ;; After inserting conditional returns we can sometimes have
9870 ;; unnecessary register moves. Unfortunately we cannot have a
9871 ;; modeless peephole here, because some single SImode sets have early
9872 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9873 ;; sequences, using get_attr_length here will smash the operands
9874 ;; array. Neither is there an early_cobbler_p predicate.
9875 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9876 ;; Also this optimization interferes with scalars going into
9877 ;; altivec registers (the code does reloading through the FPRs).
9879 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9880 (match_operand:DF 1 "any_operand" ""))
9881 (set (match_operand:DF 2 "gpc_reg_operand" "")
9883 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9884 && !TARGET_UPPER_REGS_DF
9885 && peep2_reg_dead_p (2, operands[0])"
9886 [(set (match_dup 2) (match_dup 1))])
9889 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9890 (match_operand:SF 1 "any_operand" ""))
9891 (set (match_operand:SF 2 "gpc_reg_operand" "")
9893 "!TARGET_UPPER_REGS_SF
9894 && peep2_reg_dead_p (2, operands[0])"
9895 [(set (match_dup 2) (match_dup 1))])
9900 ;; Mode attributes for different ABIs.
9901 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9902 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9903 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9904 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9906 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9907 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9908 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9909 (match_operand 4 "" "g")))
9910 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9911 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9913 (clobber (reg:SI LR_REGNO))]
9914 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9916 if (TARGET_CMODEL != CMODEL_SMALL)
9917 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9920 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9922 "&& TARGET_TLS_MARKERS"
9924 (unspec:TLSmode [(match_dup 1)
9927 (parallel [(set (match_dup 0)
9928 (call (mem:TLSmode (match_dup 3))
9930 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9931 (clobber (reg:SI LR_REGNO))])]
9933 [(set_attr "type" "two")
9934 (set (attr "length")
9935 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9939 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9940 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9941 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9942 (match_operand 4 "" "g")))
9943 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9944 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9946 (clobber (reg:SI LR_REGNO))]
9947 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9951 if (TARGET_SECURE_PLT && flag_pic == 2)
9952 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9954 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9957 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9959 "&& TARGET_TLS_MARKERS"
9961 (unspec:TLSmode [(match_dup 1)
9964 (parallel [(set (match_dup 0)
9965 (call (mem:TLSmode (match_dup 3))
9967 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9968 (clobber (reg:SI LR_REGNO))])]
9970 [(set_attr "type" "two")
9971 (set_attr "length" "8")])
9973 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9974 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9975 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9976 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9978 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9979 "addi %0,%1,%2@got@tlsgd"
9980 "&& TARGET_CMODEL != CMODEL_SMALL"
9983 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9985 (lo_sum:TLSmode (match_dup 3)
9986 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9989 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9991 [(set (attr "length")
9992 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9996 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9997 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9999 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10000 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10002 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10003 "addis %0,%1,%2@got@tlsgd@ha"
10004 [(set_attr "length" "4")])
10006 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
10007 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10008 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10009 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10010 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10012 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10013 "addi %0,%1,%2@got@tlsgd@l"
10014 [(set_attr "length" "4")])
10016 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
10017 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10018 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10019 (match_operand 2 "" "g")))
10020 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10022 (clobber (reg:SI LR_REGNO))]
10023 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10024 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10025 "bl %z1(%3@tlsgd)\;nop"
10026 [(set_attr "type" "branch")
10027 (set_attr "length" "8")])
10029 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
10030 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10031 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10032 (match_operand 2 "" "g")))
10033 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10035 (clobber (reg:SI LR_REGNO))]
10036 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10040 if (TARGET_SECURE_PLT && flag_pic == 2)
10041 return "bl %z1+32768(%3@tlsgd)@plt";
10042 return "bl %z1(%3@tlsgd)@plt";
10044 return "bl %z1(%3@tlsgd)";
10046 [(set_attr "type" "branch")
10047 (set_attr "length" "4")])
10049 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
10050 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10051 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10052 (match_operand 3 "" "g")))
10053 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10055 (clobber (reg:SI LR_REGNO))]
10056 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10058 if (TARGET_CMODEL != CMODEL_SMALL)
10059 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
10062 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
10064 "&& TARGET_TLS_MARKERS"
10065 [(set (match_dup 0)
10066 (unspec:TLSmode [(match_dup 1)]
10068 (parallel [(set (match_dup 0)
10069 (call (mem:TLSmode (match_dup 2))
10071 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10072 (clobber (reg:SI LR_REGNO))])]
10074 [(set_attr "type" "two")
10075 (set (attr "length")
10076 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10080 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
10081 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10082 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10083 (match_operand 3 "" "g")))
10084 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10086 (clobber (reg:SI LR_REGNO))]
10087 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
10091 if (TARGET_SECURE_PLT && flag_pic == 2)
10092 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
10094 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
10097 return "addi %0,%1,%&@got@tlsld\;bl %z2";
10099 "&& TARGET_TLS_MARKERS"
10100 [(set (match_dup 0)
10101 (unspec:TLSmode [(match_dup 1)]
10103 (parallel [(set (match_dup 0)
10104 (call (mem:TLSmode (match_dup 2))
10106 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10107 (clobber (reg:SI LR_REGNO))])]
10109 [(set_attr "length" "8")])
10111 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10112 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10113 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10115 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10116 "addi %0,%1,%&@got@tlsld"
10117 "&& TARGET_CMODEL != CMODEL_SMALL"
10118 [(set (match_dup 2)
10120 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10122 (lo_sum:TLSmode (match_dup 2)
10123 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10126 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10128 [(set (attr "length")
10129 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10133 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10134 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10136 (unspec:TLSmode [(const_int 0)
10137 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10139 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10140 "addis %0,%1,%&@got@tlsld@ha"
10141 [(set_attr "length" "4")])
10143 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10144 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10145 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10146 (unspec:TLSmode [(const_int 0)
10147 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10149 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10150 "addi %0,%1,%&@got@tlsld@l"
10151 [(set_attr "length" "4")])
10153 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10154 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10155 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10156 (match_operand 2 "" "g")))
10157 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10158 (clobber (reg:SI LR_REGNO))]
10159 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10160 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10161 "bl %z1(%&@tlsld)\;nop"
10162 [(set_attr "type" "branch")
10163 (set_attr "length" "8")])
10165 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10166 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10167 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10168 (match_operand 2 "" "g")))
10169 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10170 (clobber (reg:SI LR_REGNO))]
10171 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10175 if (TARGET_SECURE_PLT && flag_pic == 2)
10176 return "bl %z1+32768(%&@tlsld)@plt";
10177 return "bl %z1(%&@tlsld)@plt";
10179 return "bl %z1(%&@tlsld)";
10181 [(set_attr "type" "branch")
10182 (set_attr "length" "4")])
10184 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10185 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10186 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10187 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10188 UNSPEC_TLSDTPREL))]
10190 "addi %0,%1,%2@dtprel")
10192 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10193 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10194 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10195 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10196 UNSPEC_TLSDTPRELHA))]
10198 "addis %0,%1,%2@dtprel@ha")
10200 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10201 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10202 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10203 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10204 UNSPEC_TLSDTPRELLO))]
10206 "addi %0,%1,%2@dtprel@l")
10208 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10209 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10210 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10211 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10212 UNSPEC_TLSGOTDTPREL))]
10214 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10215 "&& TARGET_CMODEL != CMODEL_SMALL"
10216 [(set (match_dup 3)
10218 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10220 (lo_sum:TLSmode (match_dup 3)
10221 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10224 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10226 [(set (attr "length")
10227 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10231 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10232 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10234 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10235 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10236 UNSPEC_TLSGOTDTPREL)))]
10237 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10238 "addis %0,%1,%2@got@dtprel@ha"
10239 [(set_attr "length" "4")])
10241 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10242 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10243 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10244 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10245 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10246 UNSPEC_TLSGOTDTPREL)))]
10247 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10248 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10249 [(set_attr "length" "4")])
10251 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10252 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10253 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10254 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10257 "addi %0,%1,%2@tprel")
10259 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10260 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10261 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10262 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10263 UNSPEC_TLSTPRELHA))]
10265 "addis %0,%1,%2@tprel@ha")
10267 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10268 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10269 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10270 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10271 UNSPEC_TLSTPRELLO))]
10273 "addi %0,%1,%2@tprel@l")
10275 ;; "b" output constraint here and on tls_tls input to support linker tls
10276 ;; optimization. The linker may edit the instructions emitted by a
10277 ;; tls_got_tprel/tls_tls pair to addis,addi.
10278 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10279 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10280 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10281 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10282 UNSPEC_TLSGOTTPREL))]
10284 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10285 "&& TARGET_CMODEL != CMODEL_SMALL"
10286 [(set (match_dup 3)
10288 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10290 (lo_sum:TLSmode (match_dup 3)
10291 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10294 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10296 [(set (attr "length")
10297 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10301 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10302 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10304 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10305 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10306 UNSPEC_TLSGOTTPREL)))]
10307 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10308 "addis %0,%1,%2@got@tprel@ha"
10309 [(set_attr "length" "4")])
10311 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10312 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10313 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10314 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10315 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10316 UNSPEC_TLSGOTTPREL)))]
10317 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10318 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10319 [(set_attr "length" "4")])
10321 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10322 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10323 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10324 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10326 "TARGET_ELF && HAVE_AS_TLS"
10327 "add %0,%1,%2@tls")
10329 (define_expand "tls_get_tpointer"
10330 [(set (match_operand:SI 0 "gpc_reg_operand" "")
10331 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10332 "TARGET_XCOFF && HAVE_AS_TLS"
10335 emit_insn (gen_tls_get_tpointer_internal ());
10336 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10340 (define_insn "tls_get_tpointer_internal"
10342 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10343 (clobber (reg:SI LR_REGNO))]
10344 "TARGET_XCOFF && HAVE_AS_TLS"
10345 "bla __get_tpointer")
10347 (define_expand "tls_get_addr<mode>"
10348 [(set (match_operand:P 0 "gpc_reg_operand" "")
10349 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10350 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10351 "TARGET_XCOFF && HAVE_AS_TLS"
10354 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10355 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10356 emit_insn (gen_tls_get_addr_internal<mode> ());
10357 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10361 (define_insn "tls_get_addr_internal<mode>"
10363 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10364 (clobber (reg:P 0))
10365 (clobber (reg:P 4))
10366 (clobber (reg:P 5))
10367 (clobber (reg:P 11))
10368 (clobber (reg:CC CR0_REGNO))
10369 (clobber (reg:P LR_REGNO))]
10370 "TARGET_XCOFF && HAVE_AS_TLS"
10371 "bla __tls_get_addr")
10373 ;; Next come insns related to the calling sequence.
10375 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10376 ;; We move the back-chain and decrement the stack pointer.
10378 (define_expand "allocate_stack"
10379 [(set (match_operand 0 "gpc_reg_operand" "")
10380 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10382 (minus (reg 1) (match_dup 1)))]
10385 { rtx chain = gen_reg_rtx (Pmode);
10386 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10388 rtx insn, par, set, mem;
10390 emit_move_insn (chain, stack_bot);
10392 /* Check stack bounds if necessary. */
10393 if (crtl->limit_stack)
10396 available = expand_binop (Pmode, sub_optab,
10397 stack_pointer_rtx, stack_limit_rtx,
10398 NULL_RTX, 1, OPTAB_WIDEN);
10399 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10402 if (GET_CODE (operands[1]) != CONST_INT
10403 || INTVAL (operands[1]) < -32767
10404 || INTVAL (operands[1]) > 32768)
10406 neg_op0 = gen_reg_rtx (Pmode);
10408 emit_insn (gen_negsi2 (neg_op0, operands[1]));
10410 emit_insn (gen_negdi2 (neg_op0, operands[1]));
10413 neg_op0 = GEN_INT (- INTVAL (operands[1]));
10415 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10416 : gen_movdi_di_update_stack))
10417 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10419 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10420 it now and set the alias set/attributes. The above gen_*_update
10421 calls will generate a PARALLEL with the MEM set being the first
10423 par = PATTERN (insn);
10424 gcc_assert (GET_CODE (par) == PARALLEL);
10425 set = XVECEXP (par, 0, 0);
10426 gcc_assert (GET_CODE (set) == SET);
10427 mem = SET_DEST (set);
10428 gcc_assert (MEM_P (mem));
10429 MEM_NOTRAP_P (mem) = 1;
10430 set_mem_alias_set (mem, get_frame_alias_set ());
10432 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10436 ;; These patterns say how to save and restore the stack pointer. We need not
10437 ;; save the stack pointer at function level since we are careful to
10438 ;; preserve the backchain. At block level, we have to restore the backchain
10439 ;; when we restore the stack pointer.
10441 ;; For nonlocal gotos, we must save both the stack pointer and its
10442 ;; backchain and restore both. Note that in the nonlocal case, the
10443 ;; save area is a memory location.
10445 (define_expand "save_stack_function"
10446 [(match_operand 0 "any_operand" "")
10447 (match_operand 1 "any_operand" "")]
10451 (define_expand "restore_stack_function"
10452 [(match_operand 0 "any_operand" "")
10453 (match_operand 1 "any_operand" "")]
10457 ;; Adjust stack pointer (op0) to a new value (op1).
10458 ;; First copy old stack backchain to new location, and ensure that the
10459 ;; scheduler won't reorder the sp assignment before the backchain write.
10460 (define_expand "restore_stack_block"
10461 [(set (match_dup 2) (match_dup 3))
10462 (set (match_dup 4) (match_dup 2))
10464 (set (match_operand 0 "register_operand" "")
10465 (match_operand 1 "register_operand" ""))]
10471 operands[1] = force_reg (Pmode, operands[1]);
10472 operands[2] = gen_reg_rtx (Pmode);
10473 operands[3] = gen_frame_mem (Pmode, operands[0]);
10474 operands[4] = gen_frame_mem (Pmode, operands[1]);
10475 p = rtvec_alloc (1);
10476 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10478 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10481 (define_expand "save_stack_nonlocal"
10482 [(set (match_dup 3) (match_dup 4))
10483 (set (match_operand 0 "memory_operand" "") (match_dup 3))
10484 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10488 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10490 /* Copy the backchain to the first word, sp to the second. */
10491 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10492 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10493 operands[3] = gen_reg_rtx (Pmode);
10494 operands[4] = gen_frame_mem (Pmode, operands[1]);
10497 (define_expand "restore_stack_nonlocal"
10498 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10499 (set (match_dup 3) (match_dup 4))
10500 (set (match_dup 5) (match_dup 2))
10502 (set (match_operand 0 "register_operand" "") (match_dup 3))]
10506 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10509 /* Restore the backchain from the first word, sp from the second. */
10510 operands[2] = gen_reg_rtx (Pmode);
10511 operands[3] = gen_reg_rtx (Pmode);
10512 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10513 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10514 operands[5] = gen_frame_mem (Pmode, operands[3]);
10515 p = rtvec_alloc (1);
10516 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10518 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10521 ;; TOC register handling.
10523 ;; Code to initialize the TOC register...
10525 (define_insn "load_toc_aix_si"
10526 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10527 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10528 (use (reg:SI 2))])]
10529 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10533 extern int need_toc_init;
10535 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10536 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10537 operands[2] = gen_rtx_REG (Pmode, 2);
10538 return \"lwz %0,%1(%2)\";
10540 [(set_attr "type" "load")
10541 (set_attr "update" "no")
10542 (set_attr "indexed" "no")])
10544 (define_insn "load_toc_aix_di"
10545 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10546 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10547 (use (reg:DI 2))])]
10548 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10552 extern int need_toc_init;
10554 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10555 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10557 strcat (buf, \"@toc\");
10558 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10559 operands[2] = gen_rtx_REG (Pmode, 2);
10560 return \"ld %0,%1(%2)\";
10562 [(set_attr "type" "load")
10563 (set_attr "update" "no")
10564 (set_attr "indexed" "no")])
10566 (define_insn "load_toc_v4_pic_si"
10567 [(set (reg:SI LR_REGNO)
10568 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10569 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10570 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10571 [(set_attr "type" "branch")
10572 (set_attr "length" "4")])
10574 (define_expand "load_toc_v4_PIC_1"
10575 [(parallel [(set (reg:SI LR_REGNO)
10576 (match_operand:SI 0 "immediate_operand" "s"))
10577 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10578 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10579 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10582 (define_insn "load_toc_v4_PIC_1_normal"
10583 [(set (reg:SI LR_REGNO)
10584 (match_operand:SI 0 "immediate_operand" "s"))
10585 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10586 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10587 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10588 "bcl 20,31,%0\\n%0:"
10589 [(set_attr "type" "branch")
10590 (set_attr "length" "4")
10591 (set_attr "cannot_copy" "yes")])
10593 (define_insn "load_toc_v4_PIC_1_476"
10594 [(set (reg:SI LR_REGNO)
10595 (match_operand:SI 0 "immediate_operand" "s"))
10596 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10597 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10598 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10602 static char templ[32];
10604 get_ppc476_thunk_name (name);
10605 sprintf (templ, \"bl %s\\n%%0:\", name);
10608 [(set_attr "type" "branch")
10609 (set_attr "length" "4")
10610 (set_attr "cannot_copy" "yes")])
10612 (define_expand "load_toc_v4_PIC_1b"
10613 [(parallel [(set (reg:SI LR_REGNO)
10614 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10615 (label_ref (match_operand 1 "" ""))]
10618 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10621 (define_insn "load_toc_v4_PIC_1b_normal"
10622 [(set (reg:SI LR_REGNO)
10623 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10624 (label_ref (match_operand 1 "" ""))]
10627 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10628 "bcl 20,31,$+8\;.long %0-$"
10629 [(set_attr "type" "branch")
10630 (set_attr "length" "8")])
10632 (define_insn "load_toc_v4_PIC_1b_476"
10633 [(set (reg:SI LR_REGNO)
10634 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10635 (label_ref (match_operand 1 "" ""))]
10638 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10642 static char templ[32];
10644 get_ppc476_thunk_name (name);
10645 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10648 [(set_attr "type" "branch")
10649 (set_attr "length" "16")])
10651 (define_insn "load_toc_v4_PIC_2"
10652 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10653 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10654 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10655 (match_operand:SI 3 "immediate_operand" "s")))))]
10656 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10658 [(set_attr "type" "load")])
10660 (define_insn "load_toc_v4_PIC_3b"
10661 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10662 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10664 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10665 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10666 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10667 "addis %0,%1,%2-%3@ha")
10669 (define_insn "load_toc_v4_PIC_3c"
10670 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10671 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10672 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10673 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10674 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10675 "addi %0,%1,%2-%3@l")
10677 ;; If the TOC is shared over a translation unit, as happens with all
10678 ;; the kinds of PIC that we support, we need to restore the TOC
10679 ;; pointer only when jumping over units of translation.
10680 ;; On Darwin, we need to reload the picbase.
10682 (define_expand "builtin_setjmp_receiver"
10683 [(use (label_ref (match_operand 0 "" "")))]
10684 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10685 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10686 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10690 if (DEFAULT_ABI == ABI_DARWIN)
10692 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10693 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10697 crtl->uses_pic_offset_table = 1;
10698 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10699 CODE_LABEL_NUMBER (operands[0]));
10700 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10702 emit_insn (gen_load_macho_picbase (tmplabrtx));
10703 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10704 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10708 rs6000_emit_load_toc_table (FALSE);
10712 ;; Largetoc support
10713 (define_insn "*largetoc_high"
10714 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10716 (unspec [(match_operand:DI 1 "" "")
10717 (match_operand:DI 2 "gpc_reg_operand" "b")]
10719 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10720 "addis %0,%2,%1@toc@ha")
10722 (define_insn "*largetoc_high_aix<mode>"
10723 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10725 (unspec [(match_operand:P 1 "" "")
10726 (match_operand:P 2 "gpc_reg_operand" "b")]
10728 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10729 "addis %0,%1@u(%2)")
10731 (define_insn "*largetoc_high_plus"
10732 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10735 (unspec [(match_operand:DI 1 "" "")
10736 (match_operand:DI 2 "gpc_reg_operand" "b")]
10738 (match_operand:DI 3 "add_cint_operand" "n"))))]
10739 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10740 "addis %0,%2,%1+%3@toc@ha")
10742 (define_insn "*largetoc_high_plus_aix<mode>"
10743 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10746 (unspec [(match_operand:P 1 "" "")
10747 (match_operand:P 2 "gpc_reg_operand" "b")]
10749 (match_operand:P 3 "add_cint_operand" "n"))))]
10750 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10751 "addis %0,%1+%3@u(%2)")
10753 (define_insn "*largetoc_low"
10754 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10755 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10756 (match_operand:DI 2 "" "")))]
10757 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10760 (define_insn "*largetoc_low_aix<mode>"
10761 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10762 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10763 (match_operand:P 2 "" "")))]
10764 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10767 (define_insn_and_split "*tocref<mode>"
10768 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10769 (match_operand:P 1 "small_toc_ref" "R"))]
10772 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10773 [(set (match_dup 0) (high:P (match_dup 1)))
10774 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10776 ;; Elf specific ways of loading addresses for non-PIC code.
10777 ;; The output of this could be r0, but we make a very strong
10778 ;; preference for a base register because it will usually
10779 ;; be needed there.
10780 (define_insn "elf_high"
10781 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10782 (high:SI (match_operand 1 "" "")))]
10783 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10786 (define_insn "elf_low"
10787 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10788 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10789 (match_operand 2 "" "")))]
10790 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10793 ;; Call and call_value insns
10794 (define_expand "call"
10795 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10796 (match_operand 1 "" ""))
10797 (use (match_operand 2 "" ""))
10798 (clobber (reg:SI LR_REGNO))])]
10803 if (MACHOPIC_INDIRECT)
10804 operands[0] = machopic_indirect_call_target (operands[0]);
10807 gcc_assert (GET_CODE (operands[0]) == MEM);
10808 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10810 operands[0] = XEXP (operands[0], 0);
10812 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10814 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10818 if (GET_CODE (operands[0]) != SYMBOL_REF
10819 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10821 if (INTVAL (operands[2]) & CALL_LONG)
10822 operands[0] = rs6000_longcall_ref (operands[0]);
10824 switch (DEFAULT_ABI)
10828 operands[0] = force_reg (Pmode, operands[0]);
10832 gcc_unreachable ();
10837 (define_expand "call_value"
10838 [(parallel [(set (match_operand 0 "" "")
10839 (call (mem:SI (match_operand 1 "address_operand" ""))
10840 (match_operand 2 "" "")))
10841 (use (match_operand 3 "" ""))
10842 (clobber (reg:SI LR_REGNO))])]
10847 if (MACHOPIC_INDIRECT)
10848 operands[1] = machopic_indirect_call_target (operands[1]);
10851 gcc_assert (GET_CODE (operands[1]) == MEM);
10852 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10854 operands[1] = XEXP (operands[1], 0);
10856 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10858 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10862 if (GET_CODE (operands[1]) != SYMBOL_REF
10863 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10865 if (INTVAL (operands[3]) & CALL_LONG)
10866 operands[1] = rs6000_longcall_ref (operands[1]);
10868 switch (DEFAULT_ABI)
10872 operands[1] = force_reg (Pmode, operands[1]);
10876 gcc_unreachable ();
10881 ;; Call to function in current module. No TOC pointer reload needed.
10882 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10883 ;; either the function was not prototyped, or it was prototyped as a
10884 ;; variable argument function. It is > 0 if FP registers were passed
10885 ;; and < 0 if they were not.
10887 (define_insn "*call_local32"
10888 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10889 (match_operand 1 "" "g,g"))
10890 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10891 (clobber (reg:SI LR_REGNO))]
10892 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10895 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10896 output_asm_insn (\"crxor 6,6,6\", operands);
10898 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10899 output_asm_insn (\"creqv 6,6,6\", operands);
10901 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10903 [(set_attr "type" "branch")
10904 (set_attr "length" "4,8")])
10906 (define_insn "*call_local64"
10907 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10908 (match_operand 1 "" "g,g"))
10909 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10910 (clobber (reg:SI LR_REGNO))]
10911 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10914 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10915 output_asm_insn (\"crxor 6,6,6\", operands);
10917 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10918 output_asm_insn (\"creqv 6,6,6\", operands);
10920 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10922 [(set_attr "type" "branch")
10923 (set_attr "length" "4,8")])
10925 (define_insn "*call_value_local32"
10926 [(set (match_operand 0 "" "")
10927 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10928 (match_operand 2 "" "g,g")))
10929 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10930 (clobber (reg:SI LR_REGNO))]
10931 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10934 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10935 output_asm_insn (\"crxor 6,6,6\", operands);
10937 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10938 output_asm_insn (\"creqv 6,6,6\", operands);
10940 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10942 [(set_attr "type" "branch")
10943 (set_attr "length" "4,8")])
10946 (define_insn "*call_value_local64"
10947 [(set (match_operand 0 "" "")
10948 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10949 (match_operand 2 "" "g,g")))
10950 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10951 (clobber (reg:SI LR_REGNO))]
10952 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10955 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10956 output_asm_insn (\"crxor 6,6,6\", operands);
10958 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10959 output_asm_insn (\"creqv 6,6,6\", operands);
10961 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10963 [(set_attr "type" "branch")
10964 (set_attr "length" "4,8")])
10967 ;; A function pointer under System V is just a normal pointer
10968 ;; operands[0] is the function pointer
10969 ;; operands[1] is the stack size to clean up
10970 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10971 ;; which indicates how to set cr1
10973 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10974 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10975 (match_operand 1 "" "g,g,g,g"))
10976 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10977 (clobber (reg:SI LR_REGNO))]
10978 "DEFAULT_ABI == ABI_V4
10979 || DEFAULT_ABI == ABI_DARWIN"
10981 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10982 output_asm_insn ("crxor 6,6,6", operands);
10984 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10985 output_asm_insn ("creqv 6,6,6", operands);
10989 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10990 (set_attr "length" "4,4,8,8")])
10992 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10993 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10994 (match_operand 1 "" "g,g"))
10995 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10996 (clobber (reg:SI LR_REGNO))]
10997 "(DEFAULT_ABI == ABI_DARWIN
10998 || (DEFAULT_ABI == ABI_V4
10999 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
11001 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11002 output_asm_insn ("crxor 6,6,6", operands);
11004 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11005 output_asm_insn ("creqv 6,6,6", operands);
11008 return output_call(insn, operands, 0, 2);
11010 if (DEFAULT_ABI == ABI_V4 && flag_pic)
11012 gcc_assert (!TARGET_SECURE_PLT);
11013 return "bl %z0@plt";
11019 "DEFAULT_ABI == ABI_V4
11020 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11021 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11022 [(parallel [(call (mem:SI (match_dup 0))
11024 (use (match_dup 2))
11025 (use (match_dup 3))
11026 (clobber (reg:SI LR_REGNO))])]
11028 operands[3] = pic_offset_table_rtx;
11030 [(set_attr "type" "branch,branch")
11031 (set_attr "length" "4,8")])
11033 (define_insn "*call_nonlocal_sysv_secure<mode>"
11034 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11035 (match_operand 1 "" "g,g"))
11036 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11037 (use (match_operand:SI 3 "register_operand" "r,r"))
11038 (clobber (reg:SI LR_REGNO))]
11039 "(DEFAULT_ABI == ABI_V4
11040 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11041 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11043 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11044 output_asm_insn ("crxor 6,6,6", operands);
11046 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11047 output_asm_insn ("creqv 6,6,6", operands);
11050 /* The magic 32768 offset here and in the other sysv call insns
11051 corresponds to the offset of r30 in .got2, as given by LCTOC1.
11052 See sysv4.h:toc_section. */
11053 return "bl %z0+32768@plt";
11055 return "bl %z0@plt";
11057 [(set_attr "type" "branch,branch")
11058 (set_attr "length" "4,8")])
11060 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11061 [(set (match_operand 0 "" "")
11062 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11063 (match_operand 2 "" "g,g,g,g")))
11064 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11065 (clobber (reg:SI LR_REGNO))]
11066 "DEFAULT_ABI == ABI_V4
11067 || DEFAULT_ABI == ABI_DARWIN"
11069 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11070 output_asm_insn ("crxor 6,6,6", operands);
11072 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11073 output_asm_insn ("creqv 6,6,6", operands);
11077 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11078 (set_attr "length" "4,4,8,8")])
11080 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11081 [(set (match_operand 0 "" "")
11082 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11083 (match_operand 2 "" "g,g")))
11084 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11085 (clobber (reg:SI LR_REGNO))]
11086 "(DEFAULT_ABI == ABI_DARWIN
11087 || (DEFAULT_ABI == ABI_V4
11088 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11090 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11091 output_asm_insn ("crxor 6,6,6", operands);
11093 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11094 output_asm_insn ("creqv 6,6,6", operands);
11097 return output_call(insn, operands, 1, 3);
11099 if (DEFAULT_ABI == ABI_V4 && flag_pic)
11101 gcc_assert (!TARGET_SECURE_PLT);
11102 return "bl %z1@plt";
11108 "DEFAULT_ABI == ABI_V4
11109 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11110 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11111 [(parallel [(set (match_dup 0)
11112 (call (mem:SI (match_dup 1))
11114 (use (match_dup 3))
11115 (use (match_dup 4))
11116 (clobber (reg:SI LR_REGNO))])]
11118 operands[4] = pic_offset_table_rtx;
11120 [(set_attr "type" "branch,branch")
11121 (set_attr "length" "4,8")])
11123 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11124 [(set (match_operand 0 "" "")
11125 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11126 (match_operand 2 "" "g,g")))
11127 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11128 (use (match_operand:SI 4 "register_operand" "r,r"))
11129 (clobber (reg:SI LR_REGNO))]
11130 "(DEFAULT_ABI == ABI_V4
11131 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11132 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11134 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11135 output_asm_insn ("crxor 6,6,6", operands);
11137 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11138 output_asm_insn ("creqv 6,6,6", operands);
11141 return "bl %z1+32768@plt";
11143 return "bl %z1@plt";
11145 [(set_attr "type" "branch,branch")
11146 (set_attr "length" "4,8")])
11149 ;; Call to AIX abi function in the same module.
11151 (define_insn "*call_local_aix<mode>"
11152 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11153 (match_operand 1 "" "g"))
11154 (clobber (reg:P LR_REGNO))]
11155 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11157 [(set_attr "type" "branch")
11158 (set_attr "length" "4")])
11160 (define_insn "*call_value_local_aix<mode>"
11161 [(set (match_operand 0 "" "")
11162 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11163 (match_operand 2 "" "g")))
11164 (clobber (reg:P LR_REGNO))]
11165 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11167 [(set_attr "type" "branch")
11168 (set_attr "length" "4")])
11170 ;; Call to AIX abi function which may be in another module.
11171 ;; Restore the TOC pointer (r2) after the call.
11173 (define_insn "*call_nonlocal_aix<mode>"
11174 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11175 (match_operand 1 "" "g"))
11176 (clobber (reg:P LR_REGNO))]
11177 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11179 [(set_attr "type" "branch")
11180 (set_attr "length" "8")])
11182 (define_insn "*call_value_nonlocal_aix<mode>"
11183 [(set (match_operand 0 "" "")
11184 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11185 (match_operand 2 "" "g")))
11186 (clobber (reg:P LR_REGNO))]
11187 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11189 [(set_attr "type" "branch")
11190 (set_attr "length" "8")])
11192 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11193 ;; Operand0 is the addresss of the function to call
11194 ;; Operand2 is the location in the function descriptor to load r2 from
11195 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11197 (define_insn "*call_indirect_aix<mode>"
11198 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11199 (match_operand 1 "" "g,g"))
11200 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11201 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11202 (clobber (reg:P LR_REGNO))]
11203 "DEFAULT_ABI == ABI_AIX"
11204 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11205 [(set_attr "type" "jmpreg")
11206 (set_attr "length" "12")])
11208 (define_insn "*call_value_indirect_aix<mode>"
11209 [(set (match_operand 0 "" "")
11210 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11211 (match_operand 2 "" "g,g")))
11212 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11213 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11214 (clobber (reg:P LR_REGNO))]
11215 "DEFAULT_ABI == ABI_AIX"
11216 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11217 [(set_attr "type" "jmpreg")
11218 (set_attr "length" "12")])
11220 ;; Call to indirect functions with the ELFv2 ABI.
11221 ;; Operand0 is the addresss of the function to call
11222 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11224 (define_insn "*call_indirect_elfv2<mode>"
11225 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11226 (match_operand 1 "" "g,g"))
11227 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11228 (clobber (reg:P LR_REGNO))]
11229 "DEFAULT_ABI == ABI_ELFv2"
11230 "b%T0l\;<ptrload> 2,%2(1)"
11231 [(set_attr "type" "jmpreg")
11232 (set_attr "length" "8")])
11234 (define_insn "*call_value_indirect_elfv2<mode>"
11235 [(set (match_operand 0 "" "")
11236 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11237 (match_operand 2 "" "g,g")))
11238 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11239 (clobber (reg:P LR_REGNO))]
11240 "DEFAULT_ABI == ABI_ELFv2"
11241 "b%T1l\;<ptrload> 2,%3(1)"
11242 [(set_attr "type" "jmpreg")
11243 (set_attr "length" "8")])
11246 ;; Call subroutine returning any type.
11247 (define_expand "untyped_call"
11248 [(parallel [(call (match_operand 0 "" "")
11250 (match_operand 1 "" "")
11251 (match_operand 2 "" "")])]
11257 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11259 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11261 rtx set = XVECEXP (operands[2], 0, i);
11262 emit_move_insn (SET_DEST (set), SET_SRC (set));
11265 /* The optimizer does not know that the call sets the function value
11266 registers we stored in the result block. We avoid problems by
11267 claiming that all hard registers are used and clobbered at this
11269 emit_insn (gen_blockage ());
11274 ;; sibling call patterns
11275 (define_expand "sibcall"
11276 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11277 (match_operand 1 "" ""))
11278 (use (match_operand 2 "" ""))
11284 if (MACHOPIC_INDIRECT)
11285 operands[0] = machopic_indirect_call_target (operands[0]);
11288 gcc_assert (GET_CODE (operands[0]) == MEM);
11289 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11291 operands[0] = XEXP (operands[0], 0);
11293 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11295 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11300 (define_expand "sibcall_value"
11301 [(parallel [(set (match_operand 0 "register_operand" "")
11302 (call (mem:SI (match_operand 1 "address_operand" ""))
11303 (match_operand 2 "" "")))
11304 (use (match_operand 3 "" ""))
11310 if (MACHOPIC_INDIRECT)
11311 operands[1] = machopic_indirect_call_target (operands[1]);
11314 gcc_assert (GET_CODE (operands[1]) == MEM);
11315 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11317 operands[1] = XEXP (operands[1], 0);
11319 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11321 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11326 (define_insn "*sibcall_local32"
11327 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11328 (match_operand 1 "" "g,g"))
11329 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11331 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11334 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11335 output_asm_insn (\"crxor 6,6,6\", operands);
11337 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11338 output_asm_insn (\"creqv 6,6,6\", operands);
11340 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11342 [(set_attr "type" "branch")
11343 (set_attr "length" "4,8")])
11345 (define_insn "*sibcall_local64"
11346 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11347 (match_operand 1 "" "g,g"))
11348 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11350 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11353 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11354 output_asm_insn (\"crxor 6,6,6\", operands);
11356 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11357 output_asm_insn (\"creqv 6,6,6\", operands);
11359 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11361 [(set_attr "type" "branch")
11362 (set_attr "length" "4,8")])
11364 (define_insn "*sibcall_value_local32"
11365 [(set (match_operand 0 "" "")
11366 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11367 (match_operand 2 "" "g,g")))
11368 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11370 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11373 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11374 output_asm_insn (\"crxor 6,6,6\", operands);
11376 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11377 output_asm_insn (\"creqv 6,6,6\", operands);
11379 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11381 [(set_attr "type" "branch")
11382 (set_attr "length" "4,8")])
11384 (define_insn "*sibcall_value_local64"
11385 [(set (match_operand 0 "" "")
11386 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11387 (match_operand 2 "" "g,g")))
11388 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11390 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11393 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11394 output_asm_insn (\"crxor 6,6,6\", operands);
11396 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11397 output_asm_insn (\"creqv 6,6,6\", operands);
11399 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11401 [(set_attr "type" "branch")
11402 (set_attr "length" "4,8")])
11404 (define_insn "*sibcall_nonlocal_sysv<mode>"
11405 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11406 (match_operand 1 "" ""))
11407 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11409 "(DEFAULT_ABI == ABI_DARWIN
11410 || DEFAULT_ABI == ABI_V4)
11411 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11414 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11415 output_asm_insn (\"crxor 6,6,6\", operands);
11417 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11418 output_asm_insn (\"creqv 6,6,6\", operands);
11420 if (which_alternative >= 2)
11422 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11424 gcc_assert (!TARGET_SECURE_PLT);
11425 return \"b %z0@plt\";
11430 [(set_attr "type" "branch")
11431 (set_attr "length" "4,8,4,8")])
11433 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11434 [(set (match_operand 0 "" "")
11435 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11436 (match_operand 2 "" "")))
11437 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11439 "(DEFAULT_ABI == ABI_DARWIN
11440 || DEFAULT_ABI == ABI_V4)
11441 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11444 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11445 output_asm_insn (\"crxor 6,6,6\", operands);
11447 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11448 output_asm_insn (\"creqv 6,6,6\", operands);
11450 if (which_alternative >= 2)
11452 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11454 gcc_assert (!TARGET_SECURE_PLT);
11455 return \"b %z1@plt\";
11460 [(set_attr "type" "branch")
11461 (set_attr "length" "4,8,4,8")])
11463 ;; AIX ABI sibling call patterns.
11465 (define_insn "*sibcall_aix<mode>"
11466 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11467 (match_operand 1 "" "g,g"))
11469 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11473 [(set_attr "type" "branch")
11474 (set_attr "length" "4")])
11476 (define_insn "*sibcall_value_aix<mode>"
11477 [(set (match_operand 0 "" "")
11478 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11479 (match_operand 2 "" "g,g")))
11481 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11485 [(set_attr "type" "branch")
11486 (set_attr "length" "4")])
11488 (define_expand "sibcall_epilogue"
11489 [(use (const_int 0))]
11492 if (!TARGET_SCHED_PROLOG)
11493 emit_insn (gen_blockage ());
11494 rs6000_emit_epilogue (TRUE);
11498 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11499 ;; all of memory. This blocks insns from being moved across this point.
11501 (define_insn "blockage"
11502 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11506 (define_expand "probe_stack_address"
11507 [(use (match_operand 0 "address_operand"))]
11510 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11511 MEM_VOLATILE_P (operands[0]) = 1;
11514 emit_insn (gen_probe_stack_di (operands[0]));
11516 emit_insn (gen_probe_stack_si (operands[0]));
11520 (define_insn "probe_stack_<mode>"
11521 [(set (match_operand:P 0 "memory_operand" "=m")
11522 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11525 operands[1] = gen_rtx_REG (Pmode, 0);
11526 return "st<wd>%U0%X0 %1,%0";
11528 [(set_attr "type" "store")
11529 (set (attr "update")
11530 (if_then_else (match_operand 0 "update_address_mem")
11531 (const_string "yes")
11532 (const_string "no")))
11533 (set (attr "indexed")
11534 (if_then_else (match_operand 0 "indexed_address_mem")
11535 (const_string "yes")
11536 (const_string "no")))
11537 (set_attr "length" "4")])
11539 (define_insn "probe_stack_range<P:mode>"
11540 [(set (match_operand:P 0 "register_operand" "=r")
11541 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11542 (match_operand:P 2 "register_operand" "r")]
11543 UNSPECV_PROBE_STACK_RANGE))]
11545 "* return output_probe_stack_range (operands[0], operands[2]);"
11546 [(set_attr "type" "three")])
11548 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11549 ;; signed & unsigned, and one type of branch.
11551 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11552 ;; insns, and branches.
11554 (define_expand "cbranch<mode>4"
11555 [(use (match_operator 0 "rs6000_cbranch_operator"
11556 [(match_operand:GPR 1 "gpc_reg_operand" "")
11557 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11558 (use (match_operand 3 ""))]
11562 /* Take care of the possibility that operands[2] might be negative but
11563 this might be a logical operation. That insn doesn't exist. */
11564 if (GET_CODE (operands[2]) == CONST_INT
11565 && INTVAL (operands[2]) < 0)
11567 operands[2] = force_reg (<MODE>mode, operands[2]);
11568 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11569 GET_MODE (operands[0]),
11570 operands[1], operands[2]);
11573 rs6000_emit_cbranch (<MODE>mode, operands);
11577 (define_expand "cbranch<mode>4"
11578 [(use (match_operator 0 "rs6000_cbranch_operator"
11579 [(match_operand:FP 1 "gpc_reg_operand" "")
11580 (match_operand:FP 2 "gpc_reg_operand" "")]))
11581 (use (match_operand 3 ""))]
11585 rs6000_emit_cbranch (<MODE>mode, operands);
11589 (define_expand "cstore<mode>4_signed"
11590 [(use (match_operator 1 "signed_comparison_operator"
11591 [(match_operand:P 2 "gpc_reg_operand")
11592 (match_operand:P 3 "gpc_reg_operand")]))
11593 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11596 enum rtx_code cond_code = GET_CODE (operands[1]);
11598 rtx op0 = operands[0];
11599 rtx op1 = operands[2];
11600 rtx op2 = operands[3];
11602 if (cond_code == GE || cond_code == LT)
11604 cond_code = swap_condition (cond_code);
11605 std::swap (op1, op2);
11608 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11609 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11610 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11612 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11613 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11614 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11616 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11618 if (cond_code == LE)
11619 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11622 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11623 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11624 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11630 (define_expand "cstore<mode>4_unsigned"
11631 [(use (match_operator 1 "unsigned_comparison_operator"
11632 [(match_operand:P 2 "gpc_reg_operand")
11633 (match_operand:P 3 "reg_or_short_operand")]))
11634 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11637 enum rtx_code cond_code = GET_CODE (operands[1]);
11639 rtx op0 = operands[0];
11640 rtx op1 = operands[2];
11641 rtx op2 = operands[3];
11643 if (cond_code == GEU || cond_code == LTU)
11645 cond_code = swap_condition (cond_code);
11646 std::swap (op1, op2);
11649 if (!gpc_reg_operand (op1, <MODE>mode))
11650 op1 = force_reg (<MODE>mode, op1);
11651 if (!reg_or_short_operand (op2, <MODE>mode))
11652 op2 = force_reg (<MODE>mode, op2);
11654 rtx tmp = gen_reg_rtx (<MODE>mode);
11655 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11657 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11658 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11660 if (cond_code == LEU)
11661 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11663 emit_insn (gen_neg<mode>2 (op0, tmp2));
11668 (define_expand "cstore_si_as_di"
11669 [(use (match_operator 1 "unsigned_comparison_operator"
11670 [(match_operand:SI 2 "gpc_reg_operand")
11671 (match_operand:SI 3 "reg_or_short_operand")]))
11672 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11675 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11676 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11678 operands[2] = force_reg (SImode, operands[2]);
11679 operands[3] = force_reg (SImode, operands[3]);
11680 rtx op1 = gen_reg_rtx (DImode);
11681 rtx op2 = gen_reg_rtx (DImode);
11682 convert_move (op1, operands[2], uns_flag);
11683 convert_move (op2, operands[3], uns_flag);
11685 if (cond_code == GT || cond_code == LE)
11687 cond_code = swap_condition (cond_code);
11688 std::swap (op1, op2);
11691 rtx tmp = gen_reg_rtx (DImode);
11692 rtx tmp2 = gen_reg_rtx (DImode);
11693 emit_insn (gen_subdi3 (tmp, op1, op2));
11694 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11700 gcc_unreachable ();
11705 tmp3 = gen_reg_rtx (DImode);
11706 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11710 convert_move (operands[0], tmp3, 1);
11715 (define_expand "cstore<mode>4_signed_imm"
11716 [(use (match_operator 1 "signed_comparison_operator"
11717 [(match_operand:GPR 2 "gpc_reg_operand")
11718 (match_operand:GPR 3 "immediate_operand")]))
11719 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11722 bool invert = false;
11724 enum rtx_code cond_code = GET_CODE (operands[1]);
11726 rtx op0 = operands[0];
11727 rtx op1 = operands[2];
11728 HOST_WIDE_INT val = INTVAL (operands[3]);
11730 if (cond_code == GE || cond_code == GT)
11732 cond_code = reverse_condition (cond_code);
11736 if (cond_code == LE)
11739 rtx tmp = gen_reg_rtx (<MODE>mode);
11740 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11741 rtx x = gen_reg_rtx (<MODE>mode);
11743 emit_insn (gen_and<mode>3 (x, op1, tmp));
11745 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11749 rtx tmp = gen_reg_rtx (<MODE>mode);
11750 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11754 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11755 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11760 (define_expand "cstore<mode>4_unsigned_imm"
11761 [(use (match_operator 1 "unsigned_comparison_operator"
11762 [(match_operand:GPR 2 "gpc_reg_operand")
11763 (match_operand:GPR 3 "immediate_operand")]))
11764 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11767 bool invert = false;
11769 enum rtx_code cond_code = GET_CODE (operands[1]);
11771 rtx op0 = operands[0];
11772 rtx op1 = operands[2];
11773 HOST_WIDE_INT val = INTVAL (operands[3]);
11775 if (cond_code == GEU || cond_code == GTU)
11777 cond_code = reverse_condition (cond_code);
11781 if (cond_code == LEU)
11784 rtx tmp = gen_reg_rtx (<MODE>mode);
11785 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11786 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11787 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11788 rtx x = gen_reg_rtx (<MODE>mode);
11790 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11792 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11796 rtx tmp = gen_reg_rtx (<MODE>mode);
11797 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11801 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11802 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11807 (define_expand "cstore<mode>4"
11808 [(use (match_operator 1 "rs6000_cbranch_operator"
11809 [(match_operand:GPR 2 "gpc_reg_operand")
11810 (match_operand:GPR 3 "reg_or_short_operand")]))
11811 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11814 /* Use ISEL if the user asked for it. */
11816 rs6000_emit_sISEL (<MODE>mode, operands);
11818 /* Expanding EQ and NE directly to some machine instructions does not help
11819 but does hurt combine. So don't. */
11820 else if (GET_CODE (operands[1]) == EQ)
11821 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11822 else if (<MODE>mode == Pmode
11823 && GET_CODE (operands[1]) == NE)
11824 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11825 else if (GET_CODE (operands[1]) == NE)
11827 rtx tmp = gen_reg_rtx (<MODE>mode);
11828 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11829 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11832 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11833 etc. combinations magically work out just right. */
11834 else if (<MODE>mode == Pmode
11835 && unsigned_comparison_operator (operands[1], VOIDmode))
11836 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11837 operands[2], operands[3]));
11839 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11840 else if (<MODE>mode == SImode && Pmode == DImode)
11841 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11842 operands[2], operands[3]));
11844 /* For signed comparisons against a constant, we can do some simple
11846 else if (signed_comparison_operator (operands[1], VOIDmode)
11847 && CONST_INT_P (operands[3]))
11848 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11849 operands[2], operands[3]));
11851 /* And similarly for unsigned comparisons. */
11852 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11853 && CONST_INT_P (operands[3]))
11854 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11855 operands[2], operands[3]));
11857 /* We also do not want to use mfcr for signed comparisons. */
11858 else if (<MODE>mode == Pmode
11859 && signed_comparison_operator (operands[1], VOIDmode))
11860 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11861 operands[2], operands[3]));
11863 /* Everything else, use the mfcr brute force. */
11865 rs6000_emit_sCOND (<MODE>mode, operands);
11870 (define_expand "cstore<mode>4"
11871 [(use (match_operator 1 "rs6000_cbranch_operator"
11872 [(match_operand:FP 2 "gpc_reg_operand")
11873 (match_operand:FP 3 "gpc_reg_operand")]))
11874 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11877 rs6000_emit_sCOND (<MODE>mode, operands);
11882 (define_expand "stack_protect_set"
11883 [(match_operand 0 "memory_operand")
11884 (match_operand 1 "memory_operand")]
11887 if (rs6000_stack_protector_guard == SSP_TLS)
11889 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11890 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11891 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11892 operands[1] = gen_rtx_MEM (Pmode, addr);
11896 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11898 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11903 (define_insn "stack_protect_setsi"
11904 [(set (match_operand:SI 0 "memory_operand" "=m")
11905 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11906 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11908 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11909 [(set_attr "type" "three")
11910 (set_attr "length" "12")])
11912 (define_insn "stack_protect_setdi"
11913 [(set (match_operand:DI 0 "memory_operand" "=Y")
11914 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11915 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11917 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11918 [(set_attr "type" "three")
11919 (set_attr "length" "12")])
11921 (define_expand "stack_protect_test"
11922 [(match_operand 0 "memory_operand")
11923 (match_operand 1 "memory_operand")
11924 (match_operand 2 "")]
11927 rtx guard = operands[1];
11929 if (rs6000_stack_protector_guard == SSP_TLS)
11931 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11932 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11933 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11934 guard = gen_rtx_MEM (Pmode, addr);
11937 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11938 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11939 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11940 emit_jump_insn (jump);
11945 (define_insn "stack_protect_testsi"
11946 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11947 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11948 (match_operand:SI 2 "memory_operand" "m,m")]
11950 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11951 (clobber (match_scratch:SI 3 "=&r,&r"))]
11954 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11955 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11956 [(set_attr "length" "16,20")])
11958 (define_insn "stack_protect_testdi"
11959 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11960 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11961 (match_operand:DI 2 "memory_operand" "Y,Y")]
11963 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11964 (clobber (match_scratch:DI 3 "=&r,&r"))]
11967 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11968 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11969 [(set_attr "length" "16,20")])
11972 ;; Here are the actual compare insns.
11973 (define_insn "*cmp<mode>_signed"
11974 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11975 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11976 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11978 "cmp<wd>%I2 %0,%1,%2"
11979 [(set_attr "type" "cmp")])
11981 (define_insn "*cmp<mode>_unsigned"
11982 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11983 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11984 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11986 "cmpl<wd>%I2 %0,%1,%2"
11987 [(set_attr "type" "cmp")])
11989 ;; If we are comparing a register for equality with a large constant,
11990 ;; we can do this with an XOR followed by a compare. But this is profitable
11991 ;; only if the large constant is only used for the comparison (and in this
11992 ;; case we already have a register to reuse as scratch).
11994 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11995 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11998 [(set (match_operand:SI 0 "register_operand")
11999 (match_operand:SI 1 "logical_const_operand" ""))
12000 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
12002 (match_operand:SI 2 "logical_const_operand" "")]))
12003 (set (match_operand:CC 4 "cc_reg_operand" "")
12004 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
12007 (if_then_else (match_operator 6 "equality_operator"
12008 [(match_dup 4) (const_int 0)])
12009 (match_operand 7 "" "")
12010 (match_operand 8 "" "")))]
12011 "peep2_reg_dead_p (3, operands[0])
12012 && peep2_reg_dead_p (4, operands[4])
12013 && REGNO (operands[0]) != REGNO (operands[5])"
12014 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12015 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12016 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12019 /* Get the constant we are comparing against, and see what it looks like
12020 when sign-extended from 16 to 32 bits. Then see what constant we could
12021 XOR with SEXTC to get the sign-extended value. */
12022 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12024 operands[1], operands[2]);
12025 HOST_WIDE_INT c = INTVAL (cnst);
12026 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
12027 HOST_WIDE_INT xorv = c ^ sextc;
12029 operands[9] = GEN_INT (xorv);
12030 operands[10] = GEN_INT (sextc);
12033 ;; The following two insns don't exist as single insns, but if we provide
12034 ;; them, we can swap an add and compare, which will enable us to overlap more
12035 ;; of the required delay between a compare and branch. We generate code for
12036 ;; them by splitting.
12039 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12040 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
12041 (match_operand:SI 2 "short_cint_operand" "i")))
12042 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12043 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12046 [(set_attr "length" "8")])
12049 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
12050 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
12051 (match_operand:SI 2 "u_short_cint_operand" "i")))
12052 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12053 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12056 [(set_attr "length" "8")])
12059 [(set (match_operand:CC 3 "cc_reg_operand" "")
12060 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
12061 (match_operand:SI 2 "short_cint_operand" "")))
12062 (set (match_operand:SI 0 "gpc_reg_operand" "")
12063 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12065 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
12066 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12069 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
12070 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
12071 (match_operand:SI 2 "u_short_cint_operand" "")))
12072 (set (match_operand:SI 0 "gpc_reg_operand" "")
12073 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12075 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
12076 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12078 ;; Only need to compare second words if first words equal
12079 (define_insn "*cmp<mode>_internal1"
12080 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12081 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12082 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12083 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12084 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12085 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12086 [(set_attr "type" "fpcompare")
12087 (set_attr "length" "12")])
12089 (define_insn_and_split "*cmp<mode>_internal2"
12090 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12091 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12092 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12093 (clobber (match_scratch:DF 3 "=d"))
12094 (clobber (match_scratch:DF 4 "=d"))
12095 (clobber (match_scratch:DF 5 "=d"))
12096 (clobber (match_scratch:DF 6 "=d"))
12097 (clobber (match_scratch:DF 7 "=d"))
12098 (clobber (match_scratch:DF 8 "=d"))
12099 (clobber (match_scratch:DF 9 "=d"))
12100 (clobber (match_scratch:DF 10 "=d"))
12101 (clobber (match_scratch:GPR 11 "=b"))]
12102 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12103 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12105 "&& reload_completed"
12106 [(set (match_dup 3) (match_dup 14))
12107 (set (match_dup 4) (match_dup 15))
12108 (set (match_dup 9) (abs:DF (match_dup 5)))
12109 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12110 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12111 (label_ref (match_dup 12))
12113 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12114 (set (pc) (label_ref (match_dup 13)))
12116 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12117 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12118 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12119 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12122 REAL_VALUE_TYPE rv;
12123 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12124 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12126 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12127 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12128 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12129 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12130 operands[12] = gen_label_rtx ();
12131 operands[13] = gen_label_rtx ();
12133 operands[14] = force_const_mem (DFmode,
12134 const_double_from_real_value (rv, DFmode));
12135 operands[15] = force_const_mem (DFmode,
12136 const_double_from_real_value (dconst0,
12141 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12142 operands[14] = gen_const_mem (DFmode, tocref);
12143 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12144 operands[15] = gen_const_mem (DFmode, tocref);
12145 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12146 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12150 ;; Now we have the scc insns. We can do some combinations because of the
12151 ;; way the machine works.
12153 ;; Note that this is probably faster if we can put an insn between the
12154 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12155 ;; cases the insns below which don't use an intermediate CR field will
12156 ;; be used instead.
12158 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12159 (match_operator:SI 1 "scc_comparison_operator"
12160 [(match_operand 2 "cc_reg_operand" "y")
12163 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12164 [(set (attr "type")
12165 (cond [(match_test "TARGET_MFCRF")
12166 (const_string "mfcrf")
12168 (const_string "mfcr")))
12169 (set_attr "length" "8")])
12171 ;; Same as above, but get the GT bit.
12172 (define_insn "move_from_CR_gt_bit"
12173 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12174 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
12175 "TARGET_HARD_FLOAT && !TARGET_FPRS"
12176 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
12177 [(set_attr "type" "mfcr")
12178 (set_attr "length" "8")])
12180 ;; Same as above, but get the OV/ORDERED bit.
12181 (define_insn "move_from_CR_ov_bit"
12182 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12183 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12186 "mfcr %0\;rlwinm %0,%0,%t1,1"
12187 [(set_attr "type" "mfcr")
12188 (set_attr "length" "8")])
12191 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12192 (match_operator:DI 1 "scc_comparison_operator"
12193 [(match_operand 2 "cc_reg_operand" "y")
12196 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12197 [(set (attr "type")
12198 (cond [(match_test "TARGET_MFCRF")
12199 (const_string "mfcrf")
12201 (const_string "mfcr")))
12202 (set_attr "length" "8")])
12205 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12206 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12207 [(match_operand 2 "cc_reg_operand" "y,y")
12210 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12211 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12214 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12216 [(set_attr "type" "shift")
12217 (set_attr "dot" "yes")
12218 (set_attr "length" "8,16")])
12221 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12222 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12223 [(match_operand 2 "cc_reg_operand" "")
12226 (set (match_operand:SI 3 "gpc_reg_operand" "")
12227 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12228 "TARGET_32BIT && reload_completed"
12229 [(set (match_dup 3)
12230 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12232 (compare:CC (match_dup 3)
12237 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12238 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12239 [(match_operand 2 "cc_reg_operand" "y")
12241 (match_operand:SI 3 "const_int_operand" "n")))]
12245 int is_bit = ccr_bit (operands[1], 1);
12246 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12249 if (is_bit >= put_bit)
12250 count = is_bit - put_bit;
12252 count = 32 - (put_bit - is_bit);
12254 operands[4] = GEN_INT (count);
12255 operands[5] = GEN_INT (put_bit);
12257 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12259 [(set (attr "type")
12260 (cond [(match_test "TARGET_MFCRF")
12261 (const_string "mfcrf")
12263 (const_string "mfcr")))
12264 (set_attr "length" "8")])
12267 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12269 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12270 [(match_operand 2 "cc_reg_operand" "y,y")
12272 (match_operand:SI 3 "const_int_operand" "n,n"))
12274 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12275 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12280 int is_bit = ccr_bit (operands[1], 1);
12281 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12284 /* Force split for non-cc0 compare. */
12285 if (which_alternative == 1)
12288 if (is_bit >= put_bit)
12289 count = is_bit - put_bit;
12291 count = 32 - (put_bit - is_bit);
12293 operands[5] = GEN_INT (count);
12294 operands[6] = GEN_INT (put_bit);
12296 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12298 [(set_attr "type" "shift")
12299 (set_attr "dot" "yes")
12300 (set_attr "length" "8,16")])
12303 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12305 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12306 [(match_operand 2 "cc_reg_operand" "")
12308 (match_operand:SI 3 "const_int_operand" ""))
12310 (set (match_operand:SI 4 "gpc_reg_operand" "")
12311 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12314 [(set (match_dup 4)
12315 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12318 (compare:CC (match_dup 4)
12323 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12326 (define_insn_and_split "eq<mode>3"
12327 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12328 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12329 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12330 (clobber (match_scratch:GPR 3 "=r"))
12331 (clobber (match_scratch:GPR 4 "=r"))]
12335 [(set (match_dup 4)
12336 (clz:GPR (match_dup 3)))
12338 (lshiftrt:GPR (match_dup 4)
12341 operands[3] = rs6000_emit_eqne (<MODE>mode,
12342 operands[1], operands[2], operands[3]);
12344 if (GET_CODE (operands[4]) == SCRATCH)
12345 operands[4] = gen_reg_rtx (<MODE>mode);
12347 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12349 [(set (attr "length")
12350 (if_then_else (match_test "operands[2] == const0_rtx")
12352 (const_string "12")))])
12354 (define_insn_and_split "ne<mode>3"
12355 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12356 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12357 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12358 (clobber (match_scratch:P 3 "=r"))
12359 (clobber (match_scratch:P 4 "=r"))
12360 (clobber (reg:P CA_REGNO))]
12364 [(parallel [(set (match_dup 4)
12365 (plus:P (match_dup 3)
12367 (set (reg:P CA_REGNO)
12368 (ne:P (match_dup 3)
12370 (parallel [(set (match_dup 0)
12371 (plus:P (plus:P (not:P (match_dup 4))
12374 (clobber (reg:P CA_REGNO))])]
12376 operands[3] = rs6000_emit_eqne (<MODE>mode,
12377 operands[1], operands[2], operands[3]);
12379 if (GET_CODE (operands[4]) == SCRATCH)
12380 operands[4] = gen_reg_rtx (<MODE>mode);
12382 [(set (attr "length")
12383 (if_then_else (match_test "operands[2] == const0_rtx")
12385 (const_string "12")))])
12387 (define_insn_and_split "*neg_eq_<mode>"
12388 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12389 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12390 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12391 (clobber (match_scratch:P 3 "=r"))
12392 (clobber (match_scratch:P 4 "=r"))
12393 (clobber (reg:P CA_REGNO))]
12397 [(parallel [(set (match_dup 4)
12398 (plus:P (match_dup 3)
12400 (set (reg:P CA_REGNO)
12401 (ne:P (match_dup 3)
12403 (parallel [(set (match_dup 0)
12404 (plus:P (reg:P CA_REGNO)
12406 (clobber (reg:P CA_REGNO))])]
12408 operands[3] = rs6000_emit_eqne (<MODE>mode,
12409 operands[1], operands[2], operands[3]);
12411 if (GET_CODE (operands[4]) == SCRATCH)
12412 operands[4] = gen_reg_rtx (<MODE>mode);
12414 [(set (attr "length")
12415 (if_then_else (match_test "operands[2] == const0_rtx")
12417 (const_string "12")))])
12419 (define_insn_and_split "*neg_ne_<mode>"
12420 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12421 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12422 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12423 (clobber (match_scratch:P 3 "=r"))
12424 (clobber (match_scratch:P 4 "=r"))
12425 (clobber (reg:P CA_REGNO))]
12429 [(parallel [(set (match_dup 4)
12430 (neg:P (match_dup 3)))
12431 (set (reg:P CA_REGNO)
12432 (eq:P (match_dup 3)
12434 (parallel [(set (match_dup 0)
12435 (plus:P (reg:P CA_REGNO)
12437 (clobber (reg:P CA_REGNO))])]
12439 operands[3] = rs6000_emit_eqne (<MODE>mode,
12440 operands[1], operands[2], operands[3]);
12442 if (GET_CODE (operands[4]) == SCRATCH)
12443 operands[4] = gen_reg_rtx (<MODE>mode);
12445 [(set (attr "length")
12446 (if_then_else (match_test "operands[2] == const0_rtx")
12448 (const_string "12")))])
12450 (define_insn_and_split "*plus_eq_<mode>"
12451 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12452 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12453 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12454 (match_operand:P 3 "gpc_reg_operand" "r")))
12455 (clobber (match_scratch:P 4 "=r"))
12456 (clobber (match_scratch:P 5 "=r"))
12457 (clobber (reg:P CA_REGNO))]
12461 [(parallel [(set (match_dup 5)
12462 (neg:P (match_dup 4)))
12463 (set (reg:P CA_REGNO)
12464 (eq:P (match_dup 4)
12466 (parallel [(set (match_dup 0)
12467 (plus:P (match_dup 3)
12469 (clobber (reg:P CA_REGNO))])]
12471 operands[4] = rs6000_emit_eqne (<MODE>mode,
12472 operands[1], operands[2], operands[4]);
12474 if (GET_CODE (operands[5]) == SCRATCH)
12475 operands[5] = gen_reg_rtx (<MODE>mode);
12477 [(set (attr "length")
12478 (if_then_else (match_test "operands[2] == const0_rtx")
12480 (const_string "12")))])
12482 (define_insn_and_split "*plus_ne_<mode>"
12483 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12484 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12485 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12486 (match_operand:P 3 "gpc_reg_operand" "r")))
12487 (clobber (match_scratch:P 4 "=r"))
12488 (clobber (match_scratch:P 5 "=r"))
12489 (clobber (reg:P CA_REGNO))]
12493 [(parallel [(set (match_dup 5)
12494 (plus:P (match_dup 4)
12496 (set (reg:P CA_REGNO)
12497 (ne:P (match_dup 4)
12499 (parallel [(set (match_dup 0)
12500 (plus:P (match_dup 3)
12502 (clobber (reg:P CA_REGNO))])]
12504 operands[4] = rs6000_emit_eqne (<MODE>mode,
12505 operands[1], operands[2], operands[4]);
12507 if (GET_CODE (operands[5]) == SCRATCH)
12508 operands[5] = gen_reg_rtx (<MODE>mode);
12510 [(set (attr "length")
12511 (if_then_else (match_test "operands[2] == const0_rtx")
12513 (const_string "12")))])
12515 (define_insn_and_split "*minus_eq_<mode>"
12516 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12517 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12518 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12519 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12520 (clobber (match_scratch:P 4 "=r"))
12521 (clobber (match_scratch:P 5 "=r"))
12522 (clobber (reg:P CA_REGNO))]
12526 [(parallel [(set (match_dup 5)
12527 (plus:P (match_dup 4)
12529 (set (reg:P CA_REGNO)
12530 (ne:P (match_dup 4)
12532 (parallel [(set (match_dup 0)
12533 (plus:P (plus:P (match_dup 3)
12536 (clobber (reg:P CA_REGNO))])]
12538 operands[4] = rs6000_emit_eqne (<MODE>mode,
12539 operands[1], operands[2], operands[4]);
12541 if (GET_CODE (operands[5]) == SCRATCH)
12542 operands[5] = gen_reg_rtx (<MODE>mode);
12544 [(set (attr "length")
12545 (if_then_else (match_test "operands[2] == const0_rtx")
12547 (const_string "12")))])
12549 (define_insn_and_split "*minus_ne_<mode>"
12550 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12551 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12552 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12553 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12554 (clobber (match_scratch:P 4 "=r"))
12555 (clobber (match_scratch:P 5 "=r"))
12556 (clobber (reg:P CA_REGNO))]
12560 [(parallel [(set (match_dup 5)
12561 (neg:P (match_dup 4)))
12562 (set (reg:P CA_REGNO)
12563 (eq:P (match_dup 4)
12565 (parallel [(set (match_dup 0)
12566 (plus:P (plus:P (match_dup 3)
12569 (clobber (reg:P CA_REGNO))])]
12571 operands[4] = rs6000_emit_eqne (<MODE>mode,
12572 operands[1], operands[2], operands[4]);
12574 if (GET_CODE (operands[5]) == SCRATCH)
12575 operands[5] = gen_reg_rtx (<MODE>mode);
12577 [(set (attr "length")
12578 (if_then_else (match_test "operands[2] == const0_rtx")
12580 (const_string "12")))])
12582 (define_insn_and_split "*eqsi3_ext<mode>"
12583 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12584 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12585 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12586 (clobber (match_scratch:SI 3 "=r"))
12587 (clobber (match_scratch:SI 4 "=r"))]
12591 [(set (match_dup 4)
12592 (clz:SI (match_dup 3)))
12595 (lshiftrt:SI (match_dup 4)
12598 operands[3] = rs6000_emit_eqne (SImode,
12599 operands[1], operands[2], operands[3]);
12601 if (GET_CODE (operands[4]) == SCRATCH)
12602 operands[4] = gen_reg_rtx (SImode);
12604 [(set (attr "length")
12605 (if_then_else (match_test "operands[2] == const0_rtx")
12607 (const_string "12")))])
12609 (define_insn_and_split "*nesi3_ext<mode>"
12610 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12611 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12612 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12613 (clobber (match_scratch:SI 3 "=r"))
12614 (clobber (match_scratch:SI 4 "=r"))
12615 (clobber (match_scratch:EXTSI 5 "=r"))]
12619 [(set (match_dup 4)
12620 (clz:SI (match_dup 3)))
12623 (lshiftrt:SI (match_dup 4)
12626 (xor:EXTSI (match_dup 5)
12629 operands[3] = rs6000_emit_eqne (SImode,
12630 operands[1], operands[2], operands[3]);
12632 if (GET_CODE (operands[4]) == SCRATCH)
12633 operands[4] = gen_reg_rtx (SImode);
12634 if (GET_CODE (operands[5]) == SCRATCH)
12635 operands[5] = gen_reg_rtx (<MODE>mode);
12637 [(set (attr "length")
12638 (if_then_else (match_test "operands[2] == const0_rtx")
12639 (const_string "12")
12640 (const_string "16")))])
12642 ;; Define both directions of branch and return. If we need a reload
12643 ;; register, we'd rather use CR0 since it is much easier to copy a
12644 ;; register CC value to there.
12648 (if_then_else (match_operator 1 "branch_comparison_operator"
12650 "cc_reg_operand" "y")
12652 (label_ref (match_operand 0 "" ""))
12657 return output_cbranch (operands[1], \"%l0\", 0, insn);
12659 [(set_attr "type" "branch")])
12663 (if_then_else (match_operator 0 "branch_comparison_operator"
12665 "cc_reg_operand" "y")
12672 return output_cbranch (operands[0], NULL, 0, insn);
12674 [(set_attr "type" "jmpreg")
12675 (set_attr "length" "4")])
12679 (if_then_else (match_operator 1 "branch_comparison_operator"
12681 "cc_reg_operand" "y")
12684 (label_ref (match_operand 0 "" ""))))]
12688 return output_cbranch (operands[1], \"%l0\", 1, insn);
12690 [(set_attr "type" "branch")])
12694 (if_then_else (match_operator 0 "branch_comparison_operator"
12696 "cc_reg_operand" "y")
12703 return output_cbranch (operands[0], NULL, 1, insn);
12705 [(set_attr "type" "jmpreg")
12706 (set_attr "length" "4")])
12708 ;; Logic on condition register values.
12710 ; This pattern matches things like
12711 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12712 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12714 ; which are generated by the branch logic.
12715 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12717 (define_insn "*cceq_ior_compare"
12718 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12719 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12720 [(match_operator:SI 2
12721 "branch_positive_comparison_operator"
12723 "cc_reg_operand" "y,y")
12725 (match_operator:SI 4
12726 "branch_positive_comparison_operator"
12728 "cc_reg_operand" "0,y")
12732 "cr%q1 %E0,%j2,%j4"
12733 [(set_attr "type" "cr_logical,delayed_cr")])
12735 ; Why is the constant -1 here, but 1 in the previous pattern?
12736 ; Because ~1 has all but the low bit set.
12738 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12739 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12740 [(not:SI (match_operator:SI 2
12741 "branch_positive_comparison_operator"
12743 "cc_reg_operand" "y,y")
12745 (match_operator:SI 4
12746 "branch_positive_comparison_operator"
12748 "cc_reg_operand" "0,y")
12752 "cr%q1 %E0,%j2,%j4"
12753 [(set_attr "type" "cr_logical,delayed_cr")])
12755 (define_insn "*cceq_rev_compare"
12756 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12757 (compare:CCEQ (match_operator:SI 1
12758 "branch_positive_comparison_operator"
12760 "cc_reg_operand" "0,y")
12765 [(set_attr "type" "cr_logical,delayed_cr")])
12767 ;; If we are comparing the result of two comparisons, this can be done
12768 ;; using creqv or crxor.
12770 (define_insn_and_split ""
12771 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12772 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12773 [(match_operand 2 "cc_reg_operand" "y")
12775 (match_operator 3 "branch_comparison_operator"
12776 [(match_operand 4 "cc_reg_operand" "y")
12781 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12785 int positive_1, positive_2;
12787 positive_1 = branch_positive_comparison_operator (operands[1],
12788 GET_MODE (operands[1]));
12789 positive_2 = branch_positive_comparison_operator (operands[3],
12790 GET_MODE (operands[3]));
12793 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12794 GET_CODE (operands[1])),
12796 operands[2], const0_rtx);
12797 else if (GET_MODE (operands[1]) != SImode)
12798 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12799 operands[2], const0_rtx);
12802 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12803 GET_CODE (operands[3])),
12805 operands[4], const0_rtx);
12806 else if (GET_MODE (operands[3]) != SImode)
12807 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12808 operands[4], const0_rtx);
12810 if (positive_1 == positive_2)
12812 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12813 operands[5] = constm1_rtx;
12817 operands[5] = const1_rtx;
12821 ;; Unconditional branch and return.
12823 (define_insn "jump"
12825 (label_ref (match_operand 0 "" "")))]
12828 [(set_attr "type" "branch")])
12830 (define_insn "<return_str>return"
12834 [(set_attr "type" "jmpreg")])
12836 (define_expand "indirect_jump"
12837 [(set (pc) (match_operand 0 "register_operand" ""))])
12839 (define_insn "*indirect_jump<mode>"
12840 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12845 [(set_attr "type" "jmpreg")])
12847 ;; Table jump for switch statements:
12848 (define_expand "tablejump"
12849 [(use (match_operand 0 "" ""))
12850 (use (label_ref (match_operand 1 "" "")))]
12855 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12857 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12861 (define_expand "tablejumpsi"
12862 [(set (match_dup 3)
12863 (plus:SI (match_operand:SI 0 "" "")
12865 (parallel [(set (pc) (match_dup 3))
12866 (use (label_ref (match_operand 1 "" "")))])]
12869 { operands[0] = force_reg (SImode, operands[0]);
12870 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12871 operands[3] = gen_reg_rtx (SImode);
12874 (define_expand "tablejumpdi"
12875 [(set (match_dup 4)
12876 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12878 (plus:DI (match_dup 4)
12880 (parallel [(set (pc) (match_dup 3))
12881 (use (label_ref (match_operand 1 "" "")))])]
12884 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12885 operands[3] = gen_reg_rtx (DImode);
12886 operands[4] = gen_reg_rtx (DImode);
12889 (define_insn "*tablejump<mode>_internal1"
12891 (match_operand:P 0 "register_operand" "c,*l"))
12892 (use (label_ref (match_operand 1 "" "")))]
12897 [(set_attr "type" "jmpreg")])
12900 [(unspec [(const_int 0)] UNSPEC_NOP)]
12904 (define_insn "group_ending_nop"
12905 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12909 if (rs6000_cpu_attr == CPU_POWER6)
12910 return \"ori 1,1,0\";
12911 return \"ori 2,2,0\";
12914 ;; Define the subtract-one-and-jump insns, starting with the template
12915 ;; so loop.c knows what to generate.
12917 (define_expand "doloop_end"
12918 [(use (match_operand 0 "" "")) ; loop pseudo
12919 (use (match_operand 1 "" ""))] ; label
12925 if (GET_MODE (operands[0]) != DImode)
12927 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12931 if (GET_MODE (operands[0]) != SImode)
12933 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12938 (define_expand "ctr<mode>"
12939 [(parallel [(set (pc)
12940 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12942 (label_ref (match_operand 1 "" ""))
12945 (plus:P (match_dup 0)
12947 (clobber (match_scratch:CC 2 ""))
12948 (clobber (match_scratch:P 3 ""))])]
12952 ;; We need to be able to do this for any operand, including MEM, or we
12953 ;; will cause reload to blow up since we don't allow output reloads on
12955 ;; For the length attribute to be calculated correctly, the
12956 ;; label MUST be operand 0.
12957 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12958 ;; the ctr<mode> insns.
12960 (define_insn "ctr<mode>_internal1"
12962 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12964 (label_ref (match_operand 0 "" ""))
12966 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12967 (plus:P (match_dup 1)
12969 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12970 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12974 if (which_alternative != 0)
12976 else if (get_attr_length (insn) == 4)
12977 return \"bdnz %l0\";
12979 return \"bdz $+8\;b %l0\";
12981 [(set_attr "type" "branch")
12982 (set_attr "length" "*,16,20,20")])
12984 (define_insn "ctr<mode>_internal2"
12986 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12989 (label_ref (match_operand 0 "" ""))))
12990 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12991 (plus:P (match_dup 1)
12993 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12994 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12998 if (which_alternative != 0)
13000 else if (get_attr_length (insn) == 4)
13001 return \"bdz %l0\";
13003 return \"bdnz $+8\;b %l0\";
13005 [(set_attr "type" "branch")
13006 (set_attr "length" "*,16,20,20")])
13008 ;; Similar but use EQ
13010 (define_insn "ctr<mode>_internal3"
13012 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13014 (label_ref (match_operand 0 "" ""))
13016 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13017 (plus:P (match_dup 1)
13019 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13020 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13024 if (which_alternative != 0)
13026 else if (get_attr_length (insn) == 4)
13027 return \"bdz %l0\";
13029 return \"bdnz $+8\;b %l0\";
13031 [(set_attr "type" "branch")
13032 (set_attr "length" "*,16,20,20")])
13034 (define_insn "ctr<mode>_internal4"
13036 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13039 (label_ref (match_operand 0 "" ""))))
13040 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13041 (plus:P (match_dup 1)
13043 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13044 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13048 if (which_alternative != 0)
13050 else if (get_attr_length (insn) == 4)
13051 return \"bdnz %l0\";
13053 return \"bdz $+8\;b %l0\";
13055 [(set_attr "type" "branch")
13056 (set_attr "length" "*,16,20,20")])
13058 ;; Now the splitters if we could not allocate the CTR register
13062 (if_then_else (match_operator 2 "comparison_operator"
13063 [(match_operand:P 1 "gpc_reg_operand" "")
13065 (match_operand 5 "" "")
13066 (match_operand 6 "" "")))
13067 (set (match_operand:P 0 "int_reg_operand" "")
13068 (plus:P (match_dup 1) (const_int -1)))
13069 (clobber (match_scratch:CC 3 ""))
13070 (clobber (match_scratch:P 4 ""))]
13072 [(set (match_dup 3)
13073 (compare:CC (match_dup 1)
13076 (plus:P (match_dup 1)
13078 (set (pc) (if_then_else (match_dup 7)
13082 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13083 operands[3], const0_rtx); }")
13087 (if_then_else (match_operator 2 "comparison_operator"
13088 [(match_operand:P 1 "gpc_reg_operand" "")
13090 (match_operand 5 "" "")
13091 (match_operand 6 "" "")))
13092 (set (match_operand:P 0 "nonimmediate_operand" "")
13093 (plus:P (match_dup 1) (const_int -1)))
13094 (clobber (match_scratch:CC 3 ""))
13095 (clobber (match_scratch:P 4 ""))]
13096 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
13097 [(set (match_dup 3)
13098 (compare:CC (match_dup 1)
13101 (plus:P (match_dup 1)
13105 (set (pc) (if_then_else (match_dup 7)
13109 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13110 operands[3], const0_rtx); }")
13112 (define_insn "trap"
13113 [(trap_if (const_int 1) (const_int 0))]
13116 [(set_attr "type" "trap")])
13118 (define_expand "ctrap<mode>4"
13119 [(trap_if (match_operator 0 "ordered_comparison_operator"
13120 [(match_operand:GPR 1 "register_operand")
13121 (match_operand:GPR 2 "reg_or_short_operand")])
13122 (match_operand 3 "zero_constant" ""))]
13127 [(trap_if (match_operator 0 "ordered_comparison_operator"
13128 [(match_operand:GPR 1 "register_operand" "r")
13129 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13132 "t<wd>%V0%I2 %1,%2"
13133 [(set_attr "type" "trap")])
13135 ;; Insns related to generating the function prologue and epilogue.
13137 (define_expand "prologue"
13138 [(use (const_int 0))]
13141 rs6000_emit_prologue ();
13142 if (!TARGET_SCHED_PROLOG)
13143 emit_insn (gen_blockage ());
13147 (define_insn "*movesi_from_cr_one"
13148 [(match_parallel 0 "mfcr_operation"
13149 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13150 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13151 (match_operand 3 "immediate_operand" "n")]
13152 UNSPEC_MOVESI_FROM_CR))])]
13158 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13160 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13161 operands[4] = GEN_INT (mask);
13162 output_asm_insn (\"mfcr %1,%4\", operands);
13166 [(set_attr "type" "mfcrf")])
13168 (define_insn "movesi_from_cr"
13169 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13170 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13171 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13172 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13173 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13174 UNSPEC_MOVESI_FROM_CR))]
13177 [(set_attr "type" "mfcr")])
13179 (define_insn "*crsave"
13180 [(match_parallel 0 "crsave_operation"
13181 [(set (match_operand:SI 1 "memory_operand" "=m")
13182 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13185 [(set_attr "type" "store")])
13187 (define_insn "*stmw"
13188 [(match_parallel 0 "stmw_operation"
13189 [(set (match_operand:SI 1 "memory_operand" "=m")
13190 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13193 [(set_attr "type" "store")
13194 (set_attr "update" "yes")
13195 (set_attr "indexed" "yes")])
13197 ; The following comment applies to:
13201 ; return_and_restore_gpregs*
13202 ; return_and_restore_fpregs*
13203 ; return_and_restore_fpregs_aix*
13205 ; The out-of-line save / restore functions expects one input argument.
13206 ; Since those are not standard call_insn's, we must avoid using
13207 ; MATCH_OPERAND for that argument. That way the register rename
13208 ; optimization will not try to rename this register.
13209 ; Each pattern is repeated for each possible register number used in
13210 ; various ABIs (r11, r1, and for some functions r12)
13212 (define_insn "*save_gpregs_<mode>_r11"
13213 [(match_parallel 0 "any_parallel_operand"
13214 [(clobber (reg:P LR_REGNO))
13215 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13217 (set (match_operand:P 2 "memory_operand" "=m")
13218 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13221 [(set_attr "type" "branch")
13222 (set_attr "length" "4")])
13224 (define_insn "*save_gpregs_<mode>_r12"
13225 [(match_parallel 0 "any_parallel_operand"
13226 [(clobber (reg:P LR_REGNO))
13227 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13229 (set (match_operand:P 2 "memory_operand" "=m")
13230 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13233 [(set_attr "type" "branch")
13234 (set_attr "length" "4")])
13236 (define_insn "*save_gpregs_<mode>_r1"
13237 [(match_parallel 0 "any_parallel_operand"
13238 [(clobber (reg:P LR_REGNO))
13239 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13241 (set (match_operand:P 2 "memory_operand" "=m")
13242 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13245 [(set_attr "type" "branch")
13246 (set_attr "length" "4")])
13248 (define_insn "*save_fpregs_<mode>_r11"
13249 [(match_parallel 0 "any_parallel_operand"
13250 [(clobber (reg:P LR_REGNO))
13251 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13253 (set (match_operand:DF 2 "memory_operand" "=m")
13254 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13257 [(set_attr "type" "branch")
13258 (set_attr "length" "4")])
13260 (define_insn "*save_fpregs_<mode>_r12"
13261 [(match_parallel 0 "any_parallel_operand"
13262 [(clobber (reg:P LR_REGNO))
13263 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13265 (set (match_operand:DF 2 "memory_operand" "=m")
13266 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13269 [(set_attr "type" "branch")
13270 (set_attr "length" "4")])
13272 (define_insn "*save_fpregs_<mode>_r1"
13273 [(match_parallel 0 "any_parallel_operand"
13274 [(clobber (reg:P LR_REGNO))
13275 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13277 (set (match_operand:DF 2 "memory_operand" "=m")
13278 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13281 [(set_attr "type" "branch")
13282 (set_attr "length" "4")])
13284 ; This is to explain that changes to the stack pointer should
13285 ; not be moved over loads from or stores to stack memory.
13286 (define_insn "stack_tie"
13287 [(match_parallel 0 "tie_operand"
13288 [(set (mem:BLK (reg 1)) (const_int 0))])]
13291 [(set_attr "length" "0")])
13293 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13294 ; stay behind all restores from the stack, it cannot be reordered to before
13295 ; one. See PR77687. This insn is an add or mr, and a stack_tie on the
13296 ; operands of that.
13297 (define_insn "stack_restore_tie"
13298 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13299 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13300 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13301 (set (mem:BLK (match_dup 0)) (const_int 0))
13302 (set (mem:BLK (match_dup 1)) (const_int 0))]
13307 [(set_attr "type" "*,add")])
13309 (define_expand "epilogue"
13310 [(use (const_int 0))]
13313 if (!TARGET_SCHED_PROLOG)
13314 emit_insn (gen_blockage ());
13315 rs6000_emit_epilogue (FALSE);
13319 ; On some processors, doing the mtcrf one CC register at a time is
13320 ; faster (like on the 604e). On others, doing them all at once is
13321 ; faster; for instance, on the 601 and 750.
13323 (define_expand "movsi_to_cr_one"
13324 [(set (match_operand:CC 0 "cc_reg_operand" "")
13325 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13326 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13328 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13330 (define_insn "*movsi_to_cr"
13331 [(match_parallel 0 "mtcrf_operation"
13332 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13333 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13334 (match_operand 3 "immediate_operand" "n")]
13335 UNSPEC_MOVESI_TO_CR))])]
13341 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13342 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13343 operands[4] = GEN_INT (mask);
13344 return \"mtcrf %4,%2\";
13346 [(set_attr "type" "mtcr")])
13348 (define_insn "*mtcrfsi"
13349 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13350 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13351 (match_operand 2 "immediate_operand" "n")]
13352 UNSPEC_MOVESI_TO_CR))]
13353 "GET_CODE (operands[0]) == REG
13354 && CR_REGNO_P (REGNO (operands[0]))
13355 && GET_CODE (operands[2]) == CONST_INT
13356 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13358 [(set_attr "type" "mtcr")])
13360 ; The load-multiple instructions have similar properties.
13361 ; Note that "load_multiple" is a name known to the machine-independent
13362 ; code that actually corresponds to the PowerPC load-string.
13364 (define_insn "*lmw"
13365 [(match_parallel 0 "lmw_operation"
13366 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13367 (match_operand:SI 2 "memory_operand" "m"))])]
13370 [(set_attr "type" "load")
13371 (set_attr "update" "yes")
13372 (set_attr "indexed" "yes")
13373 (set_attr "cell_micro" "always")])
13375 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13376 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13378 ; The following comment applies to:
13382 ; return_and_restore_gpregs*
13383 ; return_and_restore_fpregs*
13384 ; return_and_restore_fpregs_aix*
13386 ; The out-of-line save / restore functions expects one input argument.
13387 ; Since those are not standard call_insn's, we must avoid using
13388 ; MATCH_OPERAND for that argument. That way the register rename
13389 ; optimization will not try to rename this register.
13390 ; Each pattern is repeated for each possible register number used in
13391 ; various ABIs (r11, r1, and for some functions r12)
13393 (define_insn "*restore_gpregs_<mode>_r11"
13394 [(match_parallel 0 "any_parallel_operand"
13395 [(clobber (reg:P LR_REGNO))
13396 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13398 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13399 (match_operand:P 3 "memory_operand" "m"))])]
13402 [(set_attr "type" "branch")
13403 (set_attr "length" "4")])
13405 (define_insn "*restore_gpregs_<mode>_r12"
13406 [(match_parallel 0 "any_parallel_operand"
13407 [(clobber (reg:P LR_REGNO))
13408 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13410 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13411 (match_operand:P 3 "memory_operand" "m"))])]
13414 [(set_attr "type" "branch")
13415 (set_attr "length" "4")])
13417 (define_insn "*restore_gpregs_<mode>_r1"
13418 [(match_parallel 0 "any_parallel_operand"
13419 [(clobber (reg:P LR_REGNO))
13420 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13422 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13423 (match_operand:P 3 "memory_operand" "m"))])]
13426 [(set_attr "type" "branch")
13427 (set_attr "length" "4")])
13429 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13430 [(match_parallel 0 "any_parallel_operand"
13432 (clobber (reg:P LR_REGNO))
13433 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13435 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13436 (match_operand:P 3 "memory_operand" "m"))])]
13439 [(set_attr "type" "branch")
13440 (set_attr "length" "4")])
13442 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13443 [(match_parallel 0 "any_parallel_operand"
13445 (clobber (reg:P LR_REGNO))
13446 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13448 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13449 (match_operand:P 3 "memory_operand" "m"))])]
13452 [(set_attr "type" "branch")
13453 (set_attr "length" "4")])
13455 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13456 [(match_parallel 0 "any_parallel_operand"
13458 (clobber (reg:P LR_REGNO))
13459 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13461 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13462 (match_operand:P 3 "memory_operand" "m"))])]
13465 [(set_attr "type" "branch")
13466 (set_attr "length" "4")])
13468 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13469 [(match_parallel 0 "any_parallel_operand"
13471 (clobber (reg:P LR_REGNO))
13472 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13474 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13475 (match_operand:DF 3 "memory_operand" "m"))])]
13478 [(set_attr "type" "branch")
13479 (set_attr "length" "4")])
13481 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13482 [(match_parallel 0 "any_parallel_operand"
13484 (clobber (reg:P LR_REGNO))
13485 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13487 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13488 (match_operand:DF 3 "memory_operand" "m"))])]
13491 [(set_attr "type" "branch")
13492 (set_attr "length" "4")])
13494 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13495 [(match_parallel 0 "any_parallel_operand"
13497 (clobber (reg:P LR_REGNO))
13498 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13500 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13501 (match_operand:DF 3 "memory_operand" "m"))])]
13504 [(set_attr "type" "branch")
13505 (set_attr "length" "4")])
13507 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13508 [(match_parallel 0 "any_parallel_operand"
13510 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13512 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13513 (match_operand:DF 3 "memory_operand" "m"))])]
13516 [(set_attr "type" "branch")
13517 (set_attr "length" "4")])
13519 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13520 [(match_parallel 0 "any_parallel_operand"
13522 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13524 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13525 (match_operand:DF 3 "memory_operand" "m"))])]
13528 [(set_attr "type" "branch")
13529 (set_attr "length" "4")])
13531 ; This is used in compiling the unwind routines.
13532 (define_expand "eh_return"
13533 [(use (match_operand 0 "general_operand" ""))]
13538 emit_insn (gen_eh_set_lr_si (operands[0]));
13540 emit_insn (gen_eh_set_lr_di (operands[0]));
13544 ; We can't expand this before we know where the link register is stored.
13545 (define_insn "eh_set_lr_<mode>"
13546 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13548 (clobber (match_scratch:P 1 "=&b"))]
13553 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13554 (clobber (match_scratch 1 ""))]
13559 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13563 (define_insn "prefetch"
13564 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13565 (match_operand:SI 1 "const_int_operand" "n")
13566 (match_operand:SI 2 "const_int_operand" "n"))]
13570 if (GET_CODE (operands[0]) == REG)
13571 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13572 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13574 [(set_attr "type" "load")])
13576 ;; Handle -fsplit-stack.
13578 (define_expand "split_stack_prologue"
13582 rs6000_expand_split_stack_prologue ();
13586 (define_expand "load_split_stack_limit"
13587 [(set (match_operand 0)
13588 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13591 emit_insn (gen_rtx_SET (operands[0],
13592 gen_rtx_UNSPEC (Pmode,
13593 gen_rtvec (1, const0_rtx),
13594 UNSPEC_STACK_CHECK)));
13598 (define_insn "load_split_stack_limit_di"
13599 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13600 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13602 "ld %0,-0x7040(13)"
13603 [(set_attr "type" "load")
13604 (set_attr "update" "no")
13605 (set_attr "indexed" "no")])
13607 (define_insn "load_split_stack_limit_si"
13608 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13609 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13611 "lwz %0,-0x7020(2)"
13612 [(set_attr "type" "load")
13613 (set_attr "update" "no")
13614 (set_attr "indexed" "no")])
13616 ;; A return instruction which the middle-end doesn't see.
13617 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13618 ;; after the call to __morestack.
13619 (define_insn "split_stack_return"
13620 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13623 [(set_attr "type" "jmpreg")])
13625 ;; If there are operand 0 bytes available on the stack, jump to
13627 (define_expand "split_stack_space_check"
13628 [(set (match_dup 2)
13629 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13631 (minus (reg STACK_POINTER_REGNUM)
13632 (match_operand 0)))
13633 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13634 (set (pc) (if_then_else
13635 (geu (match_dup 4) (const_int 0))
13636 (label_ref (match_operand 1))
13640 rs6000_split_stack_space_check (operands[0], operands[1]);
13644 (define_insn "bpermd_<mode>"
13645 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13646 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13647 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13650 [(set_attr "type" "popcnt")])
13653 ;; Builtin fma support. Handle
13654 ;; Note that the conditions for expansion are in the FMA_F iterator.
13656 (define_expand "fma<mode>4"
13657 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13659 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13660 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13661 (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13665 (define_insn "*fma<mode>4_fpr"
13666 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13668 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13669 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13670 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13671 "TARGET_<MODE>_FPR"
13673 fmadd<Ftrad> %0,%1,%2,%3
13674 xsmadda<Fvsx> %x0,%x1,%x2
13675 xsmaddm<Fvsx> %x0,%x1,%x3"
13676 [(set_attr "type" "fp")
13677 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13679 ; Altivec only has fma and nfms.
13680 (define_expand "fms<mode>4"
13681 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13683 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13684 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13685 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13686 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13689 (define_insn "*fms<mode>4_fpr"
13690 [(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 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13695 "TARGET_<MODE>_FPR"
13697 fmsub<Ftrad> %0,%1,%2,%3
13698 xsmsuba<Fvsx> %x0,%x1,%x2
13699 xsmsubm<Fvsx> %x0,%x1,%x3"
13700 [(set_attr "type" "fp")
13701 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13703 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13704 (define_expand "fnma<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" "")))))]
13711 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13714 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13715 (define_expand "fnms<mode>4"
13716 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13719 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13720 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13721 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13722 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13725 ; Not an official optab name, but used from builtins.
13726 (define_expand "nfma<mode>4"
13727 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13730 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13731 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13732 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13733 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13736 (define_insn "*nfma<mode>4_fpr"
13737 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13740 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13741 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13742 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13743 "TARGET_<MODE>_FPR"
13745 fnmadd<Ftrad> %0,%1,%2,%3
13746 xsnmadda<Fvsx> %x0,%x1,%x2
13747 xsnmaddm<Fvsx> %x0,%x1,%x3"
13748 [(set_attr "type" "fp")
13749 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13751 ; Not an official optab name, but used from builtins.
13752 (define_expand "nfms<mode>4"
13753 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13756 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13757 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13758 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13762 (define_insn "*nfmssf4_fpr"
13763 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13766 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13767 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13769 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13770 "TARGET_<MODE>_FPR"
13772 fnmsub<Ftrad> %0,%1,%2,%3
13773 xsnmsuba<Fvsx> %x0,%x1,%x2
13774 xsnmsubm<Fvsx> %x0,%x1,%x3"
13775 [(set_attr "type" "fp")
13776 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13779 (define_expand "rs6000_get_timebase"
13780 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13783 if (TARGET_POWERPC64)
13784 emit_insn (gen_rs6000_mftb_di (operands[0]));
13786 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13790 (define_insn "rs6000_get_timebase_ppc32"
13791 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13792 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13793 (clobber (match_scratch:SI 1 "=r"))
13794 (clobber (match_scratch:CC 2 "=y"))]
13795 "!TARGET_POWERPC64"
13797 if (WORDS_BIG_ENDIAN)
13800 return "mfspr %0,269\;"
13808 return "mftbu %0\;"
13817 return "mfspr %L0,269\;"
13825 return "mftbu %L0\;"
13832 [(set_attr "length" "20")])
13834 (define_insn "rs6000_mftb_<mode>"
13835 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13836 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13840 return "mfspr %0,268";
13846 (define_insn "rs6000_mffs"
13847 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13848 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13849 "TARGET_HARD_FLOAT && TARGET_FPRS"
13852 (define_insn "rs6000_mtfsf"
13853 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13854 (match_operand:DF 1 "gpc_reg_operand" "d")]
13856 "TARGET_HARD_FLOAT && TARGET_FPRS"
13860 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13861 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13862 ;; register that is being loaded. The fused ops must be physically adjacent.
13864 ;; There are two parts to addis fusion. The support for fused TOCs occur
13865 ;; before register allocation, and is meant to reduce the lifetime for the
13866 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13867 ;; to use the register that is being load. The peephole2 then gathers any
13868 ;; other fused possibilities that it can find after register allocation. If
13869 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13871 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13872 ;; before register allocation, so that we can avoid allocating a temporary base
13873 ;; register that won't be used, and that we try to load into base registers,
13874 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13875 ;; (addis followed by load) even on power8.
13878 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13879 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13880 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13881 [(parallel [(set (match_dup 0) (match_dup 2))
13882 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13883 (use (match_dup 3))
13884 (clobber (scratch:DI))])]
13886 operands[2] = fusion_wrap_memory_address (operands[1]);
13887 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13890 (define_insn "*toc_fusionload_<mode>"
13891 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13892 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13893 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13894 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13895 (clobber (match_scratch:DI 3 "=X,&b"))]
13896 "TARGET_TOC_FUSION_INT"
13898 if (base_reg_operand (operands[0], <MODE>mode))
13899 return emit_fusion_gpr_load (operands[0], operands[1]);
13901 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13903 [(set_attr "type" "load")
13904 (set_attr "length" "8")])
13906 (define_insn "*toc_fusionload_di"
13907 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13908 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13909 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13910 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13911 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13912 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13913 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13915 if (base_reg_operand (operands[0], DImode))
13916 return emit_fusion_gpr_load (operands[0], operands[1]);
13918 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13920 [(set_attr "type" "load")
13921 (set_attr "length" "8")])
13924 ;; Find cases where the addis that feeds into a load instruction is either used
13925 ;; once or is the same as the target register, and replace it with the fusion
13929 [(set (match_operand:P 0 "base_reg_operand" "")
13930 (match_operand:P 1 "fusion_gpr_addis" ""))
13931 (set (match_operand:INT1 2 "base_reg_operand" "")
13932 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13934 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13938 expand_fusion_gpr_load (operands);
13942 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13945 (define_insn "fusion_gpr_load_<mode>"
13946 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13947 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13948 UNSPEC_FUSION_GPR))]
13951 return emit_fusion_gpr_load (operands[0], operands[1]);
13953 [(set_attr "type" "load")
13954 (set_attr "length" "8")])
13957 ;; ISA 3.0 (power9) fusion support
13958 ;; Merge addis with floating load/store to FPRs (or GPRs).
13960 [(set (match_operand:P 0 "base_reg_operand" "")
13961 (match_operand:P 1 "fusion_gpr_addis" ""))
13962 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13963 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13964 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13965 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13968 expand_fusion_p9_load (operands);
13973 [(set (match_operand:P 0 "base_reg_operand" "")
13974 (match_operand:P 1 "fusion_gpr_addis" ""))
13975 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13976 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13977 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13978 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13979 && !rtx_equal_p (operands[0], operands[3])"
13982 expand_fusion_p9_store (operands);
13987 [(set (match_operand:SDI 0 "int_reg_operand" "")
13988 (match_operand:SDI 1 "upper16_cint_operand" ""))
13990 (ior:SDI (match_dup 0)
13991 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13993 [(set (match_dup 0)
13994 (unspec:SDI [(match_dup 1)
13995 (match_dup 2)] UNSPEC_FUSION_P9))])
13998 [(set (match_operand:SDI 0 "int_reg_operand" "")
13999 (match_operand:SDI 1 "upper16_cint_operand" ""))
14000 (set (match_operand:SDI 2 "int_reg_operand" "")
14001 (ior:SDI (match_dup 0)
14002 (match_operand:SDI 3 "u_short_cint_operand" "")))]
14004 && !rtx_equal_p (operands[0], operands[2])
14005 && peep2_reg_dead_p (2, operands[0])"
14006 [(set (match_dup 2)
14007 (unspec:SDI [(match_dup 1)
14008 (match_dup 3)] UNSPEC_FUSION_P9))])
14010 ;; Fusion insns, created by the define_peephole2 above (and eventually by
14011 ;; reload). Because we want to eventually have secondary_reload generate
14012 ;; these, they have to have a single alternative that gives the register
14013 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
14014 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
14015 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
14017 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14019 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14022 /* This insn is a secondary reload insn, which cannot have alternatives.
14023 If we are not loading up register 0, use the power8 fusion instead. */
14024 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
14025 return emit_fusion_gpr_load (operands[0], operands[1]);
14027 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14029 [(set_attr "type" "load")
14030 (set_attr "length" "8")])
14032 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
14033 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14035 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
14037 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14040 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14042 [(set_attr "type" "store")
14043 (set_attr "length" "8")])
14045 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
14046 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
14048 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14050 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14053 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14055 [(set_attr "type" "fpload")
14056 (set_attr "length" "8")])
14058 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
14059 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14061 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
14063 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14066 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14068 [(set_attr "type" "fpstore")
14069 (set_attr "length" "8")])
14071 (define_insn "*fusion_p9_<mode>_constant"
14072 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
14073 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
14074 (match_operand:SDI 2 "u_short_cint_operand" "K")]
14075 UNSPEC_FUSION_P9))]
14078 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
14079 return "ori %0,%0,%2";
14081 [(set_attr "type" "two")
14082 (set_attr "length" "8")])
14085 ;; Optimize cases where we want to do a D-form load (register+offset) on
14086 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14091 ;; and we change this to:
14096 [(match_scratch:DI 0 "b")
14097 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14098 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14099 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14101 "TARGET_VSX && TARGET_POWERPC64 && TARGET_UPPER_REGS_<MODE>
14102 && !TARGET_P9_DFORM_SCALAR && peep2_reg_dead_p (2, operands[1])"
14103 [(set (match_dup 0)
14108 rtx tmp_reg = operands[0];
14109 rtx mem = operands[2];
14110 rtx addr = XEXP (mem, 0);
14111 rtx add_op0, add_op1, new_addr;
14113 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14114 add_op0 = XEXP (addr, 0);
14115 add_op1 = XEXP (addr, 1);
14116 gcc_assert (REG_P (add_op0));
14117 new_addr = gen_rtx_PLUS (DImode, add_op0, tmp_reg);
14119 operands[4] = add_op1;
14120 operands[5] = change_address (mem, <MODE>mode, new_addr);
14123 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14124 ;; Altivec register, and the register allocator has generated:
14128 ;; and we change this to:
14133 [(match_scratch:DI 0 "b")
14134 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14135 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14136 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14138 "TARGET_VSX && TARGET_POWERPC64 && TARGET_UPPER_REGS_<MODE>
14139 && !TARGET_P9_DFORM_SCALAR && peep2_reg_dead_p (2, operands[1])"
14140 [(set (match_dup 0)
14145 rtx tmp_reg = operands[0];
14146 rtx mem = operands[3];
14147 rtx addr = XEXP (mem, 0);
14148 rtx add_op0, add_op1, new_addr;
14150 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14151 add_op0 = XEXP (addr, 0);
14152 add_op1 = XEXP (addr, 1);
14153 gcc_assert (REG_P (add_op0));
14154 new_addr = gen_rtx_PLUS (DImode, add_op0, tmp_reg);
14156 operands[4] = add_op1;
14157 operands[5] = change_address (mem, <MODE>mode, new_addr);
14161 ;; Miscellaneous ISA 2.06 (power7) instructions
14162 (define_insn "addg6s"
14163 [(set (match_operand:SI 0 "register_operand" "=r")
14164 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14165 (match_operand:SI 2 "register_operand" "r")]
14169 [(set_attr "type" "integer")
14170 (set_attr "length" "4")])
14172 (define_insn "cdtbcd"
14173 [(set (match_operand:SI 0 "register_operand" "=r")
14174 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14178 [(set_attr "type" "integer")
14179 (set_attr "length" "4")])
14181 (define_insn "cbcdtd"
14182 [(set (match_operand:SI 0 "register_operand" "=r")
14183 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14187 [(set_attr "type" "integer")
14188 (set_attr "length" "4")])
14190 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14195 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14196 (UNSPEC_DIVEO "eo")
14197 (UNSPEC_DIVEU "eu")
14198 (UNSPEC_DIVEUO "euo")])
14200 (define_insn "div<div_extend>_<mode>"
14201 [(set (match_operand:GPR 0 "register_operand" "=r")
14202 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14203 (match_operand:GPR 2 "register_operand" "r")]
14204 UNSPEC_DIV_EXTEND))]
14206 "div<wd><div_extend> %0,%1,%2"
14207 [(set_attr "type" "div")
14208 (set_attr "size" "<bits>")])
14211 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14213 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14214 (define_mode_attr FP128_64 [(TF "DF")
14219 (define_expand "unpack<mode>"
14220 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14222 [(match_operand:FMOVE128 1 "register_operand" "")
14223 (match_operand:QI 2 "const_0_to_1_operand" "")]
14224 UNSPEC_UNPACK_128BIT))]
14225 "FLOAT128_2REG_P (<MODE>mode)"
14228 (define_insn_and_split "unpack<mode>_dm"
14229 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14231 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14232 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14233 UNSPEC_UNPACK_128BIT))]
14234 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14236 "&& reload_completed"
14237 [(set (match_dup 0) (match_dup 3))]
14239 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14241 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14243 emit_note (NOTE_INSN_DELETED);
14247 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14249 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14250 (set_attr "length" "4")])
14252 (define_insn_and_split "unpack<mode>_nodm"
14253 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14255 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14256 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14257 UNSPEC_UNPACK_128BIT))]
14258 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14260 "&& reload_completed"
14261 [(set (match_dup 0) (match_dup 3))]
14263 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14265 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14267 emit_note (NOTE_INSN_DELETED);
14271 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14273 [(set_attr "type" "fp,fpstore")
14274 (set_attr "length" "4")])
14276 (define_insn_and_split "pack<mode>"
14277 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14279 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14280 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14281 UNSPEC_PACK_128BIT))]
14282 "FLOAT128_2REG_P (<MODE>mode)"
14286 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14287 [(set (match_dup 3) (match_dup 1))
14288 (set (match_dup 4) (match_dup 2))]
14290 unsigned dest_hi = REGNO (operands[0]);
14291 unsigned dest_lo = dest_hi + 1;
14293 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14294 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14296 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14297 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14299 [(set_attr "type" "fpsimple,fp")
14300 (set_attr "length" "4,8")])
14302 (define_insn "unpack<mode>"
14303 [(set (match_operand:DI 0 "register_operand" "=d,d")
14304 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14305 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14306 UNSPEC_UNPACK_128BIT))]
14307 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14309 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14310 return ASM_COMMENT_START " xxpermdi to same register";
14312 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14313 return "xxpermdi %x0,%x1,%x1,%3";
14315 [(set_attr "type" "vecperm")])
14317 (define_insn "pack<mode>"
14318 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14319 (unspec:FMOVE128_VSX
14320 [(match_operand:DI 1 "register_operand" "d")
14321 (match_operand:DI 2 "register_operand" "d")]
14322 UNSPEC_PACK_128BIT))]
14324 "xxpermdi %x0,%x1,%x2,0"
14325 [(set_attr "type" "vecperm")])
14329 ;; ISA 2.08 IEEE 128-bit floating point support.
14331 (define_insn "add<mode>3"
14332 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14334 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14335 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14336 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14338 [(set_attr "type" "vecfloat")
14339 (set_attr "size" "128")])
14341 (define_insn "sub<mode>3"
14342 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14344 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14345 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14346 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14348 [(set_attr "type" "vecfloat")
14349 (set_attr "size" "128")])
14351 (define_insn "mul<mode>3"
14352 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14354 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14355 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14356 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14358 [(set_attr "type" "vecfloat")
14359 (set_attr "size" "128")])
14361 (define_insn "div<mode>3"
14362 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14364 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14365 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14366 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14368 [(set_attr "type" "vecdiv")
14369 (set_attr "size" "128")])
14371 (define_insn "sqrt<mode>2"
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" "vecdiv")
14378 (set_attr "size" "128")])
14380 (define_expand "copysign<mode>3"
14381 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14382 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14383 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14384 "FLOAT128_IEEE_P (<MODE>mode)"
14386 if (TARGET_FLOAT128_HW)
14387 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14391 rtx tmp = gen_reg_rtx (<MODE>mode);
14392 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14393 operands[2], tmp));
14398 (define_insn "copysign<mode>3_hard"
14399 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14401 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14402 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14404 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14405 "xscpsgnqp %0,%2,%1"
14406 [(set_attr "type" "vecmove")
14407 (set_attr "size" "128")])
14409 (define_insn "copysign<mode>3_soft"
14410 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14412 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14413 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14414 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14416 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14417 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14418 [(set_attr "type" "veccomplex")
14419 (set_attr "length" "8")])
14421 (define_insn "neg<mode>2_hw"
14422 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14424 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14425 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14427 [(set_attr "type" "vecmove")
14428 (set_attr "size" "128")])
14431 (define_insn "abs<mode>2_hw"
14432 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14434 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14435 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14437 [(set_attr "type" "vecmove")
14438 (set_attr "size" "128")])
14441 (define_insn "*nabs<mode>2_hw"
14442 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14445 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14446 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14448 [(set_attr "type" "vecmove")
14449 (set_attr "size" "128")])
14451 ;; Initially don't worry about doing fusion
14452 (define_insn "*fma<mode>4_hw"
14453 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14455 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14456 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14457 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14458 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14459 "xsmaddqp %0,%1,%2"
14460 [(set_attr "type" "vecfloat")
14461 (set_attr "size" "128")])
14463 (define_insn "*fms<mode>4_hw"
14464 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14466 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14467 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14469 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14470 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14471 "xsmsubqp %0,%1,%2"
14472 [(set_attr "type" "vecfloat")
14473 (set_attr "size" "128")])
14475 (define_insn "*nfma<mode>4_hw"
14476 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14479 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14480 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14481 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14482 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14483 "xsnmaddqp %0,%1,%2"
14484 [(set_attr "type" "vecfloat")
14485 (set_attr "size" "128")])
14487 (define_insn "*nfms<mode>4_hw"
14488 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14491 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14492 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14494 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14495 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14496 "xsnmsubqp %0,%1,%2"
14497 [(set_attr "type" "vecfloat")
14498 (set_attr "size" "128")])
14500 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14501 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14502 (float_extend:IEEE128
14503 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14504 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14506 [(set_attr "type" "vecfloat")
14507 (set_attr "size" "128")])
14509 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14510 ;; point is a simple copy.
14511 (define_insn_and_split "extendkftf2"
14512 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14513 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14514 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14518 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14521 emit_note (NOTE_INSN_DELETED);
14524 [(set_attr "type" "*,veclogical")
14525 (set_attr "length" "0,4")])
14527 (define_insn_and_split "trunctfkf2"
14528 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14529 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14530 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14534 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14537 emit_note (NOTE_INSN_DELETED);
14540 [(set_attr "type" "*,veclogical")
14541 (set_attr "length" "0,4")])
14543 (define_insn "trunc<mode>df2_hw"
14544 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14546 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14547 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14549 [(set_attr "type" "vecfloat")
14550 (set_attr "size" "128")])
14552 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14553 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14555 (define_insn_and_split "trunc<mode>sf2_hw"
14556 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14558 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14559 (clobber (match_scratch:DF 2 "=v"))]
14560 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14563 [(set (match_dup 2)
14564 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14566 (float_truncate:SF (match_dup 2)))]
14568 if (GET_CODE (operands[2]) == SCRATCH)
14569 operands[2] = gen_reg_rtx (DFmode);
14571 [(set_attr "type" "vecfloat")
14572 (set_attr "length" "8")])
14574 ;; Conversion between IEEE 128-bit and integer types
14575 (define_insn "fix_<mode>di2_hw"
14576 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14577 (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14578 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14580 [(set_attr "type" "vecfloat")
14581 (set_attr "size" "128")])
14583 (define_insn "fixuns_<mode>di2_hw"
14584 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14585 (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14586 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14588 [(set_attr "type" "vecfloat")
14589 (set_attr "size" "128")])
14591 (define_insn "fix_<mode>si2_hw"
14592 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14593 (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14594 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14596 [(set_attr "type" "vecfloat")
14597 (set_attr "size" "128")])
14599 (define_insn "fixuns_<mode>si2_hw"
14600 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14601 (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14602 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14604 [(set_attr "type" "vecfloat")
14605 (set_attr "size" "128")])
14607 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14608 ;; floating point value to 32-bit integer to GPR in order to save it.
14609 (define_insn_and_split "*fix<uns>_<mode>_mem"
14610 [(set (match_operand:SI 0 "memory_operand" "=Z")
14611 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14612 (clobber (match_scratch:SI 2 "=v"))]
14613 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14615 "&& reload_completed"
14616 [(set (match_dup 2)
14617 (any_fix:SI (match_dup 1)))
14621 (define_insn "float_<mode>di2_hw"
14622 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14623 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14624 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14626 [(set_attr "type" "vecfloat")
14627 (set_attr "size" "128")])
14629 (define_insn_and_split "float_<mode>si2_hw"
14630 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14631 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14632 (clobber (match_scratch:DI 2 "=v"))]
14633 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14636 [(set (match_dup 2)
14637 (sign_extend:DI (match_dup 1)))
14639 (float:IEEE128 (match_dup 2)))]
14641 if (GET_CODE (operands[2]) == SCRATCH)
14642 operands[2] = gen_reg_rtx (DImode);
14645 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14646 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14647 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14648 (clobber (match_scratch:DI 2 "=X,r,X"))]
14649 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14651 "&& reload_completed"
14654 rtx dest = operands[0];
14655 rtx src = operands[1];
14656 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14658 if (altivec_register_operand (src, <QHI:MODE>mode))
14659 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14660 else if (int_reg_operand (src, <QHI:MODE>mode))
14662 rtx ext_di = operands[2];
14663 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14664 emit_move_insn (dest_di, ext_di);
14666 else if (MEM_P (src))
14668 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14669 emit_move_insn (dest_qhi, src);
14670 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14673 gcc_unreachable ();
14675 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14678 [(set_attr "length" "8,12,12")
14679 (set_attr "type" "vecfloat")
14680 (set_attr "size" "128")])
14682 (define_insn "floatuns_<mode>di2_hw"
14683 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14684 (unsigned_float:IEEE128
14685 (match_operand:DI 1 "altivec_register_operand" "v")))]
14686 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14688 [(set_attr "type" "vecfloat")
14689 (set_attr "size" "128")])
14691 (define_insn_and_split "floatuns_<mode>si2_hw"
14692 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14693 (unsigned_float:IEEE128
14694 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14695 (clobber (match_scratch:DI 2 "=v"))]
14696 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14699 [(set (match_dup 2)
14700 (zero_extend:DI (match_dup 1)))
14702 (float:IEEE128 (match_dup 2)))]
14704 if (GET_CODE (operands[2]) == SCRATCH)
14705 operands[2] = gen_reg_rtx (DImode);
14708 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14709 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14710 (unsigned_float:IEEE128
14711 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14712 (clobber (match_scratch:DI 2 "=X,r,X"))]
14713 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14715 "&& reload_completed"
14718 rtx dest = operands[0];
14719 rtx src = operands[1];
14720 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14722 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14723 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14724 else if (int_reg_operand (src, <QHI:MODE>mode))
14726 rtx ext_di = operands[2];
14727 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14728 emit_move_insn (dest_di, ext_di);
14731 gcc_unreachable ();
14733 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14736 [(set_attr "length" "8,12,8")
14737 (set_attr "type" "vecfloat")
14738 (set_attr "size" "128")])
14740 ;; IEEE 128-bit instructions with round to odd semantics
14741 (define_insn "*trunc<mode>df2_odd"
14742 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14743 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14744 UNSPEC_ROUND_TO_ODD))]
14745 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14747 [(set_attr "type" "vecfloat")
14748 (set_attr "size" "128")])
14750 ;; IEEE 128-bit comparisons
14751 (define_insn "*cmp<mode>_hw"
14752 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14753 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14754 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14755 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14756 "xscmpuqp %0,%1,%2"
14757 [(set_attr "type" "veccmp")
14758 (set_attr "size" "128")])
14762 (include "sync.md")
14763 (include "vector.md")
14765 (include "altivec.md")
14768 (include "paired.md")
14769 (include "crypto.md")