1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2017 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (STACK_POINTER_REGNUM 1)
31 (STATIC_CHAIN_REGNUM 11)
32 (HARD_FRAME_POINTER_REGNUM 31)
38 (ARG_POINTER_REGNUM 67)
49 (FIRST_ALTIVEC_REGNO 77)
50 (LAST_ALTIVEC_REGNO 108)
53 (FRAME_POINTER_REGNUM 111)
63 (define_c_enum "unspec"
64 [UNSPEC_FRSP ; frsp for POWER machines
65 UNSPEC_PROBE_STACK ; probe stack memory reference
66 UNSPEC_TOCPTR ; address of a word pointing to the TOC
67 UNSPEC_TOC ; address of the TOC (more-or-less)
68 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
70 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
77 UNSPEC_LD_MPIC ; load_macho_picbase
78 UNSPEC_RELD_MPIC ; re-load_macho_picbase
79 UNSPEC_MPIC_CORRECT ; macho_correct_pic
93 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
111 UNSPEC_MACHOPIC_OFFSET
125 UNSPEC_P8V_RELOAD_FROM_GPR
128 UNSPEC_P8V_RELOAD_FROM_VSX
150 ;; UNSPEC_VOLATILE usage
153 (define_c_enum "unspecv"
155 UNSPECV_LL ; load-locked
156 UNSPECV_SC ; store-conditional
157 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
158 UNSPECV_EH_RR ; eh_reg_restore
159 UNSPECV_ISYNC ; isync instruction
160 UNSPECV_MFTB ; move from time base
161 UNSPECV_NLGR ; non-local goto receiver
162 UNSPECV_MFFS ; Move from FPSCR
163 UNSPECV_MTFSF ; Move to FPSCR Fields
164 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
168 ;; Define an insn type attribute. This is used in function unit delay
172 add,logical,shift,insert,
174 exts,cntlz,popcnt,isel,
175 load,store,fpload,fpstore,vecload,vecstore,
177 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
178 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
179 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
180 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
181 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
182 veclogical,veccmpfx,vecexts,vecmove,
184 (const_string "integer"))
186 ;; What data size does this instruction work on?
187 ;; This is used for insert, mul and others as necessary.
188 (define_attr "size" "8,16,32,64,128" (const_string "32"))
190 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
191 ;; This is used for add, logical, shift, exts, mul.
192 (define_attr "dot" "no,yes" (const_string "no"))
194 ;; Does this instruction sign-extend its result?
195 ;; This is used for load insns.
196 (define_attr "sign_extend" "no,yes" (const_string "no"))
198 ;; Does this instruction use indexed (that is, reg+reg) addressing?
199 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
200 ;; it is automatically set based on that. If a load or store instruction
201 ;; has fewer than two operands it needs to set this attribute manually
202 ;; or the compiler will crash.
203 (define_attr "indexed" "no,yes"
204 (if_then_else (ior (match_operand 0 "indexed_address_mem")
205 (match_operand 1 "indexed_address_mem"))
207 (const_string "no")))
209 ;; Does this instruction use update addressing?
210 ;; This is used for load and store insns. See the comments for "indexed".
211 (define_attr "update" "no,yes"
212 (if_then_else (ior (match_operand 0 "update_address_mem")
213 (match_operand 1 "update_address_mem"))
215 (const_string "no")))
217 ;; Is this instruction using operands[2] as shift amount, and can that be a
219 ;; This is used for shift insns.
220 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
222 ;; Is this instruction using a shift amount from a register?
223 ;; This is used for shift insns.
224 (define_attr "var_shift" "no,yes"
225 (if_then_else (and (eq_attr "type" "shift")
226 (eq_attr "maybe_var_shift" "yes"))
227 (if_then_else (match_operand 2 "gpc_reg_operand")
230 (const_string "no")))
232 ;; Is copying of this instruction disallowed?
233 (define_attr "cannot_copy" "no,yes" (const_string "no"))
235 ;; Define floating point instruction sub-types for use with Xfpu.md
236 (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"))
238 ;; Length (in bytes).
239 ; '(pc)' in the following doesn't include the instruction itself; it is
240 ; calculated as if the instruction had zero size.
241 (define_attr "length" ""
242 (if_then_else (eq_attr "type" "branch")
243 (if_then_else (and (ge (minus (match_dup 0) (pc))
245 (lt (minus (match_dup 0) (pc))
251 ;; Processor type -- this attribute must exactly match the processor_type
252 ;; enumeration in rs6000-opts.h.
254 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
255 ppc750,ppc7400,ppc7450,
256 ppc403,ppc405,ppc440,ppc476,
257 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
258 power4,power5,power6,power7,power8,power9,
259 rs64a,mpccore,cell,ppca2,titan"
260 (const (symbol_ref "rs6000_cpu_attr")))
263 ;; If this instruction is microcoded on the CELL processor
264 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
265 (define_attr "cell_micro" "not,conditional,always"
266 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
267 (eq_attr "dot" "yes"))
268 (and (eq_attr "type" "load")
269 (eq_attr "sign_extend" "yes"))
270 (and (eq_attr "type" "shift")
271 (eq_attr "var_shift" "yes")))
272 (const_string "always")
273 (const_string "not")))
275 (automata_option "ndfa")
288 (include "e300c2c3.md")
289 (include "e500mc.md")
290 (include "e500mc64.md")
293 (include "power4.md")
294 (include "power5.md")
295 (include "power6.md")
296 (include "power7.md")
297 (include "power8.md")
298 (include "power9.md")
304 (include "predicates.md")
305 (include "constraints.md")
307 (include "darwin.md")
312 ; This mode iterator allows :GPR to be used to indicate the allowable size
313 ; of whole values in GPRs.
314 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
316 ; Any supported integer mode.
317 (define_mode_iterator INT [QI HI SI DI TI PTI])
319 ; Any supported integer mode that fits in one register.
320 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
322 ; Integer modes supported in VSX registers with ISA 3.0 instructions
323 (define_mode_iterator INT_ISA3 [QI HI SI DI])
325 ; Everything we can extend QImode to.
326 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
328 ; Everything we can extend HImode to.
329 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
331 ; Everything we can extend SImode to.
332 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
334 ; QImode or HImode for small integer moves and small atomic ops
335 (define_mode_iterator QHI [QI HI])
337 ; QImode, HImode, SImode for fused ops only for GPR loads
338 (define_mode_iterator QHSI [QI HI SI])
340 ; HImode or SImode for sign extended fusion ops
341 (define_mode_iterator HSI [HI SI])
343 ; SImode or DImode, even if DImode doesn't fit in GPRs.
344 (define_mode_iterator SDI [SI DI])
346 ; Types that can be fused with an ADDIS instruction to load or store a GPR
347 ; register that has reg+offset addressing.
348 (define_mode_iterator GPR_FUSION [QI
351 (DI "TARGET_POWERPC64")
353 (DF "TARGET_POWERPC64")])
355 ; Types that can be fused with an ADDIS instruction to load or store a FPR
356 ; register that has reg+offset addressing.
357 (define_mode_iterator FPR_FUSION [DI SF DF])
359 ; The size of a pointer. Also, the size of the value that a record-condition
360 ; (one with a '.') will compare; and the size used for arithmetic carries.
361 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
363 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
364 ; PTImode is GPR only)
365 (define_mode_iterator TI2 [TI PTI])
367 ; Any hardware-supported floating-point mode
368 (define_mode_iterator FP [
369 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
370 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
371 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
372 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
373 (KF "TARGET_FLOAT128_TYPE")
377 ; Any fma capable floating-point mode.
378 (define_mode_iterator FMA_F [
379 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
380 (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
381 || VECTOR_UNIT_VSX_P (DFmode)")
382 (V2SF "TARGET_PAIRED_FLOAT")
383 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
384 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
385 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
386 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
389 ; Floating point move iterators to combine binary and decimal moves
390 (define_mode_iterator FMOVE32 [SF SD])
391 (define_mode_iterator FMOVE64 [DF DD])
392 (define_mode_iterator FMOVE64X [DI DF DD])
393 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
394 (IF "FLOAT128_IBM_P (IFmode)")
395 (TD "TARGET_HARD_FLOAT")])
397 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
398 (IF "FLOAT128_2REG_P (IFmode)")
399 (TD "TARGET_HARD_FLOAT")])
401 ; Iterators for 128 bit types for direct move
402 (define_mode_iterator FMOVE128_GPR [TI
410 (KF "FLOAT128_VECTOR_P (KFmode)")
411 (TF "FLOAT128_VECTOR_P (TFmode)")])
413 ; Iterator for 128-bit VSX types for pack/unpack
414 (define_mode_iterator FMOVE128_VSX [V1TI KF])
416 ; Whether a floating point move is ok, don't allow SD without hardware FP
417 (define_mode_attr fmove_ok [(SF "")
419 (SD "TARGET_HARD_FLOAT")
422 ; Convert REAL_VALUE to the appropriate bits
423 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
424 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
425 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
426 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
428 ; Whether 0.0 has an all-zero bit pattern
429 (define_mode_attr zero_fp [(SF "j")
438 ; Definitions for 64-bit VSX
439 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
441 ; Definitions for 64-bit direct move
442 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
444 ; Definitions for 64-bit use of altivec registers
445 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
447 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
448 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
450 ; These modes do not fit in integer registers in 32-bit mode.
451 (define_mode_iterator DIFD [DI DF DD])
453 ; Iterator for reciprocal estimate instructions
454 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
456 ; Iterator for just SF/DF
457 (define_mode_iterator SFDF [SF DF])
459 ; Like SFDF, but a different name to match conditional move where the
460 ; comparison operands may be a different mode than the input operands.
461 (define_mode_iterator SFDF2 [SF DF])
463 ; Iterator for 128-bit floating point that uses the IBM double-double format
464 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
465 (TF "FLOAT128_IBM_P (TFmode)")])
467 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
468 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
469 (TF "FLOAT128_IEEE_P (TFmode)")])
471 ; Iterator for 128-bit floating point
472 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
473 (IF "TARGET_FLOAT128_TYPE")
474 (TF "TARGET_LONG_DOUBLE_128")])
476 ; Iterator for signbit on 64-bit machines with direct move
477 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
478 (TF "FLOAT128_VECTOR_P (TFmode)")])
480 ; Iterator for ISA 3.0 supported floating point types
481 (define_mode_iterator FP_ISA3 [SF DF])
483 ; SF/DF suffix for traditional floating instructions
484 (define_mode_attr Ftrad [(SF "s") (DF "")])
486 ; SF/DF suffix for VSX instructions
487 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
489 ; SF/DF constraint for arithmetic on traditional floating point registers
490 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
492 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
493 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
494 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
496 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
498 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
499 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
500 ; instructions added in ISA 2.07 (power8)
501 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
503 ; SF/DF constraint for arithmetic on altivec registers
504 (define_mode_attr Fa [(SF "wu") (DF "wv")])
506 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
507 (define_mode_attr Fs [(SF "s") (DF "d")])
510 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
511 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
513 ; Conditional returns.
514 (define_code_iterator any_return [return simple_return])
515 (define_code_attr return_pred [(return "direct_return ()")
516 (simple_return "1")])
517 (define_code_attr return_str [(return "") (simple_return "simple_")])
520 (define_code_iterator iorxor [ior xor])
521 (define_code_iterator and_ior_xor [and ior xor])
523 ; Signed/unsigned variants of ops.
524 (define_code_iterator any_extend [sign_extend zero_extend])
525 (define_code_iterator any_fix [fix unsigned_fix])
526 (define_code_iterator any_float [float unsigned_float])
528 (define_code_attr u [(sign_extend "")
533 (define_code_attr su [(sign_extend "s")
538 (unsigned_float "u")])
540 (define_code_attr az [(sign_extend "a")
545 (unsigned_float "z")])
547 (define_code_attr uns [(fix "")
550 (unsigned_float "uns")])
552 ; Various instructions that come in SI and DI forms.
553 ; A generic w/d attribute, for things like cmpw/cmpd.
554 (define_mode_attr wd [(QI "b")
565 ;; How many bits in this mode?
566 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
569 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
571 ;; ISEL/ISEL64 target selection
572 (define_mode_attr sel [(SI "") (DI "64")])
574 ;; Bitmask for shift instructions
575 (define_mode_attr hH [(SI "h") (DI "H")])
577 ;; A mode twice the size of the given mode
578 (define_mode_attr dmode [(SI "di") (DI "ti")])
579 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
581 ;; Suffix for reload patterns
582 (define_mode_attr ptrsize [(SI "32bit")
585 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
586 (DI "TARGET_64BIT")])
588 (define_mode_attr mptrsize [(SI "si")
591 (define_mode_attr ptrload [(SI "lwz")
594 (define_mode_attr ptrm [(SI "m")
597 (define_mode_attr rreg [(SF "f")
604 (define_mode_attr rreg2 [(SF "f")
607 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
608 (DF "TARGET_FCFID")])
610 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
611 (DF "TARGET_DOUBLE_FLOAT")])
613 ;; Mode iterator for logical operations on 128-bit types
614 (define_mode_iterator BOOL_128 [TI
616 (V16QI "TARGET_ALTIVEC")
617 (V8HI "TARGET_ALTIVEC")
618 (V4SI "TARGET_ALTIVEC")
619 (V4SF "TARGET_ALTIVEC")
620 (V2DI "TARGET_ALTIVEC")
621 (V2DF "TARGET_ALTIVEC")
622 (V1TI "TARGET_ALTIVEC")])
624 ;; For the GPRs we use 3 constraints for register outputs, two that are the
625 ;; same as the output register, and a third where the output register is an
626 ;; early clobber, so we don't have to deal with register overlaps. For the
627 ;; vector types, we prefer to use the vector registers. For TI mode, allow
630 ;; Mode attribute for boolean operation register constraints for output
631 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
633 (V16QI "wa,v,&?r,?r,?r")
634 (V8HI "wa,v,&?r,?r,?r")
635 (V4SI "wa,v,&?r,?r,?r")
636 (V4SF "wa,v,&?r,?r,?r")
637 (V2DI "wa,v,&?r,?r,?r")
638 (V2DF "wa,v,&?r,?r,?r")
639 (V1TI "wa,v,&?r,?r,?r")])
641 ;; Mode attribute for boolean operation register constraints for operand1
642 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
650 (V1TI "wa,v,r,0,r")])
652 ;; Mode attribute for boolean operation register constraints for operand2
653 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
661 (V1TI "wa,v,r,r,0")])
663 ;; Mode attribute for boolean operation register constraints for operand1
664 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
665 ;; is used for operand1 or operand2
666 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
674 (V1TI "wa,v,r,0,0")])
676 ;; Reload iterator for creating the function to allocate a base register to
677 ;; supplement addressing modes.
678 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
679 SF SD SI DF DD DI TI PTI KF IF TF])
681 ;; Iterate over smin, smax
682 (define_code_iterator fp_minmax [smin smax])
684 (define_code_attr minmax [(smin "min")
687 (define_code_attr SMINMAX [(smin "SMIN")
690 ;; Iterator to optimize the following cases:
691 ;; D-form load to FPR register & move to Altivec register
692 ;; Move Altivec register to FPR register and store
693 (define_mode_iterator ALTIVEC_DFORM [DF
694 (SF "TARGET_P8_VECTOR")
695 (DI "TARGET_POWERPC64")])
698 ;; Start with fixed-point load and store insns. Here we put only the more
699 ;; complex forms. Basic data transfer is done later.
701 (define_insn "zero_extendqi<mode>2"
702 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
703 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
710 [(set_attr "type" "load,shift,fpload,vecperm")])
712 (define_insn_and_split "*zero_extendqi<mode>2_dot"
713 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
714 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
716 (clobber (match_scratch:EXTQI 0 "=r,r"))]
721 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
723 (zero_extend:EXTQI (match_dup 1)))
725 (compare:CC (match_dup 0)
728 [(set_attr "type" "logical")
729 (set_attr "dot" "yes")
730 (set_attr "length" "4,8")])
732 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
733 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
734 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
736 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
737 (zero_extend:EXTQI (match_dup 1)))]
742 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
744 (zero_extend:EXTQI (match_dup 1)))
746 (compare:CC (match_dup 0)
749 [(set_attr "type" "logical")
750 (set_attr "dot" "yes")
751 (set_attr "length" "4,8")])
754 (define_insn "zero_extendhi<mode>2"
755 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
756 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
760 rlwinm %0,%1,0,0xffff
763 [(set_attr "type" "load,shift,fpload,vecperm")])
765 (define_insn_and_split "*zero_extendhi<mode>2_dot"
766 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
767 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
769 (clobber (match_scratch:EXTHI 0 "=r,r"))]
774 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
776 (zero_extend:EXTHI (match_dup 1)))
778 (compare:CC (match_dup 0)
781 [(set_attr "type" "logical")
782 (set_attr "dot" "yes")
783 (set_attr "length" "4,8")])
785 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
786 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
787 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
789 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
790 (zero_extend:EXTHI (match_dup 1)))]
795 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
797 (zero_extend:EXTHI (match_dup 1)))
799 (compare:CC (match_dup 0)
802 [(set_attr "type" "logical")
803 (set_attr "dot" "yes")
804 (set_attr "length" "4,8")])
807 (define_insn "zero_extendsi<mode>2"
808 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
809 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
818 xxextractuw %x0,%x1,4"
819 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
821 (define_insn_and_split "*zero_extendsi<mode>2_dot"
822 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
823 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
825 (clobber (match_scratch:EXTSI 0 "=r,r"))]
830 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
832 (zero_extend:DI (match_dup 1)))
834 (compare:CC (match_dup 0)
837 [(set_attr "type" "shift")
838 (set_attr "dot" "yes")
839 (set_attr "length" "4,8")])
841 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
842 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
843 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
845 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
846 (zero_extend:EXTSI (match_dup 1)))]
851 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
853 (zero_extend:EXTSI (match_dup 1)))
855 (compare:CC (match_dup 0)
858 [(set_attr "type" "shift")
859 (set_attr "dot" "yes")
860 (set_attr "length" "4,8")])
863 (define_insn "extendqi<mode>2"
864 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
865 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
870 [(set_attr "type" "exts,vecperm")])
872 (define_insn_and_split "*extendqi<mode>2_dot"
873 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
874 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
876 (clobber (match_scratch:EXTQI 0 "=r,r"))]
881 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
883 (sign_extend:EXTQI (match_dup 1)))
885 (compare:CC (match_dup 0)
888 [(set_attr "type" "exts")
889 (set_attr "dot" "yes")
890 (set_attr "length" "4,8")])
892 (define_insn_and_split "*extendqi<mode>2_dot2"
893 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
894 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
896 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
897 (sign_extend:EXTQI (match_dup 1)))]
902 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
904 (sign_extend:EXTQI (match_dup 1)))
906 (compare:CC (match_dup 0)
909 [(set_attr "type" "exts")
910 (set_attr "dot" "yes")
911 (set_attr "length" "4,8")])
914 (define_expand "extendhi<mode>2"
915 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
916 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
920 (define_insn "*extendhi<mode>2"
921 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
922 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
929 [(set_attr "type" "load,exts,fpload,vecperm")
930 (set_attr "sign_extend" "yes")
931 (set_attr "length" "4,4,8,4")])
934 [(set (match_operand:EXTHI 0 "altivec_register_operand")
936 (match_operand:HI 1 "indexed_or_indirect_operand")))]
937 "TARGET_P9_VECTOR && reload_completed"
941 (sign_extend:EXTHI (match_dup 2)))]
943 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
946 (define_insn_and_split "*extendhi<mode>2_dot"
947 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
948 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
950 (clobber (match_scratch:EXTHI 0 "=r,r"))]
955 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
957 (sign_extend:EXTHI (match_dup 1)))
959 (compare:CC (match_dup 0)
962 [(set_attr "type" "exts")
963 (set_attr "dot" "yes")
964 (set_attr "length" "4,8")])
966 (define_insn_and_split "*extendhi<mode>2_dot2"
967 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
968 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
970 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
971 (sign_extend:EXTHI (match_dup 1)))]
976 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
978 (sign_extend:EXTHI (match_dup 1)))
980 (compare:CC (match_dup 0)
983 [(set_attr "type" "exts")
984 (set_attr "dot" "yes")
985 (set_attr "length" "4,8")])
988 (define_insn "extendsi<mode>2"
989 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK,wH")
990 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK,wH")))]
1000 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm")
1001 (set_attr "sign_extend" "yes")
1002 (set_attr "length" "4,4,4,4,4,4,8")])
1005 [(set (match_operand:DI 0 "altivec_register_operand")
1006 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1007 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1010 rtx dest = operands[0];
1011 rtx src = operands[1];
1012 int dest_regno = REGNO (dest);
1013 int src_regno = REGNO (src);
1014 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1015 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1017 if (VECTOR_ELT_ORDER_BIG)
1019 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1020 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1024 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1025 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1030 (define_insn_and_split "*extendsi<mode>2_dot"
1031 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1032 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1034 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1039 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1041 (sign_extend:EXTSI (match_dup 1)))
1043 (compare:CC (match_dup 0)
1046 [(set_attr "type" "exts")
1047 (set_attr "dot" "yes")
1048 (set_attr "length" "4,8")])
1050 (define_insn_and_split "*extendsi<mode>2_dot2"
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 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1055 (sign_extend:EXTSI (match_dup 1)))]
1060 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1062 (sign_extend:EXTSI (match_dup 1)))
1064 (compare:CC (match_dup 0)
1067 [(set_attr "type" "exts")
1068 (set_attr "dot" "yes")
1069 (set_attr "length" "4,8")])
1071 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1073 (define_insn "*macchwc"
1074 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1075 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1076 (match_operand:SI 2 "gpc_reg_operand" "r")
1079 (match_operand:HI 1 "gpc_reg_operand" "r")))
1080 (match_operand:SI 4 "gpc_reg_operand" "0"))
1082 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1083 (plus:SI (mult:SI (ashiftrt:SI
1091 [(set_attr "type" "halfmul")])
1093 (define_insn "*macchw"
1094 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1095 (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 3 "gpc_reg_operand" "0")))]
1103 [(set_attr "type" "halfmul")])
1105 (define_insn "*macchwuc"
1106 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1107 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1108 (match_operand:SI 2 "gpc_reg_operand" "r")
1111 (match_operand:HI 1 "gpc_reg_operand" "r")))
1112 (match_operand:SI 4 "gpc_reg_operand" "0"))
1114 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1115 (plus:SI (mult:SI (lshiftrt:SI
1123 [(set_attr "type" "halfmul")])
1125 (define_insn "*macchwu"
1126 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1127 (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 3 "gpc_reg_operand" "0")))]
1135 [(set_attr "type" "halfmul")])
1137 (define_insn "*machhwc"
1138 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1139 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1140 (match_operand:SI 1 "gpc_reg_operand" "%r")
1143 (match_operand:SI 2 "gpc_reg_operand" "r")
1145 (match_operand:SI 4 "gpc_reg_operand" "0"))
1147 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1148 (plus:SI (mult:SI (ashiftrt:SI
1157 [(set_attr "type" "halfmul")])
1159 (define_insn "*machhw"
1160 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1161 (plus:SI (mult:SI (ashiftrt:SI
1162 (match_operand:SI 1 "gpc_reg_operand" "%r")
1165 (match_operand:SI 2 "gpc_reg_operand" "r")
1167 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1170 [(set_attr "type" "halfmul")])
1172 (define_insn "*machhwuc"
1173 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1174 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1175 (match_operand:SI 1 "gpc_reg_operand" "%r")
1178 (match_operand:SI 2 "gpc_reg_operand" "r")
1180 (match_operand:SI 4 "gpc_reg_operand" "0"))
1182 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1183 (plus:SI (mult:SI (lshiftrt:SI
1192 [(set_attr "type" "halfmul")])
1194 (define_insn "*machhwu"
1195 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1196 (plus:SI (mult:SI (lshiftrt:SI
1197 (match_operand:SI 1 "gpc_reg_operand" "%r")
1200 (match_operand:SI 2 "gpc_reg_operand" "r")
1202 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1205 [(set_attr "type" "halfmul")])
1207 (define_insn "*maclhwc"
1208 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1209 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1210 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1212 (match_operand:HI 2 "gpc_reg_operand" "r")))
1213 (match_operand:SI 4 "gpc_reg_operand" "0"))
1215 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1216 (plus:SI (mult:SI (sign_extend:SI
1223 [(set_attr "type" "halfmul")])
1225 (define_insn "*maclhw"
1226 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1227 (plus:SI (mult:SI (sign_extend:SI
1228 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1230 (match_operand:HI 2 "gpc_reg_operand" "r")))
1231 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1234 [(set_attr "type" "halfmul")])
1236 (define_insn "*maclhwuc"
1237 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1238 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1239 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1241 (match_operand:HI 2 "gpc_reg_operand" "r")))
1242 (match_operand:SI 4 "gpc_reg_operand" "0"))
1244 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1245 (plus:SI (mult:SI (zero_extend:SI
1252 [(set_attr "type" "halfmul")])
1254 (define_insn "*maclhwu"
1255 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1256 (plus:SI (mult:SI (zero_extend:SI
1257 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1259 (match_operand:HI 2 "gpc_reg_operand" "r")))
1260 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1263 [(set_attr "type" "halfmul")])
1265 (define_insn "*nmacchwc"
1266 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1267 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1268 (mult:SI (ashiftrt:SI
1269 (match_operand:SI 2 "gpc_reg_operand" "r")
1272 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1274 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1275 (minus:SI (match_dup 4)
1276 (mult:SI (ashiftrt:SI
1283 [(set_attr "type" "halfmul")])
1285 (define_insn "*nmacchw"
1286 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1287 (minus:SI (match_operand:SI 3 "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")))))]
1295 [(set_attr "type" "halfmul")])
1297 (define_insn "*nmachhwc"
1298 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1299 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1300 (mult:SI (ashiftrt:SI
1301 (match_operand:SI 1 "gpc_reg_operand" "%r")
1304 (match_operand:SI 2 "gpc_reg_operand" "r")
1307 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1308 (minus:SI (match_dup 4)
1309 (mult:SI (ashiftrt:SI
1317 [(set_attr "type" "halfmul")])
1319 (define_insn "*nmachhw"
1320 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1321 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1322 (mult:SI (ashiftrt:SI
1323 (match_operand:SI 1 "gpc_reg_operand" "%r")
1326 (match_operand:SI 2 "gpc_reg_operand" "r")
1330 [(set_attr "type" "halfmul")])
1332 (define_insn "*nmaclhwc"
1333 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1334 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1335 (mult:SI (sign_extend:SI
1336 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1338 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1340 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341 (minus:SI (match_dup 4)
1342 (mult:SI (sign_extend:SI
1348 [(set_attr "type" "halfmul")])
1350 (define_insn "*nmaclhw"
1351 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1352 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1353 (mult:SI (sign_extend:SI
1354 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1356 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1359 [(set_attr "type" "halfmul")])
1361 (define_insn "*mulchwc"
1362 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1363 (compare:CC (mult:SI (ashiftrt:SI
1364 (match_operand:SI 2 "gpc_reg_operand" "r")
1367 (match_operand:HI 1 "gpc_reg_operand" "r")))
1369 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1370 (mult:SI (ashiftrt:SI
1377 [(set_attr "type" "halfmul")])
1379 (define_insn "*mulchw"
1380 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1381 (mult:SI (ashiftrt:SI
1382 (match_operand:SI 2 "gpc_reg_operand" "r")
1385 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1388 [(set_attr "type" "halfmul")])
1390 (define_insn "*mulchwuc"
1391 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1392 (compare:CC (mult:SI (lshiftrt:SI
1393 (match_operand:SI 2 "gpc_reg_operand" "r")
1396 (match_operand:HI 1 "gpc_reg_operand" "r")))
1398 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1399 (mult:SI (lshiftrt:SI
1406 [(set_attr "type" "halfmul")])
1408 (define_insn "*mulchwu"
1409 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1410 (mult:SI (lshiftrt:SI
1411 (match_operand:SI 2 "gpc_reg_operand" "r")
1414 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1417 [(set_attr "type" "halfmul")])
1419 (define_insn "*mulhhwc"
1420 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1421 (compare:CC (mult:SI (ashiftrt:SI
1422 (match_operand:SI 1 "gpc_reg_operand" "%r")
1425 (match_operand:SI 2 "gpc_reg_operand" "r")
1428 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1429 (mult:SI (ashiftrt:SI
1437 [(set_attr "type" "halfmul")])
1439 (define_insn "*mulhhw"
1440 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1441 (mult:SI (ashiftrt:SI
1442 (match_operand:SI 1 "gpc_reg_operand" "%r")
1445 (match_operand:SI 2 "gpc_reg_operand" "r")
1449 [(set_attr "type" "halfmul")])
1451 (define_insn "*mulhhwuc"
1452 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1453 (compare:CC (mult:SI (lshiftrt:SI
1454 (match_operand:SI 1 "gpc_reg_operand" "%r")
1457 (match_operand:SI 2 "gpc_reg_operand" "r")
1460 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1461 (mult:SI (lshiftrt:SI
1469 [(set_attr "type" "halfmul")])
1471 (define_insn "*mulhhwu"
1472 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1473 (mult:SI (lshiftrt:SI
1474 (match_operand:SI 1 "gpc_reg_operand" "%r")
1477 (match_operand:SI 2 "gpc_reg_operand" "r")
1481 [(set_attr "type" "halfmul")])
1483 (define_insn "*mullhwc"
1484 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1485 (compare:CC (mult:SI (sign_extend:SI
1486 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1488 (match_operand:HI 2 "gpc_reg_operand" "r")))
1490 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1491 (mult:SI (sign_extend:SI
1497 [(set_attr "type" "halfmul")])
1499 (define_insn "*mullhw"
1500 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1501 (mult:SI (sign_extend:SI
1502 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1504 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1507 [(set_attr "type" "halfmul")])
1509 (define_insn "*mullhwuc"
1510 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1511 (compare:CC (mult:SI (zero_extend:SI
1512 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1514 (match_operand:HI 2 "gpc_reg_operand" "r")))
1516 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1517 (mult:SI (zero_extend:SI
1523 [(set_attr "type" "halfmul")])
1525 (define_insn "*mullhwu"
1526 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1527 (mult:SI (zero_extend:SI
1528 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1530 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1533 [(set_attr "type" "halfmul")])
1535 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1536 (define_insn "dlmzb"
1537 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1538 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1539 (match_operand:SI 2 "gpc_reg_operand" "r")]
1541 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1542 (unspec:SI [(match_dup 1)
1548 (define_expand "strlensi"
1549 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1550 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1551 (match_operand:QI 2 "const_int_operand" "")
1552 (match_operand 3 "const_int_operand" "")]
1553 UNSPEC_DLMZB_STRLEN))
1554 (clobber (match_scratch:CC 4 "=x"))]
1555 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1557 rtx result = operands[0];
1558 rtx src = operands[1];
1559 rtx search_char = operands[2];
1560 rtx align = operands[3];
1561 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1562 rtx loop_label, end_label, mem, cr0, cond;
1563 if (search_char != const0_rtx
1564 || GET_CODE (align) != CONST_INT
1565 || INTVAL (align) < 8)
1567 word1 = gen_reg_rtx (SImode);
1568 word2 = gen_reg_rtx (SImode);
1569 scratch_dlmzb = gen_reg_rtx (SImode);
1570 scratch_string = gen_reg_rtx (Pmode);
1571 loop_label = gen_label_rtx ();
1572 end_label = gen_label_rtx ();
1573 addr = force_reg (Pmode, XEXP (src, 0));
1574 emit_move_insn (scratch_string, addr);
1575 emit_label (loop_label);
1576 mem = change_address (src, SImode, scratch_string);
1577 emit_move_insn (word1, mem);
1578 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1579 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1580 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1581 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1582 emit_jump_insn (gen_rtx_SET (pc_rtx,
1583 gen_rtx_IF_THEN_ELSE (VOIDmode,
1589 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1590 emit_jump_insn (gen_rtx_SET (pc_rtx,
1591 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1593 emit_label (end_label);
1594 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1595 emit_insn (gen_subsi3 (result, scratch_string, addr));
1596 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1600 ;; Fixed-point arithmetic insns.
1602 (define_expand "add<mode>3"
1603 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1604 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1605 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1608 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1610 rtx lo0 = gen_lowpart (SImode, operands[0]);
1611 rtx lo1 = gen_lowpart (SImode, operands[1]);
1612 rtx lo2 = gen_lowpart (SImode, operands[2]);
1613 rtx hi0 = gen_highpart (SImode, operands[0]);
1614 rtx hi1 = gen_highpart (SImode, operands[1]);
1615 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1617 if (!reg_or_short_operand (lo2, SImode))
1618 lo2 = force_reg (SImode, lo2);
1619 if (!adde_operand (hi2, SImode))
1620 hi2 = force_reg (SImode, hi2);
1622 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1623 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1627 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1629 rtx tmp = ((!can_create_pseudo_p ()
1630 || rtx_equal_p (operands[0], operands[1]))
1631 ? operands[0] : gen_reg_rtx (<MODE>mode));
1633 /* Adding a constant to r0 is not a valid insn, so use a different
1634 strategy in that case. */
1635 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1637 if (operands[0] == operands[1])
1639 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1640 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1644 HOST_WIDE_INT val = INTVAL (operands[2]);
1645 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1646 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1648 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1651 /* The ordering here is important for the prolog expander.
1652 When space is allocated from the stack, adding 'low' first may
1653 produce a temporary deallocation (which would be bad). */
1654 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1655 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1660 (define_insn "*add<mode>3"
1661 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1662 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1663 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1669 [(set_attr "type" "add")])
1671 (define_insn "addsi3_high"
1672 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1673 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1674 (high:SI (match_operand 2 "" ""))))]
1675 "TARGET_MACHO && !TARGET_64BIT"
1676 "addis %0,%1,ha16(%2)"
1677 [(set_attr "type" "add")])
1679 (define_insn_and_split "*add<mode>3_dot"
1680 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1681 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1682 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1684 (clobber (match_scratch:GPR 0 "=r,r"))]
1685 "<MODE>mode == Pmode"
1689 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1691 (plus:GPR (match_dup 1)
1694 (compare:CC (match_dup 0)
1697 [(set_attr "type" "add")
1698 (set_attr "dot" "yes")
1699 (set_attr "length" "4,8")])
1701 (define_insn_and_split "*add<mode>3_dot2"
1702 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1703 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1704 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1706 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1707 (plus:GPR (match_dup 1)
1709 "<MODE>mode == Pmode"
1713 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1715 (plus:GPR (match_dup 1)
1718 (compare:CC (match_dup 0)
1721 [(set_attr "type" "add")
1722 (set_attr "dot" "yes")
1723 (set_attr "length" "4,8")])
1725 (define_insn_and_split "*add<mode>3_imm_dot"
1726 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1727 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1728 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1730 (clobber (match_scratch:GPR 0 "=r,r"))
1731 (clobber (reg:GPR CA_REGNO))]
1732 "<MODE>mode == Pmode"
1736 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1738 (plus:GPR (match_dup 1)
1741 (compare:CC (match_dup 0)
1744 [(set_attr "type" "add")
1745 (set_attr "dot" "yes")
1746 (set_attr "length" "4,8")])
1748 (define_insn_and_split "*add<mode>3_imm_dot2"
1749 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1750 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1751 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1753 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1754 (plus:GPR (match_dup 1)
1756 (clobber (reg:GPR CA_REGNO))]
1757 "<MODE>mode == Pmode"
1761 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1763 (plus:GPR (match_dup 1)
1766 (compare:CC (match_dup 0)
1769 [(set_attr "type" "add")
1770 (set_attr "dot" "yes")
1771 (set_attr "length" "4,8")])
1773 ;; Split an add that we can't do in one insn into two insns, each of which
1774 ;; does one 16-bit part. This is used by combine. Note that the low-order
1775 ;; add should be last in case the result gets used in an address.
1778 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1779 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1780 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1782 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1783 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1785 HOST_WIDE_INT val = INTVAL (operands[2]);
1786 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1787 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1789 operands[4] = GEN_INT (low);
1790 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1791 operands[3] = GEN_INT (rest);
1792 else if (can_create_pseudo_p ())
1794 operands[3] = gen_reg_rtx (DImode);
1795 emit_move_insn (operands[3], operands[2]);
1796 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1804 (define_insn "add<mode>3_carry"
1805 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1806 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1807 (match_operand:P 2 "reg_or_short_operand" "rI")))
1808 (set (reg:P CA_REGNO)
1809 (ltu:P (plus:P (match_dup 1)
1814 [(set_attr "type" "add")])
1816 (define_insn "*add<mode>3_imm_carry_pos"
1817 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1818 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1819 (match_operand:P 2 "short_cint_operand" "n")))
1820 (set (reg:P CA_REGNO)
1821 (geu:P (match_dup 1)
1822 (match_operand:P 3 "const_int_operand" "n")))]
1823 "INTVAL (operands[2]) > 0
1824 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1826 [(set_attr "type" "add")])
1828 (define_insn "*add<mode>3_imm_carry_0"
1829 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1830 (match_operand:P 1 "gpc_reg_operand" "r"))
1831 (set (reg:P CA_REGNO)
1835 [(set_attr "type" "add")])
1837 (define_insn "*add<mode>3_imm_carry_m1"
1838 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1839 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1841 (set (reg:P CA_REGNO)
1846 [(set_attr "type" "add")])
1848 (define_insn "*add<mode>3_imm_carry_neg"
1849 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1850 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1851 (match_operand:P 2 "short_cint_operand" "n")))
1852 (set (reg:P CA_REGNO)
1853 (gtu:P (match_dup 1)
1854 (match_operand:P 3 "const_int_operand" "n")))]
1855 "INTVAL (operands[2]) < 0
1856 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1858 [(set_attr "type" "add")])
1861 (define_expand "add<mode>3_carry_in"
1863 (set (match_operand:GPR 0 "gpc_reg_operand")
1864 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1865 (match_operand:GPR 2 "adde_operand"))
1866 (reg:GPR CA_REGNO)))
1867 (clobber (reg:GPR CA_REGNO))])]
1870 if (operands[2] == const0_rtx)
1872 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1875 if (operands[2] == constm1_rtx)
1877 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1882 (define_insn "*add<mode>3_carry_in_internal"
1883 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1884 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1885 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1886 (reg:GPR CA_REGNO)))
1887 (clobber (reg:GPR CA_REGNO))]
1890 [(set_attr "type" "add")])
1892 (define_insn "add<mode>3_carry_in_0"
1893 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1894 (plus:GPR (match_operand:GPR 1 "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_m1"
1902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1906 (clobber (reg:GPR CA_REGNO))]
1909 [(set_attr "type" "add")])
1912 (define_expand "one_cmpl<mode>2"
1913 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1914 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1917 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1919 rs6000_split_logical (operands, NOT, false, false, false);
1924 (define_insn "*one_cmpl<mode>2"
1925 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1926 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1930 (define_insn_and_split "*one_cmpl<mode>2_dot"
1931 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1932 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1934 (clobber (match_scratch:GPR 0 "=r,r"))]
1935 "<MODE>mode == Pmode"
1939 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1941 (not:GPR (match_dup 1)))
1943 (compare:CC (match_dup 0)
1946 [(set_attr "type" "logical")
1947 (set_attr "dot" "yes")
1948 (set_attr "length" "4,8")])
1950 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1951 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1952 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1954 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1955 (not:GPR (match_dup 1)))]
1956 "<MODE>mode == Pmode"
1960 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1962 (not:GPR (match_dup 1)))
1964 (compare:CC (match_dup 0)
1967 [(set_attr "type" "logical")
1968 (set_attr "dot" "yes")
1969 (set_attr "length" "4,8")])
1972 (define_expand "sub<mode>3"
1973 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1974 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1975 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1978 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1980 rtx lo0 = gen_lowpart (SImode, operands[0]);
1981 rtx lo1 = gen_lowpart (SImode, operands[1]);
1982 rtx lo2 = gen_lowpart (SImode, operands[2]);
1983 rtx hi0 = gen_highpart (SImode, operands[0]);
1984 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1985 rtx hi2 = gen_highpart (SImode, operands[2]);
1987 if (!reg_or_short_operand (lo1, SImode))
1988 lo1 = force_reg (SImode, lo1);
1989 if (!adde_operand (hi1, SImode))
1990 hi1 = force_reg (SImode, hi1);
1992 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1993 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1997 if (short_cint_operand (operands[1], <MODE>mode))
1999 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2004 (define_insn "*subf<mode>3"
2005 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2006 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2007 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2010 [(set_attr "type" "add")])
2012 (define_insn_and_split "*subf<mode>3_dot"
2013 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2014 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2015 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2017 (clobber (match_scratch:GPR 0 "=r,r"))]
2018 "<MODE>mode == Pmode"
2022 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2024 (minus:GPR (match_dup 2)
2027 (compare:CC (match_dup 0)
2030 [(set_attr "type" "add")
2031 (set_attr "dot" "yes")
2032 (set_attr "length" "4,8")])
2034 (define_insn_and_split "*subf<mode>3_dot2"
2035 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2036 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2037 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2039 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2040 (minus:GPR (match_dup 2)
2042 "<MODE>mode == Pmode"
2046 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2048 (minus:GPR (match_dup 2)
2051 (compare:CC (match_dup 0)
2054 [(set_attr "type" "add")
2055 (set_attr "dot" "yes")
2056 (set_attr "length" "4,8")])
2058 (define_insn "subf<mode>3_imm"
2059 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2060 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2061 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2062 (clobber (reg:GPR CA_REGNO))]
2065 [(set_attr "type" "add")])
2067 (define_insn_and_split "subf<mode>3_carry_dot2"
2068 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2069 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2070 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2072 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2073 (minus:P (match_dup 2)
2075 (set (reg:P CA_REGNO)
2076 (leu:P (match_dup 1)
2078 "<MODE>mode == Pmode"
2082 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2083 [(parallel [(set (match_dup 0)
2084 (minus:P (match_dup 2)
2086 (set (reg:P CA_REGNO)
2087 (leu:P (match_dup 1)
2090 (compare:CC (match_dup 0)
2093 [(set_attr "type" "add")
2094 (set_attr "dot" "yes")
2095 (set_attr "length" "4,8")])
2097 (define_insn "subf<mode>3_carry"
2098 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2099 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2100 (match_operand:P 1 "gpc_reg_operand" "r")))
2101 (set (reg:P CA_REGNO)
2102 (leu:P (match_dup 1)
2106 [(set_attr "type" "add")])
2108 (define_insn "*subf<mode>3_imm_carry_0"
2109 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2110 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2111 (set (reg:P CA_REGNO)
2116 [(set_attr "type" "add")])
2118 (define_insn "*subf<mode>3_imm_carry_m1"
2119 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2120 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2121 (set (reg:P CA_REGNO)
2125 [(set_attr "type" "add")])
2128 (define_expand "subf<mode>3_carry_in"
2130 (set (match_operand:GPR 0 "gpc_reg_operand")
2131 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2133 (match_operand:GPR 2 "adde_operand")))
2134 (clobber (reg:GPR CA_REGNO))])]
2137 if (operands[2] == const0_rtx)
2139 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2142 if (operands[2] == constm1_rtx)
2144 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2149 (define_insn "*subf<mode>3_carry_in_internal"
2150 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2151 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2153 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2154 (clobber (reg:GPR CA_REGNO))]
2157 [(set_attr "type" "add")])
2159 (define_insn "subf<mode>3_carry_in_0"
2160 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2161 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2162 (reg:GPR CA_REGNO)))
2163 (clobber (reg:GPR CA_REGNO))]
2166 [(set_attr "type" "add")])
2168 (define_insn "subf<mode>3_carry_in_m1"
2169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2170 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2171 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2173 (clobber (reg:GPR CA_REGNO))]
2176 [(set_attr "type" "add")])
2178 (define_insn "subf<mode>3_carry_in_xx"
2179 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180 (plus:GPR (reg:GPR CA_REGNO)
2182 (clobber (reg:GPR CA_REGNO))]
2185 [(set_attr "type" "add")])
2188 (define_insn "neg<mode>2"
2189 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2190 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2193 [(set_attr "type" "add")])
2195 (define_insn_and_split "*neg<mode>2_dot"
2196 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2197 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2199 (clobber (match_scratch:GPR 0 "=r,r"))]
2200 "<MODE>mode == Pmode"
2204 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2206 (neg:GPR (match_dup 1)))
2208 (compare:CC (match_dup 0)
2211 [(set_attr "type" "add")
2212 (set_attr "dot" "yes")
2213 (set_attr "length" "4,8")])
2215 (define_insn_and_split "*neg<mode>2_dot2"
2216 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2217 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2219 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2220 (neg:GPR (match_dup 1)))]
2221 "<MODE>mode == Pmode"
2225 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2227 (neg:GPR (match_dup 1)))
2229 (compare:CC (match_dup 0)
2232 [(set_attr "type" "add")
2233 (set_attr "dot" "yes")
2234 (set_attr "length" "4,8")])
2237 (define_insn "clz<mode>2"
2238 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2239 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2242 [(set_attr "type" "cntlz")])
2244 (define_expand "ctz<mode>2"
2245 [(set (match_operand:GPR 0 "gpc_reg_operand")
2246 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2251 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2255 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2256 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2257 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2261 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2262 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2263 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2264 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2268 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2269 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2270 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2271 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2277 (define_insn "ctz<mode>2_hw"
2278 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2279 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2282 [(set_attr "type" "cntlz")])
2284 (define_expand "ffs<mode>2"
2285 [(set (match_operand:GPR 0 "gpc_reg_operand")
2286 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2289 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2290 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2291 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2292 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2293 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2294 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2295 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2300 (define_expand "popcount<mode>2"
2301 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2302 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2303 "TARGET_POPCNTB || TARGET_POPCNTD"
2305 rs6000_emit_popcount (operands[0], operands[1]);
2309 (define_insn "popcntb<mode>2"
2310 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2311 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2315 [(set_attr "type" "popcnt")])
2317 (define_insn "popcntd<mode>2"
2318 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2319 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2322 [(set_attr "type" "popcnt")])
2325 (define_expand "parity<mode>2"
2326 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2327 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2330 rs6000_emit_parity (operands[0], operands[1]);
2334 (define_insn "parity<mode>2_cmpb"
2335 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2336 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2337 "TARGET_CMPB && TARGET_POPCNTB"
2339 [(set_attr "type" "popcnt")])
2341 (define_insn "cmpb<mode>3"
2342 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2343 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2344 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2347 [(set_attr "type" "cmp")])
2349 ;; Since the hardware zeros the upper part of the register, save generating the
2350 ;; AND immediate if we are converting to unsigned
2351 (define_insn "*bswap<mode>2_extenddi"
2352 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2354 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2357 [(set_attr "length" "4")
2358 (set_attr "type" "load")])
2360 (define_insn "*bswaphi2_extendsi"
2361 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2363 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2366 [(set_attr "length" "4")
2367 (set_attr "type" "load")])
2369 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2370 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2371 ;; load with byte swap, which can be slower than doing it in the registers. It
2372 ;; also prevents certain failures with the RELOAD register allocator.
2374 (define_expand "bswap<mode>2"
2375 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2376 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2379 rtx dest = operands[0];
2380 rtx src = operands[1];
2382 if (!REG_P (dest) && !REG_P (src))
2383 src = force_reg (<MODE>mode, src);
2386 emit_insn (gen_bswap<mode>2_load (dest, src));
2387 else if (MEM_P (dest))
2388 emit_insn (gen_bswap<mode>2_store (dest, src));
2390 emit_insn (gen_bswap<mode>2_reg (dest, src));
2394 (define_insn "bswap<mode>2_load"
2395 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2396 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2399 [(set_attr "type" "load")])
2401 (define_insn "bswap<mode>2_store"
2402 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2403 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2406 [(set_attr "type" "store")])
2408 (define_insn_and_split "bswaphi2_reg"
2409 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
2411 (match_operand:HI 1 "gpc_reg_operand" "r")))
2412 (clobber (match_scratch:SI 2 "=&r"))]
2417 (and:SI (lshiftrt:SI (match_dup 4)
2421 (and:SI (ashift:SI (match_dup 4)
2423 (const_int 65280))) ;; 0xff00
2425 (ior:SI (match_dup 3)
2428 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2429 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2431 [(set_attr "length" "12")
2432 (set_attr "type" "*")])
2434 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2435 ;; zero_extract insns do not change for -mlittle.
2436 (define_insn_and_split "bswapsi2_reg"
2437 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
2439 (match_operand:SI 1 "gpc_reg_operand" "r")))]
2443 [(set (match_dup 0) ; DABC
2444 (rotate:SI (match_dup 1)
2446 (set (match_dup 0) ; DCBC
2447 (ior:SI (and:SI (ashift:SI (match_dup 1)
2449 (const_int 16711680))
2450 (and:SI (match_dup 0)
2451 (const_int -16711681))))
2452 (set (match_dup 0) ; DCBA
2453 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2456 (and:SI (match_dup 0)
2457 (const_int -256))))]
2460 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2461 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2464 (define_expand "bswapdi2"
2465 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2467 (match_operand:DI 1 "reg_or_mem_operand" "")))
2468 (clobber (match_scratch:DI 2 ""))
2469 (clobber (match_scratch:DI 3 ""))])]
2472 rtx dest = operands[0];
2473 rtx src = operands[1];
2475 if (!REG_P (dest) && !REG_P (src))
2476 operands[1] = src = force_reg (DImode, src);
2478 if (TARGET_POWERPC64 && TARGET_LDBRX)
2481 emit_insn (gen_bswapdi2_load (dest, src));
2482 else if (MEM_P (dest))
2483 emit_insn (gen_bswapdi2_store (dest, src));
2485 emit_insn (gen_bswapdi2_reg (dest, src));
2489 if (!TARGET_POWERPC64)
2491 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2492 that uses 64-bit registers needs the same scratch registers as 64-bit
2494 emit_insn (gen_bswapdi2_32bit (dest, src));
2499 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2500 (define_insn "bswapdi2_load"
2501 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2502 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2503 "TARGET_POWERPC64 && TARGET_LDBRX"
2505 [(set_attr "type" "load")])
2507 (define_insn "bswapdi2_store"
2508 [(set (match_operand:DI 0 "memory_operand" "=Z")
2509 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2510 "TARGET_POWERPC64 && TARGET_LDBRX"
2512 [(set_attr "type" "store")])
2514 (define_insn "bswapdi2_reg"
2515 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2516 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2517 (clobber (match_scratch:DI 2 "=&r"))
2518 (clobber (match_scratch:DI 3 "=&r"))]
2519 "TARGET_POWERPC64 && TARGET_LDBRX"
2521 [(set_attr "length" "36")])
2523 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2524 (define_insn "*bswapdi2_64bit"
2525 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2526 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2527 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2528 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2529 "TARGET_POWERPC64 && !TARGET_LDBRX
2530 && (REG_P (operands[0]) || REG_P (operands[1]))
2531 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2532 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2534 [(set_attr "length" "16,12,36")])
2537 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2538 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2539 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2540 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2541 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2545 rtx dest = operands[0];
2546 rtx src = operands[1];
2547 rtx op2 = operands[2];
2548 rtx op3 = operands[3];
2549 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2550 BYTES_BIG_ENDIAN ? 4 : 0);
2551 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2552 BYTES_BIG_ENDIAN ? 4 : 0);
2558 addr1 = XEXP (src, 0);
2559 if (GET_CODE (addr1) == PLUS)
2561 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2562 if (TARGET_AVOID_XFORM)
2564 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2568 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2570 else if (TARGET_AVOID_XFORM)
2572 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2577 emit_move_insn (op2, GEN_INT (4));
2578 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2581 word1 = change_address (src, SImode, addr1);
2582 word2 = change_address (src, SImode, addr2);
2584 if (BYTES_BIG_ENDIAN)
2586 emit_insn (gen_bswapsi2 (op3_32, word2));
2587 emit_insn (gen_bswapsi2 (dest_32, word1));
2591 emit_insn (gen_bswapsi2 (op3_32, word1));
2592 emit_insn (gen_bswapsi2 (dest_32, word2));
2595 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2596 emit_insn (gen_iordi3 (dest, dest, op3));
2601 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2602 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2603 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2604 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2605 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2609 rtx dest = operands[0];
2610 rtx src = operands[1];
2611 rtx op2 = operands[2];
2612 rtx op3 = operands[3];
2613 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2614 BYTES_BIG_ENDIAN ? 4 : 0);
2615 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2616 BYTES_BIG_ENDIAN ? 4 : 0);
2622 addr1 = XEXP (dest, 0);
2623 if (GET_CODE (addr1) == PLUS)
2625 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2626 if (TARGET_AVOID_XFORM)
2628 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2632 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2634 else if (TARGET_AVOID_XFORM)
2636 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2641 emit_move_insn (op2, GEN_INT (4));
2642 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2645 word1 = change_address (dest, SImode, addr1);
2646 word2 = change_address (dest, SImode, addr2);
2648 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2650 if (BYTES_BIG_ENDIAN)
2652 emit_insn (gen_bswapsi2 (word1, src_si));
2653 emit_insn (gen_bswapsi2 (word2, op3_si));
2657 emit_insn (gen_bswapsi2 (word2, src_si));
2658 emit_insn (gen_bswapsi2 (word1, op3_si));
2664 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2665 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2666 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2667 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2668 "TARGET_POWERPC64 && reload_completed"
2672 rtx dest = operands[0];
2673 rtx src = operands[1];
2674 rtx op2 = operands[2];
2675 rtx op3 = operands[3];
2676 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2677 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2678 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2679 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2680 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2682 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2683 emit_insn (gen_bswapsi2 (dest_si, src_si));
2684 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2685 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2686 emit_insn (gen_iordi3 (dest, dest, op3));
2690 (define_insn "bswapdi2_32bit"
2691 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2692 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2693 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2694 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2696 [(set_attr "length" "16,12,36")])
2699 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2700 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2701 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2702 "!TARGET_POWERPC64 && reload_completed"
2706 rtx dest = operands[0];
2707 rtx src = operands[1];
2708 rtx op2 = operands[2];
2709 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2710 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2716 addr1 = XEXP (src, 0);
2717 if (GET_CODE (addr1) == PLUS)
2719 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2720 if (TARGET_AVOID_XFORM
2721 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2723 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2727 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2729 else if (TARGET_AVOID_XFORM
2730 || REGNO (addr1) == REGNO (dest2))
2732 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2737 emit_move_insn (op2, GEN_INT (4));
2738 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2741 word1 = change_address (src, SImode, addr1);
2742 word2 = change_address (src, SImode, addr2);
2744 emit_insn (gen_bswapsi2 (dest2, word1));
2745 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2746 thus allowing us to omit an early clobber on the output. */
2747 emit_insn (gen_bswapsi2 (dest1, word2));
2752 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2753 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2754 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2755 "!TARGET_POWERPC64 && reload_completed"
2759 rtx dest = operands[0];
2760 rtx src = operands[1];
2761 rtx op2 = operands[2];
2762 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2763 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2769 addr1 = XEXP (dest, 0);
2770 if (GET_CODE (addr1) == PLUS)
2772 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2773 if (TARGET_AVOID_XFORM)
2775 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2779 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2781 else if (TARGET_AVOID_XFORM)
2783 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2788 emit_move_insn (op2, GEN_INT (4));
2789 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2792 word1 = change_address (dest, SImode, addr1);
2793 word2 = change_address (dest, SImode, addr2);
2795 emit_insn (gen_bswapsi2 (word2, src1));
2796 emit_insn (gen_bswapsi2 (word1, src2));
2801 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2802 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2803 (clobber (match_operand:SI 2 "" ""))]
2804 "!TARGET_POWERPC64 && reload_completed"
2808 rtx dest = operands[0];
2809 rtx src = operands[1];
2810 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2811 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2812 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2813 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2815 emit_insn (gen_bswapsi2 (dest1, src2));
2816 emit_insn (gen_bswapsi2 (dest2, src1));
2821 (define_insn "mul<mode>3"
2822 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2823 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2824 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2829 [(set_attr "type" "mul")
2831 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2833 (match_operand:GPR 2 "short_cint_operand" "")
2834 (const_string "16")]
2835 (const_string "<bits>")))])
2837 (define_insn_and_split "*mul<mode>3_dot"
2838 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2839 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2840 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2842 (clobber (match_scratch:GPR 0 "=r,r"))]
2843 "<MODE>mode == Pmode"
2847 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2849 (mult:GPR (match_dup 1)
2852 (compare:CC (match_dup 0)
2855 [(set_attr "type" "mul")
2856 (set_attr "size" "<bits>")
2857 (set_attr "dot" "yes")
2858 (set_attr "length" "4,8")])
2860 (define_insn_and_split "*mul<mode>3_dot2"
2861 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2862 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2863 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2865 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2866 (mult:GPR (match_dup 1)
2868 "<MODE>mode == Pmode"
2872 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2874 (mult:GPR (match_dup 1)
2877 (compare:CC (match_dup 0)
2880 [(set_attr "type" "mul")
2881 (set_attr "size" "<bits>")
2882 (set_attr "dot" "yes")
2883 (set_attr "length" "4,8")])
2886 (define_expand "<su>mul<mode>3_highpart"
2887 [(set (match_operand:GPR 0 "gpc_reg_operand")
2889 (mult:<DMODE> (any_extend:<DMODE>
2890 (match_operand:GPR 1 "gpc_reg_operand"))
2892 (match_operand:GPR 2 "gpc_reg_operand")))
2896 if (<MODE>mode == SImode && TARGET_POWERPC64)
2898 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2903 if (!WORDS_BIG_ENDIAN)
2905 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2911 (define_insn "*<su>mul<mode>3_highpart"
2912 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2914 (mult:<DMODE> (any_extend:<DMODE>
2915 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2917 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2919 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2920 "mulh<wd><u> %0,%1,%2"
2921 [(set_attr "type" "mul")
2922 (set_attr "size" "<bits>")])
2924 (define_insn "<su>mulsi3_highpart_le"
2925 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2927 (mult:DI (any_extend:DI
2928 (match_operand:SI 1 "gpc_reg_operand" "r"))
2930 (match_operand:SI 2 "gpc_reg_operand" "r")))
2932 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2934 [(set_attr "type" "mul")])
2936 (define_insn "<su>muldi3_highpart_le"
2937 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2939 (mult:TI (any_extend:TI
2940 (match_operand:DI 1 "gpc_reg_operand" "r"))
2942 (match_operand:DI 2 "gpc_reg_operand" "r")))
2944 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2946 [(set_attr "type" "mul")
2947 (set_attr "size" "64")])
2949 (define_insn "<su>mulsi3_highpart_64"
2950 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2953 (mult:DI (any_extend:DI
2954 (match_operand:SI 1 "gpc_reg_operand" "r"))
2956 (match_operand:SI 2 "gpc_reg_operand" "r")))
2960 [(set_attr "type" "mul")])
2962 (define_expand "<u>mul<mode><dmode>3"
2963 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2964 (mult:<DMODE> (any_extend:<DMODE>
2965 (match_operand:GPR 1 "gpc_reg_operand"))
2967 (match_operand:GPR 2 "gpc_reg_operand"))))]
2968 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2970 rtx l = gen_reg_rtx (<MODE>mode);
2971 rtx h = gen_reg_rtx (<MODE>mode);
2972 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2973 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2974 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2975 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2979 (define_insn "*maddld4"
2980 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2981 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2982 (match_operand:DI 2 "gpc_reg_operand" "r"))
2983 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2985 "maddld %0,%1,%2,%3"
2986 [(set_attr "type" "mul")])
2988 (define_insn "udiv<mode>3"
2989 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2990 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2991 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2994 [(set_attr "type" "div")
2995 (set_attr "size" "<bits>")])
2998 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2999 ;; modulus. If it isn't a power of two, force operands into register and do
3001 (define_expand "div<mode>3"
3002 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3003 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3004 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3007 if (CONST_INT_P (operands[2])
3008 && INTVAL (operands[2]) > 0
3009 && exact_log2 (INTVAL (operands[2])) >= 0)
3011 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3015 operands[2] = force_reg (<MODE>mode, operands[2]);
3018 (define_insn "*div<mode>3"
3019 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3020 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3021 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3024 [(set_attr "type" "div")
3025 (set_attr "size" "<bits>")])
3027 (define_insn "div<mode>3_sra"
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 "exact_log2_cint_operand" "N")))
3031 (clobber (reg:GPR CA_REGNO))]
3033 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3034 [(set_attr "type" "two")
3035 (set_attr "length" "8")])
3037 (define_insn_and_split "*div<mode>3_sra_dot"
3038 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3039 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3040 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3042 (clobber (match_scratch:GPR 0 "=r,r"))
3043 (clobber (reg:GPR CA_REGNO))]
3044 "<MODE>mode == Pmode"
3046 sra<wd>i %0,%1,%p2\;addze. %0,%0
3048 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3049 [(parallel [(set (match_dup 0)
3050 (div:GPR (match_dup 1)
3052 (clobber (reg:GPR CA_REGNO))])
3054 (compare:CC (match_dup 0)
3057 [(set_attr "type" "two")
3058 (set_attr "length" "8,12")
3059 (set_attr "cell_micro" "not")])
3061 (define_insn_and_split "*div<mode>3_sra_dot2"
3062 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3063 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3064 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3066 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3067 (div:GPR (match_dup 1)
3069 (clobber (reg:GPR CA_REGNO))]
3070 "<MODE>mode == Pmode"
3072 sra<wd>i %0,%1,%p2\;addze. %0,%0
3074 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3075 [(parallel [(set (match_dup 0)
3076 (div:GPR (match_dup 1)
3078 (clobber (reg:GPR CA_REGNO))])
3080 (compare:CC (match_dup 0)
3083 [(set_attr "type" "two")
3084 (set_attr "length" "8,12")
3085 (set_attr "cell_micro" "not")])
3087 (define_expand "mod<mode>3"
3088 [(set (match_operand:GPR 0 "gpc_reg_operand")
3089 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3090 (match_operand:GPR 2 "reg_or_cint_operand")))]
3097 if (GET_CODE (operands[2]) != CONST_INT
3098 || INTVAL (operands[2]) <= 0
3099 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3104 operands[2] = force_reg (<MODE>mode, operands[2]);
3108 temp1 = gen_reg_rtx (<MODE>mode);
3109 temp2 = gen_reg_rtx (<MODE>mode);
3111 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3112 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3113 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3118 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3119 ;; mod, prefer putting the result of mod into a different register
3120 (define_insn "*mod<mode>3"
3121 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3122 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3123 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3126 [(set_attr "type" "div")
3127 (set_attr "size" "<bits>")])
3130 (define_insn "umod<mode>3"
3131 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3132 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3133 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3136 [(set_attr "type" "div")
3137 (set_attr "size" "<bits>")])
3139 ;; On machines with modulo support, do a combined div/mod the old fashioned
3140 ;; method, since the multiply/subtract is faster than doing the mod instruction
3144 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3145 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3146 (match_operand:GPR 2 "gpc_reg_operand" "")))
3147 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3148 (mod:GPR (match_dup 1)
3151 && ! reg_mentioned_p (operands[0], operands[1])
3152 && ! reg_mentioned_p (operands[0], operands[2])
3153 && ! reg_mentioned_p (operands[3], operands[1])
3154 && ! reg_mentioned_p (operands[3], operands[2])"
3156 (div:GPR (match_dup 1)
3159 (mult:GPR (match_dup 0)
3162 (minus:GPR (match_dup 1)
3166 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3167 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3168 (match_operand:GPR 2 "gpc_reg_operand" "")))
3169 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3170 (umod:GPR (match_dup 1)
3173 && ! reg_mentioned_p (operands[0], operands[1])
3174 && ! reg_mentioned_p (operands[0], operands[2])
3175 && ! reg_mentioned_p (operands[3], operands[1])
3176 && ! reg_mentioned_p (operands[3], operands[2])"
3178 (udiv:GPR (match_dup 1)
3181 (mult:GPR (match_dup 0)
3184 (minus:GPR (match_dup 1)
3188 ;; Logical instructions
3189 ;; The logical instructions are mostly combined by using match_operator,
3190 ;; but the plain AND insns are somewhat different because there is no
3191 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3192 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3194 (define_expand "and<mode>3"
3195 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3196 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3197 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3200 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3202 rs6000_split_logical (operands, AND, false, false, false);
3206 if (CONST_INT_P (operands[2]))
3208 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3210 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3214 if (logical_const_operand (operands[2], <MODE>mode))
3216 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3220 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3222 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3226 operands[2] = force_reg (<MODE>mode, operands[2]);
3231 (define_insn "and<mode>3_imm"
3232 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3233 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3234 (match_operand:GPR 2 "logical_const_operand" "n")))
3235 (clobber (match_scratch:CC 3 "=x"))]
3236 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3237 "andi%e2. %0,%1,%u2"
3238 [(set_attr "type" "logical")
3239 (set_attr "dot" "yes")])
3241 (define_insn_and_split "*and<mode>3_imm_dot"
3242 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3243 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3244 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3246 (clobber (match_scratch:GPR 0 "=r,r"))
3247 (clobber (match_scratch:CC 4 "=X,x"))]
3248 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3249 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3253 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3254 [(parallel [(set (match_dup 0)
3255 (and:GPR (match_dup 1)
3257 (clobber (match_dup 4))])
3259 (compare:CC (match_dup 0)
3262 [(set_attr "type" "logical")
3263 (set_attr "dot" "yes")
3264 (set_attr "length" "4,8")])
3266 (define_insn_and_split "*and<mode>3_imm_dot2"
3267 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3268 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3269 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3271 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3272 (and:GPR (match_dup 1)
3274 (clobber (match_scratch:CC 4 "=X,x"))]
3275 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3276 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3280 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3281 [(parallel [(set (match_dup 0)
3282 (and:GPR (match_dup 1)
3284 (clobber (match_dup 4))])
3286 (compare:CC (match_dup 0)
3289 [(set_attr "type" "logical")
3290 (set_attr "dot" "yes")
3291 (set_attr "length" "4,8")])
3293 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3294 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3295 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3296 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3298 (clobber (match_scratch:GPR 0 "=r,r"))]
3299 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3300 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3304 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3306 (and:GPR (match_dup 1)
3309 (compare:CC (match_dup 0)
3312 [(set_attr "type" "logical")
3313 (set_attr "dot" "yes")
3314 (set_attr "length" "4,8")])
3316 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3317 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3318 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3319 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3321 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3322 (and:GPR (match_dup 1)
3324 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3325 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3329 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3331 (and:GPR (match_dup 1)
3334 (compare:CC (match_dup 0)
3337 [(set_attr "type" "logical")
3338 (set_attr "dot" "yes")
3339 (set_attr "length" "4,8")])
3341 (define_insn "*and<mode>3_imm_dot_shifted"
3342 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3345 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3346 (match_operand:SI 4 "const_int_operand" "n"))
3347 (match_operand:GPR 2 "const_int_operand" "n"))
3349 (clobber (match_scratch:GPR 0 "=r"))]
3350 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3351 << INTVAL (operands[4])),
3353 && (<MODE>mode == Pmode
3354 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3356 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3357 return "andi%e2. %0,%1,%u2";
3359 [(set_attr "type" "logical")
3360 (set_attr "dot" "yes")])
3363 (define_insn "and<mode>3_mask"
3364 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3365 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3366 (match_operand:GPR 2 "const_int_operand" "n")))]
3367 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3369 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3371 [(set_attr "type" "shift")])
3373 (define_insn_and_split "*and<mode>3_mask_dot"
3374 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3375 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3376 (match_operand:GPR 2 "const_int_operand" "n,n"))
3378 (clobber (match_scratch:GPR 0 "=r,r"))]
3379 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3380 && !logical_const_operand (operands[2], <MODE>mode)
3381 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3383 if (which_alternative == 0)
3384 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3388 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3390 (and:GPR (match_dup 1)
3393 (compare:CC (match_dup 0)
3396 [(set_attr "type" "shift")
3397 (set_attr "dot" "yes")
3398 (set_attr "length" "4,8")])
3400 (define_insn_and_split "*and<mode>3_mask_dot2"
3401 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3402 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3403 (match_operand:GPR 2 "const_int_operand" "n,n"))
3405 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3406 (and:GPR (match_dup 1)
3408 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3409 && !logical_const_operand (operands[2], <MODE>mode)
3410 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3412 if (which_alternative == 0)
3413 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3417 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3419 (and:GPR (match_dup 1)
3422 (compare:CC (match_dup 0)
3425 [(set_attr "type" "shift")
3426 (set_attr "dot" "yes")
3427 (set_attr "length" "4,8")])
3430 (define_insn_and_split "*and<mode>3_2insn"
3431 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3432 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3433 (match_operand:GPR 2 "const_int_operand" "n")))]
3434 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3435 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3436 || logical_const_operand (operands[2], <MODE>mode))"
3441 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3444 [(set_attr "type" "shift")
3445 (set_attr "length" "8")])
3447 (define_insn_and_split "*and<mode>3_2insn_dot"
3448 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3449 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3450 (match_operand:GPR 2 "const_int_operand" "n,n"))
3452 (clobber (match_scratch:GPR 0 "=r,r"))]
3453 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3454 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3455 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3456 || logical_const_operand (operands[2], <MODE>mode))"
3458 "&& reload_completed"
3461 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3464 [(set_attr "type" "shift")
3465 (set_attr "dot" "yes")
3466 (set_attr "length" "8,12")])
3468 (define_insn_and_split "*and<mode>3_2insn_dot2"
3469 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3470 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3471 (match_operand:GPR 2 "const_int_operand" "n,n"))
3473 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3474 (and:GPR (match_dup 1)
3476 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3477 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3478 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3479 || logical_const_operand (operands[2], <MODE>mode))"
3481 "&& reload_completed"
3484 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3487 [(set_attr "type" "shift")
3488 (set_attr "dot" "yes")
3489 (set_attr "length" "8,12")])
3492 (define_expand "<code><mode>3"
3493 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3494 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3495 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3498 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3500 rs6000_split_logical (operands, <CODE>, false, false, false);
3504 if (non_logical_cint_operand (operands[2], <MODE>mode))
3506 rtx tmp = ((!can_create_pseudo_p ()
3507 || rtx_equal_p (operands[0], operands[1]))
3508 ? operands[0] : gen_reg_rtx (<MODE>mode));
3510 HOST_WIDE_INT value = INTVAL (operands[2]);
3511 HOST_WIDE_INT lo = value & 0xffff;
3512 HOST_WIDE_INT hi = value - lo;
3514 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3515 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3519 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3520 operands[2] = force_reg (<MODE>mode, operands[2]);
3524 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3525 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3526 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3529 (iorxor:GPR (match_dup 1)
3532 (iorxor:GPR (match_dup 3)
3535 operands[3] = ((!can_create_pseudo_p ()
3536 || rtx_equal_p (operands[0], operands[1]))
3537 ? operands[0] : gen_reg_rtx (<MODE>mode));
3539 HOST_WIDE_INT value = INTVAL (operands[2]);
3540 HOST_WIDE_INT lo = value & 0xffff;
3541 HOST_WIDE_INT hi = value - lo;
3543 operands[4] = GEN_INT (hi);
3544 operands[5] = GEN_INT (lo);
3547 (define_insn "*bool<mode>3_imm"
3548 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3549 (match_operator:GPR 3 "boolean_or_operator"
3550 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3551 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3554 [(set_attr "type" "logical")])
3556 (define_insn "*bool<mode>3"
3557 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3558 (match_operator:GPR 3 "boolean_operator"
3559 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3560 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3563 [(set_attr "type" "logical")])
3565 (define_insn_and_split "*bool<mode>3_dot"
3566 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3567 (compare:CC (match_operator:GPR 3 "boolean_operator"
3568 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3569 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3571 (clobber (match_scratch:GPR 0 "=r,r"))]
3572 "<MODE>mode == Pmode"
3576 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3580 (compare:CC (match_dup 0)
3583 [(set_attr "type" "logical")
3584 (set_attr "dot" "yes")
3585 (set_attr "length" "4,8")])
3587 (define_insn_and_split "*bool<mode>3_dot2"
3588 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3589 (compare:CC (match_operator:GPR 3 "boolean_operator"
3590 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3591 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3593 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3595 "<MODE>mode == Pmode"
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")])
3611 (define_insn "*boolc<mode>3"
3612 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3613 (match_operator:GPR 3 "boolean_operator"
3614 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3615 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3618 [(set_attr "type" "logical")])
3620 (define_insn_and_split "*boolc<mode>3_dot"
3621 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3622 (compare:CC (match_operator:GPR 3 "boolean_operator"
3623 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3624 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3626 (clobber (match_scratch:GPR 0 "=r,r"))]
3627 "<MODE>mode == Pmode"
3631 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3635 (compare:CC (match_dup 0)
3638 [(set_attr "type" "logical")
3639 (set_attr "dot" "yes")
3640 (set_attr "length" "4,8")])
3642 (define_insn_and_split "*boolc<mode>3_dot2"
3643 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3644 (compare:CC (match_operator:GPR 3 "boolean_operator"
3645 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3646 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3648 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3650 "<MODE>mode == Pmode"
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")])
3666 (define_insn "*boolcc<mode>3"
3667 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3668 (match_operator:GPR 3 "boolean_operator"
3669 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3670 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3673 [(set_attr "type" "logical")])
3675 (define_insn_and_split "*boolcc<mode>3_dot"
3676 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3677 (compare:CC (match_operator:GPR 3 "boolean_operator"
3678 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3679 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3681 (clobber (match_scratch:GPR 0 "=r,r"))]
3682 "<MODE>mode == Pmode"
3686 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3690 (compare:CC (match_dup 0)
3693 [(set_attr "type" "logical")
3694 (set_attr "dot" "yes")
3695 (set_attr "length" "4,8")])
3697 (define_insn_and_split "*boolcc<mode>3_dot2"
3698 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3699 (compare:CC (match_operator:GPR 3 "boolean_operator"
3700 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3701 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3703 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3705 "<MODE>mode == Pmode"
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")])
3721 ;; TODO: Should have dots of this as well.
3722 (define_insn "*eqv<mode>3"
3723 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3724 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3725 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3728 [(set_attr "type" "logical")])
3730 ;; Rotate-and-mask and insert.
3732 (define_insn "*rotl<mode>3_mask"
3733 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3734 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3735 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3736 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3737 (match_operand:GPR 3 "const_int_operand" "n")))]
3738 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3740 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3742 [(set_attr "type" "shift")
3743 (set_attr "maybe_var_shift" "yes")])
3745 (define_insn_and_split "*rotl<mode>3_mask_dot"
3746 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3748 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3749 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3750 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3751 (match_operand:GPR 3 "const_int_operand" "n,n"))
3753 (clobber (match_scratch:GPR 0 "=r,r"))]
3754 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3755 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3757 if (which_alternative == 0)
3758 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3762 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3764 (and:GPR (match_dup 4)
3767 (compare:CC (match_dup 0)
3770 [(set_attr "type" "shift")
3771 (set_attr "maybe_var_shift" "yes")
3772 (set_attr "dot" "yes")
3773 (set_attr "length" "4,8")])
3775 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3776 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3778 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3779 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3780 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3781 (match_operand:GPR 3 "const_int_operand" "n,n"))
3783 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3784 (and:GPR (match_dup 4)
3786 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3787 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3789 if (which_alternative == 0)
3790 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3794 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3796 (and:GPR (match_dup 4)
3799 (compare:CC (match_dup 0)
3802 [(set_attr "type" "shift")
3803 (set_attr "maybe_var_shift" "yes")
3804 (set_attr "dot" "yes")
3805 (set_attr "length" "4,8")])
3807 ; Special case for less-than-0. We can do it with just one machine
3808 ; instruction, but the generic optimizers do not realise it is cheap.
3809 (define_insn "*lt0_disi"
3810 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3811 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3814 "rlwinm %0,%1,1,31,31"
3815 [(set_attr "type" "shift")])
3819 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3820 ; both are an AND so are the same precedence).
3821 (define_insn "*rotl<mode>3_insert"
3822 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3823 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3824 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3825 (match_operand:SI 2 "const_int_operand" "n")])
3826 (match_operand:GPR 3 "const_int_operand" "n"))
3827 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3828 (match_operand:GPR 6 "const_int_operand" "n"))))]
3829 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3830 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3832 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3834 [(set_attr "type" "insert")])
3835 ; FIXME: this needs an attr "size", so that the scheduler can see the
3836 ; difference between rlwimi and rldimi. We also might want dot forms,
3837 ; but not for rlwimi on POWER4 and similar processors.
3839 (define_insn "*rotl<mode>3_insert_2"
3840 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3841 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3842 (match_operand:GPR 6 "const_int_operand" "n"))
3843 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3844 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3845 (match_operand:SI 2 "const_int_operand" "n")])
3846 (match_operand:GPR 3 "const_int_operand" "n"))))]
3847 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3848 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3850 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3852 [(set_attr "type" "insert")])
3854 ; There are also some forms without one of the ANDs.
3855 (define_insn "*rotl<mode>3_insert_3"
3856 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3857 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3858 (match_operand:GPR 4 "const_int_operand" "n"))
3859 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3860 (match_operand:SI 2 "const_int_operand" "n"))))]
3861 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3863 if (<MODE>mode == SImode)
3864 return "rlwimi %0,%1,%h2,0,31-%h2";
3866 return "rldimi %0,%1,%H2,0";
3868 [(set_attr "type" "insert")])
3870 (define_insn "*rotl<mode>3_insert_4"
3871 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3872 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3873 (match_operand:GPR 4 "const_int_operand" "n"))
3874 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3875 (match_operand:SI 2 "const_int_operand" "n"))))]
3876 "<MODE>mode == SImode &&
3877 GET_MODE_PRECISION (<MODE>mode)
3878 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3880 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3881 - INTVAL (operands[2]));
3882 if (<MODE>mode == SImode)
3883 return "rlwimi %0,%1,%h2,32-%h2,31";
3885 return "rldimi %0,%1,%H2,64-%H2";
3887 [(set_attr "type" "insert")])
3889 (define_insn "*rotlsi3_insert_5"
3890 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3891 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3892 (match_operand:SI 2 "const_int_operand" "n,n"))
3893 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3894 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3895 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3896 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3897 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3901 [(set_attr "type" "insert")])
3903 (define_insn "*rotldi3_insert_6"
3904 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3905 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3906 (match_operand:DI 2 "const_int_operand" "n"))
3907 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3908 (match_operand:DI 4 "const_int_operand" "n"))))]
3909 "exact_log2 (-UINTVAL (operands[2])) > 0
3910 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3912 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3913 return "rldimi %0,%3,0,%5";
3915 [(set_attr "type" "insert")
3916 (set_attr "size" "64")])
3918 (define_insn "*rotldi3_insert_7"
3919 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3920 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3921 (match_operand:DI 4 "const_int_operand" "n"))
3922 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3923 (match_operand:DI 2 "const_int_operand" "n"))))]
3924 "exact_log2 (-UINTVAL (operands[2])) > 0
3925 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3927 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3928 return "rldimi %0,%3,0,%5";
3930 [(set_attr "type" "insert")
3931 (set_attr "size" "64")])
3934 ; This handles the important case of multiple-precision shifts. There is
3935 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3937 [(set (match_operand:GPR 0 "gpc_reg_operand")
3938 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3939 (match_operand:SI 3 "const_int_operand"))
3940 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3941 (match_operand:SI 4 "const_int_operand"))))]
3942 "can_create_pseudo_p ()
3943 && INTVAL (operands[3]) + INTVAL (operands[4])
3944 >= GET_MODE_PRECISION (<MODE>mode)"
3946 (lshiftrt:GPR (match_dup 2)
3949 (ior:GPR (and:GPR (match_dup 5)
3951 (ashift:GPR (match_dup 1)
3954 unsigned HOST_WIDE_INT mask = 1;
3955 mask = (mask << INTVAL (operands[3])) - 1;
3956 operands[5] = gen_reg_rtx (<MODE>mode);
3957 operands[6] = GEN_INT (mask);
3961 [(set (match_operand:GPR 0 "gpc_reg_operand")
3962 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3963 (match_operand:SI 4 "const_int_operand"))
3964 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3965 (match_operand:SI 3 "const_int_operand"))))]
3966 "can_create_pseudo_p ()
3967 && INTVAL (operands[3]) + INTVAL (operands[4])
3968 >= GET_MODE_PRECISION (<MODE>mode)"
3970 (lshiftrt:GPR (match_dup 2)
3973 (ior:GPR (and:GPR (match_dup 5)
3975 (ashift:GPR (match_dup 1)
3978 unsigned HOST_WIDE_INT mask = 1;
3979 mask = (mask << INTVAL (operands[3])) - 1;
3980 operands[5] = gen_reg_rtx (<MODE>mode);
3981 operands[6] = GEN_INT (mask);
3985 ; Another important case is setting some bits to 1; we can do that with
3986 ; an insert instruction, in many cases.
3987 (define_insn_and_split "*ior<mode>_mask"
3988 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3989 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3990 (match_operand:GPR 2 "const_int_operand" "n")))
3991 (clobber (match_scratch:GPR 3 "=r"))]
3992 "!logical_const_operand (operands[2], <MODE>mode)
3993 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3999 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4002 (and:GPR (match_dup 1)
4006 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4007 if (GET_CODE (operands[3]) == SCRATCH)
4008 operands[3] = gen_reg_rtx (<MODE>mode);
4009 operands[4] = GEN_INT (ne);
4010 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4012 [(set_attr "type" "two")
4013 (set_attr "length" "8")])
4016 ;; Now the simple shifts.
4018 (define_insn "rotl<mode>3"
4019 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4020 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4021 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4023 "rotl<wd>%I2 %0,%1,%<hH>2"
4024 [(set_attr "type" "shift")
4025 (set_attr "maybe_var_shift" "yes")])
4027 (define_insn "*rotlsi3_64"
4028 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4030 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4031 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4033 "rotlw%I2 %0,%1,%h2"
4034 [(set_attr "type" "shift")
4035 (set_attr "maybe_var_shift" "yes")])
4037 (define_insn_and_split "*rotl<mode>3_dot"
4038 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4039 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4040 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4042 (clobber (match_scratch:GPR 0 "=r,r"))]
4043 "<MODE>mode == Pmode"
4045 rotl<wd>%I2. %0,%1,%<hH>2
4047 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4049 (rotate:GPR (match_dup 1)
4052 (compare:CC (match_dup 0)
4055 [(set_attr "type" "shift")
4056 (set_attr "maybe_var_shift" "yes")
4057 (set_attr "dot" "yes")
4058 (set_attr "length" "4,8")])
4060 (define_insn_and_split "*rotl<mode>3_dot2"
4061 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4062 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4063 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4065 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4066 (rotate:GPR (match_dup 1)
4068 "<MODE>mode == Pmode"
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")])
4086 (define_insn "ashl<mode>3"
4087 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4088 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4089 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4091 "sl<wd>%I2 %0,%1,%<hH>2"
4092 [(set_attr "type" "shift")
4093 (set_attr "maybe_var_shift" "yes")])
4095 (define_insn "*ashlsi3_64"
4096 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4098 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4099 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4102 [(set_attr "type" "shift")
4103 (set_attr "maybe_var_shift" "yes")])
4105 (define_insn_and_split "*ashl<mode>3_dot"
4106 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4107 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4108 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4110 (clobber (match_scratch:GPR 0 "=r,r"))]
4111 "<MODE>mode == Pmode"
4113 sl<wd>%I2. %0,%1,%<hH>2
4115 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4117 (ashift:GPR (match_dup 1)
4120 (compare:CC (match_dup 0)
4123 [(set_attr "type" "shift")
4124 (set_attr "maybe_var_shift" "yes")
4125 (set_attr "dot" "yes")
4126 (set_attr "length" "4,8")])
4128 (define_insn_and_split "*ashl<mode>3_dot2"
4129 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4130 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4131 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4133 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4134 (ashift:GPR (match_dup 1)
4136 "<MODE>mode == Pmode"
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 ;; Pretend we have a memory form of extswsli until register allocation is done
4154 ;; so that we use LWZ to load the value from memory, instead of LWA.
4155 (define_insn_and_split "ashdi3_extswsli"
4156 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4158 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4159 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4164 "&& reload_completed && MEM_P (operands[1])"
4168 (ashift:DI (sign_extend:DI (match_dup 3))
4171 operands[3] = gen_lowpart (SImode, operands[0]);
4173 [(set_attr "type" "shift")
4174 (set_attr "maybe_var_shift" "no")])
4177 (define_insn_and_split "ashdi3_extswsli_dot"
4178 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4181 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4182 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4184 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4191 "&& reload_completed
4192 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4193 || memory_operand (operands[1], SImode))"
4196 rtx dest = operands[0];
4197 rtx src = operands[1];
4198 rtx shift = operands[2];
4199 rtx cr = operands[3];
4206 src2 = gen_lowpart (SImode, dest);
4207 emit_move_insn (src2, src);
4210 if (REGNO (cr) == CR0_REGNO)
4212 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4216 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4217 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4220 [(set_attr "type" "shift")
4221 (set_attr "maybe_var_shift" "no")
4222 (set_attr "dot" "yes")
4223 (set_attr "length" "4,8,8,12")])
4225 (define_insn_and_split "ashdi3_extswsli_dot2"
4226 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4229 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4230 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4232 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4233 (ashift:DI (sign_extend:DI (match_dup 1))
4241 "&& reload_completed
4242 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4243 || memory_operand (operands[1], SImode))"
4246 rtx dest = operands[0];
4247 rtx src = operands[1];
4248 rtx shift = operands[2];
4249 rtx cr = operands[3];
4256 src2 = gen_lowpart (SImode, dest);
4257 emit_move_insn (src2, src);
4260 if (REGNO (cr) == CR0_REGNO)
4262 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4266 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4267 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4270 [(set_attr "type" "shift")
4271 (set_attr "maybe_var_shift" "no")
4272 (set_attr "dot" "yes")
4273 (set_attr "length" "4,8,8,12")])
4275 (define_insn "lshr<mode>3"
4276 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4277 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4278 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4280 "sr<wd>%I2 %0,%1,%<hH>2"
4281 [(set_attr "type" "shift")
4282 (set_attr "maybe_var_shift" "yes")])
4284 (define_insn "*lshrsi3_64"
4285 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4287 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4288 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4291 [(set_attr "type" "shift")
4292 (set_attr "maybe_var_shift" "yes")])
4294 (define_insn_and_split "*lshr<mode>3_dot"
4295 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4296 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4297 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4299 (clobber (match_scratch:GPR 0 "=r,r"))]
4300 "<MODE>mode == Pmode"
4302 sr<wd>%I2. %0,%1,%<hH>2
4304 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4306 (lshiftrt:GPR (match_dup 1)
4309 (compare:CC (match_dup 0)
4312 [(set_attr "type" "shift")
4313 (set_attr "maybe_var_shift" "yes")
4314 (set_attr "dot" "yes")
4315 (set_attr "length" "4,8")])
4317 (define_insn_and_split "*lshr<mode>3_dot2"
4318 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4319 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4320 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4322 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4323 (lshiftrt:GPR (match_dup 1)
4325 "<MODE>mode == Pmode"
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")])
4343 (define_insn "ashr<mode>3"
4344 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4345 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4346 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4347 (clobber (reg:GPR CA_REGNO))]
4349 "sra<wd>%I2 %0,%1,%<hH>2"
4350 [(set_attr "type" "shift")
4351 (set_attr "maybe_var_shift" "yes")])
4353 (define_insn "*ashrsi3_64"
4354 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4356 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4357 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4358 (clobber (reg:SI CA_REGNO))]
4361 [(set_attr "type" "shift")
4362 (set_attr "maybe_var_shift" "yes")])
4364 (define_insn_and_split "*ashr<mode>3_dot"
4365 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4366 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4367 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4369 (clobber (match_scratch:GPR 0 "=r,r"))
4370 (clobber (reg:GPR CA_REGNO))]
4371 "<MODE>mode == Pmode"
4373 sra<wd>%I2. %0,%1,%<hH>2
4375 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4376 [(parallel [(set (match_dup 0)
4377 (ashiftrt:GPR (match_dup 1)
4379 (clobber (reg:GPR CA_REGNO))])
4381 (compare:CC (match_dup 0)
4384 [(set_attr "type" "shift")
4385 (set_attr "maybe_var_shift" "yes")
4386 (set_attr "dot" "yes")
4387 (set_attr "length" "4,8")])
4389 (define_insn_and_split "*ashr<mode>3_dot2"
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 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4395 (ashiftrt:GPR (match_dup 1)
4397 (clobber (reg:GPR CA_REGNO))]
4398 "<MODE>mode == Pmode"
4400 sra<wd>%I2. %0,%1,%<hH>2
4402 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4403 [(parallel [(set (match_dup 0)
4404 (ashiftrt:GPR (match_dup 1)
4406 (clobber (reg:GPR CA_REGNO))])
4408 (compare:CC (match_dup 0)
4411 [(set_attr "type" "shift")
4412 (set_attr "maybe_var_shift" "yes")
4413 (set_attr "dot" "yes")
4414 (set_attr "length" "4,8")])
4416 ;; Builtins to replace a division to generate FRE reciprocal estimate
4417 ;; instructions and the necessary fixup instructions
4418 (define_expand "recip<mode>3"
4419 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4420 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4421 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4422 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4424 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4428 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4429 ;; hardware division. This is only done before register allocation and with
4430 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4431 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4432 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4434 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4435 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4436 (match_operand 2 "gpc_reg_operand" "")))]
4437 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4438 && can_create_pseudo_p () && flag_finite_math_only
4439 && !flag_trapping_math && flag_reciprocal_math"
4442 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4446 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4447 ;; appropriate fixup.
4448 (define_expand "rsqrt<mode>2"
4449 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4450 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4451 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4453 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4457 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4458 ;; modes here, and also add in conditional vsx/power8-vector support to access
4459 ;; values in the traditional Altivec registers if the appropriate
4460 ;; -mupper-regs-{df,sf} option is enabled.
4462 (define_expand "abs<mode>2"
4463 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4464 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4465 "TARGET_<MODE>_INSN"
4468 (define_insn "*abs<mode>2_fpr"
4469 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4470 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4475 [(set_attr "type" "fpsimple")
4476 (set_attr "fp_type" "fp_addsub_<Fs>")])
4478 (define_insn "*nabs<mode>2_fpr"
4479 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4482 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4487 [(set_attr "type" "fpsimple")
4488 (set_attr "fp_type" "fp_addsub_<Fs>")])
4490 (define_expand "neg<mode>2"
4491 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4492 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4493 "TARGET_<MODE>_INSN"
4496 (define_insn "*neg<mode>2_fpr"
4497 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4498 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4503 [(set_attr "type" "fpsimple")
4504 (set_attr "fp_type" "fp_addsub_<Fs>")])
4506 (define_expand "add<mode>3"
4507 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4508 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4509 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4510 "TARGET_<MODE>_INSN"
4513 (define_insn "*add<mode>3_fpr"
4514 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4515 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4516 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4519 fadd<Ftrad> %0,%1,%2
4520 xsadd<Fvsx> %x0,%x1,%x2"
4521 [(set_attr "type" "fp")
4522 (set_attr "fp_type" "fp_addsub_<Fs>")])
4524 (define_expand "sub<mode>3"
4525 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4526 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4527 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4528 "TARGET_<MODE>_INSN"
4531 (define_insn "*sub<mode>3_fpr"
4532 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4533 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4534 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4537 fsub<Ftrad> %0,%1,%2
4538 xssub<Fvsx> %x0,%x1,%x2"
4539 [(set_attr "type" "fp")
4540 (set_attr "fp_type" "fp_addsub_<Fs>")])
4542 (define_expand "mul<mode>3"
4543 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4544 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4545 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4546 "TARGET_<MODE>_INSN"
4549 (define_insn "*mul<mode>3_fpr"
4550 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4551 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4552 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4555 fmul<Ftrad> %0,%1,%2
4556 xsmul<Fvsx> %x0,%x1,%x2"
4557 [(set_attr "type" "dmul")
4558 (set_attr "fp_type" "fp_mul_<Fs>")])
4560 (define_expand "div<mode>3"
4561 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4562 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4563 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4564 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4566 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4567 && can_create_pseudo_p () && flag_finite_math_only
4568 && !flag_trapping_math && flag_reciprocal_math)
4570 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4575 (define_insn "*div<mode>3_fpr"
4576 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4577 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4578 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4579 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4581 fdiv<Ftrad> %0,%1,%2
4582 xsdiv<Fvsx> %x0,%x1,%x2"
4583 [(set_attr "type" "<Fs>div")
4584 (set_attr "fp_type" "fp_div_<Fs>")])
4586 (define_insn "*sqrt<mode>2_internal"
4587 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4588 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4589 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4590 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4593 xssqrt<Fvsx> %x0,%x1"
4594 [(set_attr "type" "<Fs>sqrt")
4595 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4597 (define_expand "sqrt<mode>2"
4598 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4599 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4600 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4601 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4603 if (<MODE>mode == SFmode
4604 && TARGET_RECIP_PRECISION
4605 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4606 && !optimize_function_for_size_p (cfun)
4607 && flag_finite_math_only && !flag_trapping_math
4608 && flag_unsafe_math_optimizations)
4610 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4615 ;; Floating point reciprocal approximation
4616 (define_insn "fre<Fs>"
4617 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4618 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4624 [(set_attr "type" "fp")])
4626 (define_insn "*rsqrt<mode>2"
4627 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4628 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4630 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4632 frsqrte<Ftrad> %0,%1
4633 xsrsqrte<Fvsx> %x0,%x1"
4634 [(set_attr "type" "fp")])
4636 ;; Floating point comparisons
4637 (define_insn "*cmp<mode>_fpr"
4638 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4639 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4640 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4644 xscmpudp %0,%x1,%x2"
4645 [(set_attr "type" "fpcompare")])
4647 ;; Floating point conversions
4648 (define_expand "extendsfdf2"
4649 [(set (match_operand:DF 0 "gpc_reg_operand")
4650 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4651 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4653 if (HONOR_SNANS (SFmode))
4654 operands[1] = force_reg (SFmode, operands[1]);
4657 (define_insn_and_split "*extendsfdf2_fpr"
4658 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4659 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4660 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4666 xscpsgndp %x0,%x1,%x1
4669 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4672 emit_note (NOTE_INSN_DELETED);
4675 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4677 (define_insn "*extendsfdf2_snan"
4678 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4679 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4680 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4684 [(set_attr "type" "fp")])
4686 (define_expand "truncdfsf2"
4687 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4688 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4689 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4692 (define_insn "*truncdfsf2_fpr"
4693 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4694 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4695 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4699 [(set_attr "type" "fp")])
4701 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4702 ;; builtins.c and optabs.c that are not correct for IBM long double
4703 ;; when little-endian.
4704 (define_expand "signbit<mode>2"
4706 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4708 (subreg:DI (match_dup 2) 0))
4711 (set (match_operand:SI 0 "gpc_reg_operand" "")
4714 && (!FLOAT128_IEEE_P (<MODE>mode)
4715 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4717 if (FLOAT128_IEEE_P (<MODE>mode))
4719 if (<MODE>mode == KFmode)
4720 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4721 else if (<MODE>mode == TFmode)
4722 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4727 operands[2] = gen_reg_rtx (DFmode);
4728 operands[3] = gen_reg_rtx (DImode);
4729 if (TARGET_POWERPC64)
4731 operands[4] = gen_reg_rtx (DImode);
4732 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4733 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4734 WORDS_BIG_ENDIAN ? 4 : 0);
4738 operands[4] = gen_reg_rtx (SImode);
4739 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4740 WORDS_BIG_ENDIAN ? 0 : 4);
4741 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4745 (define_expand "copysign<mode>3"
4747 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4749 (neg:SFDF (abs:SFDF (match_dup 1))))
4750 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4751 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4755 "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4756 && ((TARGET_PPC_GFXOPT
4757 && !HONOR_NANS (<MODE>mode)
4758 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4760 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4762 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4764 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4769 operands[3] = gen_reg_rtx (<MODE>mode);
4770 operands[4] = gen_reg_rtx (<MODE>mode);
4771 operands[5] = CONST0_RTX (<MODE>mode);
4774 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4776 (define_insn_and_split "signbit<mode>2_dm"
4777 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4779 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4781 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4783 "&& reload_completed"
4786 rs6000_split_signbit (operands[0], operands[1]);
4789 [(set_attr "length" "8,8,4")
4790 (set_attr "type" "mftgpr,load,integer")])
4792 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4793 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4796 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4798 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4800 "&& reload_completed"
4803 rs6000_split_signbit (operands[0], operands[1]);
4806 [(set_attr "length" "8,8,4")
4807 (set_attr "type" "mftgpr,load,integer")])
4809 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4810 ;; point types, which makes normal SUBREG's problematical. Instead use a
4811 ;; special pattern to avoid using a normal movdi.
4812 (define_insn "signbit<mode>2_dm2"
4813 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4814 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4817 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4819 [(set_attr "type" "mftgpr")])
4822 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4823 ;; compiler from optimizing -0.0
4824 (define_insn "copysign<mode>3_fcpsgn"
4825 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4826 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4827 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4829 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4832 xscpsgndp %x0,%x2,%x1"
4833 [(set_attr "type" "fpsimple")])
4835 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4836 ;; fsel instruction and some auxiliary computations. Then we just have a
4837 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4839 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4840 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4841 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4842 ;; define_splits to make them if made by combine. On VSX machines we have the
4843 ;; min/max instructions.
4845 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4846 ;; to allow either DF/SF to use only traditional registers.
4848 (define_expand "s<minmax><mode>3"
4849 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4850 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4851 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4852 "TARGET_MINMAX_<MODE>"
4854 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4858 (define_insn "*s<minmax><mode>3_vsx"
4859 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4860 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4861 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4862 "TARGET_VSX && TARGET_<MODE>_FPR"
4864 return (TARGET_P9_MINMAX
4865 ? "xs<minmax>cdp %x0,%x1,%x2"
4866 : "xs<minmax>dp %x0,%x1,%x2");
4868 [(set_attr "type" "fp")])
4870 ;; The conditional move instructions allow us to perform max and min operations
4871 ;; even when we don't have the appropriate max/min instruction using the FSEL
4874 (define_insn_and_split "*s<minmax><mode>3_fpr"
4875 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4876 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4877 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4878 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4883 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4887 (define_expand "mov<mode>cc"
4888 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4889 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4890 (match_operand:GPR 2 "gpc_reg_operand" "")
4891 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4895 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4901 ;; We use the BASE_REGS for the isel input operands because, if rA is
4902 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4903 ;; because we may switch the operands and rB may end up being rA.
4905 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4906 ;; leave out the mode in operand 4 and use one pattern, but reload can
4907 ;; change the mode underneath our feet and then gets confused trying
4908 ;; to reload the value.
4909 (define_insn "isel_signed_<mode>"
4910 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4912 (match_operator 1 "scc_comparison_operator"
4913 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4915 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4916 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4919 { return output_isel (operands); }"
4920 [(set_attr "type" "isel")
4921 (set_attr "length" "4")])
4923 (define_insn "isel_unsigned_<mode>"
4924 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4926 (match_operator 1 "scc_comparison_operator"
4927 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4929 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4930 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4933 { return output_isel (operands); }"
4934 [(set_attr "type" "isel")
4935 (set_attr "length" "4")])
4937 ;; These patterns can be useful for combine; they let combine know that
4938 ;; isel can handle reversed comparisons so long as the operands are
4941 (define_insn "*isel_reversed_signed_<mode>"
4942 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4944 (match_operator 1 "scc_rev_comparison_operator"
4945 [(match_operand:CC 4 "cc_reg_operand" "y")
4947 (match_operand:GPR 2 "gpc_reg_operand" "b")
4948 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4951 { return output_isel (operands); }"
4952 [(set_attr "type" "isel")
4953 (set_attr "length" "4")])
4955 (define_insn "*isel_reversed_unsigned_<mode>"
4956 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4958 (match_operator 1 "scc_rev_comparison_operator"
4959 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4961 (match_operand:GPR 2 "gpc_reg_operand" "b")
4962 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4965 { return output_isel (operands); }"
4966 [(set_attr "type" "isel")
4967 (set_attr "length" "4")])
4969 ;; Floating point conditional move
4970 (define_expand "mov<mode>cc"
4971 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4972 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4973 (match_operand:SFDF 2 "gpc_reg_operand" "")
4974 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4975 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4978 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4984 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4985 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
4987 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
4988 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4989 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
4990 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
4991 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4993 [(set_attr "type" "fp")])
4995 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4996 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4998 (match_operator:CCFP 1 "fpmask_comparison_operator"
4999 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5000 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5001 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5002 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5003 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5008 (if_then_else:V2DI (match_dup 1)
5012 (if_then_else:SFDF (ne (match_dup 6)
5017 if (GET_CODE (operands[6]) == SCRATCH)
5018 operands[6] = gen_reg_rtx (V2DImode);
5020 operands[7] = CONSTM1_RTX (V2DImode);
5021 operands[8] = CONST0_RTX (V2DImode);
5023 [(set_attr "length" "8")
5024 (set_attr "type" "vecperm")])
5026 ;; Handle inverting the fpmask comparisons.
5027 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5028 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5030 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5031 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5032 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5033 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5034 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5035 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5040 (if_then_else:V2DI (match_dup 9)
5044 (if_then_else:SFDF (ne (match_dup 6)
5049 rtx op1 = operands[1];
5050 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5052 if (GET_CODE (operands[6]) == SCRATCH)
5053 operands[6] = gen_reg_rtx (V2DImode);
5055 operands[7] = CONSTM1_RTX (V2DImode);
5056 operands[8] = CONST0_RTX (V2DImode);
5058 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5060 [(set_attr "length" "8")
5061 (set_attr "type" "vecperm")])
5063 (define_insn "*fpmask<mode>"
5064 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5066 (match_operator:CCFP 1 "fpmask_comparison_operator"
5067 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5068 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5069 (match_operand:V2DI 4 "all_ones_constant" "")
5070 (match_operand:V2DI 5 "zero_constant" "")))]
5072 "xscmp%V1dp %x0,%x2,%x3"
5073 [(set_attr "type" "fpcompare")])
5075 (define_insn "*xxsel<mode>"
5076 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5077 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5078 (match_operand:V2DI 2 "zero_constant" ""))
5079 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5080 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5082 "xxsel %x0,%x4,%x3,%x1"
5083 [(set_attr "type" "vecmove")])
5086 ;; Conversions to and from floating-point.
5088 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5089 ; don't want to support putting SImode in FPR registers.
5090 (define_insn "lfiwax"
5091 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5092 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5094 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5100 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5102 ; This split must be run before register allocation because it allocates the
5103 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5104 ; it earlier to allow for the combiner to merge insns together where it might
5105 ; not be needed and also in case the insns are deleted as dead code.
5107 (define_insn_and_split "floatsi<mode>2_lfiwax"
5108 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5109 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5110 (clobber (match_scratch:DI 2 "=wi"))]
5111 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5112 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5118 rtx dest = operands[0];
5119 rtx src = operands[1];
5122 if (!MEM_P (src) && TARGET_POWERPC64
5123 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5124 tmp = convert_to_mode (DImode, src, false);
5128 if (GET_CODE (tmp) == SCRATCH)
5129 tmp = gen_reg_rtx (DImode);
5132 src = rs6000_address_for_fpconvert (src);
5133 emit_insn (gen_lfiwax (tmp, src));
5137 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5138 emit_move_insn (stack, src);
5139 emit_insn (gen_lfiwax (tmp, stack));
5142 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5145 [(set_attr "length" "12")
5146 (set_attr "type" "fpload")])
5148 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5149 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5152 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5153 (clobber (match_scratch:DI 2 "=wi"))]
5154 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5160 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5161 if (GET_CODE (operands[2]) == SCRATCH)
5162 operands[2] = gen_reg_rtx (DImode);
5163 if (TARGET_P8_VECTOR)
5164 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5166 emit_insn (gen_lfiwax (operands[2], operands[1]));
5167 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5170 [(set_attr "length" "8")
5171 (set_attr "type" "fpload")])
5173 (define_insn "lfiwzx"
5174 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5175 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5177 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5182 xxextractuw %x0,%x1,4"
5183 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5185 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5186 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5187 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5188 (clobber (match_scratch:DI 2 "=wi"))]
5189 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5195 rtx dest = operands[0];
5196 rtx src = operands[1];
5199 if (!MEM_P (src) && TARGET_POWERPC64
5200 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5201 tmp = convert_to_mode (DImode, src, true);
5205 if (GET_CODE (tmp) == SCRATCH)
5206 tmp = gen_reg_rtx (DImode);
5209 src = rs6000_address_for_fpconvert (src);
5210 emit_insn (gen_lfiwzx (tmp, src));
5214 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5215 emit_move_insn (stack, src);
5216 emit_insn (gen_lfiwzx (tmp, stack));
5219 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5222 [(set_attr "length" "12")
5223 (set_attr "type" "fpload")])
5225 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5226 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5227 (unsigned_float:SFDF
5229 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5230 (clobber (match_scratch:DI 2 "=wi"))]
5231 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5237 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5238 if (GET_CODE (operands[2]) == SCRATCH)
5239 operands[2] = gen_reg_rtx (DImode);
5240 if (TARGET_P8_VECTOR)
5241 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5243 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5244 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5247 [(set_attr "length" "8")
5248 (set_attr "type" "fpload")])
5250 ; For each of these conversions, there is a define_expand, a define_insn
5251 ; with a '#' template, and a define_split (with C code). The idea is
5252 ; to allow constant folding with the template of the define_insn,
5253 ; then to have the insns split later (between sched1 and final).
5255 (define_expand "floatsidf2"
5256 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5257 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5260 (clobber (match_dup 4))
5261 (clobber (match_dup 5))
5262 (clobber (match_dup 6))])]
5263 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5266 if (TARGET_LFIWAX && TARGET_FCFID)
5268 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5271 else if (TARGET_FCFID)
5273 rtx dreg = operands[1];
5275 dreg = force_reg (SImode, dreg);
5276 dreg = convert_to_mode (DImode, dreg, false);
5277 emit_insn (gen_floatdidf2 (operands[0], dreg));
5281 if (!REG_P (operands[1]))
5282 operands[1] = force_reg (SImode, operands[1]);
5283 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5284 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5285 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5286 operands[5] = gen_reg_rtx (DFmode);
5287 operands[6] = gen_reg_rtx (SImode);
5290 (define_insn_and_split "*floatsidf2_internal"
5291 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5292 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5293 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5294 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5295 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5296 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5297 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5298 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5304 rtx lowword, highword;
5305 gcc_assert (MEM_P (operands[4]));
5306 highword = adjust_address (operands[4], SImode, 0);
5307 lowword = adjust_address (operands[4], SImode, 4);
5308 if (! WORDS_BIG_ENDIAN)
5309 std::swap (lowword, highword);
5311 emit_insn (gen_xorsi3 (operands[6], operands[1],
5312 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5313 emit_move_insn (lowword, operands[6]);
5314 emit_move_insn (highword, operands[2]);
5315 emit_move_insn (operands[5], operands[4]);
5316 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5319 [(set_attr "length" "24")
5320 (set_attr "type" "fp")])
5322 ;; If we don't have a direct conversion to single precision, don't enable this
5323 ;; conversion for 32-bit without fast math, because we don't have the insn to
5324 ;; generate the fixup swizzle to avoid double rounding problems.
5325 (define_expand "floatunssisf2"
5326 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5327 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5328 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5329 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5330 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5331 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5334 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5336 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5341 rtx dreg = operands[1];
5343 dreg = force_reg (SImode, dreg);
5344 dreg = convert_to_mode (DImode, dreg, true);
5345 emit_insn (gen_floatdisf2 (operands[0], dreg));
5350 (define_expand "floatunssidf2"
5351 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5352 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5355 (clobber (match_dup 4))
5356 (clobber (match_dup 5))])]
5357 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5360 if (TARGET_LFIWZX && TARGET_FCFID)
5362 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5365 else if (TARGET_FCFID)
5367 rtx dreg = operands[1];
5369 dreg = force_reg (SImode, dreg);
5370 dreg = convert_to_mode (DImode, dreg, true);
5371 emit_insn (gen_floatdidf2 (operands[0], dreg));
5375 if (!REG_P (operands[1]))
5376 operands[1] = force_reg (SImode, operands[1]);
5377 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5378 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5379 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5380 operands[5] = gen_reg_rtx (DFmode);
5383 (define_insn_and_split "*floatunssidf2_internal"
5384 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5385 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5386 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5387 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5388 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5389 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5390 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5391 && !(TARGET_FCFID && TARGET_POWERPC64)"
5397 rtx lowword, highword;
5398 gcc_assert (MEM_P (operands[4]));
5399 highword = adjust_address (operands[4], SImode, 0);
5400 lowword = adjust_address (operands[4], SImode, 4);
5401 if (! WORDS_BIG_ENDIAN)
5402 std::swap (lowword, highword);
5404 emit_move_insn (lowword, operands[1]);
5405 emit_move_insn (highword, operands[2]);
5406 emit_move_insn (operands[5], operands[4]);
5407 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5410 [(set_attr "length" "20")
5411 (set_attr "type" "fp")])
5413 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5414 ;; vector registers. These insns favor doing the sign/zero extension in
5415 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5416 ;; extension and then a direct move.
5418 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5419 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5421 (match_operand:QHI 1 "input_operand")))
5422 (clobber (match_scratch:DI 2))
5423 (clobber (match_scratch:DI 3))
5424 (clobber (match_scratch:<QHI:MODE> 4))])]
5425 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5427 if (MEM_P (operands[1]))
5428 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5431 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5432 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5434 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5435 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5436 (clobber (match_scratch:DI 3 "=X,r,X"))
5437 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5438 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5440 "&& reload_completed"
5443 rtx result = operands[0];
5444 rtx input = operands[1];
5445 rtx di = operands[2];
5449 rtx tmp = operands[3];
5450 if (altivec_register_operand (input, <QHI:MODE>mode))
5451 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5452 else if (GET_CODE (tmp) == SCRATCH)
5453 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5456 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5457 emit_move_insn (di, tmp);
5462 rtx tmp = operands[4];
5463 emit_move_insn (tmp, input);
5464 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5467 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5471 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5472 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5473 (unsigned_float:FP_ISA3
5474 (match_operand:QHI 1 "input_operand" "")))
5475 (clobber (match_scratch:DI 2 ""))
5476 (clobber (match_scratch:DI 3 ""))])]
5477 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5479 if (MEM_P (operands[1]))
5480 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5483 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5484 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5485 (unsigned_float:FP_ISA3
5486 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5487 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5488 (clobber (match_scratch:DI 3 "=X,r,X"))]
5489 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5491 "&& reload_completed"
5494 rtx result = operands[0];
5495 rtx input = operands[1];
5496 rtx di = operands[2];
5498 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5499 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5502 rtx tmp = operands[3];
5503 if (GET_CODE (tmp) == SCRATCH)
5504 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5507 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5508 emit_move_insn (di, tmp);
5512 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5516 (define_expand "fix_trunc<mode>si2"
5517 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5518 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5519 "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5522 if (!TARGET_P8_VECTOR)
5524 rtx src = force_reg (<MODE>mode, operands[1]);
5527 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5530 rtx tmp = gen_reg_rtx (DImode);
5531 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5532 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5539 ; Like the convert to float patterns, this insn must be split before
5540 ; register allocation so that it can allocate the memory slot if it
5542 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5543 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5544 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5545 (clobber (match_scratch:DI 2 "=d"))]
5546 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5547 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5548 && TARGET_STFIWX && can_create_pseudo_p ()
5549 && !TARGET_P8_VECTOR"
5554 rtx dest = operands[0];
5555 rtx src = operands[1];
5556 rtx tmp = operands[2];
5558 if (GET_CODE (tmp) == SCRATCH)
5559 tmp = gen_reg_rtx (DImode);
5561 emit_insn (gen_fctiwz_<mode> (tmp, src));
5564 dest = rs6000_address_for_fpconvert (dest);
5565 emit_insn (gen_stfiwx (dest, tmp));
5568 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5570 dest = gen_lowpart (DImode, dest);
5571 emit_move_insn (dest, tmp);
5576 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5577 emit_insn (gen_stfiwx (stack, tmp));
5578 emit_move_insn (dest, stack);
5582 [(set_attr "length" "12")
5583 (set_attr "type" "fp")])
5585 (define_insn_and_split "fix_trunc<mode>si2_internal"
5586 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5587 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5588 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5589 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5590 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
5597 gcc_assert (MEM_P (operands[3]));
5598 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5600 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5601 emit_move_insn (operands[3], operands[2]);
5602 emit_move_insn (operands[0], lowword);
5605 [(set_attr "length" "16")
5606 (set_attr "type" "fp")])
5608 (define_expand "fix_trunc<mode>di2"
5609 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5610 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5611 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5614 (define_insn "*fix_trunc<mode>di2_fctidz"
5615 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5616 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5617 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5621 [(set_attr "type" "fp")])
5623 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5624 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5625 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5626 (clobber (match_scratch:DI 2))])]
5627 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5629 if (MEM_P (operands[0]))
5630 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5633 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5634 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5636 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5637 (clobber (match_scratch:DI 2 "=X,wi"))]
5638 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5640 "&& reload_completed"
5643 rtx dest = operands[0];
5644 rtx src = operands[1];
5646 if (vsx_register_operand (dest, <QHI:MODE>mode))
5648 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5649 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5653 rtx tmp = operands[2];
5654 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5656 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5657 emit_move_insn (dest, tmp2);
5662 (define_expand "fixuns_trunc<mode>si2"
5663 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5664 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5665 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5668 if (!TARGET_P8_VECTOR)
5670 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5675 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5676 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5677 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5678 (clobber (match_scratch:DI 2 "=d"))]
5679 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5680 && TARGET_STFIWX && can_create_pseudo_p ()
5681 && !TARGET_P8_VECTOR"
5686 rtx dest = operands[0];
5687 rtx src = operands[1];
5688 rtx tmp = operands[2];
5690 if (GET_CODE (tmp) == SCRATCH)
5691 tmp = gen_reg_rtx (DImode);
5693 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5696 dest = rs6000_address_for_fpconvert (dest);
5697 emit_insn (gen_stfiwx (dest, tmp));
5700 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5702 dest = gen_lowpart (DImode, dest);
5703 emit_move_insn (dest, tmp);
5708 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5709 emit_insn (gen_stfiwx (stack, tmp));
5710 emit_move_insn (dest, stack);
5714 [(set_attr "length" "12")
5715 (set_attr "type" "fp")])
5717 (define_insn "fixuns_trunc<mode>di2"
5718 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5719 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5720 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5724 [(set_attr "type" "fp")])
5726 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5727 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5728 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5729 (clobber (match_scratch:DI 2))])]
5730 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5732 if (MEM_P (operands[0]))
5733 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5736 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5737 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5739 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5740 (clobber (match_scratch:DI 2 "=X,wi"))]
5741 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5743 "&& reload_completed"
5746 rtx dest = operands[0];
5747 rtx src = operands[1];
5749 if (vsx_register_operand (dest, <QHI:MODE>mode))
5751 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5752 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5756 rtx tmp = operands[2];
5757 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5759 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5760 emit_move_insn (dest, tmp2);
5765 ;; If -mvsx-small-integer, we can represent the FIX operation directly. On
5766 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5767 ;; to another location, since SImode is not allowed in vector registers.
5768 (define_insn "*fctiw<u>z_<mode>_smallint"
5769 [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5770 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5771 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5774 xscvdp<su>xws %x0,%x1"
5775 [(set_attr "type" "fp")])
5777 ;; Combiner pattern to prevent moving the result of converting a floating point
5778 ;; value to 32-bit integer to GPR in order to save it.
5779 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5780 [(set (match_operand:SI 0 "memory_operand" "=Z")
5781 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5782 (clobber (match_scratch:SI 2 "=wa"))]
5783 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5785 "&& reload_completed"
5787 (any_fix:SI (match_dup 1)))
5791 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5792 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5793 ;; because the first makes it clear that operand 0 is not live
5794 ;; before the instruction.
5795 (define_insn "fctiwz_<mode>"
5796 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5798 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5800 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5804 [(set_attr "type" "fp")])
5806 (define_insn "fctiwuz_<mode>"
5807 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5808 (unspec:DI [(unsigned_fix:SI
5809 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5811 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5815 [(set_attr "type" "fp")])
5817 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5818 ;; since the friz instruction does not truncate the value if the floating
5819 ;; point value is < LONG_MIN or > LONG_MAX.
5820 (define_insn "*friz"
5821 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5822 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5823 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5824 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5828 [(set_attr "type" "fp")])
5830 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5831 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5832 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5833 ;; extend it, store it back on the stack from the GPR, load it back into the
5834 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5835 ;; disable using store and load to sign/zero extend the value.
5836 (define_insn_and_split "*round32<mode>2_fprs"
5837 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5839 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5840 (clobber (match_scratch:DI 2 "=d"))
5841 (clobber (match_scratch:DI 3 "=d"))]
5842 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5843 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5844 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5849 rtx dest = operands[0];
5850 rtx src = operands[1];
5851 rtx tmp1 = operands[2];
5852 rtx tmp2 = operands[3];
5853 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5855 if (GET_CODE (tmp1) == SCRATCH)
5856 tmp1 = gen_reg_rtx (DImode);
5857 if (GET_CODE (tmp2) == SCRATCH)
5858 tmp2 = gen_reg_rtx (DImode);
5860 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5861 emit_insn (gen_stfiwx (stack, tmp1));
5862 emit_insn (gen_lfiwax (tmp2, stack));
5863 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5866 [(set_attr "type" "fpload")
5867 (set_attr "length" "16")])
5869 (define_insn_and_split "*roundu32<mode>2_fprs"
5870 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5871 (unsigned_float:SFDF
5872 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5873 (clobber (match_scratch:DI 2 "=d"))
5874 (clobber (match_scratch:DI 3 "=d"))]
5875 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5876 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5877 && can_create_pseudo_p ()"
5882 rtx dest = operands[0];
5883 rtx src = operands[1];
5884 rtx tmp1 = operands[2];
5885 rtx tmp2 = operands[3];
5886 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5888 if (GET_CODE (tmp1) == SCRATCH)
5889 tmp1 = gen_reg_rtx (DImode);
5890 if (GET_CODE (tmp2) == SCRATCH)
5891 tmp2 = gen_reg_rtx (DImode);
5893 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5894 emit_insn (gen_stfiwx (stack, tmp1));
5895 emit_insn (gen_lfiwzx (tmp2, stack));
5896 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5899 [(set_attr "type" "fpload")
5900 (set_attr "length" "16")])
5902 ;; No VSX equivalent to fctid
5903 (define_insn "lrint<mode>di2"
5904 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5905 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5907 "TARGET_<MODE>_FPR && TARGET_FPRND"
5909 [(set_attr "type" "fp")])
5911 (define_insn "btrunc<mode>2"
5912 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5913 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5915 "TARGET_<MODE>_FPR && TARGET_FPRND"
5919 [(set_attr "type" "fp")
5920 (set_attr "fp_type" "fp_addsub_<Fs>")])
5922 (define_insn "ceil<mode>2"
5923 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5924 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5926 "TARGET_<MODE>_FPR && TARGET_FPRND"
5930 [(set_attr "type" "fp")
5931 (set_attr "fp_type" "fp_addsub_<Fs>")])
5933 (define_insn "floor<mode>2"
5934 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5935 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5937 "TARGET_<MODE>_FPR && TARGET_FPRND"
5941 [(set_attr "type" "fp")
5942 (set_attr "fp_type" "fp_addsub_<Fs>")])
5944 ;; No VSX equivalent to frin
5945 (define_insn "round<mode>2"
5946 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5947 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5949 "TARGET_<MODE>_FPR && TARGET_FPRND"
5951 [(set_attr "type" "fp")
5952 (set_attr "fp_type" "fp_addsub_<Fs>")])
5954 (define_insn "*xsrdpi<mode>2"
5955 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5956 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5958 "TARGET_<MODE>_FPR && TARGET_VSX"
5960 [(set_attr "type" "fp")
5961 (set_attr "fp_type" "fp_addsub_<Fs>")])
5963 (define_expand "lround<mode>di2"
5965 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5967 (set (match_operand:DI 0 "gpc_reg_operand" "")
5968 (unspec:DI [(match_dup 2)]
5970 "TARGET_<MODE>_FPR && TARGET_VSX"
5972 operands[2] = gen_reg_rtx (<MODE>mode);
5975 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5976 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5977 ; is only generated for Power8 or later.
5978 (define_insn "stfiwx"
5979 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5980 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5986 [(set_attr "type" "fpstore")])
5988 ;; If we don't have a direct conversion to single precision, don't enable this
5989 ;; conversion for 32-bit without fast math, because we don't have the insn to
5990 ;; generate the fixup swizzle to avoid double rounding problems.
5991 (define_expand "floatsisf2"
5992 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5993 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5994 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5995 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5996 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5997 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6000 if (TARGET_FCFIDS && TARGET_LFIWAX)
6002 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6005 else if (TARGET_FCFID && TARGET_LFIWAX)
6007 rtx dfreg = gen_reg_rtx (DFmode);
6008 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6009 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6014 rtx dreg = operands[1];
6016 dreg = force_reg (SImode, dreg);
6017 dreg = convert_to_mode (DImode, dreg, false);
6018 emit_insn (gen_floatdisf2 (operands[0], dreg));
6023 (define_insn "floatdidf2"
6024 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6025 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6026 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6030 [(set_attr "type" "fp")])
6032 ; Allow the combiner to merge source memory operands to the conversion so that
6033 ; the optimizer/register allocator doesn't try to load the value too early in a
6034 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6035 ; hit. We will split after reload to avoid the trip through the GPRs
6037 (define_insn_and_split "*floatdidf2_mem"
6038 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6039 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6040 (clobber (match_scratch:DI 2 "=d,wi"))]
6041 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6043 "&& reload_completed"
6044 [(set (match_dup 2) (match_dup 1))
6045 (set (match_dup 0) (float:DF (match_dup 2)))]
6047 [(set_attr "length" "8")
6048 (set_attr "type" "fpload")])
6050 (define_expand "floatunsdidf2"
6051 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6053 (match_operand:DI 1 "gpc_reg_operand" "")))]
6054 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6057 (define_insn "*floatunsdidf2_fcfidu"
6058 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6059 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6060 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6064 [(set_attr "type" "fp")
6065 (set_attr "length" "4")])
6067 (define_insn_and_split "*floatunsdidf2_mem"
6068 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6069 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6070 (clobber (match_scratch:DI 2 "=d,wi"))]
6071 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6073 "&& reload_completed"
6074 [(set (match_dup 2) (match_dup 1))
6075 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6077 [(set_attr "length" "8")
6078 (set_attr "type" "fpload")])
6080 (define_expand "floatdisf2"
6081 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6082 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6083 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6084 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6089 rtx val = operands[1];
6090 if (!flag_unsafe_math_optimizations)
6092 rtx label = gen_label_rtx ();
6093 val = gen_reg_rtx (DImode);
6094 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6097 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6102 (define_insn "floatdisf2_fcfids"
6103 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6104 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6105 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6106 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6110 [(set_attr "type" "fp")])
6112 (define_insn_and_split "*floatdisf2_mem"
6113 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6114 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6115 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6116 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6117 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6119 "&& reload_completed"
6123 emit_move_insn (operands[2], operands[1]);
6124 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6127 [(set_attr "length" "8")])
6129 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6130 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6131 ;; from double rounding.
6132 ;; Instead of creating a new cpu type for two FP operations, just use fp
6133 (define_insn_and_split "floatdisf2_internal1"
6134 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6135 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6136 (clobber (match_scratch:DF 2 "=d"))]
6137 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6139 "&& reload_completed"
6141 (float:DF (match_dup 1)))
6143 (float_truncate:SF (match_dup 2)))]
6145 [(set_attr "length" "8")
6146 (set_attr "type" "fp")])
6148 ;; Twiddles bits to avoid double rounding.
6149 ;; Bits that might be truncated when converting to DFmode are replaced
6150 ;; by a bit that won't be lost at that stage, but is below the SFmode
6151 ;; rounding position.
6152 (define_expand "floatdisf2_internal2"
6153 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6155 (clobber (reg:DI CA_REGNO))])
6156 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6158 (set (match_dup 3) (plus:DI (match_dup 3)
6160 (set (match_dup 0) (plus:DI (match_dup 0)
6162 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6164 (set (match_dup 0) (ior:DI (match_dup 0)
6166 (set (match_dup 0) (and:DI (match_dup 0)
6168 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6169 (label_ref (match_operand:DI 2 "" ""))
6171 (set (match_dup 0) (match_dup 1))]
6172 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6176 operands[3] = gen_reg_rtx (DImode);
6177 operands[4] = gen_reg_rtx (CCUNSmode);
6180 (define_expand "floatunsdisf2"
6181 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6182 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6183 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6184 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6187 (define_insn "floatunsdisf2_fcfidus"
6188 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6189 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6190 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6191 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6195 [(set_attr "type" "fp")])
6197 (define_insn_and_split "*floatunsdisf2_mem"
6198 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6199 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6200 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6201 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6202 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6204 "&& reload_completed"
6208 emit_move_insn (operands[2], operands[1]);
6209 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6212 [(set_attr "length" "8")
6213 (set_attr "type" "fpload")])
6215 ;; Define the TImode operations that can be done in a small number
6216 ;; of instructions. The & constraints are to prevent the register
6217 ;; allocator from allocating registers that overlap with the inputs
6218 ;; (for example, having an input in 7,8 and an output in 6,7). We
6219 ;; also allow for the output being the same as one of the inputs.
6221 (define_expand "addti3"
6222 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6223 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6224 (match_operand:TI 2 "reg_or_short_operand" "")))]
6227 rtx lo0 = gen_lowpart (DImode, operands[0]);
6228 rtx lo1 = gen_lowpart (DImode, operands[1]);
6229 rtx lo2 = gen_lowpart (DImode, operands[2]);
6230 rtx hi0 = gen_highpart (DImode, operands[0]);
6231 rtx hi1 = gen_highpart (DImode, operands[1]);
6232 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6234 if (!reg_or_short_operand (lo2, DImode))
6235 lo2 = force_reg (DImode, lo2);
6236 if (!adde_operand (hi2, DImode))
6237 hi2 = force_reg (DImode, hi2);
6239 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6240 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6244 (define_expand "subti3"
6245 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6246 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6247 (match_operand:TI 2 "gpc_reg_operand" "")))]
6250 rtx lo0 = gen_lowpart (DImode, operands[0]);
6251 rtx lo1 = gen_lowpart (DImode, operands[1]);
6252 rtx lo2 = gen_lowpart (DImode, operands[2]);
6253 rtx hi0 = gen_highpart (DImode, operands[0]);
6254 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6255 rtx hi2 = gen_highpart (DImode, operands[2]);
6257 if (!reg_or_short_operand (lo1, DImode))
6258 lo1 = force_reg (DImode, lo1);
6259 if (!adde_operand (hi1, DImode))
6260 hi1 = force_reg (DImode, hi1);
6262 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6263 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6267 ;; 128-bit logical operations expanders
6269 (define_expand "and<mode>3"
6270 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6271 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6272 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6276 (define_expand "ior<mode>3"
6277 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6278 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6279 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6283 (define_expand "xor<mode>3"
6284 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6285 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6286 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6290 (define_expand "one_cmpl<mode>2"
6291 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6292 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6296 (define_expand "nor<mode>3"
6297 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6299 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6300 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6304 (define_expand "andc<mode>3"
6305 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6307 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6308 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6312 ;; Power8 vector logical instructions.
6313 (define_expand "eqv<mode>3"
6314 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6316 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6317 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6318 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6321 ;; Rewrite nand into canonical form
6322 (define_expand "nand<mode>3"
6323 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6325 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6326 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6327 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6330 ;; The canonical form is to have the negated element first, so we need to
6331 ;; reverse arguments.
6332 (define_expand "orc<mode>3"
6333 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6335 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6336 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6337 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6340 ;; 128-bit logical operations insns and split operations
6341 (define_insn_and_split "*and<mode>3_internal"
6342 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6344 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6345 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6348 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6349 return "xxland %x0,%x1,%x2";
6351 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6352 return "vand %0,%1,%2";
6356 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6359 rs6000_split_logical (operands, AND, false, false, false);
6364 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6365 (const_string "veclogical")
6366 (const_string "integer")))
6367 (set (attr "length")
6369 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6372 (match_test "TARGET_POWERPC64")
6374 (const_string "16"))))])
6377 (define_insn_and_split "*bool<mode>3_internal"
6378 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6379 (match_operator:BOOL_128 3 "boolean_or_operator"
6380 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6381 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6384 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6385 return "xxl%q3 %x0,%x1,%x2";
6387 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6388 return "v%q3 %0,%1,%2";
6392 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6395 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6400 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6401 (const_string "veclogical")
6402 (const_string "integer")))
6403 (set (attr "length")
6405 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6408 (match_test "TARGET_POWERPC64")
6410 (const_string "16"))))])
6413 (define_insn_and_split "*boolc<mode>3_internal1"
6414 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6415 (match_operator:BOOL_128 3 "boolean_operator"
6417 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6418 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6419 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6421 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6422 return "xxl%q3 %x0,%x1,%x2";
6424 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6425 return "v%q3 %0,%1,%2";
6429 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6430 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6433 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6438 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6439 (const_string "veclogical")
6440 (const_string "integer")))
6441 (set (attr "length")
6443 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6446 (match_test "TARGET_POWERPC64")
6448 (const_string "16"))))])
6450 (define_insn_and_split "*boolc<mode>3_internal2"
6451 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6452 (match_operator:TI2 3 "boolean_operator"
6454 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6455 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6456 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6458 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6461 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6464 [(set_attr "type" "integer")
6465 (set (attr "length")
6467 (match_test "TARGET_POWERPC64")
6469 (const_string "16")))])
6472 (define_insn_and_split "*boolcc<mode>3_internal1"
6473 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6474 (match_operator:BOOL_128 3 "boolean_operator"
6476 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6478 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6479 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6481 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6482 return "xxl%q3 %x0,%x1,%x2";
6484 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6485 return "v%q3 %0,%1,%2";
6489 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6490 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6493 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6498 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6499 (const_string "veclogical")
6500 (const_string "integer")))
6501 (set (attr "length")
6503 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6506 (match_test "TARGET_POWERPC64")
6508 (const_string "16"))))])
6510 (define_insn_and_split "*boolcc<mode>3_internal2"
6511 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6512 (match_operator:TI2 3 "boolean_operator"
6514 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6516 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6517 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6519 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6522 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6525 [(set_attr "type" "integer")
6526 (set (attr "length")
6528 (match_test "TARGET_POWERPC64")
6530 (const_string "16")))])
6534 (define_insn_and_split "*eqv<mode>3_internal1"
6535 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6538 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6539 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6542 if (vsx_register_operand (operands[0], <MODE>mode))
6543 return "xxleqv %x0,%x1,%x2";
6547 "TARGET_P8_VECTOR && reload_completed
6548 && int_reg_operand (operands[0], <MODE>mode)"
6551 rs6000_split_logical (operands, XOR, true, false, false);
6556 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6557 (const_string "veclogical")
6558 (const_string "integer")))
6559 (set (attr "length")
6561 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6564 (match_test "TARGET_POWERPC64")
6566 (const_string "16"))))])
6568 (define_insn_and_split "*eqv<mode>3_internal2"
6569 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6572 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6573 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6576 "reload_completed && !TARGET_P8_VECTOR"
6579 rs6000_split_logical (operands, XOR, true, false, false);
6582 [(set_attr "type" "integer")
6583 (set (attr "length")
6585 (match_test "TARGET_POWERPC64")
6587 (const_string "16")))])
6589 ;; 128-bit one's complement
6590 (define_insn_and_split "*one_cmpl<mode>3_internal"
6591 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6593 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6596 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6597 return "xxlnor %x0,%x1,%x1";
6599 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6600 return "vnor %0,%1,%1";
6604 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6607 rs6000_split_logical (operands, NOT, false, false, false);
6612 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6613 (const_string "veclogical")
6614 (const_string "integer")))
6615 (set (attr "length")
6617 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6620 (match_test "TARGET_POWERPC64")
6622 (const_string "16"))))])
6625 ;; Now define ways of moving data around.
6627 ;; Set up a register with a value from the GOT table
6629 (define_expand "movsi_got"
6630 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6631 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6632 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6633 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6636 if (GET_CODE (operands[1]) == CONST)
6638 rtx offset = const0_rtx;
6639 HOST_WIDE_INT value;
6641 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6642 value = INTVAL (offset);
6645 rtx tmp = (!can_create_pseudo_p ()
6647 : gen_reg_rtx (Pmode));
6648 emit_insn (gen_movsi_got (tmp, operands[1]));
6649 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6654 operands[2] = rs6000_got_register (operands[1]);
6657 (define_insn "*movsi_got_internal"
6658 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6659 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6660 (match_operand:SI 2 "gpc_reg_operand" "b")]
6662 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6663 "lwz %0,%a1@got(%2)"
6664 [(set_attr "type" "load")])
6666 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6667 ;; didn't get allocated to a hard register.
6669 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6670 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6671 (match_operand:SI 2 "memory_operand" "")]
6673 "DEFAULT_ABI == ABI_V4
6675 && reload_completed"
6676 [(set (match_dup 0) (match_dup 2))
6677 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6681 ;; For SI, we special-case integers that can't be loaded in one insn. We
6682 ;; do the load 16-bits at a time. We could do this by loading from memory,
6683 ;; and this is even supposed to be faster, but it is simpler not to get
6684 ;; integers in the TOC.
6685 (define_insn "movsi_low"
6686 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6687 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6688 (match_operand 2 "" ""))))]
6689 "TARGET_MACHO && ! TARGET_64BIT"
6690 "lwz %0,lo16(%2)(%1)"
6691 [(set_attr "type" "load")
6692 (set_attr "length" "4")])
6694 ;; MR LA LWZ LFIWZX LXSIWZX
6695 ;; STW STFIWX STXSIWX LI LIS
6696 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6697 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6698 ;; MF%1 MT%0 MT%0 NOP
6699 (define_insn "*movsi_internal1"
6700 [(set (match_operand:SI 0 "nonimmediate_operand"
6701 "=r, r, r, ?*wI, ?*wH,
6703 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6704 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6707 (match_operand:SI 1 "input_operand"
6714 "!TARGET_SINGLE_FPU &&
6715 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6742 "*, *, load, fpload, fpload,
6743 store, fpstore, fpstore, *, *,
6744 *, veclogical, vecsimple, vecsimple, vecsimple,
6745 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6755 (define_insn "*movsi_internal1_single"
6756 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6757 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6758 "TARGET_SINGLE_FPU &&
6759 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6774 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6775 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6777 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6778 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6780 ;; Because SF values are actually stored as DF values within the vector
6781 ;; registers, we need to convert the value to the vector SF format when
6782 ;; we need to use the bits in a union or similar cases. We only need
6783 ;; to do this transformation when the value is a vector register. Loads,
6784 ;; stores, and transfers within GPRs are assumed to be safe.
6786 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6787 ;; no alternatives, because the call is created as part of secondary_reload,
6788 ;; and operand #2's register class is used to allocate the temporary register.
6789 ;; This function is called before reload, and it creates the temporary as
6792 ;; MR LWZ LFIWZX LXSIWZX STW
6793 ;; STFS STXSSP STXSSPX VSX->GPR MTVSRWZ
6796 (define_insn_and_split "movsi_from_sf"
6797 [(set (match_operand:SI 0 "nonimmediate_operand"
6798 "=r, r, ?*wI, ?*wH, m,
6802 (unspec:SI [(match_operand:SF 1 "input_operand"
6808 (clobber (match_scratch:V4SF 2
6813 "TARGET_NO_SF_SUBREG
6814 && (register_operand (operands[0], SImode)
6815 || register_operand (operands[1], SFmode))"
6828 "&& reload_completed
6829 && register_operand (operands[0], SImode)
6830 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6833 rtx op0 = operands[0];
6834 rtx op1 = operands[1];
6835 rtx op2 = operands[2];
6836 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6838 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6840 if (int_reg_operand (op0, SImode))
6842 emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6843 emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6847 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6848 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6849 emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6855 "*, load, fpload, fpload, store,
6856 fpstore, fpstore, fpstore, mftgpr, mffgpr,
6864 ;; movsi_from_sf with zero extension
6866 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6869 (define_insn_and_split "*movdi_from_sf_zero_ext"
6870 [(set (match_operand:DI 0 "gpc_reg_operand"
6871 "=r, r, ?*wI, ?*wH, r,
6875 (unspec:SI [(match_operand:SF 1 "input_operand"
6878 UNSPEC_SI_FROM_SF)))
6880 (clobber (match_scratch:V4SF 2
6884 "TARGET_DIRECT_MOVE_64BIT
6885 && (register_operand (operands[0], DImode)
6886 || register_operand (operands[1], SImode))"
6895 "&& reload_completed
6896 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6899 rtx op0 = operands[0];
6900 rtx op1 = operands[1];
6901 rtx op2 = operands[2];
6903 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6905 if (int_reg_operand (op0, DImode))
6907 emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6908 emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6912 rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6913 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6914 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6915 emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
6921 "*, load, fpload, fpload, mftgpr,
6922 mffgpr, veclogical")
6928 ;; Split a load of a large constant into the appropriate two-insn
6932 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6933 (match_operand:SI 1 "const_int_operand" ""))]
6934 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6935 && (INTVAL (operands[1]) & 0xffff) != 0"
6939 (ior:SI (match_dup 0)
6943 if (rs6000_emit_set_const (operands[0], operands[1]))
6949 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6951 [(set (match_operand:DI 0 "altivec_register_operand")
6952 (match_operand:DI 1 "xxspltib_constant_split"))]
6953 "TARGET_P9_VECTOR && reload_completed"
6956 rtx op0 = operands[0];
6957 rtx op1 = operands[1];
6958 int r = REGNO (op0);
6959 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6961 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6962 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6966 (define_insn "*mov<mode>_internal2"
6967 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6968 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6970 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6976 [(set_attr "type" "cmp,logical,cmp")
6977 (set_attr "dot" "yes")
6978 (set_attr "length" "4,4,8")])
6981 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
6982 (compare:CC (match_operand:P 1 "gpc_reg_operand")
6984 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
6986 [(set (match_dup 0) (match_dup 1))
6988 (compare:CC (match_dup 0)
6992 (define_expand "mov<mode>"
6993 [(set (match_operand:INT 0 "general_operand" "")
6994 (match_operand:INT 1 "any_operand" ""))]
6996 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6998 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
6999 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7000 ;; MTVSRWZ MF%1 MT%1 NOP
7001 (define_insn "*mov<mode>_internal"
7002 [(set (match_operand:QHI 0 "nonimmediate_operand"
7003 "=r, r, ?*wJwK, m, Z, r,
7004 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7005 ?*wJwK, r, *c*l, *h")
7007 (match_operand:QHI 1 "input_operand"
7008 "r, m, Z, r, wJwK, i,
7009 wJwK, O, wM, wB, wS, ?*wJwK,
7012 "gpc_reg_operand (operands[0], <MODE>mode)
7013 || gpc_reg_operand (operands[1], <MODE>mode)"
7032 "*, load, fpload, store, fpstore, *,
7033 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7034 mffgpr, mfjmpr, mtjmpr, *")
7042 ;; Here is how to move condition codes around. When we store CC data in
7043 ;; an integer register or memory, we store just the high-order 4 bits.
7044 ;; This lets us not shift in the most common case of CR0.
7045 (define_expand "movcc"
7046 [(set (match_operand:CC 0 "nonimmediate_operand" "")
7047 (match_operand:CC 1 "nonimmediate_operand" ""))]
7051 (define_insn "*movcc_internal1"
7052 [(set (match_operand:CC 0 "nonimmediate_operand"
7053 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7054 (match_operand:CC 1 "general_operand"
7055 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7056 "register_operand (operands[0], CCmode)
7057 || register_operand (operands[1], CCmode)"
7061 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7064 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7072 (cond [(eq_attr "alternative" "0,3")
7073 (const_string "cr_logical")
7074 (eq_attr "alternative" "1,2")
7075 (const_string "mtcr")
7076 (eq_attr "alternative" "6,7")
7077 (const_string "integer")
7078 (eq_attr "alternative" "8")
7079 (const_string "mfjmpr")
7080 (eq_attr "alternative" "9")
7081 (const_string "mtjmpr")
7082 (eq_attr "alternative" "10")
7083 (const_string "load")
7084 (eq_attr "alternative" "11")
7085 (const_string "store")
7086 (match_test "TARGET_MFCRF")
7087 (const_string "mfcrf")
7089 (const_string "mfcr")))
7090 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7092 ;; For floating-point, we normally deal with the floating-point registers
7093 ;; unless -msoft-float is used. The sole exception is that parameter passing
7094 ;; can produce floating-point values in fixed-point registers. Unless the
7095 ;; value is a simple constant or already in memory, we deal with this by
7096 ;; allocating memory and copying the value explicitly via that memory location.
7098 ;; Move 32-bit binary/decimal floating point
7099 (define_expand "mov<mode>"
7100 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7101 (match_operand:FMOVE32 1 "any_operand" ""))]
7103 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7106 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7107 (match_operand:FMOVE32 1 "const_double_operand" ""))]
7109 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7110 || (GET_CODE (operands[0]) == SUBREG
7111 && GET_CODE (SUBREG_REG (operands[0])) == REG
7112 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7113 [(set (match_dup 2) (match_dup 3))]
7118 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7120 if (! TARGET_POWERPC64)
7121 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7123 operands[2] = gen_lowpart (SImode, operands[0]);
7125 operands[3] = gen_int_mode (l, SImode);
7128 ;; Originally, we tried to keep movsf and movsd common, but the differences
7129 ;; addressing was making it rather difficult to hide with mode attributes. In
7130 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7131 ;; before the VSX stores meant that the register allocator would tend to do a
7132 ;; direct move to the GPR (which involves conversion from scalar to
7133 ;; vector/memory formats) to save values in the traditional Altivec registers,
7134 ;; while SDmode had problems on power6 if the GPR store was not first due to
7135 ;; the power6 not having an integer store operation.
7137 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7138 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7139 ;; MR MT<x> MF<x> NOP
7141 (define_insn "movsf_hardfloat"
7142 [(set (match_operand:SF 0 "nonimmediate_operand"
7143 "=!r, f, wb, wu, m, wY,
7144 Z, m, ww, !r, f, ww,
7146 (match_operand:SF 1 "input_operand"
7147 "m, m, wY, Z, f, wb,
7150 "(register_operand (operands[0], SFmode)
7151 || register_operand (operands[1], SFmode))
7152 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7153 && (TARGET_ALLOW_SF_SUBREG
7154 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7167 xscpsgndp %x0,%x1,%x1
7173 "load, fpload, fpload, fpload, fpstore, fpstore,
7174 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7175 *, mtjmpr, mfjmpr, *")])
7177 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7178 ;; FMR MR MT%0 MF%1 NOP
7179 (define_insn "movsd_hardfloat"
7180 [(set (match_operand:SD 0 "nonimmediate_operand"
7181 "=!r, wz, m, Z, ?wh, ?r,
7182 f, !r, *c*l, !r, *h")
7183 (match_operand:SD 1 "input_operand"
7184 "m, Z, r, wx, r, wh,
7186 "(register_operand (operands[0], SDmode)
7187 || register_operand (operands[1], SDmode))
7188 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7202 "load, fpload, store, fpstore, mffgpr, mftgpr,
7203 fpsimple, *, mtjmpr, mfjmpr, *")])
7205 (define_insn "*mov<mode>_softfloat"
7206 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7207 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7208 "(gpc_reg_operand (operands[0], <MODE>mode)
7209 || gpc_reg_operand (operands[1], <MODE>mode))
7210 && TARGET_SOFT_FLOAT"
7222 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7223 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7225 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7226 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7228 ;; Because SF values are actually stored as DF values within the vector
7229 ;; registers, we need to convert the value to the vector SF format when
7230 ;; we need to use the bits in a union or similar cases. We only need
7231 ;; to do this transformation when the value is a vector register. Loads,
7232 ;; stores, and transfers within GPRs are assumed to be safe.
7234 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7235 ;; no alternatives, because the call is created as part of secondary_reload,
7236 ;; and operand #2's register class is used to allocate the temporary register.
7237 ;; This function is called before reload, and it creates the temporary as
7240 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7241 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7242 (define_insn_and_split "movsf_from_si"
7243 [(set (match_operand:SF 0 "nonimmediate_operand"
7244 "=!r, f, wb, wu, m, Z,
7247 (unspec:SF [(match_operand:SI 1 "input_operand"
7252 (clobber (match_scratch:DI 2
7256 "TARGET_NO_SF_SUBREG
7257 && (register_operand (operands[0], SFmode)
7258 || register_operand (operands[1], SImode))"
7271 "&& reload_completed
7272 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7273 && int_reg_operand_not_pseudo (operands[1], SImode)"
7276 rtx op0 = operands[0];
7277 rtx op1 = operands[1];
7278 rtx op2 = operands[2];
7279 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7281 /* Move SF value to upper 32-bits for xscvspdpn. */
7282 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7283 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7284 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7291 "load, fpload, fpload, fpload, store, fpstore,
7292 fpstore, vecfloat, mffgpr, *")])
7295 ;; Move 64-bit binary/decimal floating point
7296 (define_expand "mov<mode>"
7297 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7298 (match_operand:FMOVE64 1 "any_operand" ""))]
7300 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7303 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7304 (match_operand:FMOVE64 1 "const_int_operand" ""))]
7305 "! TARGET_POWERPC64 && reload_completed
7306 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7307 || (GET_CODE (operands[0]) == SUBREG
7308 && GET_CODE (SUBREG_REG (operands[0])) == REG
7309 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7310 [(set (match_dup 2) (match_dup 4))
7311 (set (match_dup 3) (match_dup 1))]
7314 int endian = (WORDS_BIG_ENDIAN == 0);
7315 HOST_WIDE_INT value = INTVAL (operands[1]);
7317 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7318 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7319 operands[4] = GEN_INT (value >> 32);
7320 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7324 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7325 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7326 "! TARGET_POWERPC64 && reload_completed
7327 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7328 || (GET_CODE (operands[0]) == SUBREG
7329 && GET_CODE (SUBREG_REG (operands[0])) == REG
7330 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7331 [(set (match_dup 2) (match_dup 4))
7332 (set (match_dup 3) (match_dup 5))]
7335 int endian = (WORDS_BIG_ENDIAN == 0);
7338 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7340 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7341 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7342 operands[4] = gen_int_mode (l[endian], SImode);
7343 operands[5] = gen_int_mode (l[1 - endian], SImode);
7347 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7348 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7349 "TARGET_POWERPC64 && reload_completed
7350 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7351 || (GET_CODE (operands[0]) == SUBREG
7352 && GET_CODE (SUBREG_REG (operands[0])) == REG
7353 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7354 [(set (match_dup 2) (match_dup 3))]
7357 int endian = (WORDS_BIG_ENDIAN == 0);
7361 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7363 operands[2] = gen_lowpart (DImode, operands[0]);
7364 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7365 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7366 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7368 operands[3] = gen_int_mode (val, DImode);
7371 ;; Don't have reload use general registers to load a constant. It is
7372 ;; less efficient than loading the constant into an FP register, since
7373 ;; it will probably be used there.
7375 ;; The move constraints are ordered to prefer floating point registers before
7376 ;; general purpose registers to avoid doing a store and a load to get the value
7377 ;; into a floating point register when it is needed for a floating point
7378 ;; operation. Prefer traditional floating point registers over VSX registers,
7379 ;; since the D-form version of the memory instructions does not need a GPR for
7380 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7383 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7384 ;; except for 0.0 which can be created on VSX with an xor instruction.
7386 (define_insn "*mov<mode>_hardfloat32"
7387 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7388 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7389 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7390 && (gpc_reg_operand (operands[0], <MODE>mode)
7391 || gpc_reg_operand (operands[1], <MODE>mode))"
7406 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7407 (set_attr "size" "64")
7408 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7410 (define_insn "*mov<mode>_softfloat32"
7411 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7412 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7414 && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7415 && (gpc_reg_operand (operands[0], <MODE>mode)
7416 || gpc_reg_operand (operands[1], <MODE>mode))"
7418 [(set_attr "type" "store,load,two,*,*,*")
7419 (set_attr "length" "8,8,8,8,12,16")])
7421 ; ld/std require word-aligned displacements -> 'Y' constraint.
7422 ; List Y->r and r->Y before r->r for reload.
7423 (define_insn "*mov<mode>_hardfloat64"
7424 [(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>")
7425 (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"))]
7426 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7427 && (gpc_reg_operand (operands[0], <MODE>mode)
7428 || gpc_reg_operand (operands[1], <MODE>mode))"
7450 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7451 (set_attr "size" "64")
7452 (set_attr "length" "4")])
7454 (define_insn "*mov<mode>_softfloat64"
7455 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7456 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7457 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7458 && (gpc_reg_operand (operands[0], <MODE>mode)
7459 || gpc_reg_operand (operands[1], <MODE>mode))"
7470 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7471 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7473 (define_expand "mov<mode>"
7474 [(set (match_operand:FMOVE128 0 "general_operand" "")
7475 (match_operand:FMOVE128 1 "any_operand" ""))]
7477 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7479 ;; It's important to list Y->r and r->Y before r->r because otherwise
7480 ;; reload, given m->r, will try to pick r->r and reload it, which
7481 ;; doesn't make progress.
7483 ;; We can't split little endian direct moves of TDmode, because the words are
7484 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7485 ;; problematical. Don't allow direct move for this case.
7487 (define_insn_and_split "*mov<mode>_64bit_dm"
7488 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7489 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7490 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7491 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7492 && (gpc_reg_operand (operands[0], <MODE>mode)
7493 || gpc_reg_operand (operands[1], <MODE>mode))"
7495 "&& reload_completed"
7497 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7498 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7500 (define_insn_and_split "*movtd_64bit_nodm"
7501 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7502 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7503 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7504 && (gpc_reg_operand (operands[0], TDmode)
7505 || gpc_reg_operand (operands[1], TDmode))"
7507 "&& reload_completed"
7509 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7510 [(set_attr "length" "8,8,8,12,12,8")])
7512 (define_insn_and_split "*mov<mode>_32bit"
7513 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7514 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7515 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7516 && (FLOAT128_2REG_P (<MODE>mode)
7517 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7518 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7519 && (gpc_reg_operand (operands[0], <MODE>mode)
7520 || gpc_reg_operand (operands[1], <MODE>mode))"
7522 "&& reload_completed"
7524 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7525 [(set_attr "length" "8,8,8,8,20,20,16")])
7527 (define_insn_and_split "*mov<mode>_softfloat"
7528 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7529 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7531 && (gpc_reg_operand (operands[0], <MODE>mode)
7532 || gpc_reg_operand (operands[1], <MODE>mode))"
7534 "&& reload_completed"
7536 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7537 [(set_attr "length" "20,20,16")])
7539 (define_expand "extenddf<mode>2"
7540 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7541 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7542 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7544 if (FLOAT128_IEEE_P (<MODE>mode))
7545 rs6000_expand_float128_convert (operands[0], operands[1], false);
7546 else if (TARGET_VSX)
7548 if (<MODE>mode == TFmode)
7549 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7550 else if (<MODE>mode == IFmode)
7551 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7557 rtx zero = gen_reg_rtx (DFmode);
7558 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7560 if (<MODE>mode == TFmode)
7561 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7562 else if (<MODE>mode == IFmode)
7563 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7570 ;; Allow memory operands for the source to be created by the combiner.
7571 (define_insn_and_split "extenddf<mode>2_fprs"
7572 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7573 (float_extend:IBM128
7574 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7575 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7576 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7577 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7579 "&& reload_completed"
7580 [(set (match_dup 3) (match_dup 1))
7581 (set (match_dup 4) (match_dup 2))]
7583 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7584 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7586 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7587 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7590 (define_insn_and_split "extenddf<mode>2_vsx"
7591 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7592 (float_extend:IBM128
7593 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7594 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7596 "&& reload_completed"
7597 [(set (match_dup 2) (match_dup 1))
7598 (set (match_dup 3) (match_dup 4))]
7600 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7601 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7603 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7604 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7605 operands[4] = CONST0_RTX (DFmode);
7608 (define_expand "extendsf<mode>2"
7609 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7610 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7611 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7613 if (FLOAT128_IEEE_P (<MODE>mode))
7614 rs6000_expand_float128_convert (operands[0], operands[1], false);
7617 rtx tmp = gen_reg_rtx (DFmode);
7618 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7619 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7624 (define_expand "trunc<mode>df2"
7625 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7626 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7627 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7629 if (FLOAT128_IEEE_P (<MODE>mode))
7631 rs6000_expand_float128_convert (operands[0], operands[1], false);
7636 (define_insn_and_split "trunc<mode>df2_internal1"
7637 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7639 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7640 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7641 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7645 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7648 emit_note (NOTE_INSN_DELETED);
7651 [(set_attr "type" "fpsimple")])
7653 (define_insn "trunc<mode>df2_internal2"
7654 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7655 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7656 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7657 && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7659 [(set_attr "type" "fp")
7660 (set_attr "fp_type" "fp_addsub_d")])
7662 (define_expand "trunc<mode>sf2"
7663 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7664 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7665 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7667 if (FLOAT128_IEEE_P (<MODE>mode))
7668 rs6000_expand_float128_convert (operands[0], operands[1], false);
7669 else if (<MODE>mode == TFmode)
7670 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7671 else if (<MODE>mode == IFmode)
7672 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7678 (define_insn_and_split "trunc<mode>sf2_fprs"
7679 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7680 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7681 (clobber (match_scratch:DF 2 "=d"))]
7682 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7683 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7685 "&& reload_completed"
7687 (float_truncate:DF (match_dup 1)))
7689 (float_truncate:SF (match_dup 2)))]
7692 (define_expand "floatsi<mode>2"
7693 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7694 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7695 (clobber (match_scratch:DI 2))])]
7696 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7698 rtx op0 = operands[0];
7699 rtx op1 = operands[1];
7701 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7703 else if (FLOAT128_IEEE_P (<MODE>mode))
7705 rs6000_expand_float128_convert (op0, op1, false);
7710 rtx tmp = gen_reg_rtx (DFmode);
7711 expand_float (tmp, op1, false);
7712 if (<MODE>mode == TFmode)
7713 emit_insn (gen_extenddftf2 (op0, tmp));
7714 else if (<MODE>mode == IFmode)
7715 emit_insn (gen_extenddfif2 (op0, tmp));
7722 ; fadd, but rounding towards zero.
7723 ; This is probably not the optimal code sequence.
7724 (define_insn "fix_trunc_helper<mode>"
7725 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7726 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7727 UNSPEC_FIX_TRUNC_TF))
7728 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7729 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7730 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7731 [(set_attr "type" "fp")
7732 (set_attr "length" "20")])
7734 (define_expand "fix_trunc<mode>si2"
7735 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7736 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7737 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7739 rtx op0 = operands[0];
7740 rtx op1 = operands[1];
7742 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7746 if (FLOAT128_IEEE_P (<MODE>mode))
7747 rs6000_expand_float128_convert (op0, op1, false);
7748 else if (<MODE>mode == TFmode)
7749 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7750 else if (<MODE>mode == IFmode)
7751 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7758 (define_expand "fix_trunc<mode>si2_fprs"
7759 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7760 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7761 (clobber (match_dup 2))
7762 (clobber (match_dup 3))
7763 (clobber (match_dup 4))
7764 (clobber (match_dup 5))])]
7765 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7767 operands[2] = gen_reg_rtx (DFmode);
7768 operands[3] = gen_reg_rtx (DFmode);
7769 operands[4] = gen_reg_rtx (DImode);
7770 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7773 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7774 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7775 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7776 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7777 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7778 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7779 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7780 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7786 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7789 gcc_assert (MEM_P (operands[5]));
7790 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7792 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7793 emit_move_insn (operands[5], operands[4]);
7794 emit_move_insn (operands[0], lowword);
7798 (define_expand "fix_trunc<mode>di2"
7799 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7800 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7801 "TARGET_FLOAT128_TYPE"
7803 if (!TARGET_FLOAT128_HW)
7805 rs6000_expand_float128_convert (operands[0], operands[1], false);
7810 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7811 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7812 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7813 "TARGET_FLOAT128_TYPE"
7815 rs6000_expand_float128_convert (operands[0], operands[1], true);
7819 (define_expand "floatdi<mode>2"
7820 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7821 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7822 "TARGET_FLOAT128_TYPE"
7824 if (!TARGET_FLOAT128_HW)
7826 rs6000_expand_float128_convert (operands[0], operands[1], false);
7831 (define_expand "floatunsdi<IEEE128:mode>2"
7832 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7833 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7834 "TARGET_FLOAT128_TYPE"
7836 if (!TARGET_FLOAT128_HW)
7838 rs6000_expand_float128_convert (operands[0], operands[1], true);
7843 (define_expand "floatuns<IEEE128:mode>2"
7844 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7845 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7846 "TARGET_FLOAT128_TYPE"
7848 rtx op0 = operands[0];
7849 rtx op1 = operands[1];
7851 if (TARGET_FLOAT128_HW)
7852 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7854 rs6000_expand_float128_convert (op0, op1, true);
7858 (define_expand "neg<mode>2"
7859 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7860 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7861 "FLOAT128_IEEE_P (<MODE>mode)
7862 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7865 if (FLOAT128_IEEE_P (<MODE>mode))
7867 if (TARGET_FLOAT128_HW)
7869 if (<MODE>mode == TFmode)
7870 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7871 else if (<MODE>mode == KFmode)
7872 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7876 else if (TARGET_FLOAT128_TYPE)
7878 if (<MODE>mode == TFmode)
7879 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7880 else if (<MODE>mode == KFmode)
7881 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7887 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7888 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7890 operands[1], <MODE>mode);
7892 if (target && !rtx_equal_p (target, operands[0]))
7893 emit_move_insn (operands[0], target);
7899 (define_insn "neg<mode>2_internal"
7900 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7901 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7902 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7905 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7906 return \"fneg %L0,%L1\;fneg %0,%1\";
7908 return \"fneg %0,%1\;fneg %L0,%L1\";
7910 [(set_attr "type" "fpsimple")
7911 (set_attr "length" "8")])
7913 (define_expand "abs<mode>2"
7914 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7915 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7916 "FLOAT128_IEEE_P (<MODE>mode)
7917 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7922 if (FLOAT128_IEEE_P (<MODE>mode))
7924 if (TARGET_FLOAT128_HW)
7926 if (<MODE>mode == TFmode)
7927 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7928 else if (<MODE>mode == KFmode)
7929 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7934 else if (TARGET_FLOAT128_TYPE)
7936 if (<MODE>mode == TFmode)
7937 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7938 else if (<MODE>mode == KFmode)
7939 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7948 label = gen_label_rtx ();
7949 if (<MODE>mode == TFmode)
7950 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7951 else if (<MODE>mode == TFmode)
7952 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7959 (define_expand "abs<mode>2_internal"
7960 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7961 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7962 (set (match_dup 3) (match_dup 5))
7963 (set (match_dup 5) (abs:DF (match_dup 5)))
7964 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7965 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7966 (label_ref (match_operand 2 "" ""))
7968 (set (match_dup 6) (neg:DF (match_dup 6)))]
7969 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7972 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7973 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7974 operands[3] = gen_reg_rtx (DFmode);
7975 operands[4] = gen_reg_rtx (CCFPmode);
7976 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7977 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7981 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7984 (define_expand "ieee_128bit_negative_zero"
7985 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7986 "TARGET_FLOAT128_TYPE"
7988 rtvec v = rtvec_alloc (16);
7991 for (i = 0; i < 16; i++)
7992 RTVEC_ELT (v, i) = const0_rtx;
7994 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7995 RTVEC_ELT (v, high) = GEN_INT (0x80);
7997 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8001 ;; IEEE 128-bit negate
8003 ;; We have 2 insns here for negate and absolute value. The first uses
8004 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8005 ;; insns, and second insn after the first split pass loads up the bit to
8006 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8007 ;; neg/abs to create the constant just once.
8009 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8010 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8011 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8012 (clobber (match_scratch:V16QI 2 "=v"))]
8013 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8016 [(parallel [(set (match_dup 0)
8017 (neg:IEEE128 (match_dup 1)))
8018 (use (match_dup 2))])]
8020 if (GET_CODE (operands[2]) == SCRATCH)
8021 operands[2] = gen_reg_rtx (V16QImode);
8023 operands[3] = gen_reg_rtx (V16QImode);
8024 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8026 [(set_attr "length" "8")
8027 (set_attr "type" "vecsimple")])
8029 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8030 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8031 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8032 (use (match_operand:V16QI 2 "register_operand" "v"))]
8033 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8034 "xxlxor %x0,%x1,%x2"
8035 [(set_attr "type" "veclogical")])
8037 ;; IEEE 128-bit absolute value
8038 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8039 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8040 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8041 (clobber (match_scratch:V16QI 2 "=v"))]
8042 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8045 [(parallel [(set (match_dup 0)
8046 (abs:IEEE128 (match_dup 1)))
8047 (use (match_dup 2))])]
8049 if (GET_CODE (operands[2]) == SCRATCH)
8050 operands[2] = gen_reg_rtx (V16QImode);
8052 operands[3] = gen_reg_rtx (V16QImode);
8053 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8055 [(set_attr "length" "8")
8056 (set_attr "type" "vecsimple")])
8058 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8059 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8060 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8061 (use (match_operand:V16QI 2 "register_operand" "v"))]
8062 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8063 "xxlandc %x0,%x1,%x2"
8064 [(set_attr "type" "veclogical")])
8066 ;; IEEE 128-bit negative absolute value
8067 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8068 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8071 (match_operand:IEEE128 1 "register_operand" "wa"))))
8072 (clobber (match_scratch:V16QI 2 "=v"))]
8073 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8074 && FLOAT128_IEEE_P (<MODE>mode)"
8077 [(parallel [(set (match_dup 0)
8078 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8079 (use (match_dup 2))])]
8081 if (GET_CODE (operands[2]) == SCRATCH)
8082 operands[2] = gen_reg_rtx (V16QImode);
8084 operands[3] = gen_reg_rtx (V16QImode);
8085 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8087 [(set_attr "length" "8")
8088 (set_attr "type" "vecsimple")])
8090 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8091 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8094 (match_operand:IEEE128 1 "register_operand" "wa"))))
8095 (use (match_operand:V16QI 2 "register_operand" "v"))]
8096 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8098 [(set_attr "type" "veclogical")])
8100 ;; Float128 conversion functions. These expand to library function calls.
8101 ;; We use expand to convert from IBM double double to IEEE 128-bit
8102 ;; and trunc for the opposite.
8103 (define_expand "extendiftf2"
8104 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8105 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8106 "TARGET_FLOAT128_TYPE"
8108 rs6000_expand_float128_convert (operands[0], operands[1], false);
8112 (define_expand "extendifkf2"
8113 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8114 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8115 "TARGET_FLOAT128_TYPE"
8117 rs6000_expand_float128_convert (operands[0], operands[1], false);
8121 (define_expand "extendtfkf2"
8122 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8123 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8124 "TARGET_FLOAT128_TYPE"
8126 rs6000_expand_float128_convert (operands[0], operands[1], false);
8130 (define_expand "trunciftf2"
8131 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8132 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8133 "TARGET_FLOAT128_TYPE"
8135 rs6000_expand_float128_convert (operands[0], operands[1], false);
8139 (define_expand "truncifkf2"
8140 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8141 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8142 "TARGET_FLOAT128_TYPE"
8144 rs6000_expand_float128_convert (operands[0], operands[1], false);
8148 (define_expand "trunckftf2"
8149 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8150 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8151 "TARGET_FLOAT128_TYPE"
8153 rs6000_expand_float128_convert (operands[0], operands[1], false);
8157 (define_expand "trunctfif2"
8158 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8159 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8160 "TARGET_FLOAT128_TYPE"
8162 rs6000_expand_float128_convert (operands[0], operands[1], false);
8167 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8168 ;; must have 3 arguments, and scratch register constraint must be a single
8171 ;; Reload patterns to support gpr load/store with misaligned mem.
8172 ;; and multiple gpr load/store at offset >= 0xfffc
8173 (define_expand "reload_<mode>_store"
8174 [(parallel [(match_operand 0 "memory_operand" "=m")
8175 (match_operand 1 "gpc_reg_operand" "r")
8176 (match_operand:GPR 2 "register_operand" "=&b")])]
8179 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8183 (define_expand "reload_<mode>_load"
8184 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8185 (match_operand 1 "memory_operand" "m")
8186 (match_operand:GPR 2 "register_operand" "=b")])]
8189 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8194 ;; Reload patterns for various types using the vector registers. We may need
8195 ;; an additional base register to convert the reg+offset addressing to reg+reg
8196 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8197 ;; index register for gpr registers.
8198 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8199 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8200 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8201 (match_operand:P 2 "register_operand" "=b")])]
8204 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8208 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8209 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8210 (match_operand:RELOAD 1 "memory_operand" "m")
8211 (match_operand:P 2 "register_operand" "=b")])]
8214 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8219 ;; Reload sometimes tries to move the address to a GPR, and can generate
8220 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8221 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8223 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8224 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8225 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8226 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8228 "TARGET_ALTIVEC && reload_completed"
8230 "&& reload_completed"
8232 (plus:P (match_dup 1)
8235 (and:P (match_dup 0)
8238 ;; Power8 merge instructions to allow direct move to/from floating point
8239 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8240 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8241 ;; value, since it is allocated in reload and not all of the flow information
8242 ;; is setup for it. We have two patterns to do the two moves between gprs and
8243 ;; fprs. There isn't a dependancy between the two, but we could potentially
8244 ;; schedule other instructions between the two instructions.
8246 (define_insn "p8_fmrgow_<mode>"
8247 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8249 (match_operand:DF 1 "register_operand" "d")
8250 (match_operand:DF 2 "register_operand" "d")]
8251 UNSPEC_P8V_FMRGOW))]
8252 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8254 [(set_attr "type" "fpsimple")])
8256 (define_insn "p8_mtvsrwz"
8257 [(set (match_operand:DF 0 "register_operand" "=d")
8258 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8259 UNSPEC_P8V_MTVSRWZ))]
8260 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8262 [(set_attr "type" "mftgpr")])
8264 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8265 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8266 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8267 UNSPEC_P8V_RELOAD_FROM_GPR))
8268 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8269 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8271 "&& reload_completed"
8274 rtx dest = operands[0];
8275 rtx src = operands[1];
8276 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8277 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8278 rtx gpr_hi_reg = gen_highpart (SImode, src);
8279 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8281 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8282 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8283 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8286 [(set_attr "length" "12")
8287 (set_attr "type" "three")])
8289 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8290 (define_insn "p8_mtvsrd_df"
8291 [(set (match_operand:DF 0 "register_operand" "=wa")
8292 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8293 UNSPEC_P8V_MTVSRD))]
8294 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8296 [(set_attr "type" "mftgpr")])
8298 (define_insn "p8_xxpermdi_<mode>"
8299 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8300 (unspec:FMOVE128_GPR [
8301 (match_operand:DF 1 "register_operand" "wa")
8302 (match_operand:DF 2 "register_operand" "wa")]
8303 UNSPEC_P8V_XXPERMDI))]
8304 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8305 "xxpermdi %x0,%x1,%x2,0"
8306 [(set_attr "type" "vecperm")])
8308 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8309 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8310 (unspec:FMOVE128_GPR
8311 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8312 UNSPEC_P8V_RELOAD_FROM_GPR))
8313 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8314 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8316 "&& reload_completed"
8319 rtx dest = operands[0];
8320 rtx src = operands[1];
8321 /* You might think that we could use op0 as one temp and a DF clobber
8322 as op2, but you'd be wrong. Secondary reload move patterns don't
8323 check for overlap of the clobber and the destination. */
8324 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8325 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8326 rtx gpr_hi_reg = gen_highpart (DImode, src);
8327 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8329 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8330 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8331 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8334 [(set_attr "length" "12")
8335 (set_attr "type" "three")])
8338 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8339 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8341 && (int_reg_operand (operands[0], <MODE>mode)
8342 || int_reg_operand (operands[1], <MODE>mode))
8343 && (!TARGET_DIRECT_MOVE_128
8344 || (!vsx_register_operand (operands[0], <MODE>mode)
8345 && !vsx_register_operand (operands[1], <MODE>mode)))"
8347 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8349 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8350 ;; type is stored internally as double precision in the VSX registers, we have
8351 ;; to convert it from the vector format.
8352 (define_insn "p8_mtvsrd_sf"
8353 [(set (match_operand:SF 0 "register_operand" "=wa")
8354 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8355 UNSPEC_P8V_MTVSRD))]
8356 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8358 [(set_attr "type" "mftgpr")])
8360 (define_insn_and_split "reload_vsx_from_gprsf"
8361 [(set (match_operand:SF 0 "register_operand" "=wa")
8362 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8363 UNSPEC_P8V_RELOAD_FROM_GPR))
8364 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8365 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8367 "&& reload_completed"
8370 rtx op0 = operands[0];
8371 rtx op1 = operands[1];
8372 rtx op2 = operands[2];
8373 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8375 /* Move SF value to upper 32-bits for xscvspdpn. */
8376 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8377 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8378 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8381 [(set_attr "length" "8")
8382 (set_attr "type" "two")])
8384 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8385 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8386 ;; and then doing a move of that.
8387 (define_insn "p8_mfvsrd_3_<mode>"
8388 [(set (match_operand:DF 0 "register_operand" "=r")
8389 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8390 UNSPEC_P8V_RELOAD_FROM_VSX))]
8391 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8393 [(set_attr "type" "mftgpr")])
8395 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8396 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8397 (unspec:FMOVE128_GPR
8398 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8399 UNSPEC_P8V_RELOAD_FROM_VSX))
8400 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8401 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8403 "&& reload_completed"
8406 rtx dest = operands[0];
8407 rtx src = operands[1];
8408 rtx tmp = operands[2];
8409 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8410 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8412 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8413 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8414 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8417 [(set_attr "length" "12")
8418 (set_attr "type" "three")])
8420 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8421 ;; type is stored internally as double precision, we have to convert it to the
8424 (define_insn_and_split "reload_gpr_from_vsxsf"
8425 [(set (match_operand:SF 0 "register_operand" "=r")
8426 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8427 UNSPEC_P8V_RELOAD_FROM_VSX))
8428 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8429 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8431 "&& reload_completed"
8434 rtx op0 = operands[0];
8435 rtx op1 = operands[1];
8436 rtx op2 = operands[2];
8437 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8439 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8440 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8441 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8444 [(set_attr "length" "12")
8445 (set_attr "type" "three")])
8447 (define_insn "p8_mfvsrd_4_disf"
8448 [(set (match_operand:DI 0 "register_operand" "=r")
8449 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8450 UNSPEC_P8V_RELOAD_FROM_VSX))]
8451 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8453 [(set_attr "type" "mftgpr")])
8456 ;; Next come the multi-word integer load and store and the load and store
8459 ;; List r->r after r->Y, otherwise reload will try to reload a
8460 ;; non-offsettable address by using r->r which won't make progress.
8461 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8462 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8464 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8465 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8466 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8469 (define_insn "*movdi_internal32"
8470 [(set (match_operand:DI 0 "nonimmediate_operand"
8471 "=Y, r, r, ^m, ^d, ^d,
8472 r, ^wY, $Z, ^wb, $wv, ^wi,
8473 *wo, *wo, *wv, *wi, *wi, *wv,
8476 (match_operand:DI 1 "input_operand"
8478 IJKnGHF, wb, wv, wY, Z, wi,
8479 Oj, wM, OjwM, Oj, wM, wS,
8483 && (gpc_reg_operand (operands[0], DImode)
8484 || gpc_reg_operand (operands[1], DImode))"
8506 "store, load, *, fpstore, fpload, fpsimple,
8507 *, fpstore, fpstore, fpload, fpload, veclogical,
8508 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8510 (set_attr "size" "64")])
8513 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8514 (match_operand:DI 1 "const_int_operand" ""))]
8515 "! TARGET_POWERPC64 && reload_completed
8516 && gpr_or_gpr_p (operands[0], operands[1])
8517 && !direct_move_p (operands[0], operands[1])"
8518 [(set (match_dup 2) (match_dup 4))
8519 (set (match_dup 3) (match_dup 1))]
8522 HOST_WIDE_INT value = INTVAL (operands[1]);
8523 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8525 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8527 operands[4] = GEN_INT (value >> 32);
8528 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8532 [(set (match_operand:DIFD 0 "nonimmediate_operand" "")
8533 (match_operand:DIFD 1 "input_operand" ""))]
8534 "reload_completed && !TARGET_POWERPC64
8535 && gpr_or_gpr_p (operands[0], operands[1])
8536 && !direct_move_p (operands[0], operands[1])"
8538 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8540 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8541 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8542 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8543 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8544 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8545 (define_insn "*movdi_internal64"
8546 [(set (match_operand:DI 0 "nonimmediate_operand"
8548 ^m, ^d, ^d, ^wY, $Z, $wb,
8549 $wv, ^wi, *wo, *wo, *wv, *wi,
8550 *wi, *wv, *wv, r, *h, *h,
8551 ?*r, ?*wg, ?*r, ?*wj")
8553 (match_operand:DI 1 "input_operand"
8555 d, m, d, wb, wv, wY,
8556 Z, wi, Oj, wM, OjwM, Oj,
8557 wM, wS, wB, *h, r, 0,
8561 && (gpc_reg_operand (operands[0], DImode)
8562 || gpc_reg_operand (operands[1], DImode))"
8593 "store, load, *, *, *, *,
8594 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8595 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8596 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8597 mftgpr, mffgpr, mftgpr, mffgpr")
8599 (set_attr "size" "64")
8607 ; Some DImode loads are best done as a load of -1 followed by a mask
8610 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8611 (match_operand:DI 1 "const_int_operand"))]
8613 && num_insns_constant (operands[1], DImode) > 1
8614 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8615 && rs6000_is_valid_and_mask (operands[1], DImode)"
8619 (and:DI (match_dup 0)
8623 ;; Split a load of a large constant into the appropriate five-instruction
8624 ;; sequence. Handle anything in a constant number of insns.
8625 ;; When non-easy constants can go in the TOC, this should use
8626 ;; easy_fp_constant predicate.
8628 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8629 (match_operand:DI 1 "const_int_operand" ""))]
8630 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8631 [(set (match_dup 0) (match_dup 2))
8632 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8635 if (rs6000_emit_set_const (operands[0], operands[1]))
8642 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8643 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8644 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8645 [(set (match_dup 0) (match_dup 2))
8646 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8649 if (rs6000_emit_set_const (operands[0], operands[1]))
8656 [(set (match_operand:DI 0 "altivec_register_operand" "")
8657 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8658 "TARGET_VSX && reload_completed"
8661 rtx op0 = operands[0];
8662 rtx op1 = operands[1];
8663 int r = REGNO (op0);
8664 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8666 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8667 if (op1 != const0_rtx && op1 != constm1_rtx)
8669 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8670 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8675 ;; Split integer constants that can be loaded with XXSPLTIB and a
8676 ;; sign extend operation.
8678 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8679 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8680 "TARGET_P9_VECTOR && reload_completed"
8683 rtx op0 = operands[0];
8684 rtx op1 = operands[1];
8685 int r = REGNO (op0);
8686 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8688 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8689 if (<MODE>mode == DImode)
8690 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8691 else if (<MODE>mode == SImode)
8692 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8693 else if (<MODE>mode == HImode)
8695 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8696 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8702 ;; TImode/PTImode is similar, except that we usually want to compute the
8703 ;; address into a register and use lsi/stsi (the exception is during reload).
8705 (define_insn "*mov<mode>_string"
8706 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8707 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8709 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8710 && (gpc_reg_operand (operands[0], <MODE>mode)
8711 || gpc_reg_operand (operands[1], <MODE>mode))"
8714 switch (which_alternative)
8720 return \"stswi %1,%P0,16\";
8725 /* If the address is not used in the output, we can use lsi. Otherwise,
8726 fall through to generating four loads. */
8728 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8729 return \"lswi %0,%P1,16\";
8737 [(set_attr "type" "store,store,load,load,*,*")
8738 (set_attr "update" "yes")
8739 (set_attr "indexed" "yes")
8740 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8741 (const_string "always")
8742 (const_string "conditional")))])
8744 (define_insn "*mov<mode>_ppc64"
8745 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8746 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8747 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8748 && (gpc_reg_operand (operands[0], <MODE>mode)
8749 || gpc_reg_operand (operands[1], <MODE>mode)))"
8751 return rs6000_output_move_128bit (operands);
8753 [(set_attr "type" "store,store,load,load,*,*")
8754 (set_attr "length" "8")])
8757 [(set (match_operand:TI2 0 "int_reg_operand" "")
8758 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8760 && (VECTOR_MEM_NONE_P (<MODE>mode)
8761 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8762 [(set (match_dup 2) (match_dup 4))
8763 (set (match_dup 3) (match_dup 5))]
8766 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8768 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8770 if (CONST_WIDE_INT_P (operands[1]))
8772 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8773 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8775 else if (CONST_INT_P (operands[1]))
8777 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8778 operands[5] = operands[1];
8785 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8786 (match_operand:TI2 1 "input_operand" ""))]
8788 && gpr_or_gpr_p (operands[0], operands[1])
8789 && !direct_move_p (operands[0], operands[1])
8790 && !quad_load_store_p (operands[0], operands[1])"
8792 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8794 (define_expand "load_multiple"
8795 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8796 (match_operand:SI 1 "" ""))
8797 (use (match_operand:SI 2 "" ""))])]
8798 "TARGET_STRING && !TARGET_POWERPC64"
8806 /* Support only loading a constant number of fixed-point registers from
8807 memory and only bother with this if more than two; the machine
8808 doesn't support more than eight. */
8809 if (GET_CODE (operands[2]) != CONST_INT
8810 || INTVAL (operands[2]) <= 2
8811 || INTVAL (operands[2]) > 8
8812 || GET_CODE (operands[1]) != MEM
8813 || GET_CODE (operands[0]) != REG
8814 || REGNO (operands[0]) >= 32)
8817 count = INTVAL (operands[2]);
8818 regno = REGNO (operands[0]);
8820 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8821 op1 = replace_equiv_address (operands[1],
8822 force_reg (SImode, XEXP (operands[1], 0)));
8824 for (i = 0; i < count; i++)
8825 XVECEXP (operands[3], 0, i)
8826 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8827 adjust_address_nv (op1, SImode, i * 4));
8830 (define_insn "*ldmsi8"
8831 [(match_parallel 0 "load_multiple_operation"
8832 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8833 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8834 (set (match_operand:SI 3 "gpc_reg_operand" "")
8835 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8836 (set (match_operand:SI 4 "gpc_reg_operand" "")
8837 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8838 (set (match_operand:SI 5 "gpc_reg_operand" "")
8839 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8840 (set (match_operand:SI 6 "gpc_reg_operand" "")
8841 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8842 (set (match_operand:SI 7 "gpc_reg_operand" "")
8843 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8844 (set (match_operand:SI 8 "gpc_reg_operand" "")
8845 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8846 (set (match_operand:SI 9 "gpc_reg_operand" "")
8847 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8848 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8850 { return rs6000_output_load_multiple (operands); }"
8851 [(set_attr "type" "load")
8852 (set_attr "update" "yes")
8853 (set_attr "indexed" "yes")
8854 (set_attr "length" "32")])
8856 (define_insn "*ldmsi7"
8857 [(match_parallel 0 "load_multiple_operation"
8858 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8859 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8860 (set (match_operand:SI 3 "gpc_reg_operand" "")
8861 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8862 (set (match_operand:SI 4 "gpc_reg_operand" "")
8863 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8864 (set (match_operand:SI 5 "gpc_reg_operand" "")
8865 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8866 (set (match_operand:SI 6 "gpc_reg_operand" "")
8867 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8868 (set (match_operand:SI 7 "gpc_reg_operand" "")
8869 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8870 (set (match_operand:SI 8 "gpc_reg_operand" "")
8871 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8872 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8874 { return rs6000_output_load_multiple (operands); }"
8875 [(set_attr "type" "load")
8876 (set_attr "update" "yes")
8877 (set_attr "indexed" "yes")
8878 (set_attr "length" "32")])
8880 (define_insn "*ldmsi6"
8881 [(match_parallel 0 "load_multiple_operation"
8882 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8883 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8884 (set (match_operand:SI 3 "gpc_reg_operand" "")
8885 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8886 (set (match_operand:SI 4 "gpc_reg_operand" "")
8887 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8888 (set (match_operand:SI 5 "gpc_reg_operand" "")
8889 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8890 (set (match_operand:SI 6 "gpc_reg_operand" "")
8891 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8892 (set (match_operand:SI 7 "gpc_reg_operand" "")
8893 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8894 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8896 { return rs6000_output_load_multiple (operands); }"
8897 [(set_attr "type" "load")
8898 (set_attr "update" "yes")
8899 (set_attr "indexed" "yes")
8900 (set_attr "length" "32")])
8902 (define_insn "*ldmsi5"
8903 [(match_parallel 0 "load_multiple_operation"
8904 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8905 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8906 (set (match_operand:SI 3 "gpc_reg_operand" "")
8907 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8908 (set (match_operand:SI 4 "gpc_reg_operand" "")
8909 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8910 (set (match_operand:SI 5 "gpc_reg_operand" "")
8911 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8912 (set (match_operand:SI 6 "gpc_reg_operand" "")
8913 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8914 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8916 { return rs6000_output_load_multiple (operands); }"
8917 [(set_attr "type" "load")
8918 (set_attr "update" "yes")
8919 (set_attr "indexed" "yes")
8920 (set_attr "length" "32")])
8922 (define_insn "*ldmsi4"
8923 [(match_parallel 0 "load_multiple_operation"
8924 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8925 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8926 (set (match_operand:SI 3 "gpc_reg_operand" "")
8927 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8928 (set (match_operand:SI 4 "gpc_reg_operand" "")
8929 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8930 (set (match_operand:SI 5 "gpc_reg_operand" "")
8931 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8932 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8934 { return rs6000_output_load_multiple (operands); }"
8935 [(set_attr "type" "load")
8936 (set_attr "update" "yes")
8937 (set_attr "indexed" "yes")
8938 (set_attr "length" "32")])
8940 (define_insn "*ldmsi3"
8941 [(match_parallel 0 "load_multiple_operation"
8942 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8943 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8944 (set (match_operand:SI 3 "gpc_reg_operand" "")
8945 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8946 (set (match_operand:SI 4 "gpc_reg_operand" "")
8947 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8948 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8950 { return rs6000_output_load_multiple (operands); }"
8951 [(set_attr "type" "load")
8952 (set_attr "update" "yes")
8953 (set_attr "indexed" "yes")
8954 (set_attr "length" "32")])
8956 (define_expand "store_multiple"
8957 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8958 (match_operand:SI 1 "" ""))
8959 (clobber (scratch:SI))
8960 (use (match_operand:SI 2 "" ""))])]
8961 "TARGET_STRING && !TARGET_POWERPC64"
8970 /* Support only storing a constant number of fixed-point registers to
8971 memory and only bother with this if more than two; the machine
8972 doesn't support more than eight. */
8973 if (GET_CODE (operands[2]) != CONST_INT
8974 || INTVAL (operands[2]) <= 2
8975 || INTVAL (operands[2]) > 8
8976 || GET_CODE (operands[0]) != MEM
8977 || GET_CODE (operands[1]) != REG
8978 || REGNO (operands[1]) >= 32)
8981 count = INTVAL (operands[2]);
8982 regno = REGNO (operands[1]);
8984 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8985 to = force_reg (SImode, XEXP (operands[0], 0));
8986 op0 = replace_equiv_address (operands[0], to);
8988 XVECEXP (operands[3], 0, 0)
8989 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8990 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8991 gen_rtx_SCRATCH (SImode));
8993 for (i = 1; i < count; i++)
8994 XVECEXP (operands[3], 0, i + 1)
8995 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8996 gen_rtx_REG (SImode, regno + i));
8999 (define_insn "*stmsi8"
9000 [(match_parallel 0 "store_multiple_operation"
9001 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9002 (match_operand:SI 2 "gpc_reg_operand" "r"))
9003 (clobber (match_scratch:SI 3 "=X"))
9004 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9005 (match_operand:SI 4 "gpc_reg_operand" "r"))
9006 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9007 (match_operand:SI 5 "gpc_reg_operand" "r"))
9008 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9009 (match_operand:SI 6 "gpc_reg_operand" "r"))
9010 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9011 (match_operand:SI 7 "gpc_reg_operand" "r"))
9012 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9013 (match_operand:SI 8 "gpc_reg_operand" "r"))
9014 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9015 (match_operand:SI 9 "gpc_reg_operand" "r"))
9016 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9017 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9018 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9020 [(set_attr "type" "store")
9021 (set_attr "update" "yes")
9022 (set_attr "indexed" "yes")
9023 (set_attr "cell_micro" "always")])
9025 (define_insn "*stmsi7"
9026 [(match_parallel 0 "store_multiple_operation"
9027 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9028 (match_operand:SI 2 "gpc_reg_operand" "r"))
9029 (clobber (match_scratch:SI 3 "=X"))
9030 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9031 (match_operand:SI 4 "gpc_reg_operand" "r"))
9032 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9033 (match_operand:SI 5 "gpc_reg_operand" "r"))
9034 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9035 (match_operand:SI 6 "gpc_reg_operand" "r"))
9036 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9037 (match_operand:SI 7 "gpc_reg_operand" "r"))
9038 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9039 (match_operand:SI 8 "gpc_reg_operand" "r"))
9040 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9041 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9042 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9044 [(set_attr "type" "store")
9045 (set_attr "update" "yes")
9046 (set_attr "indexed" "yes")
9047 (set_attr "cell_micro" "always")])
9049 (define_insn "*stmsi6"
9050 [(match_parallel 0 "store_multiple_operation"
9051 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9052 (match_operand:SI 2 "gpc_reg_operand" "r"))
9053 (clobber (match_scratch:SI 3 "=X"))
9054 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9055 (match_operand:SI 4 "gpc_reg_operand" "r"))
9056 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9057 (match_operand:SI 5 "gpc_reg_operand" "r"))
9058 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9059 (match_operand:SI 6 "gpc_reg_operand" "r"))
9060 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9061 (match_operand:SI 7 "gpc_reg_operand" "r"))
9062 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9063 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9064 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9066 [(set_attr "type" "store")
9067 (set_attr "update" "yes")
9068 (set_attr "indexed" "yes")
9069 (set_attr "cell_micro" "always")])
9071 (define_insn "*stmsi5"
9072 [(match_parallel 0 "store_multiple_operation"
9073 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9074 (match_operand:SI 2 "gpc_reg_operand" "r"))
9075 (clobber (match_scratch:SI 3 "=X"))
9076 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9077 (match_operand:SI 4 "gpc_reg_operand" "r"))
9078 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9079 (match_operand:SI 5 "gpc_reg_operand" "r"))
9080 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9081 (match_operand:SI 6 "gpc_reg_operand" "r"))
9082 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9083 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9084 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9086 [(set_attr "type" "store")
9087 (set_attr "update" "yes")
9088 (set_attr "indexed" "yes")
9089 (set_attr "cell_micro" "always")])
9091 (define_insn "*stmsi4"
9092 [(match_parallel 0 "store_multiple_operation"
9093 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9094 (match_operand:SI 2 "gpc_reg_operand" "r"))
9095 (clobber (match_scratch:SI 3 "=X"))
9096 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9097 (match_operand:SI 4 "gpc_reg_operand" "r"))
9098 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9099 (match_operand:SI 5 "gpc_reg_operand" "r"))
9100 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9101 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9102 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9104 [(set_attr "type" "store")
9105 (set_attr "update" "yes")
9106 (set_attr "indexed" "yes")
9107 (set_attr "cell_micro" "always")])
9109 (define_insn "*stmsi3"
9110 [(match_parallel 0 "store_multiple_operation"
9111 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9112 (match_operand:SI 2 "gpc_reg_operand" "r"))
9113 (clobber (match_scratch:SI 3 "=X"))
9114 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9115 (match_operand:SI 4 "gpc_reg_operand" "r"))
9116 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9117 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9118 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9120 [(set_attr "type" "store")
9121 (set_attr "update" "yes")
9122 (set_attr "indexed" "yes")
9123 (set_attr "cell_micro" "always")])
9125 (define_expand "setmemsi"
9126 [(parallel [(set (match_operand:BLK 0 "" "")
9127 (match_operand 2 "const_int_operand" ""))
9128 (use (match_operand:SI 1 "" ""))
9129 (use (match_operand:SI 3 "" ""))])]
9133 /* If value to set is not zero, use the library routine. */
9134 if (operands[2] != const0_rtx)
9137 if (expand_block_clear (operands))
9143 ;; String compare N insn.
9144 ;; Argument 0 is the target (result)
9145 ;; Argument 1 is the destination
9146 ;; Argument 2 is the source
9147 ;; Argument 3 is the length
9148 ;; Argument 4 is the alignment
9150 (define_expand "cmpstrnsi"
9151 [(parallel [(set (match_operand:SI 0)
9152 (compare:SI (match_operand:BLK 1)
9153 (match_operand:BLK 2)))
9154 (use (match_operand:SI 3))
9155 (use (match_operand:SI 4))])]
9156 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9158 if (optimize_insn_for_size_p ())
9161 if (expand_strn_compare (operands, 0))
9167 ;; String compare insn.
9168 ;; Argument 0 is the target (result)
9169 ;; Argument 1 is the destination
9170 ;; Argument 2 is the source
9171 ;; Argument 3 is the alignment
9173 (define_expand "cmpstrsi"
9174 [(parallel [(set (match_operand:SI 0)
9175 (compare:SI (match_operand:BLK 1)
9176 (match_operand:BLK 2)))
9177 (use (match_operand:SI 3))])]
9178 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9180 if (optimize_insn_for_size_p ())
9183 if (expand_strn_compare (operands, 1))
9189 ;; Block compare insn.
9190 ;; Argument 0 is the target (result)
9191 ;; Argument 1 is the destination
9192 ;; Argument 2 is the source
9193 ;; Argument 3 is the length
9194 ;; Argument 4 is the alignment
9196 (define_expand "cmpmemsi"
9197 [(parallel [(set (match_operand:SI 0)
9198 (compare:SI (match_operand:BLK 1)
9199 (match_operand:BLK 2)))
9200 (use (match_operand:SI 3))
9201 (use (match_operand:SI 4))])]
9204 if (expand_block_compare (operands))
9210 ;; String/block move insn.
9211 ;; Argument 0 is the destination
9212 ;; Argument 1 is the source
9213 ;; Argument 2 is the length
9214 ;; Argument 3 is the alignment
9216 (define_expand "movmemsi"
9217 [(parallel [(set (match_operand:BLK 0 "" "")
9218 (match_operand:BLK 1 "" ""))
9219 (use (match_operand:SI 2 "" ""))
9220 (use (match_operand:SI 3 "" ""))])]
9224 if (expand_block_move (operands))
9230 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
9231 ;; register allocator doesn't have a clue about allocating 8 word registers.
9232 ;; rD/rS = r5 is preferred, efficient form.
9233 (define_expand "movmemsi_8reg"
9234 [(parallel [(set (match_operand 0 "" "")
9235 (match_operand 1 "" ""))
9236 (use (match_operand 2 "" ""))
9237 (use (match_operand 3 "" ""))
9238 (clobber (reg:SI 5))
9239 (clobber (reg:SI 6))
9240 (clobber (reg:SI 7))
9241 (clobber (reg:SI 8))
9242 (clobber (reg:SI 9))
9243 (clobber (reg:SI 10))
9244 (clobber (reg:SI 11))
9245 (clobber (reg:SI 12))
9246 (clobber (match_scratch:SI 4 ""))])]
9251 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9252 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9253 (use (match_operand:SI 2 "immediate_operand" "i"))
9254 (use (match_operand:SI 3 "immediate_operand" "i"))
9255 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9256 (clobber (reg:SI 6))
9257 (clobber (reg:SI 7))
9258 (clobber (reg:SI 8))
9259 (clobber (reg:SI 9))
9260 (clobber (reg:SI 10))
9261 (clobber (reg:SI 11))
9262 (clobber (reg:SI 12))
9263 (clobber (match_scratch:SI 5 "=X"))]
9265 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9266 || INTVAL (operands[2]) == 0)
9267 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9268 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9269 && REGNO (operands[4]) == 5"
9270 "lswi %4,%1,%2\;stswi %4,%0,%2"
9271 [(set_attr "type" "store")
9272 (set_attr "update" "yes")
9273 (set_attr "indexed" "yes")
9274 (set_attr "cell_micro" "always")
9275 (set_attr "length" "8")])
9277 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
9278 ;; register allocator doesn't have a clue about allocating 6 word registers.
9279 ;; rD/rS = r5 is preferred, efficient form.
9280 (define_expand "movmemsi_6reg"
9281 [(parallel [(set (match_operand 0 "" "")
9282 (match_operand 1 "" ""))
9283 (use (match_operand 2 "" ""))
9284 (use (match_operand 3 "" ""))
9285 (clobber (reg:SI 5))
9286 (clobber (reg:SI 6))
9287 (clobber (reg:SI 7))
9288 (clobber (reg:SI 8))
9289 (clobber (reg:SI 9))
9290 (clobber (reg:SI 10))
9291 (clobber (match_scratch:SI 4 ""))])]
9296 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9297 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9298 (use (match_operand:SI 2 "immediate_operand" "i"))
9299 (use (match_operand:SI 3 "immediate_operand" "i"))
9300 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9301 (clobber (reg:SI 6))
9302 (clobber (reg:SI 7))
9303 (clobber (reg:SI 8))
9304 (clobber (reg:SI 9))
9305 (clobber (reg:SI 10))
9306 (clobber (match_scratch:SI 5 "=X"))]
9308 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9309 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9310 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9311 && REGNO (operands[4]) == 5"
9312 "lswi %4,%1,%2\;stswi %4,%0,%2"
9313 [(set_attr "type" "store")
9314 (set_attr "update" "yes")
9315 (set_attr "indexed" "yes")
9316 (set_attr "cell_micro" "always")
9317 (set_attr "length" "8")])
9319 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9320 ;; problems with TImode.
9321 ;; rD/rS = r5 is preferred, efficient form.
9322 (define_expand "movmemsi_4reg"
9323 [(parallel [(set (match_operand 0 "" "")
9324 (match_operand 1 "" ""))
9325 (use (match_operand 2 "" ""))
9326 (use (match_operand 3 "" ""))
9327 (clobber (reg:SI 5))
9328 (clobber (reg:SI 6))
9329 (clobber (reg:SI 7))
9330 (clobber (reg:SI 8))
9331 (clobber (match_scratch:SI 4 ""))])]
9336 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9337 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9338 (use (match_operand:SI 2 "immediate_operand" "i"))
9339 (use (match_operand:SI 3 "immediate_operand" "i"))
9340 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9341 (clobber (reg:SI 6))
9342 (clobber (reg:SI 7))
9343 (clobber (reg:SI 8))
9344 (clobber (match_scratch:SI 5 "=X"))]
9346 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9347 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9348 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9349 && REGNO (operands[4]) == 5"
9350 "lswi %4,%1,%2\;stswi %4,%0,%2"
9351 [(set_attr "type" "store")
9352 (set_attr "update" "yes")
9353 (set_attr "indexed" "yes")
9354 (set_attr "cell_micro" "always")
9355 (set_attr "length" "8")])
9357 ;; Move up to 8 bytes at a time.
9358 (define_expand "movmemsi_2reg"
9359 [(parallel [(set (match_operand 0 "" "")
9360 (match_operand 1 "" ""))
9361 (use (match_operand 2 "" ""))
9362 (use (match_operand 3 "" ""))
9363 (clobber (match_scratch:DI 4 ""))
9364 (clobber (match_scratch:SI 5 ""))])]
9365 "TARGET_STRING && ! TARGET_POWERPC64"
9369 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9370 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9371 (use (match_operand:SI 2 "immediate_operand" "i"))
9372 (use (match_operand:SI 3 "immediate_operand" "i"))
9373 (clobber (match_scratch:DI 4 "=&r"))
9374 (clobber (match_scratch:SI 5 "=X"))]
9375 "TARGET_STRING && ! TARGET_POWERPC64
9376 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9377 "lswi %4,%1,%2\;stswi %4,%0,%2"
9378 [(set_attr "type" "store")
9379 (set_attr "update" "yes")
9380 (set_attr "indexed" "yes")
9381 (set_attr "cell_micro" "always")
9382 (set_attr "length" "8")])
9384 ;; Move up to 4 bytes at a time.
9385 (define_expand "movmemsi_1reg"
9386 [(parallel [(set (match_operand 0 "" "")
9387 (match_operand 1 "" ""))
9388 (use (match_operand 2 "" ""))
9389 (use (match_operand 3 "" ""))
9390 (clobber (match_scratch:SI 4 ""))
9391 (clobber (match_scratch:SI 5 ""))])]
9396 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9397 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9398 (use (match_operand:SI 2 "immediate_operand" "i"))
9399 (use (match_operand:SI 3 "immediate_operand" "i"))
9400 (clobber (match_scratch:SI 4 "=&r"))
9401 (clobber (match_scratch:SI 5 "=X"))]
9402 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9403 "lswi %4,%1,%2\;stswi %4,%0,%2"
9404 [(set_attr "type" "store")
9405 (set_attr "update" "yes")
9406 (set_attr "indexed" "yes")
9407 (set_attr "cell_micro" "always")
9408 (set_attr "length" "8")])
9410 ;; Define insns that do load or store with update. Some of these we can
9411 ;; get by using pre-decrement or pre-increment, but the hardware can also
9412 ;; do cases where the increment is not the size of the object.
9414 ;; In all these cases, we use operands 0 and 1 for the register being
9415 ;; incremented because those are the operands that local-alloc will
9416 ;; tie and these are the pair most likely to be tieable (and the ones
9417 ;; that will benefit the most).
9419 (define_insn "*movdi_update1"
9420 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9421 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9422 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9423 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9424 (plus:DI (match_dup 1) (match_dup 2)))]
9425 "TARGET_POWERPC64 && TARGET_UPDATE
9426 && (!avoiding_indexed_address_p (DImode)
9427 || !gpc_reg_operand (operands[2], DImode))"
9431 [(set_attr "type" "load")
9432 (set_attr "update" "yes")
9433 (set_attr "indexed" "yes,no")])
9435 (define_insn "movdi_<mode>_update"
9436 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9437 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9438 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9439 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9440 (plus:P (match_dup 1) (match_dup 2)))]
9441 "TARGET_POWERPC64 && TARGET_UPDATE
9442 && (!avoiding_indexed_address_p (Pmode)
9443 || !gpc_reg_operand (operands[2], Pmode)
9444 || (REG_P (operands[0])
9445 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9449 [(set_attr "type" "store")
9450 (set_attr "update" "yes")
9451 (set_attr "indexed" "yes,no")])
9453 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9454 ;; needed for stack allocation, even if the user passes -mno-update.
9455 (define_insn "movdi_<mode>_update_stack"
9456 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9457 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9458 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9459 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9460 (plus:P (match_dup 1) (match_dup 2)))]
9465 [(set_attr "type" "store")
9466 (set_attr "update" "yes")
9467 (set_attr "indexed" "yes,no")])
9469 (define_insn "*movsi_update1"
9470 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9471 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9472 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9473 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9474 (plus:SI (match_dup 1) (match_dup 2)))]
9476 && (!avoiding_indexed_address_p (SImode)
9477 || !gpc_reg_operand (operands[2], SImode))"
9481 [(set_attr "type" "load")
9482 (set_attr "update" "yes")
9483 (set_attr "indexed" "yes,no")])
9485 (define_insn "*movsi_update2"
9486 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9488 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9489 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9490 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9491 (plus:DI (match_dup 1) (match_dup 2)))]
9492 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9494 [(set_attr "type" "load")
9495 (set_attr "sign_extend" "yes")
9496 (set_attr "update" "yes")
9497 (set_attr "indexed" "yes")])
9499 (define_insn "movsi_update"
9500 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9501 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9502 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9503 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9504 (plus:SI (match_dup 1) (match_dup 2)))]
9506 && (!avoiding_indexed_address_p (SImode)
9507 || !gpc_reg_operand (operands[2], SImode)
9508 || (REG_P (operands[0])
9509 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9513 [(set_attr "type" "store")
9514 (set_attr "update" "yes")
9515 (set_attr "indexed" "yes,no")])
9517 ;; This is an unconditional pattern; needed for stack allocation, even
9518 ;; if the user passes -mno-update.
9519 (define_insn "movsi_update_stack"
9520 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9521 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9522 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9523 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9524 (plus:SI (match_dup 1) (match_dup 2)))]
9529 [(set_attr "type" "store")
9530 (set_attr "update" "yes")
9531 (set_attr "indexed" "yes,no")])
9533 (define_insn "*movhi_update1"
9534 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9535 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9536 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9537 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9538 (plus:SI (match_dup 1) (match_dup 2)))]
9540 && (!avoiding_indexed_address_p (SImode)
9541 || !gpc_reg_operand (operands[2], SImode))"
9545 [(set_attr "type" "load")
9546 (set_attr "update" "yes")
9547 (set_attr "indexed" "yes,no")])
9549 (define_insn "*movhi_update2"
9550 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9552 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9553 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9554 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9555 (plus:SI (match_dup 1) (match_dup 2)))]
9557 && (!avoiding_indexed_address_p (SImode)
9558 || !gpc_reg_operand (operands[2], SImode))"
9562 [(set_attr "type" "load")
9563 (set_attr "update" "yes")
9564 (set_attr "indexed" "yes,no")])
9566 (define_insn "*movhi_update3"
9567 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9569 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9570 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9571 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9572 (plus:SI (match_dup 1) (match_dup 2)))]
9574 && !(avoiding_indexed_address_p (SImode)
9575 && gpc_reg_operand (operands[2], SImode))"
9579 [(set_attr "type" "load")
9580 (set_attr "sign_extend" "yes")
9581 (set_attr "update" "yes")
9582 (set_attr "indexed" "yes,no")])
9584 (define_insn "*movhi_update4"
9585 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9586 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9587 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9588 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9589 (plus:SI (match_dup 1) (match_dup 2)))]
9591 && (!avoiding_indexed_address_p (SImode)
9592 || !gpc_reg_operand (operands[2], SImode))"
9596 [(set_attr "type" "store")
9597 (set_attr "update" "yes")
9598 (set_attr "indexed" "yes,no")])
9600 (define_insn "*movqi_update1"
9601 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9602 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9603 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9604 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9605 (plus:SI (match_dup 1) (match_dup 2)))]
9607 && (!avoiding_indexed_address_p (SImode)
9608 || !gpc_reg_operand (operands[2], SImode))"
9612 [(set_attr "type" "load")
9613 (set_attr "update" "yes")
9614 (set_attr "indexed" "yes,no")])
9616 (define_insn "*movqi_update2"
9617 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9619 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9620 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9621 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9622 (plus:SI (match_dup 1) (match_dup 2)))]
9624 && (!avoiding_indexed_address_p (SImode)
9625 || !gpc_reg_operand (operands[2], SImode))"
9629 [(set_attr "type" "load")
9630 (set_attr "update" "yes")
9631 (set_attr "indexed" "yes,no")])
9633 (define_insn "*movqi_update3"
9634 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9635 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9636 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9637 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9638 (plus:SI (match_dup 1) (match_dup 2)))]
9640 && (!avoiding_indexed_address_p (SImode)
9641 || !gpc_reg_operand (operands[2], SImode))"
9645 [(set_attr "type" "store")
9646 (set_attr "update" "yes")
9647 (set_attr "indexed" "yes,no")])
9649 (define_insn "*movsf_update1"
9650 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9651 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9652 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9653 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9654 (plus:SI (match_dup 1) (match_dup 2)))]
9655 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9656 && (!avoiding_indexed_address_p (SImode)
9657 || !gpc_reg_operand (operands[2], SImode))"
9661 [(set_attr "type" "fpload")
9662 (set_attr "update" "yes")
9663 (set_attr "indexed" "yes,no")])
9665 (define_insn "*movsf_update2"
9666 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9667 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9668 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9669 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9670 (plus:SI (match_dup 1) (match_dup 2)))]
9671 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9672 && (!avoiding_indexed_address_p (SImode)
9673 || !gpc_reg_operand (operands[2], SImode))"
9677 [(set_attr "type" "fpstore")
9678 (set_attr "update" "yes")
9679 (set_attr "indexed" "yes,no")])
9681 (define_insn "*movsf_update3"
9682 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9683 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9684 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9685 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9686 (plus:SI (match_dup 1) (match_dup 2)))]
9687 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9688 && (!avoiding_indexed_address_p (SImode)
9689 || !gpc_reg_operand (operands[2], SImode))"
9693 [(set_attr "type" "load")
9694 (set_attr "update" "yes")
9695 (set_attr "indexed" "yes,no")])
9697 (define_insn "*movsf_update4"
9698 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9699 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9700 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9701 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9702 (plus:SI (match_dup 1) (match_dup 2)))]
9703 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9704 && (!avoiding_indexed_address_p (SImode)
9705 || !gpc_reg_operand (operands[2], SImode))"
9709 [(set_attr "type" "store")
9710 (set_attr "update" "yes")
9711 (set_attr "indexed" "yes,no")])
9713 (define_insn "*movdf_update1"
9714 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9715 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9716 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9717 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9718 (plus:SI (match_dup 1) (match_dup 2)))]
9719 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9720 && (!avoiding_indexed_address_p (SImode)
9721 || !gpc_reg_operand (operands[2], SImode))"
9725 [(set_attr "type" "fpload")
9726 (set_attr "update" "yes")
9727 (set_attr "indexed" "yes,no")
9728 (set_attr "size" "64")])
9730 (define_insn "*movdf_update2"
9731 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9732 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9733 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9734 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9735 (plus:SI (match_dup 1) (match_dup 2)))]
9736 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9737 && (!avoiding_indexed_address_p (SImode)
9738 || !gpc_reg_operand (operands[2], SImode))"
9742 [(set_attr "type" "fpstore")
9743 (set_attr "update" "yes")
9744 (set_attr "indexed" "yes,no")])
9747 ;; After inserting conditional returns we can sometimes have
9748 ;; unnecessary register moves. Unfortunately we cannot have a
9749 ;; modeless peephole here, because some single SImode sets have early
9750 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9751 ;; sequences, using get_attr_length here will smash the operands
9752 ;; array. Neither is there an early_cobbler_p predicate.
9753 ;; Also this optimization interferes with scalars going into
9754 ;; altivec registers (the code does reloading through the FPRs).
9756 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9757 (match_operand:DF 1 "any_operand" ""))
9758 (set (match_operand:DF 2 "gpc_reg_operand" "")
9761 && peep2_reg_dead_p (2, operands[0])"
9762 [(set (match_dup 2) (match_dup 1))])
9765 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9766 (match_operand:SF 1 "any_operand" ""))
9767 (set (match_operand:SF 2 "gpc_reg_operand" "")
9770 && peep2_reg_dead_p (2, operands[0])"
9771 [(set (match_dup 2) (match_dup 1))])
9776 ;; Mode attributes for different ABIs.
9777 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9778 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9779 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9780 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9782 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9783 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9784 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9785 (match_operand 4 "" "g")))
9786 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9787 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9789 (clobber (reg:SI LR_REGNO))]
9790 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9792 if (TARGET_CMODEL != CMODEL_SMALL)
9793 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9796 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9798 "&& TARGET_TLS_MARKERS"
9800 (unspec:TLSmode [(match_dup 1)
9803 (parallel [(set (match_dup 0)
9804 (call (mem:TLSmode (match_dup 3))
9806 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9807 (clobber (reg:SI LR_REGNO))])]
9809 [(set_attr "type" "two")
9810 (set (attr "length")
9811 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9815 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9816 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9817 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9818 (match_operand 4 "" "g")))
9819 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9820 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9822 (clobber (reg:SI LR_REGNO))]
9823 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9827 if (TARGET_SECURE_PLT && flag_pic == 2)
9828 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9830 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9833 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9835 "&& TARGET_TLS_MARKERS"
9837 (unspec:TLSmode [(match_dup 1)
9840 (parallel [(set (match_dup 0)
9841 (call (mem:TLSmode (match_dup 3))
9843 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9844 (clobber (reg:SI LR_REGNO))])]
9846 [(set_attr "type" "two")
9847 (set_attr "length" "8")])
9849 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9850 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9851 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9852 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9854 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9855 "addi %0,%1,%2@got@tlsgd"
9856 "&& TARGET_CMODEL != CMODEL_SMALL"
9859 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9861 (lo_sum:TLSmode (match_dup 3)
9862 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9865 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9867 [(set (attr "length")
9868 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9872 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9873 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9875 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9876 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9878 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9879 "addis %0,%1,%2@got@tlsgd@ha"
9880 [(set_attr "length" "4")])
9882 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9883 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9884 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9885 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9886 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9888 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9889 "addi %0,%1,%2@got@tlsgd@l"
9890 [(set_attr "length" "4")])
9892 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9893 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9894 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9895 (match_operand 2 "" "g")))
9896 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9898 (clobber (reg:SI LR_REGNO))]
9899 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9900 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9901 "bl %z1(%3@tlsgd)\;nop"
9902 [(set_attr "type" "branch")
9903 (set_attr "length" "8")])
9905 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9906 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9907 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9908 (match_operand 2 "" "g")))
9909 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9911 (clobber (reg:SI LR_REGNO))]
9912 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9916 if (TARGET_SECURE_PLT && flag_pic == 2)
9917 return "bl %z1+32768(%3@tlsgd)@plt";
9918 return "bl %z1(%3@tlsgd)@plt";
9920 return "bl %z1(%3@tlsgd)";
9922 [(set_attr "type" "branch")
9923 (set_attr "length" "4")])
9925 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9926 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9927 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9928 (match_operand 3 "" "g")))
9929 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9931 (clobber (reg:SI LR_REGNO))]
9932 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9934 if (TARGET_CMODEL != CMODEL_SMALL)
9935 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9938 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9940 "&& TARGET_TLS_MARKERS"
9942 (unspec:TLSmode [(match_dup 1)]
9944 (parallel [(set (match_dup 0)
9945 (call (mem:TLSmode (match_dup 2))
9947 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9948 (clobber (reg:SI LR_REGNO))])]
9950 [(set_attr "type" "two")
9951 (set (attr "length")
9952 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9956 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9957 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9958 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9959 (match_operand 3 "" "g")))
9960 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9962 (clobber (reg:SI LR_REGNO))]
9963 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9967 if (TARGET_SECURE_PLT && flag_pic == 2)
9968 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9970 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9973 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9975 "&& TARGET_TLS_MARKERS"
9977 (unspec:TLSmode [(match_dup 1)]
9979 (parallel [(set (match_dup 0)
9980 (call (mem:TLSmode (match_dup 2))
9982 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9983 (clobber (reg:SI LR_REGNO))])]
9985 [(set_attr "length" "8")])
9987 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9988 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9989 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9991 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9992 "addi %0,%1,%&@got@tlsld"
9993 "&& TARGET_CMODEL != CMODEL_SMALL"
9996 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9998 (lo_sum:TLSmode (match_dup 2)
9999 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10002 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10004 [(set (attr "length")
10005 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10009 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10010 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10012 (unspec:TLSmode [(const_int 0)
10013 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10015 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10016 "addis %0,%1,%&@got@tlsld@ha"
10017 [(set_attr "length" "4")])
10019 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10020 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10021 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10022 (unspec:TLSmode [(const_int 0)
10023 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10025 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10026 "addi %0,%1,%&@got@tlsld@l"
10027 [(set_attr "length" "4")])
10029 (define_insn "*tls_ld_call_aix<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 [(const_int 0)] UNSPEC_TLSLD)
10034 (clobber (reg:SI LR_REGNO))]
10035 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10036 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10037 "bl %z1(%&@tlsld)\;nop"
10038 [(set_attr "type" "branch")
10039 (set_attr "length" "8")])
10041 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10042 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10043 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10044 (match_operand 2 "" "g")))
10045 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10046 (clobber (reg:SI LR_REGNO))]
10047 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10051 if (TARGET_SECURE_PLT && flag_pic == 2)
10052 return "bl %z1+32768(%&@tlsld)@plt";
10053 return "bl %z1(%&@tlsld)@plt";
10055 return "bl %z1(%&@tlsld)";
10057 [(set_attr "type" "branch")
10058 (set_attr "length" "4")])
10060 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10061 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10062 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10063 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10064 UNSPEC_TLSDTPREL))]
10066 "addi %0,%1,%2@dtprel")
10068 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10069 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10070 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10071 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10072 UNSPEC_TLSDTPRELHA))]
10074 "addis %0,%1,%2@dtprel@ha")
10076 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10077 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10078 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10079 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10080 UNSPEC_TLSDTPRELLO))]
10082 "addi %0,%1,%2@dtprel@l")
10084 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10085 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10086 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10087 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10088 UNSPEC_TLSGOTDTPREL))]
10090 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10091 "&& TARGET_CMODEL != CMODEL_SMALL"
10092 [(set (match_dup 3)
10094 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10096 (lo_sum:TLSmode (match_dup 3)
10097 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10100 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10102 [(set (attr "length")
10103 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10107 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10108 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10110 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10111 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10112 UNSPEC_TLSGOTDTPREL)))]
10113 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10114 "addis %0,%1,%2@got@dtprel@ha"
10115 [(set_attr "length" "4")])
10117 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10118 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10119 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10120 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10121 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10122 UNSPEC_TLSGOTDTPREL)))]
10123 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10124 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10125 [(set_attr "length" "4")])
10127 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10128 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10129 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10130 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10133 "addi %0,%1,%2@tprel")
10135 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10136 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10137 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10138 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10139 UNSPEC_TLSTPRELHA))]
10141 "addis %0,%1,%2@tprel@ha")
10143 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10144 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10145 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10146 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10147 UNSPEC_TLSTPRELLO))]
10149 "addi %0,%1,%2@tprel@l")
10151 ;; "b" output constraint here and on tls_tls input to support linker tls
10152 ;; optimization. The linker may edit the instructions emitted by a
10153 ;; tls_got_tprel/tls_tls pair to addis,addi.
10154 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10155 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10156 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10157 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10158 UNSPEC_TLSGOTTPREL))]
10160 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10161 "&& TARGET_CMODEL != CMODEL_SMALL"
10162 [(set (match_dup 3)
10164 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10166 (lo_sum:TLSmode (match_dup 3)
10167 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10170 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10172 [(set (attr "length")
10173 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10177 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10178 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10180 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10181 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10182 UNSPEC_TLSGOTTPREL)))]
10183 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10184 "addis %0,%1,%2@got@tprel@ha"
10185 [(set_attr "length" "4")])
10187 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10188 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10189 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10190 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10191 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10192 UNSPEC_TLSGOTTPREL)))]
10193 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10194 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10195 [(set_attr "length" "4")])
10197 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10198 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10199 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10200 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10202 "TARGET_ELF && HAVE_AS_TLS"
10203 "add %0,%1,%2@tls")
10205 (define_expand "tls_get_tpointer"
10206 [(set (match_operand:SI 0 "gpc_reg_operand" "")
10207 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10208 "TARGET_XCOFF && HAVE_AS_TLS"
10211 emit_insn (gen_tls_get_tpointer_internal ());
10212 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10216 (define_insn "tls_get_tpointer_internal"
10218 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10219 (clobber (reg:SI LR_REGNO))]
10220 "TARGET_XCOFF && HAVE_AS_TLS"
10221 "bla __get_tpointer")
10223 (define_expand "tls_get_addr<mode>"
10224 [(set (match_operand:P 0 "gpc_reg_operand" "")
10225 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10226 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10227 "TARGET_XCOFF && HAVE_AS_TLS"
10230 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10231 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10232 emit_insn (gen_tls_get_addr_internal<mode> ());
10233 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10237 (define_insn "tls_get_addr_internal<mode>"
10239 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10240 (clobber (reg:P 0))
10241 (clobber (reg:P 4))
10242 (clobber (reg:P 5))
10243 (clobber (reg:P 11))
10244 (clobber (reg:CC CR0_REGNO))
10245 (clobber (reg:P LR_REGNO))]
10246 "TARGET_XCOFF && HAVE_AS_TLS"
10247 "bla __tls_get_addr")
10249 ;; Next come insns related to the calling sequence.
10251 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10252 ;; We move the back-chain and decrement the stack pointer.
10254 (define_expand "allocate_stack"
10255 [(set (match_operand 0 "gpc_reg_operand" "")
10256 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10258 (minus (reg 1) (match_dup 1)))]
10261 { rtx chain = gen_reg_rtx (Pmode);
10262 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10264 rtx insn, par, set, mem;
10266 emit_move_insn (chain, stack_bot);
10268 /* Check stack bounds if necessary. */
10269 if (crtl->limit_stack)
10272 available = expand_binop (Pmode, sub_optab,
10273 stack_pointer_rtx, stack_limit_rtx,
10274 NULL_RTX, 1, OPTAB_WIDEN);
10275 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10278 if (GET_CODE (operands[1]) != CONST_INT
10279 || INTVAL (operands[1]) < -32767
10280 || INTVAL (operands[1]) > 32768)
10282 neg_op0 = gen_reg_rtx (Pmode);
10284 emit_insn (gen_negsi2 (neg_op0, operands[1]));
10286 emit_insn (gen_negdi2 (neg_op0, operands[1]));
10289 neg_op0 = GEN_INT (- INTVAL (operands[1]));
10291 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10292 : gen_movdi_di_update_stack))
10293 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10295 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10296 it now and set the alias set/attributes. The above gen_*_update
10297 calls will generate a PARALLEL with the MEM set being the first
10299 par = PATTERN (insn);
10300 gcc_assert (GET_CODE (par) == PARALLEL);
10301 set = XVECEXP (par, 0, 0);
10302 gcc_assert (GET_CODE (set) == SET);
10303 mem = SET_DEST (set);
10304 gcc_assert (MEM_P (mem));
10305 MEM_NOTRAP_P (mem) = 1;
10306 set_mem_alias_set (mem, get_frame_alias_set ());
10308 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10312 ;; These patterns say how to save and restore the stack pointer. We need not
10313 ;; save the stack pointer at function level since we are careful to
10314 ;; preserve the backchain. At block level, we have to restore the backchain
10315 ;; when we restore the stack pointer.
10317 ;; For nonlocal gotos, we must save both the stack pointer and its
10318 ;; backchain and restore both. Note that in the nonlocal case, the
10319 ;; save area is a memory location.
10321 (define_expand "save_stack_function"
10322 [(match_operand 0 "any_operand" "")
10323 (match_operand 1 "any_operand" "")]
10327 (define_expand "restore_stack_function"
10328 [(match_operand 0 "any_operand" "")
10329 (match_operand 1 "any_operand" "")]
10333 ;; Adjust stack pointer (op0) to a new value (op1).
10334 ;; First copy old stack backchain to new location, and ensure that the
10335 ;; scheduler won't reorder the sp assignment before the backchain write.
10336 (define_expand "restore_stack_block"
10337 [(set (match_dup 2) (match_dup 3))
10338 (set (match_dup 4) (match_dup 2))
10340 (set (match_operand 0 "register_operand" "")
10341 (match_operand 1 "register_operand" ""))]
10347 operands[1] = force_reg (Pmode, operands[1]);
10348 operands[2] = gen_reg_rtx (Pmode);
10349 operands[3] = gen_frame_mem (Pmode, operands[0]);
10350 operands[4] = gen_frame_mem (Pmode, operands[1]);
10351 p = rtvec_alloc (1);
10352 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10354 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10357 (define_expand "save_stack_nonlocal"
10358 [(set (match_dup 3) (match_dup 4))
10359 (set (match_operand 0 "memory_operand" "") (match_dup 3))
10360 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10364 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10366 /* Copy the backchain to the first word, sp to the second. */
10367 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10368 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10369 operands[3] = gen_reg_rtx (Pmode);
10370 operands[4] = gen_frame_mem (Pmode, operands[1]);
10373 (define_expand "restore_stack_nonlocal"
10374 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10375 (set (match_dup 3) (match_dup 4))
10376 (set (match_dup 5) (match_dup 2))
10378 (set (match_operand 0 "register_operand" "") (match_dup 3))]
10382 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10385 /* Restore the backchain from the first word, sp from the second. */
10386 operands[2] = gen_reg_rtx (Pmode);
10387 operands[3] = gen_reg_rtx (Pmode);
10388 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10389 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10390 operands[5] = gen_frame_mem (Pmode, operands[3]);
10391 p = rtvec_alloc (1);
10392 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10394 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10397 ;; TOC register handling.
10399 ;; Code to initialize the TOC register...
10401 (define_insn "load_toc_aix_si"
10402 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10403 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10404 (use (reg:SI 2))])]
10405 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10409 extern int need_toc_init;
10411 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10412 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10413 operands[2] = gen_rtx_REG (Pmode, 2);
10414 return \"lwz %0,%1(%2)\";
10416 [(set_attr "type" "load")
10417 (set_attr "update" "no")
10418 (set_attr "indexed" "no")])
10420 (define_insn "load_toc_aix_di"
10421 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10422 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10423 (use (reg:DI 2))])]
10424 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10428 extern int need_toc_init;
10430 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10431 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10433 strcat (buf, \"@toc\");
10434 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10435 operands[2] = gen_rtx_REG (Pmode, 2);
10436 return \"ld %0,%1(%2)\";
10438 [(set_attr "type" "load")
10439 (set_attr "update" "no")
10440 (set_attr "indexed" "no")])
10442 (define_insn "load_toc_v4_pic_si"
10443 [(set (reg:SI LR_REGNO)
10444 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10445 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10446 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10447 [(set_attr "type" "branch")
10448 (set_attr "length" "4")])
10450 (define_expand "load_toc_v4_PIC_1"
10451 [(parallel [(set (reg:SI LR_REGNO)
10452 (match_operand:SI 0 "immediate_operand" "s"))
10453 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10454 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10455 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10458 (define_insn "load_toc_v4_PIC_1_normal"
10459 [(set (reg:SI LR_REGNO)
10460 (match_operand:SI 0 "immediate_operand" "s"))
10461 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10462 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10463 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10464 "bcl 20,31,%0\\n%0:"
10465 [(set_attr "type" "branch")
10466 (set_attr "length" "4")
10467 (set_attr "cannot_copy" "yes")])
10469 (define_insn "load_toc_v4_PIC_1_476"
10470 [(set (reg:SI LR_REGNO)
10471 (match_operand:SI 0 "immediate_operand" "s"))
10472 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10473 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10474 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10478 static char templ[32];
10480 get_ppc476_thunk_name (name);
10481 sprintf (templ, \"bl %s\\n%%0:\", name);
10484 [(set_attr "type" "branch")
10485 (set_attr "length" "4")
10486 (set_attr "cannot_copy" "yes")])
10488 (define_expand "load_toc_v4_PIC_1b"
10489 [(parallel [(set (reg:SI LR_REGNO)
10490 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10491 (label_ref (match_operand 1 "" ""))]
10494 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10497 (define_insn "load_toc_v4_PIC_1b_normal"
10498 [(set (reg:SI LR_REGNO)
10499 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10500 (label_ref (match_operand 1 "" ""))]
10503 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10504 "bcl 20,31,$+8\;.long %0-$"
10505 [(set_attr "type" "branch")
10506 (set_attr "length" "8")])
10508 (define_insn "load_toc_v4_PIC_1b_476"
10509 [(set (reg:SI LR_REGNO)
10510 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10511 (label_ref (match_operand 1 "" ""))]
10514 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10518 static char templ[32];
10520 get_ppc476_thunk_name (name);
10521 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10524 [(set_attr "type" "branch")
10525 (set_attr "length" "16")])
10527 (define_insn "load_toc_v4_PIC_2"
10528 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10529 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10530 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10531 (match_operand:SI 3 "immediate_operand" "s")))))]
10532 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10534 [(set_attr "type" "load")])
10536 (define_insn "load_toc_v4_PIC_3b"
10537 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10538 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10540 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10541 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10542 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10543 "addis %0,%1,%2-%3@ha")
10545 (define_insn "load_toc_v4_PIC_3c"
10546 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10547 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10548 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10549 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10550 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10551 "addi %0,%1,%2-%3@l")
10553 ;; If the TOC is shared over a translation unit, as happens with all
10554 ;; the kinds of PIC that we support, we need to restore the TOC
10555 ;; pointer only when jumping over units of translation.
10556 ;; On Darwin, we need to reload the picbase.
10558 (define_expand "builtin_setjmp_receiver"
10559 [(use (label_ref (match_operand 0 "" "")))]
10560 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10561 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10562 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10566 if (DEFAULT_ABI == ABI_DARWIN)
10568 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10569 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10573 crtl->uses_pic_offset_table = 1;
10574 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10575 CODE_LABEL_NUMBER (operands[0]));
10576 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10578 emit_insn (gen_load_macho_picbase (tmplabrtx));
10579 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10580 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10584 rs6000_emit_load_toc_table (FALSE);
10588 ;; Largetoc support
10589 (define_insn "*largetoc_high"
10590 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10592 (unspec [(match_operand:DI 1 "" "")
10593 (match_operand:DI 2 "gpc_reg_operand" "b")]
10595 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10596 "addis %0,%2,%1@toc@ha")
10598 (define_insn "*largetoc_high_aix<mode>"
10599 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10601 (unspec [(match_operand:P 1 "" "")
10602 (match_operand:P 2 "gpc_reg_operand" "b")]
10604 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10605 "addis %0,%1@u(%2)")
10607 (define_insn "*largetoc_high_plus"
10608 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10611 (unspec [(match_operand:DI 1 "" "")
10612 (match_operand:DI 2 "gpc_reg_operand" "b")]
10614 (match_operand:DI 3 "add_cint_operand" "n"))))]
10615 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10616 "addis %0,%2,%1+%3@toc@ha")
10618 (define_insn "*largetoc_high_plus_aix<mode>"
10619 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10622 (unspec [(match_operand:P 1 "" "")
10623 (match_operand:P 2 "gpc_reg_operand" "b")]
10625 (match_operand:P 3 "add_cint_operand" "n"))))]
10626 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10627 "addis %0,%1+%3@u(%2)")
10629 (define_insn "*largetoc_low"
10630 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10631 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10632 (match_operand:DI 2 "" "")))]
10633 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10636 (define_insn "*largetoc_low_aix<mode>"
10637 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10638 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10639 (match_operand:P 2 "" "")))]
10640 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10643 (define_insn_and_split "*tocref<mode>"
10644 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10645 (match_operand:P 1 "small_toc_ref" "R"))]
10648 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10649 [(set (match_dup 0) (high:P (match_dup 1)))
10650 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10652 ;; Elf specific ways of loading addresses for non-PIC code.
10653 ;; The output of this could be r0, but we make a very strong
10654 ;; preference for a base register because it will usually
10655 ;; be needed there.
10656 (define_insn "elf_high"
10657 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10658 (high:SI (match_operand 1 "" "")))]
10659 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10662 (define_insn "elf_low"
10663 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10664 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10665 (match_operand 2 "" "")))]
10666 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10669 ;; Call and call_value insns
10670 (define_expand "call"
10671 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10672 (match_operand 1 "" ""))
10673 (use (match_operand 2 "" ""))
10674 (clobber (reg:SI LR_REGNO))])]
10679 if (MACHOPIC_INDIRECT)
10680 operands[0] = machopic_indirect_call_target (operands[0]);
10683 gcc_assert (GET_CODE (operands[0]) == MEM);
10684 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10686 operands[0] = XEXP (operands[0], 0);
10688 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10690 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10694 if (GET_CODE (operands[0]) != SYMBOL_REF
10695 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10697 if (INTVAL (operands[2]) & CALL_LONG)
10698 operands[0] = rs6000_longcall_ref (operands[0]);
10700 switch (DEFAULT_ABI)
10704 operands[0] = force_reg (Pmode, operands[0]);
10708 gcc_unreachable ();
10713 (define_expand "call_value"
10714 [(parallel [(set (match_operand 0 "" "")
10715 (call (mem:SI (match_operand 1 "address_operand" ""))
10716 (match_operand 2 "" "")))
10717 (use (match_operand 3 "" ""))
10718 (clobber (reg:SI LR_REGNO))])]
10723 if (MACHOPIC_INDIRECT)
10724 operands[1] = machopic_indirect_call_target (operands[1]);
10727 gcc_assert (GET_CODE (operands[1]) == MEM);
10728 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10730 operands[1] = XEXP (operands[1], 0);
10732 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10734 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10738 if (GET_CODE (operands[1]) != SYMBOL_REF
10739 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10741 if (INTVAL (operands[3]) & CALL_LONG)
10742 operands[1] = rs6000_longcall_ref (operands[1]);
10744 switch (DEFAULT_ABI)
10748 operands[1] = force_reg (Pmode, operands[1]);
10752 gcc_unreachable ();
10757 ;; Call to function in current module. No TOC pointer reload needed.
10758 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10759 ;; either the function was not prototyped, or it was prototyped as a
10760 ;; variable argument function. It is > 0 if FP registers were passed
10761 ;; and < 0 if they were not.
10763 (define_insn "*call_local32"
10764 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10765 (match_operand 1 "" "g,g"))
10766 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10767 (clobber (reg:SI LR_REGNO))]
10768 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10771 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10772 output_asm_insn (\"crxor 6,6,6\", operands);
10774 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10775 output_asm_insn (\"creqv 6,6,6\", operands);
10777 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10779 [(set_attr "type" "branch")
10780 (set_attr "length" "4,8")])
10782 (define_insn "*call_local64"
10783 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10784 (match_operand 1 "" "g,g"))
10785 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10786 (clobber (reg:SI LR_REGNO))]
10787 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10790 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10791 output_asm_insn (\"crxor 6,6,6\", operands);
10793 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10794 output_asm_insn (\"creqv 6,6,6\", operands);
10796 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10798 [(set_attr "type" "branch")
10799 (set_attr "length" "4,8")])
10801 (define_insn "*call_value_local32"
10802 [(set (match_operand 0 "" "")
10803 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10804 (match_operand 2 "" "g,g")))
10805 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10806 (clobber (reg:SI LR_REGNO))]
10807 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10810 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10811 output_asm_insn (\"crxor 6,6,6\", operands);
10813 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10814 output_asm_insn (\"creqv 6,6,6\", operands);
10816 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10818 [(set_attr "type" "branch")
10819 (set_attr "length" "4,8")])
10822 (define_insn "*call_value_local64"
10823 [(set (match_operand 0 "" "")
10824 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10825 (match_operand 2 "" "g,g")))
10826 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10827 (clobber (reg:SI LR_REGNO))]
10828 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10831 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10832 output_asm_insn (\"crxor 6,6,6\", operands);
10834 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10835 output_asm_insn (\"creqv 6,6,6\", operands);
10837 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10839 [(set_attr "type" "branch")
10840 (set_attr "length" "4,8")])
10843 ;; A function pointer under System V is just a normal pointer
10844 ;; operands[0] is the function pointer
10845 ;; operands[1] is the stack size to clean up
10846 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10847 ;; which indicates how to set cr1
10849 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10850 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10851 (match_operand 1 "" "g,g,g,g"))
10852 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10853 (clobber (reg:SI LR_REGNO))]
10854 "DEFAULT_ABI == ABI_V4
10855 || DEFAULT_ABI == ABI_DARWIN"
10857 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10858 output_asm_insn ("crxor 6,6,6", operands);
10860 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10861 output_asm_insn ("creqv 6,6,6", operands);
10865 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10866 (set_attr "length" "4,4,8,8")])
10868 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10869 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10870 (match_operand 1 "" "g,g"))
10871 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10872 (clobber (reg:SI LR_REGNO))]
10873 "(DEFAULT_ABI == ABI_DARWIN
10874 || (DEFAULT_ABI == ABI_V4
10875 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10877 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10878 output_asm_insn ("crxor 6,6,6", operands);
10880 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10881 output_asm_insn ("creqv 6,6,6", operands);
10884 return output_call(insn, operands, 0, 2);
10886 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10888 gcc_assert (!TARGET_SECURE_PLT);
10889 return "bl %z0@plt";
10895 "DEFAULT_ABI == ABI_V4
10896 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10897 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10898 [(parallel [(call (mem:SI (match_dup 0))
10900 (use (match_dup 2))
10901 (use (match_dup 3))
10902 (clobber (reg:SI LR_REGNO))])]
10904 operands[3] = pic_offset_table_rtx;
10906 [(set_attr "type" "branch,branch")
10907 (set_attr "length" "4,8")])
10909 (define_insn "*call_nonlocal_sysv_secure<mode>"
10910 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10911 (match_operand 1 "" "g,g"))
10912 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10913 (use (match_operand:SI 3 "register_operand" "r,r"))
10914 (clobber (reg:SI LR_REGNO))]
10915 "(DEFAULT_ABI == ABI_V4
10916 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10917 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10919 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10920 output_asm_insn ("crxor 6,6,6", operands);
10922 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10923 output_asm_insn ("creqv 6,6,6", operands);
10926 /* The magic 32768 offset here and in the other sysv call insns
10927 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10928 See sysv4.h:toc_section. */
10929 return "bl %z0+32768@plt";
10931 return "bl %z0@plt";
10933 [(set_attr "type" "branch,branch")
10934 (set_attr "length" "4,8")])
10936 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10937 [(set (match_operand 0 "" "")
10938 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10939 (match_operand 2 "" "g,g,g,g")))
10940 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10941 (clobber (reg:SI LR_REGNO))]
10942 "DEFAULT_ABI == ABI_V4
10943 || DEFAULT_ABI == ABI_DARWIN"
10945 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10946 output_asm_insn ("crxor 6,6,6", operands);
10948 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10949 output_asm_insn ("creqv 6,6,6", operands);
10953 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10954 (set_attr "length" "4,4,8,8")])
10956 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10957 [(set (match_operand 0 "" "")
10958 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10959 (match_operand 2 "" "g,g")))
10960 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10961 (clobber (reg:SI LR_REGNO))]
10962 "(DEFAULT_ABI == ABI_DARWIN
10963 || (DEFAULT_ABI == ABI_V4
10964 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10966 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10967 output_asm_insn ("crxor 6,6,6", operands);
10969 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10970 output_asm_insn ("creqv 6,6,6", operands);
10973 return output_call(insn, operands, 1, 3);
10975 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10977 gcc_assert (!TARGET_SECURE_PLT);
10978 return "bl %z1@plt";
10984 "DEFAULT_ABI == ABI_V4
10985 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10986 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10987 [(parallel [(set (match_dup 0)
10988 (call (mem:SI (match_dup 1))
10990 (use (match_dup 3))
10991 (use (match_dup 4))
10992 (clobber (reg:SI LR_REGNO))])]
10994 operands[4] = pic_offset_table_rtx;
10996 [(set_attr "type" "branch,branch")
10997 (set_attr "length" "4,8")])
10999 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11000 [(set (match_operand 0 "" "")
11001 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11002 (match_operand 2 "" "g,g")))
11003 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11004 (use (match_operand:SI 4 "register_operand" "r,r"))
11005 (clobber (reg:SI LR_REGNO))]
11006 "(DEFAULT_ABI == ABI_V4
11007 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11008 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11010 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11011 output_asm_insn ("crxor 6,6,6", operands);
11013 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11014 output_asm_insn ("creqv 6,6,6", operands);
11017 return "bl %z1+32768@plt";
11019 return "bl %z1@plt";
11021 [(set_attr "type" "branch,branch")
11022 (set_attr "length" "4,8")])
11025 ;; Call to AIX abi function in the same module.
11027 (define_insn "*call_local_aix<mode>"
11028 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11029 (match_operand 1 "" "g"))
11030 (clobber (reg:P LR_REGNO))]
11031 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11033 [(set_attr "type" "branch")
11034 (set_attr "length" "4")])
11036 (define_insn "*call_value_local_aix<mode>"
11037 [(set (match_operand 0 "" "")
11038 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11039 (match_operand 2 "" "g")))
11040 (clobber (reg:P LR_REGNO))]
11041 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11043 [(set_attr "type" "branch")
11044 (set_attr "length" "4")])
11046 ;; Call to AIX abi function which may be in another module.
11047 ;; Restore the TOC pointer (r2) after the call.
11049 (define_insn "*call_nonlocal_aix<mode>"
11050 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11051 (match_operand 1 "" "g"))
11052 (clobber (reg:P LR_REGNO))]
11053 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11055 [(set_attr "type" "branch")
11056 (set_attr "length" "8")])
11058 (define_insn "*call_value_nonlocal_aix<mode>"
11059 [(set (match_operand 0 "" "")
11060 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11061 (match_operand 2 "" "g")))
11062 (clobber (reg:P LR_REGNO))]
11063 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11065 [(set_attr "type" "branch")
11066 (set_attr "length" "8")])
11068 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11069 ;; Operand0 is the addresss of the function to call
11070 ;; Operand2 is the location in the function descriptor to load r2 from
11071 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11073 (define_insn "*call_indirect_aix<mode>"
11074 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11075 (match_operand 1 "" "g,g"))
11076 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11077 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11078 (clobber (reg:P LR_REGNO))]
11079 "DEFAULT_ABI == ABI_AIX"
11080 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11081 [(set_attr "type" "jmpreg")
11082 (set_attr "length" "12")])
11084 (define_insn "*call_value_indirect_aix<mode>"
11085 [(set (match_operand 0 "" "")
11086 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11087 (match_operand 2 "" "g,g")))
11088 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11089 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11090 (clobber (reg:P LR_REGNO))]
11091 "DEFAULT_ABI == ABI_AIX"
11092 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11093 [(set_attr "type" "jmpreg")
11094 (set_attr "length" "12")])
11096 ;; Call to indirect functions with the ELFv2 ABI.
11097 ;; Operand0 is the addresss of the function to call
11098 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11100 (define_insn "*call_indirect_elfv2<mode>"
11101 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11102 (match_operand 1 "" "g,g"))
11103 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11104 (clobber (reg:P LR_REGNO))]
11105 "DEFAULT_ABI == ABI_ELFv2"
11106 "b%T0l\;<ptrload> 2,%2(1)"
11107 [(set_attr "type" "jmpreg")
11108 (set_attr "length" "8")])
11110 (define_insn "*call_value_indirect_elfv2<mode>"
11111 [(set (match_operand 0 "" "")
11112 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11113 (match_operand 2 "" "g,g")))
11114 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11115 (clobber (reg:P LR_REGNO))]
11116 "DEFAULT_ABI == ABI_ELFv2"
11117 "b%T1l\;<ptrload> 2,%3(1)"
11118 [(set_attr "type" "jmpreg")
11119 (set_attr "length" "8")])
11122 ;; Call subroutine returning any type.
11123 (define_expand "untyped_call"
11124 [(parallel [(call (match_operand 0 "" "")
11126 (match_operand 1 "" "")
11127 (match_operand 2 "" "")])]
11133 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11135 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11137 rtx set = XVECEXP (operands[2], 0, i);
11138 emit_move_insn (SET_DEST (set), SET_SRC (set));
11141 /* The optimizer does not know that the call sets the function value
11142 registers we stored in the result block. We avoid problems by
11143 claiming that all hard registers are used and clobbered at this
11145 emit_insn (gen_blockage ());
11150 ;; sibling call patterns
11151 (define_expand "sibcall"
11152 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11153 (match_operand 1 "" ""))
11154 (use (match_operand 2 "" ""))
11160 if (MACHOPIC_INDIRECT)
11161 operands[0] = machopic_indirect_call_target (operands[0]);
11164 gcc_assert (GET_CODE (operands[0]) == MEM);
11165 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11167 operands[0] = XEXP (operands[0], 0);
11169 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11171 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11176 (define_expand "sibcall_value"
11177 [(parallel [(set (match_operand 0 "register_operand" "")
11178 (call (mem:SI (match_operand 1 "address_operand" ""))
11179 (match_operand 2 "" "")))
11180 (use (match_operand 3 "" ""))
11186 if (MACHOPIC_INDIRECT)
11187 operands[1] = machopic_indirect_call_target (operands[1]);
11190 gcc_assert (GET_CODE (operands[1]) == MEM);
11191 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11193 operands[1] = XEXP (operands[1], 0);
11195 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11197 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11202 (define_insn "*sibcall_local32"
11203 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11204 (match_operand 1 "" "g,g"))
11205 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11207 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11210 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11211 output_asm_insn (\"crxor 6,6,6\", operands);
11213 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11214 output_asm_insn (\"creqv 6,6,6\", operands);
11216 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11218 [(set_attr "type" "branch")
11219 (set_attr "length" "4,8")])
11221 (define_insn "*sibcall_local64"
11222 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11223 (match_operand 1 "" "g,g"))
11224 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11226 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11229 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11230 output_asm_insn (\"crxor 6,6,6\", operands);
11232 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11233 output_asm_insn (\"creqv 6,6,6\", operands);
11235 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11237 [(set_attr "type" "branch")
11238 (set_attr "length" "4,8")])
11240 (define_insn "*sibcall_value_local32"
11241 [(set (match_operand 0 "" "")
11242 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11243 (match_operand 2 "" "g,g")))
11244 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11246 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11249 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11250 output_asm_insn (\"crxor 6,6,6\", operands);
11252 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11253 output_asm_insn (\"creqv 6,6,6\", operands);
11255 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11257 [(set_attr "type" "branch")
11258 (set_attr "length" "4,8")])
11260 (define_insn "*sibcall_value_local64"
11261 [(set (match_operand 0 "" "")
11262 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11263 (match_operand 2 "" "g,g")))
11264 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11266 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11269 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11270 output_asm_insn (\"crxor 6,6,6\", operands);
11272 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11273 output_asm_insn (\"creqv 6,6,6\", operands);
11275 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11277 [(set_attr "type" "branch")
11278 (set_attr "length" "4,8")])
11280 (define_insn "*sibcall_nonlocal_sysv<mode>"
11281 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11282 (match_operand 1 "" ""))
11283 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11285 "(DEFAULT_ABI == ABI_DARWIN
11286 || DEFAULT_ABI == ABI_V4)
11287 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11290 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11291 output_asm_insn (\"crxor 6,6,6\", operands);
11293 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11294 output_asm_insn (\"creqv 6,6,6\", operands);
11296 if (which_alternative >= 2)
11298 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11300 gcc_assert (!TARGET_SECURE_PLT);
11301 return \"b %z0@plt\";
11306 [(set_attr "type" "branch")
11307 (set_attr "length" "4,8,4,8")])
11309 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11310 [(set (match_operand 0 "" "")
11311 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11312 (match_operand 2 "" "")))
11313 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11315 "(DEFAULT_ABI == ABI_DARWIN
11316 || DEFAULT_ABI == ABI_V4)
11317 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11320 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11321 output_asm_insn (\"crxor 6,6,6\", operands);
11323 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11324 output_asm_insn (\"creqv 6,6,6\", operands);
11326 if (which_alternative >= 2)
11328 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11330 gcc_assert (!TARGET_SECURE_PLT);
11331 return \"b %z1@plt\";
11336 [(set_attr "type" "branch")
11337 (set_attr "length" "4,8,4,8")])
11339 ;; AIX ABI sibling call patterns.
11341 (define_insn "*sibcall_aix<mode>"
11342 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11343 (match_operand 1 "" "g,g"))
11345 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11349 [(set_attr "type" "branch")
11350 (set_attr "length" "4")])
11352 (define_insn "*sibcall_value_aix<mode>"
11353 [(set (match_operand 0 "" "")
11354 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11355 (match_operand 2 "" "g,g")))
11357 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11361 [(set_attr "type" "branch")
11362 (set_attr "length" "4")])
11364 (define_expand "sibcall_epilogue"
11365 [(use (const_int 0))]
11368 if (!TARGET_SCHED_PROLOG)
11369 emit_insn (gen_blockage ());
11370 rs6000_emit_epilogue (TRUE);
11374 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11375 ;; all of memory. This blocks insns from being moved across this point.
11377 (define_insn "blockage"
11378 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11382 (define_expand "probe_stack_address"
11383 [(use (match_operand 0 "address_operand"))]
11386 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11387 MEM_VOLATILE_P (operands[0]) = 1;
11390 emit_insn (gen_probe_stack_di (operands[0]));
11392 emit_insn (gen_probe_stack_si (operands[0]));
11396 (define_insn "probe_stack_<mode>"
11397 [(set (match_operand:P 0 "memory_operand" "=m")
11398 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11401 operands[1] = gen_rtx_REG (Pmode, 0);
11402 return "st<wd>%U0%X0 %1,%0";
11404 [(set_attr "type" "store")
11405 (set (attr "update")
11406 (if_then_else (match_operand 0 "update_address_mem")
11407 (const_string "yes")
11408 (const_string "no")))
11409 (set (attr "indexed")
11410 (if_then_else (match_operand 0 "indexed_address_mem")
11411 (const_string "yes")
11412 (const_string "no")))
11413 (set_attr "length" "4")])
11415 (define_insn "probe_stack_range<P:mode>"
11416 [(set (match_operand:P 0 "register_operand" "=r")
11417 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11418 (match_operand:P 2 "register_operand" "r")]
11419 UNSPECV_PROBE_STACK_RANGE))]
11421 "* return output_probe_stack_range (operands[0], operands[2]);"
11422 [(set_attr "type" "three")])
11424 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11425 ;; signed & unsigned, and one type of branch.
11427 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11428 ;; insns, and branches.
11430 (define_expand "cbranch<mode>4"
11431 [(use (match_operator 0 "comparison_operator"
11432 [(match_operand:GPR 1 "gpc_reg_operand" "")
11433 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11434 (use (match_operand 3 ""))]
11438 /* Take care of the possibility that operands[2] might be negative but
11439 this might be a logical operation. That insn doesn't exist. */
11440 if (GET_CODE (operands[2]) == CONST_INT
11441 && INTVAL (operands[2]) < 0)
11443 operands[2] = force_reg (<MODE>mode, operands[2]);
11444 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11445 GET_MODE (operands[0]),
11446 operands[1], operands[2]);
11449 rs6000_emit_cbranch (<MODE>mode, operands);
11453 (define_expand "cbranch<mode>4"
11454 [(use (match_operator 0 "comparison_operator"
11455 [(match_operand:FP 1 "gpc_reg_operand" "")
11456 (match_operand:FP 2 "gpc_reg_operand" "")]))
11457 (use (match_operand 3 ""))]
11461 rs6000_emit_cbranch (<MODE>mode, operands);
11465 (define_expand "cstore<mode>4_signed"
11466 [(use (match_operator 1 "signed_comparison_operator"
11467 [(match_operand:P 2 "gpc_reg_operand")
11468 (match_operand:P 3 "gpc_reg_operand")]))
11469 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11472 enum rtx_code cond_code = GET_CODE (operands[1]);
11474 rtx op0 = operands[0];
11475 rtx op1 = operands[2];
11476 rtx op2 = operands[3];
11478 if (cond_code == GE || cond_code == LT)
11480 cond_code = swap_condition (cond_code);
11481 std::swap (op1, op2);
11484 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11485 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11486 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11488 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11489 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11490 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11492 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11494 if (cond_code == LE)
11495 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11498 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11499 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11500 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11506 (define_expand "cstore<mode>4_unsigned"
11507 [(use (match_operator 1 "unsigned_comparison_operator"
11508 [(match_operand:P 2 "gpc_reg_operand")
11509 (match_operand:P 3 "reg_or_short_operand")]))
11510 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11513 enum rtx_code cond_code = GET_CODE (operands[1]);
11515 rtx op0 = operands[0];
11516 rtx op1 = operands[2];
11517 rtx op2 = operands[3];
11519 if (cond_code == GEU || cond_code == LTU)
11521 cond_code = swap_condition (cond_code);
11522 std::swap (op1, op2);
11525 if (!gpc_reg_operand (op1, <MODE>mode))
11526 op1 = force_reg (<MODE>mode, op1);
11527 if (!reg_or_short_operand (op2, <MODE>mode))
11528 op2 = force_reg (<MODE>mode, op2);
11530 rtx tmp = gen_reg_rtx (<MODE>mode);
11531 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11533 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11534 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11536 if (cond_code == LEU)
11537 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11539 emit_insn (gen_neg<mode>2 (op0, tmp2));
11544 (define_expand "cstore_si_as_di"
11545 [(use (match_operator 1 "unsigned_comparison_operator"
11546 [(match_operand:SI 2 "gpc_reg_operand")
11547 (match_operand:SI 3 "reg_or_short_operand")]))
11548 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11551 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11552 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11554 operands[2] = force_reg (SImode, operands[2]);
11555 operands[3] = force_reg (SImode, operands[3]);
11556 rtx op1 = gen_reg_rtx (DImode);
11557 rtx op2 = gen_reg_rtx (DImode);
11558 convert_move (op1, operands[2], uns_flag);
11559 convert_move (op2, operands[3], uns_flag);
11561 if (cond_code == GT || cond_code == LE)
11563 cond_code = swap_condition (cond_code);
11564 std::swap (op1, op2);
11567 rtx tmp = gen_reg_rtx (DImode);
11568 rtx tmp2 = gen_reg_rtx (DImode);
11569 emit_insn (gen_subdi3 (tmp, op1, op2));
11570 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11576 gcc_unreachable ();
11581 tmp3 = gen_reg_rtx (DImode);
11582 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11586 convert_move (operands[0], tmp3, 1);
11591 (define_expand "cstore<mode>4_signed_imm"
11592 [(use (match_operator 1 "signed_comparison_operator"
11593 [(match_operand:GPR 2 "gpc_reg_operand")
11594 (match_operand:GPR 3 "immediate_operand")]))
11595 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11598 bool invert = false;
11600 enum rtx_code cond_code = GET_CODE (operands[1]);
11602 rtx op0 = operands[0];
11603 rtx op1 = operands[2];
11604 HOST_WIDE_INT val = INTVAL (operands[3]);
11606 if (cond_code == GE || cond_code == GT)
11608 cond_code = reverse_condition (cond_code);
11612 if (cond_code == LE)
11615 rtx tmp = gen_reg_rtx (<MODE>mode);
11616 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11617 rtx x = gen_reg_rtx (<MODE>mode);
11619 emit_insn (gen_and<mode>3 (x, op1, tmp));
11621 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11625 rtx tmp = gen_reg_rtx (<MODE>mode);
11626 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11630 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11631 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11636 (define_expand "cstore<mode>4_unsigned_imm"
11637 [(use (match_operator 1 "unsigned_comparison_operator"
11638 [(match_operand:GPR 2 "gpc_reg_operand")
11639 (match_operand:GPR 3 "immediate_operand")]))
11640 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11643 bool invert = false;
11645 enum rtx_code cond_code = GET_CODE (operands[1]);
11647 rtx op0 = operands[0];
11648 rtx op1 = operands[2];
11649 HOST_WIDE_INT val = INTVAL (operands[3]);
11651 if (cond_code == GEU || cond_code == GTU)
11653 cond_code = reverse_condition (cond_code);
11657 if (cond_code == LEU)
11660 rtx tmp = gen_reg_rtx (<MODE>mode);
11661 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11662 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11663 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11664 rtx x = gen_reg_rtx (<MODE>mode);
11666 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11668 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11672 rtx tmp = gen_reg_rtx (<MODE>mode);
11673 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11677 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11678 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11683 (define_expand "cstore<mode>4"
11684 [(use (match_operator 1 "comparison_operator"
11685 [(match_operand:GPR 2 "gpc_reg_operand")
11686 (match_operand:GPR 3 "reg_or_short_operand")]))
11687 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11690 /* Use ISEL if the user asked for it. */
11692 rs6000_emit_sISEL (<MODE>mode, operands);
11694 /* Expanding EQ and NE directly to some machine instructions does not help
11695 but does hurt combine. So don't. */
11696 else if (GET_CODE (operands[1]) == EQ)
11697 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11698 else if (<MODE>mode == Pmode
11699 && GET_CODE (operands[1]) == NE)
11700 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11701 else if (GET_CODE (operands[1]) == NE)
11703 rtx tmp = gen_reg_rtx (<MODE>mode);
11704 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11705 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11708 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11709 etc. combinations magically work out just right. */
11710 else if (<MODE>mode == Pmode
11711 && unsigned_comparison_operator (operands[1], VOIDmode))
11712 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11713 operands[2], operands[3]));
11715 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11716 else if (<MODE>mode == SImode && Pmode == DImode)
11717 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11718 operands[2], operands[3]));
11720 /* For signed comparisons against a constant, we can do some simple
11722 else if (signed_comparison_operator (operands[1], VOIDmode)
11723 && CONST_INT_P (operands[3]))
11724 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11725 operands[2], operands[3]));
11727 /* And similarly for unsigned comparisons. */
11728 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11729 && CONST_INT_P (operands[3]))
11730 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11731 operands[2], operands[3]));
11733 /* We also do not want to use mfcr for signed comparisons. */
11734 else if (<MODE>mode == Pmode
11735 && signed_comparison_operator (operands[1], VOIDmode))
11736 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11737 operands[2], operands[3]));
11739 /* Everything else, use the mfcr brute force. */
11741 rs6000_emit_sCOND (<MODE>mode, operands);
11746 (define_expand "cstore<mode>4"
11747 [(use (match_operator 1 "comparison_operator"
11748 [(match_operand:FP 2 "gpc_reg_operand")
11749 (match_operand:FP 3 "gpc_reg_operand")]))
11750 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11753 rs6000_emit_sCOND (<MODE>mode, operands);
11758 (define_expand "stack_protect_set"
11759 [(match_operand 0 "memory_operand")
11760 (match_operand 1 "memory_operand")]
11763 if (rs6000_stack_protector_guard == SSP_TLS)
11765 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11766 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11767 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11768 operands[1] = gen_rtx_MEM (Pmode, addr);
11772 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11774 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11779 (define_insn "stack_protect_setsi"
11780 [(set (match_operand:SI 0 "memory_operand" "=m")
11781 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11782 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11784 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11785 [(set_attr "type" "three")
11786 (set_attr "length" "12")])
11788 (define_insn "stack_protect_setdi"
11789 [(set (match_operand:DI 0 "memory_operand" "=Y")
11790 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11791 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11793 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11794 [(set_attr "type" "three")
11795 (set_attr "length" "12")])
11797 (define_expand "stack_protect_test"
11798 [(match_operand 0 "memory_operand")
11799 (match_operand 1 "memory_operand")
11800 (match_operand 2 "")]
11803 rtx guard = operands[1];
11805 if (rs6000_stack_protector_guard == SSP_TLS)
11807 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11808 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11809 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11810 guard = gen_rtx_MEM (Pmode, addr);
11813 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11814 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11815 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11816 emit_jump_insn (jump);
11821 (define_insn "stack_protect_testsi"
11822 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11823 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11824 (match_operand:SI 2 "memory_operand" "m,m")]
11826 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11827 (clobber (match_scratch:SI 3 "=&r,&r"))]
11830 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11831 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11832 [(set_attr "length" "16,20")])
11834 (define_insn "stack_protect_testdi"
11835 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11836 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11837 (match_operand:DI 2 "memory_operand" "Y,Y")]
11839 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11840 (clobber (match_scratch:DI 3 "=&r,&r"))]
11843 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11844 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11845 [(set_attr "length" "16,20")])
11848 ;; Here are the actual compare insns.
11849 (define_insn "*cmp<mode>_signed"
11850 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11851 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11852 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11854 "cmp<wd>%I2 %0,%1,%2"
11855 [(set_attr "type" "cmp")])
11857 (define_insn "*cmp<mode>_unsigned"
11858 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11859 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11860 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11862 "cmpl<wd>%I2 %0,%1,%2"
11863 [(set_attr "type" "cmp")])
11865 ;; If we are comparing a register for equality with a large constant,
11866 ;; we can do this with an XOR followed by a compare. But this is profitable
11867 ;; only if the large constant is only used for the comparison (and in this
11868 ;; case we already have a register to reuse as scratch).
11870 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11871 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11874 [(set (match_operand:SI 0 "register_operand")
11875 (match_operand:SI 1 "logical_const_operand" ""))
11876 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11878 (match_operand:SI 2 "logical_const_operand" "")]))
11879 (set (match_operand:CC 4 "cc_reg_operand" "")
11880 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11883 (if_then_else (match_operator 6 "equality_operator"
11884 [(match_dup 4) (const_int 0)])
11885 (match_operand 7 "" "")
11886 (match_operand 8 "" "")))]
11887 "peep2_reg_dead_p (3, operands[0])
11888 && peep2_reg_dead_p (4, operands[4])
11889 && REGNO (operands[0]) != REGNO (operands[5])"
11890 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11891 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11892 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11895 /* Get the constant we are comparing against, and see what it looks like
11896 when sign-extended from 16 to 32 bits. Then see what constant we could
11897 XOR with SEXTC to get the sign-extended value. */
11898 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11900 operands[1], operands[2]);
11901 HOST_WIDE_INT c = INTVAL (cnst);
11902 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11903 HOST_WIDE_INT xorv = c ^ sextc;
11905 operands[9] = GEN_INT (xorv);
11906 operands[10] = GEN_INT (sextc);
11909 ;; The following two insns don't exist as single insns, but if we provide
11910 ;; them, we can swap an add and compare, which will enable us to overlap more
11911 ;; of the required delay between a compare and branch. We generate code for
11912 ;; them by splitting.
11915 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11916 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11917 (match_operand:SI 2 "short_cint_operand" "i")))
11918 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11919 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11922 [(set_attr "length" "8")])
11925 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11926 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11927 (match_operand:SI 2 "u_short_cint_operand" "i")))
11928 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11929 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11932 [(set_attr "length" "8")])
11935 [(set (match_operand:CC 3 "cc_reg_operand" "")
11936 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11937 (match_operand:SI 2 "short_cint_operand" "")))
11938 (set (match_operand:SI 0 "gpc_reg_operand" "")
11939 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11941 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11942 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11945 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11946 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11947 (match_operand:SI 2 "u_short_cint_operand" "")))
11948 (set (match_operand:SI 0 "gpc_reg_operand" "")
11949 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11951 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11952 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11954 ;; Only need to compare second words if first words equal
11955 (define_insn "*cmp<mode>_internal1"
11956 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11957 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11958 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11959 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11960 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11961 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11962 [(set_attr "type" "fpcompare")
11963 (set_attr "length" "12")])
11965 (define_insn_and_split "*cmp<mode>_internal2"
11966 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11967 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11968 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11969 (clobber (match_scratch:DF 3 "=d"))
11970 (clobber (match_scratch:DF 4 "=d"))
11971 (clobber (match_scratch:DF 5 "=d"))
11972 (clobber (match_scratch:DF 6 "=d"))
11973 (clobber (match_scratch:DF 7 "=d"))
11974 (clobber (match_scratch:DF 8 "=d"))
11975 (clobber (match_scratch:DF 9 "=d"))
11976 (clobber (match_scratch:DF 10 "=d"))
11977 (clobber (match_scratch:GPR 11 "=b"))]
11978 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11979 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11981 "&& reload_completed"
11982 [(set (match_dup 3) (match_dup 14))
11983 (set (match_dup 4) (match_dup 15))
11984 (set (match_dup 9) (abs:DF (match_dup 5)))
11985 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11986 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11987 (label_ref (match_dup 12))
11989 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11990 (set (pc) (label_ref (match_dup 13)))
11992 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11993 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11994 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11995 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11998 REAL_VALUE_TYPE rv;
11999 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12000 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12002 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12003 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12004 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12005 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12006 operands[12] = gen_label_rtx ();
12007 operands[13] = gen_label_rtx ();
12009 operands[14] = force_const_mem (DFmode,
12010 const_double_from_real_value (rv, DFmode));
12011 operands[15] = force_const_mem (DFmode,
12012 const_double_from_real_value (dconst0,
12017 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12018 operands[14] = gen_const_mem (DFmode, tocref);
12019 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12020 operands[15] = gen_const_mem (DFmode, tocref);
12021 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12022 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12026 ;; Now we have the scc insns. We can do some combinations because of the
12027 ;; way the machine works.
12029 ;; Note that this is probably faster if we can put an insn between the
12030 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12031 ;; cases the insns below which don't use an intermediate CR field will
12032 ;; be used instead.
12034 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12035 (match_operator:SI 1 "scc_comparison_operator"
12036 [(match_operand 2 "cc_reg_operand" "y")
12039 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12040 [(set (attr "type")
12041 (cond [(match_test "TARGET_MFCRF")
12042 (const_string "mfcrf")
12044 (const_string "mfcr")))
12045 (set_attr "length" "8")])
12047 ;; Same as above, but get the OV/ORDERED bit.
12048 (define_insn "move_from_CR_ov_bit"
12049 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12050 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12053 "mfcr %0\;rlwinm %0,%0,%t1,1"
12054 [(set_attr "type" "mfcr")
12055 (set_attr "length" "8")])
12058 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12059 (match_operator:DI 1 "scc_comparison_operator"
12060 [(match_operand 2 "cc_reg_operand" "y")
12063 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12064 [(set (attr "type")
12065 (cond [(match_test "TARGET_MFCRF")
12066 (const_string "mfcrf")
12068 (const_string "mfcr")))
12069 (set_attr "length" "8")])
12072 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12073 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12074 [(match_operand 2 "cc_reg_operand" "y,y")
12077 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12078 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12081 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12083 [(set_attr "type" "shift")
12084 (set_attr "dot" "yes")
12085 (set_attr "length" "8,16")])
12088 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12089 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12090 [(match_operand 2 "cc_reg_operand" "")
12093 (set (match_operand:SI 3 "gpc_reg_operand" "")
12094 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12095 "TARGET_32BIT && reload_completed"
12096 [(set (match_dup 3)
12097 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12099 (compare:CC (match_dup 3)
12104 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12105 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12106 [(match_operand 2 "cc_reg_operand" "y")
12108 (match_operand:SI 3 "const_int_operand" "n")))]
12112 int is_bit = ccr_bit (operands[1], 1);
12113 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12116 if (is_bit >= put_bit)
12117 count = is_bit - put_bit;
12119 count = 32 - (put_bit - is_bit);
12121 operands[4] = GEN_INT (count);
12122 operands[5] = GEN_INT (put_bit);
12124 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12126 [(set (attr "type")
12127 (cond [(match_test "TARGET_MFCRF")
12128 (const_string "mfcrf")
12130 (const_string "mfcr")))
12131 (set_attr "length" "8")])
12134 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12136 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12137 [(match_operand 2 "cc_reg_operand" "y,y")
12139 (match_operand:SI 3 "const_int_operand" "n,n"))
12141 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12142 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12147 int is_bit = ccr_bit (operands[1], 1);
12148 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12151 /* Force split for non-cc0 compare. */
12152 if (which_alternative == 1)
12155 if (is_bit >= put_bit)
12156 count = is_bit - put_bit;
12158 count = 32 - (put_bit - is_bit);
12160 operands[5] = GEN_INT (count);
12161 operands[6] = GEN_INT (put_bit);
12163 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12165 [(set_attr "type" "shift")
12166 (set_attr "dot" "yes")
12167 (set_attr "length" "8,16")])
12170 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
12172 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12173 [(match_operand 2 "cc_reg_operand")
12175 (match_operand:SI 3 "const_int_operand"))
12177 (set (match_operand:SI 4 "gpc_reg_operand")
12178 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12181 [(set (match_dup 4)
12182 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12185 (compare:CC (match_dup 4)
12190 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12193 (define_insn_and_split "eq<mode>3"
12194 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12195 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12196 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12197 (clobber (match_scratch:GPR 3 "=r"))
12198 (clobber (match_scratch:GPR 4 "=r"))]
12202 [(set (match_dup 4)
12203 (clz:GPR (match_dup 3)))
12205 (lshiftrt:GPR (match_dup 4)
12208 operands[3] = rs6000_emit_eqne (<MODE>mode,
12209 operands[1], operands[2], operands[3]);
12211 if (GET_CODE (operands[4]) == SCRATCH)
12212 operands[4] = gen_reg_rtx (<MODE>mode);
12214 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12216 [(set (attr "length")
12217 (if_then_else (match_test "operands[2] == const0_rtx")
12219 (const_string "12")))])
12221 (define_insn_and_split "ne<mode>3"
12222 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12223 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12224 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12225 (clobber (match_scratch:P 3 "=r"))
12226 (clobber (match_scratch:P 4 "=r"))
12227 (clobber (reg:P CA_REGNO))]
12231 [(parallel [(set (match_dup 4)
12232 (plus:P (match_dup 3)
12234 (set (reg:P CA_REGNO)
12235 (ne:P (match_dup 3)
12237 (parallel [(set (match_dup 0)
12238 (plus:P (plus:P (not:P (match_dup 4))
12241 (clobber (reg:P CA_REGNO))])]
12243 operands[3] = rs6000_emit_eqne (<MODE>mode,
12244 operands[1], operands[2], operands[3]);
12246 if (GET_CODE (operands[4]) == SCRATCH)
12247 operands[4] = gen_reg_rtx (<MODE>mode);
12249 [(set (attr "length")
12250 (if_then_else (match_test "operands[2] == const0_rtx")
12252 (const_string "12")))])
12254 (define_insn_and_split "*neg_eq_<mode>"
12255 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12256 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12257 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12258 (clobber (match_scratch:P 3 "=r"))
12259 (clobber (match_scratch:P 4 "=r"))
12260 (clobber (reg:P CA_REGNO))]
12264 [(parallel [(set (match_dup 4)
12265 (plus:P (match_dup 3)
12267 (set (reg:P CA_REGNO)
12268 (ne:P (match_dup 3)
12270 (parallel [(set (match_dup 0)
12271 (plus:P (reg:P CA_REGNO)
12273 (clobber (reg:P CA_REGNO))])]
12275 operands[3] = rs6000_emit_eqne (<MODE>mode,
12276 operands[1], operands[2], operands[3]);
12278 if (GET_CODE (operands[4]) == SCRATCH)
12279 operands[4] = gen_reg_rtx (<MODE>mode);
12281 [(set (attr "length")
12282 (if_then_else (match_test "operands[2] == const0_rtx")
12284 (const_string "12")))])
12286 (define_insn_and_split "*neg_ne_<mode>"
12287 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12288 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12289 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12290 (clobber (match_scratch:P 3 "=r"))
12291 (clobber (match_scratch:P 4 "=r"))
12292 (clobber (reg:P CA_REGNO))]
12296 [(parallel [(set (match_dup 4)
12297 (neg:P (match_dup 3)))
12298 (set (reg:P CA_REGNO)
12299 (eq:P (match_dup 3)
12301 (parallel [(set (match_dup 0)
12302 (plus:P (reg:P CA_REGNO)
12304 (clobber (reg:P CA_REGNO))])]
12306 operands[3] = rs6000_emit_eqne (<MODE>mode,
12307 operands[1], operands[2], operands[3]);
12309 if (GET_CODE (operands[4]) == SCRATCH)
12310 operands[4] = gen_reg_rtx (<MODE>mode);
12312 [(set (attr "length")
12313 (if_then_else (match_test "operands[2] == const0_rtx")
12315 (const_string "12")))])
12317 (define_insn_and_split "*plus_eq_<mode>"
12318 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12319 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12320 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12321 (match_operand:P 3 "gpc_reg_operand" "r")))
12322 (clobber (match_scratch:P 4 "=r"))
12323 (clobber (match_scratch:P 5 "=r"))
12324 (clobber (reg:P CA_REGNO))]
12328 [(parallel [(set (match_dup 5)
12329 (neg:P (match_dup 4)))
12330 (set (reg:P CA_REGNO)
12331 (eq:P (match_dup 4)
12333 (parallel [(set (match_dup 0)
12334 (plus:P (match_dup 3)
12336 (clobber (reg:P CA_REGNO))])]
12338 operands[4] = rs6000_emit_eqne (<MODE>mode,
12339 operands[1], operands[2], operands[4]);
12341 if (GET_CODE (operands[5]) == SCRATCH)
12342 operands[5] = gen_reg_rtx (<MODE>mode);
12344 [(set (attr "length")
12345 (if_then_else (match_test "operands[2] == const0_rtx")
12347 (const_string "12")))])
12349 (define_insn_and_split "*plus_ne_<mode>"
12350 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12351 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12352 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12353 (match_operand:P 3 "gpc_reg_operand" "r")))
12354 (clobber (match_scratch:P 4 "=r"))
12355 (clobber (match_scratch:P 5 "=r"))
12356 (clobber (reg:P CA_REGNO))]
12360 [(parallel [(set (match_dup 5)
12361 (plus:P (match_dup 4)
12363 (set (reg:P CA_REGNO)
12364 (ne:P (match_dup 4)
12366 (parallel [(set (match_dup 0)
12367 (plus:P (match_dup 3)
12369 (clobber (reg:P CA_REGNO))])]
12371 operands[4] = rs6000_emit_eqne (<MODE>mode,
12372 operands[1], operands[2], operands[4]);
12374 if (GET_CODE (operands[5]) == SCRATCH)
12375 operands[5] = gen_reg_rtx (<MODE>mode);
12377 [(set (attr "length")
12378 (if_then_else (match_test "operands[2] == const0_rtx")
12380 (const_string "12")))])
12382 (define_insn_and_split "*minus_eq_<mode>"
12383 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12384 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12385 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12386 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12387 (clobber (match_scratch:P 4 "=r"))
12388 (clobber (match_scratch:P 5 "=r"))
12389 (clobber (reg:P CA_REGNO))]
12393 [(parallel [(set (match_dup 5)
12394 (plus:P (match_dup 4)
12396 (set (reg:P CA_REGNO)
12397 (ne:P (match_dup 4)
12399 (parallel [(set (match_dup 0)
12400 (plus:P (plus:P (match_dup 3)
12403 (clobber (reg:P CA_REGNO))])]
12405 operands[4] = rs6000_emit_eqne (<MODE>mode,
12406 operands[1], operands[2], operands[4]);
12408 if (GET_CODE (operands[5]) == SCRATCH)
12409 operands[5] = gen_reg_rtx (<MODE>mode);
12411 [(set (attr "length")
12412 (if_then_else (match_test "operands[2] == const0_rtx")
12414 (const_string "12")))])
12416 (define_insn_and_split "*minus_ne_<mode>"
12417 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12418 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12419 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12420 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12421 (clobber (match_scratch:P 4 "=r"))
12422 (clobber (match_scratch:P 5 "=r"))
12423 (clobber (reg:P CA_REGNO))]
12427 [(parallel [(set (match_dup 5)
12428 (neg:P (match_dup 4)))
12429 (set (reg:P CA_REGNO)
12430 (eq:P (match_dup 4)
12432 (parallel [(set (match_dup 0)
12433 (plus:P (plus:P (match_dup 3)
12436 (clobber (reg:P CA_REGNO))])]
12438 operands[4] = rs6000_emit_eqne (<MODE>mode,
12439 operands[1], operands[2], operands[4]);
12441 if (GET_CODE (operands[5]) == SCRATCH)
12442 operands[5] = gen_reg_rtx (<MODE>mode);
12444 [(set (attr "length")
12445 (if_then_else (match_test "operands[2] == const0_rtx")
12447 (const_string "12")))])
12449 (define_insn_and_split "*eqsi3_ext<mode>"
12450 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12451 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12452 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12453 (clobber (match_scratch:SI 3 "=r"))
12454 (clobber (match_scratch:SI 4 "=r"))]
12458 [(set (match_dup 4)
12459 (clz:SI (match_dup 3)))
12462 (lshiftrt:SI (match_dup 4)
12465 operands[3] = rs6000_emit_eqne (SImode,
12466 operands[1], operands[2], operands[3]);
12468 if (GET_CODE (operands[4]) == SCRATCH)
12469 operands[4] = gen_reg_rtx (SImode);
12471 [(set (attr "length")
12472 (if_then_else (match_test "operands[2] == const0_rtx")
12474 (const_string "12")))])
12476 (define_insn_and_split "*nesi3_ext<mode>"
12477 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12478 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12479 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12480 (clobber (match_scratch:SI 3 "=r"))
12481 (clobber (match_scratch:SI 4 "=r"))
12482 (clobber (match_scratch:EXTSI 5 "=r"))]
12486 [(set (match_dup 4)
12487 (clz:SI (match_dup 3)))
12490 (lshiftrt:SI (match_dup 4)
12493 (xor:EXTSI (match_dup 5)
12496 operands[3] = rs6000_emit_eqne (SImode,
12497 operands[1], operands[2], operands[3]);
12499 if (GET_CODE (operands[4]) == SCRATCH)
12500 operands[4] = gen_reg_rtx (SImode);
12501 if (GET_CODE (operands[5]) == SCRATCH)
12502 operands[5] = gen_reg_rtx (<MODE>mode);
12504 [(set (attr "length")
12505 (if_then_else (match_test "operands[2] == const0_rtx")
12506 (const_string "12")
12507 (const_string "16")))])
12509 ;; Define both directions of branch and return. If we need a reload
12510 ;; register, we'd rather use CR0 since it is much easier to copy a
12511 ;; register CC value to there.
12515 (if_then_else (match_operator 1 "branch_comparison_operator"
12517 "cc_reg_operand" "y")
12519 (label_ref (match_operand 0 "" ""))
12524 return output_cbranch (operands[1], \"%l0\", 0, insn);
12526 [(set_attr "type" "branch")])
12530 (if_then_else (match_operator 0 "branch_comparison_operator"
12532 "cc_reg_operand" "y")
12539 return output_cbranch (operands[0], NULL, 0, insn);
12541 [(set_attr "type" "jmpreg")
12542 (set_attr "length" "4")])
12546 (if_then_else (match_operator 1 "branch_comparison_operator"
12548 "cc_reg_operand" "y")
12551 (label_ref (match_operand 0 "" ""))))]
12555 return output_cbranch (operands[1], \"%l0\", 1, insn);
12557 [(set_attr "type" "branch")])
12561 (if_then_else (match_operator 0 "branch_comparison_operator"
12563 "cc_reg_operand" "y")
12570 return output_cbranch (operands[0], NULL, 1, insn);
12572 [(set_attr "type" "jmpreg")
12573 (set_attr "length" "4")])
12575 ;; Logic on condition register values.
12577 ; This pattern matches things like
12578 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12579 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12581 ; which are generated by the branch logic.
12582 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12584 (define_insn "*cceq_ior_compare"
12585 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12586 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12587 [(match_operator:SI 2
12588 "branch_positive_comparison_operator"
12590 "cc_reg_operand" "y,y")
12592 (match_operator:SI 4
12593 "branch_positive_comparison_operator"
12595 "cc_reg_operand" "0,y")
12599 "cr%q1 %E0,%j2,%j4"
12600 [(set_attr "type" "cr_logical,delayed_cr")])
12602 ; Why is the constant -1 here, but 1 in the previous pattern?
12603 ; Because ~1 has all but the low bit set.
12605 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12606 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12607 [(not:SI (match_operator:SI 2
12608 "branch_positive_comparison_operator"
12610 "cc_reg_operand" "y,y")
12612 (match_operator:SI 4
12613 "branch_positive_comparison_operator"
12615 "cc_reg_operand" "0,y")
12619 "cr%q1 %E0,%j2,%j4"
12620 [(set_attr "type" "cr_logical,delayed_cr")])
12622 (define_insn "*cceq_rev_compare"
12623 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12624 (compare:CCEQ (match_operator:SI 1
12625 "branch_positive_comparison_operator"
12627 "cc_reg_operand" "0,y")
12632 [(set_attr "type" "cr_logical,delayed_cr")])
12634 ;; If we are comparing the result of two comparisons, this can be done
12635 ;; using creqv or crxor.
12637 (define_insn_and_split ""
12638 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12639 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12640 [(match_operand 2 "cc_reg_operand" "y")
12642 (match_operator 3 "branch_comparison_operator"
12643 [(match_operand 4 "cc_reg_operand" "y")
12648 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12652 int positive_1, positive_2;
12654 positive_1 = branch_positive_comparison_operator (operands[1],
12655 GET_MODE (operands[1]));
12656 positive_2 = branch_positive_comparison_operator (operands[3],
12657 GET_MODE (operands[3]));
12660 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12661 GET_CODE (operands[1])),
12663 operands[2], const0_rtx);
12664 else if (GET_MODE (operands[1]) != SImode)
12665 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12666 operands[2], const0_rtx);
12669 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12670 GET_CODE (operands[3])),
12672 operands[4], const0_rtx);
12673 else if (GET_MODE (operands[3]) != SImode)
12674 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12675 operands[4], const0_rtx);
12677 if (positive_1 == positive_2)
12679 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12680 operands[5] = constm1_rtx;
12684 operands[5] = const1_rtx;
12688 ;; Unconditional branch and return.
12690 (define_insn "jump"
12692 (label_ref (match_operand 0 "" "")))]
12695 [(set_attr "type" "branch")])
12697 (define_insn "<return_str>return"
12701 [(set_attr "type" "jmpreg")])
12703 (define_expand "indirect_jump"
12704 [(set (pc) (match_operand 0 "register_operand" ""))])
12706 (define_insn "*indirect_jump<mode>"
12707 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12712 [(set_attr "type" "jmpreg")])
12714 ;; Table jump for switch statements:
12715 (define_expand "tablejump"
12716 [(use (match_operand 0 "" ""))
12717 (use (label_ref (match_operand 1 "" "")))]
12722 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12724 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12728 (define_expand "tablejumpsi"
12729 [(set (match_dup 3)
12730 (plus:SI (match_operand:SI 0 "" "")
12732 (parallel [(set (pc) (match_dup 3))
12733 (use (label_ref (match_operand 1 "" "")))])]
12736 { operands[0] = force_reg (SImode, operands[0]);
12737 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12738 operands[3] = gen_reg_rtx (SImode);
12741 (define_expand "tablejumpdi"
12742 [(set (match_dup 4)
12743 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12745 (plus:DI (match_dup 4)
12747 (parallel [(set (pc) (match_dup 3))
12748 (use (label_ref (match_operand 1 "" "")))])]
12751 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12752 operands[3] = gen_reg_rtx (DImode);
12753 operands[4] = gen_reg_rtx (DImode);
12756 (define_insn "*tablejump<mode>_internal1"
12758 (match_operand:P 0 "register_operand" "c,*l"))
12759 (use (label_ref (match_operand 1 "" "")))]
12764 [(set_attr "type" "jmpreg")])
12767 [(unspec [(const_int 0)] UNSPEC_NOP)]
12771 (define_insn "group_ending_nop"
12772 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12776 if (rs6000_cpu_attr == CPU_POWER6)
12777 return \"ori 1,1,0\";
12778 return \"ori 2,2,0\";
12781 ;; Define the subtract-one-and-jump insns, starting with the template
12782 ;; so loop.c knows what to generate.
12784 (define_expand "doloop_end"
12785 [(use (match_operand 0 "" "")) ; loop pseudo
12786 (use (match_operand 1 "" ""))] ; label
12792 if (GET_MODE (operands[0]) != DImode)
12794 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12798 if (GET_MODE (operands[0]) != SImode)
12800 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12805 (define_expand "ctr<mode>"
12806 [(parallel [(set (pc)
12807 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12809 (label_ref (match_operand 1 "" ""))
12812 (plus:P (match_dup 0)
12814 (clobber (match_scratch:CC 2 ""))
12815 (clobber (match_scratch:P 3 ""))])]
12819 ;; We need to be able to do this for any operand, including MEM, or we
12820 ;; will cause reload to blow up since we don't allow output reloads on
12822 ;; For the length attribute to be calculated correctly, the
12823 ;; label MUST be operand 0.
12824 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12825 ;; the ctr<mode> insns.
12827 (define_insn "ctr<mode>_internal1"
12829 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12831 (label_ref (match_operand 0 "" ""))
12833 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12834 (plus:P (match_dup 1)
12836 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12837 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12841 if (which_alternative != 0)
12843 else if (get_attr_length (insn) == 4)
12844 return \"bdnz %l0\";
12846 return \"bdz $+8\;b %l0\";
12848 [(set_attr "type" "branch")
12849 (set_attr "length" "*,16,20,20")])
12851 (define_insn "ctr<mode>_internal2"
12853 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12856 (label_ref (match_operand 0 "" ""))))
12857 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12858 (plus:P (match_dup 1)
12860 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12861 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12865 if (which_alternative != 0)
12867 else if (get_attr_length (insn) == 4)
12868 return \"bdz %l0\";
12870 return \"bdnz $+8\;b %l0\";
12872 [(set_attr "type" "branch")
12873 (set_attr "length" "*,16,20,20")])
12875 ;; Similar but use EQ
12877 (define_insn "ctr<mode>_internal3"
12879 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12881 (label_ref (match_operand 0 "" ""))
12883 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12884 (plus:P (match_dup 1)
12886 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12887 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12891 if (which_alternative != 0)
12893 else if (get_attr_length (insn) == 4)
12894 return \"bdz %l0\";
12896 return \"bdnz $+8\;b %l0\";
12898 [(set_attr "type" "branch")
12899 (set_attr "length" "*,16,20,20")])
12901 (define_insn "ctr<mode>_internal4"
12903 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12906 (label_ref (match_operand 0 "" ""))))
12907 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12908 (plus:P (match_dup 1)
12910 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12911 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12915 if (which_alternative != 0)
12917 else if (get_attr_length (insn) == 4)
12918 return \"bdnz %l0\";
12920 return \"bdz $+8\;b %l0\";
12922 [(set_attr "type" "branch")
12923 (set_attr "length" "*,16,20,20")])
12925 ;; Now the splitters if we could not allocate the CTR register
12929 (if_then_else (match_operator 2 "comparison_operator"
12930 [(match_operand:P 1 "gpc_reg_operand" "")
12932 (match_operand 5 "" "")
12933 (match_operand 6 "" "")))
12934 (set (match_operand:P 0 "int_reg_operand" "")
12935 (plus:P (match_dup 1) (const_int -1)))
12936 (clobber (match_scratch:CC 3 ""))
12937 (clobber (match_scratch:P 4 ""))]
12939 [(set (match_dup 3)
12940 (compare:CC (match_dup 1)
12943 (plus:P (match_dup 1)
12945 (set (pc) (if_then_else (match_dup 7)
12949 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12950 operands[3], const0_rtx); }")
12954 (if_then_else (match_operator 2 "comparison_operator"
12955 [(match_operand:P 1 "gpc_reg_operand" "")
12957 (match_operand 5 "" "")
12958 (match_operand 6 "" "")))
12959 (set (match_operand:P 0 "nonimmediate_operand" "")
12960 (plus:P (match_dup 1) (const_int -1)))
12961 (clobber (match_scratch:CC 3 ""))
12962 (clobber (match_scratch:P 4 ""))]
12963 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12964 [(set (match_dup 3)
12965 (compare:CC (match_dup 1)
12968 (plus:P (match_dup 1)
12972 (set (pc) (if_then_else (match_dup 7)
12976 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12977 operands[3], const0_rtx); }")
12979 (define_insn "trap"
12980 [(trap_if (const_int 1) (const_int 0))]
12983 [(set_attr "type" "trap")])
12985 (define_expand "ctrap<mode>4"
12986 [(trap_if (match_operator 0 "ordered_comparison_operator"
12987 [(match_operand:GPR 1 "register_operand")
12988 (match_operand:GPR 2 "reg_or_short_operand")])
12989 (match_operand 3 "zero_constant" ""))]
12994 [(trap_if (match_operator 0 "ordered_comparison_operator"
12995 [(match_operand:GPR 1 "register_operand" "r")
12996 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12999 "t<wd>%V0%I2 %1,%2"
13000 [(set_attr "type" "trap")])
13002 ;; Insns related to generating the function prologue and epilogue.
13004 (define_expand "prologue"
13005 [(use (const_int 0))]
13008 rs6000_emit_prologue ();
13009 if (!TARGET_SCHED_PROLOG)
13010 emit_insn (gen_blockage ());
13014 (define_insn "*movesi_from_cr_one"
13015 [(match_parallel 0 "mfcr_operation"
13016 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13017 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13018 (match_operand 3 "immediate_operand" "n")]
13019 UNSPEC_MOVESI_FROM_CR))])]
13025 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13027 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13028 operands[4] = GEN_INT (mask);
13029 output_asm_insn (\"mfcr %1,%4\", operands);
13033 [(set_attr "type" "mfcrf")])
13035 (define_insn "movesi_from_cr"
13036 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13037 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13038 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13039 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13040 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13041 UNSPEC_MOVESI_FROM_CR))]
13044 [(set_attr "type" "mfcr")])
13046 (define_insn "*crsave"
13047 [(match_parallel 0 "crsave_operation"
13048 [(set (match_operand:SI 1 "memory_operand" "=m")
13049 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13052 [(set_attr "type" "store")])
13054 (define_insn "*stmw"
13055 [(match_parallel 0 "stmw_operation"
13056 [(set (match_operand:SI 1 "memory_operand" "=m")
13057 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13060 [(set_attr "type" "store")
13061 (set_attr "update" "yes")
13062 (set_attr "indexed" "yes")])
13064 ; The following comment applies to:
13068 ; return_and_restore_gpregs*
13069 ; return_and_restore_fpregs*
13070 ; return_and_restore_fpregs_aix*
13072 ; The out-of-line save / restore functions expects one input argument.
13073 ; Since those are not standard call_insn's, we must avoid using
13074 ; MATCH_OPERAND for that argument. That way the register rename
13075 ; optimization will not try to rename this register.
13076 ; Each pattern is repeated for each possible register number used in
13077 ; various ABIs (r11, r1, and for some functions r12)
13079 (define_insn "*save_gpregs_<mode>_r11"
13080 [(match_parallel 0 "any_parallel_operand"
13081 [(clobber (reg:P LR_REGNO))
13082 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13084 (set (match_operand:P 2 "memory_operand" "=m")
13085 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13088 [(set_attr "type" "branch")
13089 (set_attr "length" "4")])
13091 (define_insn "*save_gpregs_<mode>_r12"
13092 [(match_parallel 0 "any_parallel_operand"
13093 [(clobber (reg:P LR_REGNO))
13094 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13096 (set (match_operand:P 2 "memory_operand" "=m")
13097 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13100 [(set_attr "type" "branch")
13101 (set_attr "length" "4")])
13103 (define_insn "*save_gpregs_<mode>_r1"
13104 [(match_parallel 0 "any_parallel_operand"
13105 [(clobber (reg:P LR_REGNO))
13106 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13108 (set (match_operand:P 2 "memory_operand" "=m")
13109 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13112 [(set_attr "type" "branch")
13113 (set_attr "length" "4")])
13115 (define_insn "*save_fpregs_<mode>_r11"
13116 [(match_parallel 0 "any_parallel_operand"
13117 [(clobber (reg:P LR_REGNO))
13118 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13120 (set (match_operand:DF 2 "memory_operand" "=m")
13121 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13124 [(set_attr "type" "branch")
13125 (set_attr "length" "4")])
13127 (define_insn "*save_fpregs_<mode>_r12"
13128 [(match_parallel 0 "any_parallel_operand"
13129 [(clobber (reg:P LR_REGNO))
13130 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13132 (set (match_operand:DF 2 "memory_operand" "=m")
13133 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13136 [(set_attr "type" "branch")
13137 (set_attr "length" "4")])
13139 (define_insn "*save_fpregs_<mode>_r1"
13140 [(match_parallel 0 "any_parallel_operand"
13141 [(clobber (reg:P LR_REGNO))
13142 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13144 (set (match_operand:DF 2 "memory_operand" "=m")
13145 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13148 [(set_attr "type" "branch")
13149 (set_attr "length" "4")])
13151 ; This is to explain that changes to the stack pointer should
13152 ; not be moved over loads from or stores to stack memory.
13153 (define_insn "stack_tie"
13154 [(match_parallel 0 "tie_operand"
13155 [(set (mem:BLK (reg 1)) (const_int 0))])]
13158 [(set_attr "length" "0")])
13160 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13161 ; stay behind all restores from the stack, it cannot be reordered to before
13162 ; one. See PR77687. This insn is an add or mr, and a stack_tie on the
13163 ; operands of that.
13164 (define_insn "stack_restore_tie"
13165 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13166 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13167 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13168 (set (mem:BLK (match_dup 0)) (const_int 0))
13169 (set (mem:BLK (match_dup 1)) (const_int 0))]
13174 [(set_attr "type" "*,add")])
13176 (define_expand "epilogue"
13177 [(use (const_int 0))]
13180 if (!TARGET_SCHED_PROLOG)
13181 emit_insn (gen_blockage ());
13182 rs6000_emit_epilogue (FALSE);
13186 ; On some processors, doing the mtcrf one CC register at a time is
13187 ; faster (like on the 604e). On others, doing them all at once is
13188 ; faster; for instance, on the 601 and 750.
13190 (define_expand "movsi_to_cr_one"
13191 [(set (match_operand:CC 0 "cc_reg_operand" "")
13192 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13193 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13195 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13197 (define_insn "*movsi_to_cr"
13198 [(match_parallel 0 "mtcrf_operation"
13199 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13200 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13201 (match_operand 3 "immediate_operand" "n")]
13202 UNSPEC_MOVESI_TO_CR))])]
13208 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13209 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13210 operands[4] = GEN_INT (mask);
13211 return \"mtcrf %4,%2\";
13213 [(set_attr "type" "mtcr")])
13215 (define_insn "*mtcrfsi"
13216 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13217 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13218 (match_operand 2 "immediate_operand" "n")]
13219 UNSPEC_MOVESI_TO_CR))]
13220 "GET_CODE (operands[0]) == REG
13221 && CR_REGNO_P (REGNO (operands[0]))
13222 && GET_CODE (operands[2]) == CONST_INT
13223 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13225 [(set_attr "type" "mtcr")])
13227 ; The load-multiple instructions have similar properties.
13228 ; Note that "load_multiple" is a name known to the machine-independent
13229 ; code that actually corresponds to the PowerPC load-string.
13231 (define_insn "*lmw"
13232 [(match_parallel 0 "lmw_operation"
13233 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13234 (match_operand:SI 2 "memory_operand" "m"))])]
13237 [(set_attr "type" "load")
13238 (set_attr "update" "yes")
13239 (set_attr "indexed" "yes")
13240 (set_attr "cell_micro" "always")])
13242 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13243 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13245 ; The following comment applies to:
13249 ; return_and_restore_gpregs*
13250 ; return_and_restore_fpregs*
13251 ; return_and_restore_fpregs_aix*
13253 ; The out-of-line save / restore functions expects one input argument.
13254 ; Since those are not standard call_insn's, we must avoid using
13255 ; MATCH_OPERAND for that argument. That way the register rename
13256 ; optimization will not try to rename this register.
13257 ; Each pattern is repeated for each possible register number used in
13258 ; various ABIs (r11, r1, and for some functions r12)
13260 (define_insn "*restore_gpregs_<mode>_r11"
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:P 2 "gpc_reg_operand" "=r")
13266 (match_operand:P 3 "memory_operand" "m"))])]
13269 [(set_attr "type" "branch")
13270 (set_attr "length" "4")])
13272 (define_insn "*restore_gpregs_<mode>_r12"
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:P 2 "gpc_reg_operand" "=r")
13278 (match_operand:P 3 "memory_operand" "m"))])]
13281 [(set_attr "type" "branch")
13282 (set_attr "length" "4")])
13284 (define_insn "*restore_gpregs_<mode>_r1"
13285 [(match_parallel 0 "any_parallel_operand"
13286 [(clobber (reg:P LR_REGNO))
13287 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13289 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13290 (match_operand:P 3 "memory_operand" "m"))])]
13293 [(set_attr "type" "branch")
13294 (set_attr "length" "4")])
13296 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13297 [(match_parallel 0 "any_parallel_operand"
13299 (clobber (reg:P LR_REGNO))
13300 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13302 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13303 (match_operand:P 3 "memory_operand" "m"))])]
13306 [(set_attr "type" "branch")
13307 (set_attr "length" "4")])
13309 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13310 [(match_parallel 0 "any_parallel_operand"
13312 (clobber (reg:P LR_REGNO))
13313 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13315 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13316 (match_operand:P 3 "memory_operand" "m"))])]
13319 [(set_attr "type" "branch")
13320 (set_attr "length" "4")])
13322 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13323 [(match_parallel 0 "any_parallel_operand"
13325 (clobber (reg:P LR_REGNO))
13326 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13328 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13329 (match_operand:P 3 "memory_operand" "m"))])]
13332 [(set_attr "type" "branch")
13333 (set_attr "length" "4")])
13335 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13336 [(match_parallel 0 "any_parallel_operand"
13338 (clobber (reg:P LR_REGNO))
13339 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13341 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13342 (match_operand:DF 3 "memory_operand" "m"))])]
13345 [(set_attr "type" "branch")
13346 (set_attr "length" "4")])
13348 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13349 [(match_parallel 0 "any_parallel_operand"
13351 (clobber (reg:P LR_REGNO))
13352 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13354 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13355 (match_operand:DF 3 "memory_operand" "m"))])]
13358 [(set_attr "type" "branch")
13359 (set_attr "length" "4")])
13361 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13362 [(match_parallel 0 "any_parallel_operand"
13364 (clobber (reg:P LR_REGNO))
13365 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13367 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13368 (match_operand:DF 3 "memory_operand" "m"))])]
13371 [(set_attr "type" "branch")
13372 (set_attr "length" "4")])
13374 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13375 [(match_parallel 0 "any_parallel_operand"
13377 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13379 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13380 (match_operand:DF 3 "memory_operand" "m"))])]
13383 [(set_attr "type" "branch")
13384 (set_attr "length" "4")])
13386 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13387 [(match_parallel 0 "any_parallel_operand"
13389 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13391 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13392 (match_operand:DF 3 "memory_operand" "m"))])]
13395 [(set_attr "type" "branch")
13396 (set_attr "length" "4")])
13398 ; This is used in compiling the unwind routines.
13399 (define_expand "eh_return"
13400 [(use (match_operand 0 "general_operand" ""))]
13405 emit_insn (gen_eh_set_lr_si (operands[0]));
13407 emit_insn (gen_eh_set_lr_di (operands[0]));
13411 ; We can't expand this before we know where the link register is stored.
13412 (define_insn "eh_set_lr_<mode>"
13413 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13415 (clobber (match_scratch:P 1 "=&b"))]
13420 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13421 (clobber (match_scratch 1 ""))]
13426 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13430 (define_insn "prefetch"
13431 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13432 (match_operand:SI 1 "const_int_operand" "n")
13433 (match_operand:SI 2 "const_int_operand" "n"))]
13437 if (GET_CODE (operands[0]) == REG)
13438 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13439 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13441 [(set_attr "type" "load")])
13443 ;; Handle -fsplit-stack.
13445 (define_expand "split_stack_prologue"
13449 rs6000_expand_split_stack_prologue ();
13453 (define_expand "load_split_stack_limit"
13454 [(set (match_operand 0)
13455 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13458 emit_insn (gen_rtx_SET (operands[0],
13459 gen_rtx_UNSPEC (Pmode,
13460 gen_rtvec (1, const0_rtx),
13461 UNSPEC_STACK_CHECK)));
13465 (define_insn "load_split_stack_limit_di"
13466 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13467 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13469 "ld %0,-0x7040(13)"
13470 [(set_attr "type" "load")
13471 (set_attr "update" "no")
13472 (set_attr "indexed" "no")])
13474 (define_insn "load_split_stack_limit_si"
13475 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13476 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13478 "lwz %0,-0x7020(2)"
13479 [(set_attr "type" "load")
13480 (set_attr "update" "no")
13481 (set_attr "indexed" "no")])
13483 ;; A return instruction which the middle-end doesn't see.
13484 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13485 ;; after the call to __morestack.
13486 (define_insn "split_stack_return"
13487 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13490 [(set_attr "type" "jmpreg")])
13492 ;; If there are operand 0 bytes available on the stack, jump to
13494 (define_expand "split_stack_space_check"
13495 [(set (match_dup 2)
13496 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13498 (minus (reg STACK_POINTER_REGNUM)
13499 (match_operand 0)))
13500 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13501 (set (pc) (if_then_else
13502 (geu (match_dup 4) (const_int 0))
13503 (label_ref (match_operand 1))
13507 rs6000_split_stack_space_check (operands[0], operands[1]);
13511 (define_insn "bpermd_<mode>"
13512 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13513 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13514 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13517 [(set_attr "type" "popcnt")])
13520 ;; Builtin fma support. Handle
13521 ;; Note that the conditions for expansion are in the FMA_F iterator.
13523 (define_expand "fma<mode>4"
13524 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13526 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13527 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13528 (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13532 (define_insn "*fma<mode>4_fpr"
13533 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13535 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13536 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13537 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13538 "TARGET_<MODE>_FPR"
13540 fmadd<Ftrad> %0,%1,%2,%3
13541 xsmadda<Fvsx> %x0,%x1,%x2
13542 xsmaddm<Fvsx> %x0,%x1,%x3"
13543 [(set_attr "type" "fp")
13544 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13546 ; Altivec only has fma and nfms.
13547 (define_expand "fms<mode>4"
13548 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13550 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13551 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13552 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13553 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13556 (define_insn "*fms<mode>4_fpr"
13557 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13559 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13560 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13561 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13562 "TARGET_<MODE>_FPR"
13564 fmsub<Ftrad> %0,%1,%2,%3
13565 xsmsuba<Fvsx> %x0,%x1,%x2
13566 xsmsubm<Fvsx> %x0,%x1,%x3"
13567 [(set_attr "type" "fp")
13568 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13570 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13571 (define_expand "fnma<mode>4"
13572 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13575 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13576 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13577 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13578 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13581 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13582 (define_expand "fnms<mode>4"
13583 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13586 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13587 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13588 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13589 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13592 ; Not an official optab name, but used from builtins.
13593 (define_expand "nfma<mode>4"
13594 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13597 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13598 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13599 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13600 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13603 (define_insn "*nfma<mode>4_fpr"
13604 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13607 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13608 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13609 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13610 "TARGET_<MODE>_FPR"
13612 fnmadd<Ftrad> %0,%1,%2,%3
13613 xsnmadda<Fvsx> %x0,%x1,%x2
13614 xsnmaddm<Fvsx> %x0,%x1,%x3"
13615 [(set_attr "type" "fp")
13616 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13618 ; Not an official optab name, but used from builtins.
13619 (define_expand "nfms<mode>4"
13620 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13623 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13624 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13625 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13629 (define_insn "*nfmssf4_fpr"
13630 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13633 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13634 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13636 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13637 "TARGET_<MODE>_FPR"
13639 fnmsub<Ftrad> %0,%1,%2,%3
13640 xsnmsuba<Fvsx> %x0,%x1,%x2
13641 xsnmsubm<Fvsx> %x0,%x1,%x3"
13642 [(set_attr "type" "fp")
13643 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13646 (define_expand "rs6000_get_timebase"
13647 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13650 if (TARGET_POWERPC64)
13651 emit_insn (gen_rs6000_mftb_di (operands[0]));
13653 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13657 (define_insn "rs6000_get_timebase_ppc32"
13658 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13659 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13660 (clobber (match_scratch:SI 1 "=r"))
13661 (clobber (match_scratch:CC 2 "=y"))]
13662 "!TARGET_POWERPC64"
13664 if (WORDS_BIG_ENDIAN)
13667 return "mfspr %0,269\;"
13675 return "mftbu %0\;"
13684 return "mfspr %L0,269\;"
13692 return "mftbu %L0\;"
13699 [(set_attr "length" "20")])
13701 (define_insn "rs6000_mftb_<mode>"
13702 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13703 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13707 return "mfspr %0,268";
13713 (define_insn "rs6000_mffs"
13714 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13715 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13716 "TARGET_HARD_FLOAT"
13719 (define_insn "rs6000_mtfsf"
13720 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13721 (match_operand:DF 1 "gpc_reg_operand" "d")]
13723 "TARGET_HARD_FLOAT"
13727 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13728 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13729 ;; register that is being loaded. The fused ops must be physically adjacent.
13731 ;; There are two parts to addis fusion. The support for fused TOCs occur
13732 ;; before register allocation, and is meant to reduce the lifetime for the
13733 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13734 ;; to use the register that is being load. The peephole2 then gathers any
13735 ;; other fused possibilities that it can find after register allocation. If
13736 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13738 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13739 ;; before register allocation, so that we can avoid allocating a temporary base
13740 ;; register that won't be used, and that we try to load into base registers,
13741 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13742 ;; (addis followed by load) even on power8.
13745 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13746 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13747 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13748 [(parallel [(set (match_dup 0) (match_dup 2))
13749 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13750 (use (match_dup 3))
13751 (clobber (scratch:DI))])]
13753 operands[2] = fusion_wrap_memory_address (operands[1]);
13754 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13757 (define_insn "*toc_fusionload_<mode>"
13758 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13759 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13760 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13761 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13762 (clobber (match_scratch:DI 3 "=X,&b"))]
13763 "TARGET_TOC_FUSION_INT"
13765 if (base_reg_operand (operands[0], <MODE>mode))
13766 return emit_fusion_gpr_load (operands[0], operands[1]);
13768 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13770 [(set_attr "type" "load")
13771 (set_attr "length" "8")])
13773 (define_insn "*toc_fusionload_di"
13774 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13775 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13776 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13777 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13778 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13779 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13780 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13782 if (base_reg_operand (operands[0], DImode))
13783 return emit_fusion_gpr_load (operands[0], operands[1]);
13785 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13787 [(set_attr "type" "load")
13788 (set_attr "length" "8")])
13791 ;; Find cases where the addis that feeds into a load instruction is either used
13792 ;; once or is the same as the target register, and replace it with the fusion
13796 [(set (match_operand:P 0 "base_reg_operand" "")
13797 (match_operand:P 1 "fusion_gpr_addis" ""))
13798 (set (match_operand:INT1 2 "base_reg_operand" "")
13799 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13801 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13805 expand_fusion_gpr_load (operands);
13809 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13812 (define_insn "fusion_gpr_load_<mode>"
13813 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13814 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13815 UNSPEC_FUSION_GPR))]
13818 return emit_fusion_gpr_load (operands[0], operands[1]);
13820 [(set_attr "type" "load")
13821 (set_attr "length" "8")])
13824 ;; ISA 3.0 (power9) fusion support
13825 ;; Merge addis with floating load/store to FPRs (or GPRs).
13827 [(set (match_operand:P 0 "base_reg_operand" "")
13828 (match_operand:P 1 "fusion_gpr_addis" ""))
13829 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13830 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13831 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13832 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13835 expand_fusion_p9_load (operands);
13840 [(set (match_operand:P 0 "base_reg_operand" "")
13841 (match_operand:P 1 "fusion_gpr_addis" ""))
13842 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13843 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13844 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13845 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13846 && !rtx_equal_p (operands[0], operands[3])"
13849 expand_fusion_p9_store (operands);
13854 [(set (match_operand:SDI 0 "int_reg_operand" "")
13855 (match_operand:SDI 1 "upper16_cint_operand" ""))
13857 (ior:SDI (match_dup 0)
13858 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13860 [(set (match_dup 0)
13861 (unspec:SDI [(match_dup 1)
13862 (match_dup 2)] UNSPEC_FUSION_P9))])
13865 [(set (match_operand:SDI 0 "int_reg_operand" "")
13866 (match_operand:SDI 1 "upper16_cint_operand" ""))
13867 (set (match_operand:SDI 2 "int_reg_operand" "")
13868 (ior:SDI (match_dup 0)
13869 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13871 && !rtx_equal_p (operands[0], operands[2])
13872 && peep2_reg_dead_p (2, operands[0])"
13873 [(set (match_dup 2)
13874 (unspec:SDI [(match_dup 1)
13875 (match_dup 3)] UNSPEC_FUSION_P9))])
13877 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13878 ;; reload). Because we want to eventually have secondary_reload generate
13879 ;; these, they have to have a single alternative that gives the register
13880 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13881 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13882 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13884 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13886 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13889 /* This insn is a secondary reload insn, which cannot have alternatives.
13890 If we are not loading up register 0, use the power8 fusion instead. */
13891 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13892 return emit_fusion_gpr_load (operands[0], operands[1]);
13894 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13896 [(set_attr "type" "load")
13897 (set_attr "length" "8")])
13899 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13900 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13902 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13904 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13907 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13909 [(set_attr "type" "store")
13910 (set_attr "length" "8")])
13912 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13913 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13915 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13917 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13920 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13922 [(set_attr "type" "fpload")
13923 (set_attr "length" "8")])
13925 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13926 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13928 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13930 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13933 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13935 [(set_attr "type" "fpstore")
13936 (set_attr "length" "8")])
13938 (define_insn "*fusion_p9_<mode>_constant"
13939 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13940 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13941 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13942 UNSPEC_FUSION_P9))]
13945 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13946 return "ori %0,%0,%2";
13948 [(set_attr "type" "two")
13949 (set_attr "length" "8")])
13952 ;; Optimize cases where we want to do a D-form load (register+offset) on
13953 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13958 ;; and we change this to:
13963 [(match_scratch:P 0 "b")
13964 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13965 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13966 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13968 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13969 [(set (match_dup 0)
13974 rtx tmp_reg = operands[0];
13975 rtx mem = operands[2];
13976 rtx addr = XEXP (mem, 0);
13977 rtx add_op0, add_op1, new_addr;
13979 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13980 add_op0 = XEXP (addr, 0);
13981 add_op1 = XEXP (addr, 1);
13982 gcc_assert (REG_P (add_op0));
13983 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13985 operands[4] = add_op1;
13986 operands[5] = change_address (mem, <MODE>mode, new_addr);
13989 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13990 ;; Altivec register, and the register allocator has generated:
13994 ;; and we change this to:
13999 [(match_scratch:P 0 "b")
14000 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14001 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14002 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14004 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14005 [(set (match_dup 0)
14010 rtx tmp_reg = operands[0];
14011 rtx mem = operands[3];
14012 rtx addr = XEXP (mem, 0);
14013 rtx add_op0, add_op1, new_addr;
14015 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14016 add_op0 = XEXP (addr, 0);
14017 add_op1 = XEXP (addr, 1);
14018 gcc_assert (REG_P (add_op0));
14019 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14021 operands[4] = add_op1;
14022 operands[5] = change_address (mem, <MODE>mode, new_addr);
14026 ;; Miscellaneous ISA 2.06 (power7) instructions
14027 (define_insn "addg6s"
14028 [(set (match_operand:SI 0 "register_operand" "=r")
14029 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14030 (match_operand:SI 2 "register_operand" "r")]
14034 [(set_attr "type" "integer")
14035 (set_attr "length" "4")])
14037 (define_insn "cdtbcd"
14038 [(set (match_operand:SI 0 "register_operand" "=r")
14039 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14043 [(set_attr "type" "integer")
14044 (set_attr "length" "4")])
14046 (define_insn "cbcdtd"
14047 [(set (match_operand:SI 0 "register_operand" "=r")
14048 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14052 [(set_attr "type" "integer")
14053 (set_attr "length" "4")])
14055 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14060 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14061 (UNSPEC_DIVEO "eo")
14062 (UNSPEC_DIVEU "eu")
14063 (UNSPEC_DIVEUO "euo")])
14065 (define_insn "div<div_extend>_<mode>"
14066 [(set (match_operand:GPR 0 "register_operand" "=r")
14067 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14068 (match_operand:GPR 2 "register_operand" "r")]
14069 UNSPEC_DIV_EXTEND))]
14071 "div<wd><div_extend> %0,%1,%2"
14072 [(set_attr "type" "div")
14073 (set_attr "size" "<bits>")])
14076 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14078 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14079 (define_mode_attr FP128_64 [(TF "DF")
14084 (define_expand "unpack<mode>"
14085 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14087 [(match_operand:FMOVE128 1 "register_operand" "")
14088 (match_operand:QI 2 "const_0_to_1_operand" "")]
14089 UNSPEC_UNPACK_128BIT))]
14090 "FLOAT128_2REG_P (<MODE>mode)"
14093 (define_insn_and_split "unpack<mode>_dm"
14094 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14096 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14097 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14098 UNSPEC_UNPACK_128BIT))]
14099 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14101 "&& reload_completed"
14102 [(set (match_dup 0) (match_dup 3))]
14104 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14106 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14108 emit_note (NOTE_INSN_DELETED);
14112 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14114 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14115 (set_attr "length" "4")])
14117 (define_insn_and_split "unpack<mode>_nodm"
14118 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14120 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14121 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14122 UNSPEC_UNPACK_128BIT))]
14123 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14125 "&& reload_completed"
14126 [(set (match_dup 0) (match_dup 3))]
14128 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14130 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14132 emit_note (NOTE_INSN_DELETED);
14136 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14138 [(set_attr "type" "fp,fpstore")
14139 (set_attr "length" "4")])
14141 (define_insn_and_split "pack<mode>"
14142 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14144 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14145 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14146 UNSPEC_PACK_128BIT))]
14147 "FLOAT128_2REG_P (<MODE>mode)"
14151 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14152 [(set (match_dup 3) (match_dup 1))
14153 (set (match_dup 4) (match_dup 2))]
14155 unsigned dest_hi = REGNO (operands[0]);
14156 unsigned dest_lo = dest_hi + 1;
14158 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14159 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14161 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14162 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14164 [(set_attr "type" "fpsimple,fp")
14165 (set_attr "length" "4,8")])
14167 (define_insn "unpack<mode>"
14168 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14169 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14170 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14171 UNSPEC_UNPACK_128BIT))]
14172 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14174 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14175 return ASM_COMMENT_START " xxpermdi to same register";
14177 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14178 return "xxpermdi %x0,%x1,%x1,%3";
14180 [(set_attr "type" "vecperm")])
14182 (define_insn "pack<mode>"
14183 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14184 (unspec:FMOVE128_VSX
14185 [(match_operand:DI 1 "register_operand" "wa")
14186 (match_operand:DI 2 "register_operand" "wa")]
14187 UNSPEC_PACK_128BIT))]
14189 "xxpermdi %x0,%x1,%x2,0"
14190 [(set_attr "type" "vecperm")])
14194 ;; ISA 2.08 IEEE 128-bit floating point support.
14196 (define_insn "add<mode>3"
14197 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14199 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14200 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14201 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14203 [(set_attr "type" "vecfloat")
14204 (set_attr "size" "128")])
14206 (define_insn "sub<mode>3"
14207 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14209 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14210 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14211 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14213 [(set_attr "type" "vecfloat")
14214 (set_attr "size" "128")])
14216 (define_insn "mul<mode>3"
14217 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14219 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14220 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14221 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14223 [(set_attr "type" "vecfloat")
14224 (set_attr "size" "128")])
14226 (define_insn "div<mode>3"
14227 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14229 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14230 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14231 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14233 [(set_attr "type" "vecdiv")
14234 (set_attr "size" "128")])
14236 (define_insn "sqrt<mode>2"
14237 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14239 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14240 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14242 [(set_attr "type" "vecdiv")
14243 (set_attr "size" "128")])
14245 (define_expand "copysign<mode>3"
14246 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14247 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14248 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14249 "FLOAT128_IEEE_P (<MODE>mode)"
14251 if (TARGET_FLOAT128_HW)
14252 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14256 rtx tmp = gen_reg_rtx (<MODE>mode);
14257 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14258 operands[2], tmp));
14263 (define_insn "copysign<mode>3_hard"
14264 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14266 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14267 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14269 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14270 "xscpsgnqp %0,%2,%1"
14271 [(set_attr "type" "vecmove")
14272 (set_attr "size" "128")])
14274 (define_insn "copysign<mode>3_soft"
14275 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14277 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14278 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14279 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14281 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14282 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14283 [(set_attr "type" "veccomplex")
14284 (set_attr "length" "8")])
14286 (define_insn "neg<mode>2_hw"
14287 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14289 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14290 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14292 [(set_attr "type" "vecmove")
14293 (set_attr "size" "128")])
14296 (define_insn "abs<mode>2_hw"
14297 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14299 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14300 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14302 [(set_attr "type" "vecmove")
14303 (set_attr "size" "128")])
14306 (define_insn "*nabs<mode>2_hw"
14307 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14310 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14311 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14313 [(set_attr "type" "vecmove")
14314 (set_attr "size" "128")])
14316 ;; Initially don't worry about doing fusion
14317 (define_insn "*fma<mode>4_hw"
14318 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14320 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14321 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14322 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14323 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14324 "xsmaddqp %0,%1,%2"
14325 [(set_attr "type" "vecfloat")
14326 (set_attr "size" "128")])
14328 (define_insn "*fms<mode>4_hw"
14329 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14331 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14332 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14334 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14335 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14336 "xsmsubqp %0,%1,%2"
14337 [(set_attr "type" "vecfloat")
14338 (set_attr "size" "128")])
14340 (define_insn "*nfma<mode>4_hw"
14341 [(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 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14347 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14348 "xsnmaddqp %0,%1,%2"
14349 [(set_attr "type" "vecfloat")
14350 (set_attr "size" "128")])
14352 (define_insn "*nfms<mode>4_hw"
14353 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14356 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14357 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14359 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14360 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14361 "xsnmsubqp %0,%1,%2"
14362 [(set_attr "type" "vecfloat")
14363 (set_attr "size" "128")])
14365 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14366 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14367 (float_extend:IEEE128
14368 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14369 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14371 [(set_attr "type" "vecfloat")
14372 (set_attr "size" "128")])
14374 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14375 ;; point is a simple copy.
14376 (define_insn_and_split "extendkftf2"
14377 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14378 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14379 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14383 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14386 emit_note (NOTE_INSN_DELETED);
14389 [(set_attr "type" "*,veclogical")
14390 (set_attr "length" "0,4")])
14392 (define_insn_and_split "trunctfkf2"
14393 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14394 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14395 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14399 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14402 emit_note (NOTE_INSN_DELETED);
14405 [(set_attr "type" "*,veclogical")
14406 (set_attr "length" "0,4")])
14408 (define_insn "trunc<mode>df2_hw"
14409 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14411 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14412 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14414 [(set_attr "type" "vecfloat")
14415 (set_attr "size" "128")])
14417 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14418 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14420 (define_insn_and_split "trunc<mode>sf2_hw"
14421 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14423 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14424 (clobber (match_scratch:DF 2 "=v"))]
14425 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14428 [(set (match_dup 2)
14429 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14431 (float_truncate:SF (match_dup 2)))]
14433 if (GET_CODE (operands[2]) == SCRATCH)
14434 operands[2] = gen_reg_rtx (DFmode);
14436 [(set_attr "type" "vecfloat")
14437 (set_attr "length" "8")])
14439 ;; Conversion between IEEE 128-bit and integer types
14440 (define_insn "fix_<mode>di2_hw"
14441 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14442 (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14443 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14445 [(set_attr "type" "vecfloat")
14446 (set_attr "size" "128")])
14448 (define_insn "fixuns_<mode>di2_hw"
14449 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14450 (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14451 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14453 [(set_attr "type" "vecfloat")
14454 (set_attr "size" "128")])
14456 (define_insn "fix_<mode>si2_hw"
14457 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14458 (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14459 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14461 [(set_attr "type" "vecfloat")
14462 (set_attr "size" "128")])
14464 (define_insn "fixuns_<mode>si2_hw"
14465 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14466 (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14467 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14469 [(set_attr "type" "vecfloat")
14470 (set_attr "size" "128")])
14472 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14473 ;; floating point value to 32-bit integer to GPR in order to save it.
14474 (define_insn_and_split "*fix<uns>_<mode>_mem"
14475 [(set (match_operand:SI 0 "memory_operand" "=Z")
14476 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14477 (clobber (match_scratch:SI 2 "=v"))]
14478 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14480 "&& reload_completed"
14481 [(set (match_dup 2)
14482 (any_fix:SI (match_dup 1)))
14486 (define_insn "float_<mode>di2_hw"
14487 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14488 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14489 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14491 [(set_attr "type" "vecfloat")
14492 (set_attr "size" "128")])
14494 (define_insn_and_split "float_<mode>si2_hw"
14495 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14496 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14497 (clobber (match_scratch:DI 2 "=v"))]
14498 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14501 [(set (match_dup 2)
14502 (sign_extend:DI (match_dup 1)))
14504 (float:IEEE128 (match_dup 2)))]
14506 if (GET_CODE (operands[2]) == SCRATCH)
14507 operands[2] = gen_reg_rtx (DImode);
14510 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14511 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14512 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14513 (clobber (match_scratch:DI 2 "=X,r,X"))]
14514 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14516 "&& reload_completed"
14519 rtx dest = operands[0];
14520 rtx src = operands[1];
14521 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14523 if (altivec_register_operand (src, <QHI:MODE>mode))
14524 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14525 else if (int_reg_operand (src, <QHI:MODE>mode))
14527 rtx ext_di = operands[2];
14528 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14529 emit_move_insn (dest_di, ext_di);
14531 else if (MEM_P (src))
14533 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14534 emit_move_insn (dest_qhi, src);
14535 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14538 gcc_unreachable ();
14540 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14543 [(set_attr "length" "8,12,12")
14544 (set_attr "type" "vecfloat")
14545 (set_attr "size" "128")])
14547 (define_insn "floatuns_<mode>di2_hw"
14548 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14549 (unsigned_float:IEEE128
14550 (match_operand:DI 1 "altivec_register_operand" "v")))]
14551 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14553 [(set_attr "type" "vecfloat")
14554 (set_attr "size" "128")])
14556 (define_insn_and_split "floatuns_<mode>si2_hw"
14557 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14558 (unsigned_float:IEEE128
14559 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14560 (clobber (match_scratch:DI 2 "=v"))]
14561 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14564 [(set (match_dup 2)
14565 (zero_extend:DI (match_dup 1)))
14567 (float:IEEE128 (match_dup 2)))]
14569 if (GET_CODE (operands[2]) == SCRATCH)
14570 operands[2] = gen_reg_rtx (DImode);
14573 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14574 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14575 (unsigned_float:IEEE128
14576 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14577 (clobber (match_scratch:DI 2 "=X,r,X"))]
14578 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14580 "&& reload_completed"
14583 rtx dest = operands[0];
14584 rtx src = operands[1];
14585 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14587 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14588 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14589 else if (int_reg_operand (src, <QHI:MODE>mode))
14591 rtx ext_di = operands[2];
14592 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14593 emit_move_insn (dest_di, ext_di);
14596 gcc_unreachable ();
14598 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14601 [(set_attr "length" "8,12,8")
14602 (set_attr "type" "vecfloat")
14603 (set_attr "size" "128")])
14605 ;; IEEE 128-bit instructions with round to odd semantics
14606 (define_insn "*trunc<mode>df2_odd"
14607 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14608 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14609 UNSPEC_ROUND_TO_ODD))]
14610 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14612 [(set_attr "type" "vecfloat")
14613 (set_attr "size" "128")])
14615 ;; IEEE 128-bit comparisons
14616 (define_insn "*cmp<mode>_hw"
14617 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14618 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14619 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14620 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14621 "xscmpuqp %0,%1,%2"
14622 [(set_attr "type" "veccmp")
14623 (set_attr "size" "128")])
14627 (include "sync.md")
14628 (include "vector.md")
14630 (include "altivec.md")
14632 (include "paired.md")
14633 (include "crypto.md")