1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2017 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (STACK_POINTER_REGNUM 1)
31 (STATIC_CHAIN_REGNUM 11)
32 (HARD_FRAME_POINTER_REGNUM 31)
38 (ARG_POINTER_REGNUM 67)
49 (FIRST_ALTIVEC_REGNO 77)
50 (LAST_ALTIVEC_REGNO 108)
55 (FRAME_POINTER_REGNUM 113)
59 (FIRST_SPE_HIGH_REGNO 117)
60 (LAST_SPE_HIGH_REGNO 148)
67 (define_c_enum "unspec"
68 [UNSPEC_FRSP ; frsp for POWER machines
69 UNSPEC_PROBE_STACK ; probe stack memory reference
70 UNSPEC_TOCPTR ; address of a word pointing to the TOC
71 UNSPEC_TOC ; address of the TOC (more-or-less)
72 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
74 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
81 UNSPEC_LD_MPIC ; load_macho_picbase
82 UNSPEC_RELD_MPIC ; re-load_macho_picbase
83 UNSPEC_MPIC_CORRECT ; macho_correct_pic
97 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
98 UNSPEC_MV_CR_GT ; move_from_CR_gt_bit
116 UNSPEC_MACHOPIC_OFFSET
130 UNSPEC_P8V_RELOAD_FROM_GPR
133 UNSPEC_P8V_RELOAD_FROM_VSX
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
160 UNSPECV_LL ; load-locked
161 UNSPECV_SC ; store-conditional
162 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
163 UNSPECV_EH_RR ; eh_reg_restore
164 UNSPECV_ISYNC ; isync instruction
165 UNSPECV_MFTB ; move from time base
166 UNSPECV_NLGR ; non-local goto receiver
167 UNSPECV_MFFS ; Move from FPSCR
168 UNSPECV_MTFSF ; Move to FPSCR Fields
169 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
173 ;; Define an insn type attribute. This is used in function unit delay
177 add,logical,shift,insert,
179 exts,cntlz,popcnt,isel,
180 load,store,fpload,fpstore,vecload,vecstore,
182 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
184 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
186 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
187 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
188 veclogical,veccmpfx,vecexts,vecmove,
190 (const_string "integer"))
192 ;; What data size does this instruction work on?
193 ;; This is used for insert, mul and others as necessary.
194 (define_attr "size" "8,16,32,64,128" (const_string "32"))
196 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
197 ;; This is used for add, logical, shift, exts, mul.
198 (define_attr "dot" "no,yes" (const_string "no"))
200 ;; Does this instruction sign-extend its result?
201 ;; This is used for load insns.
202 (define_attr "sign_extend" "no,yes" (const_string "no"))
204 ;; Does this instruction use indexed (that is, reg+reg) addressing?
205 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
206 ;; it is automatically set based on that. If a load or store instruction
207 ;; has fewer than two operands it needs to set this attribute manually
208 ;; or the compiler will crash.
209 (define_attr "indexed" "no,yes"
210 (if_then_else (ior (match_operand 0 "indexed_address_mem")
211 (match_operand 1 "indexed_address_mem"))
213 (const_string "no")))
215 ;; Does this instruction use update addressing?
216 ;; This is used for load and store insns. See the comments for "indexed".
217 (define_attr "update" "no,yes"
218 (if_then_else (ior (match_operand 0 "update_address_mem")
219 (match_operand 1 "update_address_mem"))
221 (const_string "no")))
223 ;; Is this instruction using operands[2] as shift amount, and can that be a
225 ;; This is used for shift insns.
226 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
228 ;; Is this instruction using a shift amount from a register?
229 ;; This is used for shift insns.
230 (define_attr "var_shift" "no,yes"
231 (if_then_else (and (eq_attr "type" "shift")
232 (eq_attr "maybe_var_shift" "yes"))
233 (if_then_else (match_operand 2 "gpc_reg_operand")
236 (const_string "no")))
238 ;; Is copying of this instruction disallowed?
239 (define_attr "cannot_copy" "no,yes" (const_string "no"))
241 ;; Define floating point instruction sub-types for use with Xfpu.md
242 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
244 ;; Length (in bytes).
245 ; '(pc)' in the following doesn't include the instruction itself; it is
246 ; calculated as if the instruction had zero size.
247 (define_attr "length" ""
248 (if_then_else (eq_attr "type" "branch")
249 (if_then_else (and (ge (minus (match_dup 0) (pc))
251 (lt (minus (match_dup 0) (pc))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
260 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261 ppc750,ppc7400,ppc7450,
262 ppc403,ppc405,ppc440,ppc476,
263 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264 power4,power5,power6,power7,power8,power9,
265 rs64a,mpccore,cell,ppca2,titan"
266 (const (symbol_ref "rs6000_cpu_attr")))
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273 (eq_attr "dot" "yes"))
274 (and (eq_attr "type" "load")
275 (eq_attr "sign_extend" "yes"))
276 (and (eq_attr "type" "shift")
277 (eq_attr "var_shift" "yes")))
278 (const_string "always")
279 (const_string "not")))
281 (automata_option "ndfa")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
310 (include "predicates.md")
311 (include "constraints.md")
313 (include "darwin.md")
318 ; This mode iterator allows :GPR to be used to indicate the allowable size
319 ; of whole values in GPRs.
320 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
322 ; Any supported integer mode.
323 (define_mode_iterator INT [QI HI SI DI TI PTI])
325 ; Any supported integer mode that fits in one register.
326 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
328 ; Integer modes supported in VSX registers with ISA 3.0 instructions
329 (define_mode_iterator INT_ISA3 [QI HI SI DI])
331 ; Everything we can extend QImode to.
332 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
334 ; Everything we can extend HImode to.
335 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
337 ; Everything we can extend SImode to.
338 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
340 ; QImode or HImode for small integer moves and small atomic ops
341 (define_mode_iterator QHI [QI HI])
343 ; QImode, HImode, SImode for fused ops only for GPR loads
344 (define_mode_iterator QHSI [QI HI SI])
346 ; HImode or SImode for sign extended fusion ops
347 (define_mode_iterator HSI [HI SI])
349 ; SImode or DImode, even if DImode doesn't fit in GPRs.
350 (define_mode_iterator SDI [SI DI])
352 ; Types that can be fused with an ADDIS instruction to load or store a GPR
353 ; register that has reg+offset addressing.
354 (define_mode_iterator GPR_FUSION [QI
357 (DI "TARGET_POWERPC64")
359 (DF "TARGET_POWERPC64")])
361 ; Types that can be fused with an ADDIS instruction to load or store a FPR
362 ; register that has reg+offset addressing.
363 (define_mode_iterator FPR_FUSION [DI SF DF])
365 ; The size of a pointer. Also, the size of the value that a record-condition
366 ; (one with a '.') will compare; and the size used for arithmetic carries.
367 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
369 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
370 ; PTImode is GPR only)
371 (define_mode_iterator TI2 [TI PTI])
373 ; Any hardware-supported floating-point mode
374 (define_mode_iterator FP [
375 (SF "TARGET_HARD_FLOAT
376 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
377 (DF "TARGET_HARD_FLOAT
378 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
379 (TF "TARGET_HARD_FLOAT
380 && (TARGET_FPRS || TARGET_E500_DOUBLE)
381 && TARGET_LONG_DOUBLE_128")
382 (IF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")
383 (KF "TARGET_FLOAT128_TYPE")
387 ; Any fma capable floating-point mode.
388 (define_mode_iterator FMA_F [
389 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
390 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
391 || VECTOR_UNIT_VSX_P (DFmode)")
392 (V2SF "TARGET_PAIRED_FLOAT")
393 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
394 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
395 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
396 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
399 ; Floating point move iterators to combine binary and decimal moves
400 (define_mode_iterator FMOVE32 [SF SD])
401 (define_mode_iterator FMOVE64 [DF DD])
402 (define_mode_iterator FMOVE64X [DI DF DD])
403 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
404 (IF "FLOAT128_IBM_P (IFmode)")
405 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
407 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
408 (IF "FLOAT128_2REG_P (IFmode)")
409 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
411 ; Iterators for 128 bit types for direct move
412 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
420 (KF "FLOAT128_VECTOR_P (KFmode)")
421 (TF "FLOAT128_VECTOR_P (TFmode)")])
423 ; Iterator for 128-bit VSX types for pack/unpack
424 (define_mode_iterator FMOVE128_VSX [V1TI KF])
426 ; Whether a floating point move is ok, don't allow SD without hardware FP
427 (define_mode_attr fmove_ok [(SF "")
429 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
432 ; Convert REAL_VALUE to the appropriate bits
433 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
434 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
435 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
436 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
438 ; Whether 0.0 has an all-zero bit pattern
439 (define_mode_attr zero_fp [(SF "j")
448 ; Definitions for load to 32-bit fpr register
449 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
450 (define_mode_attr f32_lr2 [(SF "wb") (SD "wn")])
451 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
452 (define_mode_attr f32_lm2 [(SF "wY") (SD "wn")])
453 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
454 (define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
455 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
457 ; Definitions for store from 32-bit fpr register
458 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
459 (define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
460 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
461 (define_mode_attr f32_sm2 [(SF "wY") (SD "wn")])
462 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
463 (define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
464 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwx %x1,%y0")])
466 ; Definitions for 32-bit fpr direct move
467 ; At present, the decimal modes are not allowed in the traditional altivec
468 ; registers, so restrict the constraints to just the traditional FPRs.
469 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
471 ; Definitions for 32-bit VSX
472 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
474 ; Definitions for 32-bit use of altivec registers
475 (define_mode_attr f32_av [(SF "wu") (SD "wn")])
477 ; Definitions for 64-bit VSX
478 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
480 ; Definitions for 64-bit direct move
481 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
483 ; Definitions for 64-bit use of altivec registers
484 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
486 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
487 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
489 ; These modes do not fit in integer registers in 32-bit mode.
490 ; but on e500v2, the gpr are 64 bit registers
491 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
493 ; Iterator for reciprocal estimate instructions
494 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
496 ; Iterator for just SF/DF
497 (define_mode_iterator SFDF [SF DF])
499 ; Like SFDF, but a different name to match conditional move where the
500 ; comparison operands may be a different mode than the input operands.
501 (define_mode_iterator SFDF2 [SF DF])
503 ; Iterator for 128-bit floating point that uses the IBM double-double format
504 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
505 (TF "FLOAT128_IBM_P (TFmode)")])
507 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
508 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
509 (TF "FLOAT128_IEEE_P (TFmode)")])
511 ; Iterator for 128-bit floating point
512 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
513 (IF "TARGET_FLOAT128_TYPE")
514 (TF "TARGET_LONG_DOUBLE_128")])
516 ; Iterator for signbit on 64-bit machines with direct move
517 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
518 (TF "FLOAT128_VECTOR_P (TFmode)")])
520 ; Iterator for ISA 3.0 supported floating point types
521 (define_mode_iterator FP_ISA3 [SF DF])
523 ; SF/DF suffix for traditional floating instructions
524 (define_mode_attr Ftrad [(SF "s") (DF "")])
526 ; SF/DF suffix for VSX instructions
527 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
529 ; SF/DF constraint for arithmetic on traditional floating point registers
530 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
532 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
533 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
534 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
536 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
538 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
539 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
540 ; instructions added in ISA 2.07 (power8)
541 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
543 ; SF/DF constraint for arithmetic on altivec registers
544 (define_mode_attr Fa [(SF "wu") (DF "wv")])
546 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
547 (define_mode_attr Fs [(SF "s") (DF "d")])
550 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
551 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
553 ; Conditional returns.
554 (define_code_iterator any_return [return simple_return])
555 (define_code_attr return_pred [(return "direct_return ()")
556 (simple_return "1")])
557 (define_code_attr return_str [(return "") (simple_return "simple_")])
560 (define_code_iterator iorxor [ior xor])
561 (define_code_iterator and_ior_xor [and ior xor])
563 ; Signed/unsigned variants of ops.
564 (define_code_iterator any_extend [sign_extend zero_extend])
565 (define_code_iterator any_fix [fix unsigned_fix])
566 (define_code_iterator any_float [float unsigned_float])
568 (define_code_attr u [(sign_extend "")
571 (define_code_attr su [(sign_extend "s")
576 (unsigned_float "u")])
578 (define_code_attr az [(sign_extend "a")
583 (unsigned_float "z")])
585 (define_code_attr uns [(fix "")
588 (unsigned_float "uns")])
590 ; Various instructions that come in SI and DI forms.
591 ; A generic w/d attribute, for things like cmpw/cmpd.
592 (define_mode_attr wd [(QI "b")
603 ;; How many bits in this mode?
604 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
607 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
609 ;; ISEL/ISEL64 target selection
610 (define_mode_attr sel [(SI "") (DI "64")])
612 ;; Bitmask for shift instructions
613 (define_mode_attr hH [(SI "h") (DI "H")])
615 ;; A mode twice the size of the given mode
616 (define_mode_attr dmode [(SI "di") (DI "ti")])
617 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
619 ;; Suffix for reload patterns
620 (define_mode_attr ptrsize [(SI "32bit")
623 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
624 (DI "TARGET_64BIT")])
626 (define_mode_attr mptrsize [(SI "si")
629 (define_mode_attr ptrload [(SI "lwz")
632 (define_mode_attr ptrm [(SI "m")
635 (define_mode_attr rreg [(SF "f")
642 (define_mode_attr rreg2 [(SF "f")
645 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
646 (DF "TARGET_FCFID")])
648 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
649 (DF "TARGET_E500_DOUBLE")])
651 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
652 (DF "TARGET_DOUBLE_FLOAT")])
654 ;; Mode iterator for logical operations on 128-bit types
655 (define_mode_iterator BOOL_128 [TI
657 (V16QI "TARGET_ALTIVEC")
658 (V8HI "TARGET_ALTIVEC")
659 (V4SI "TARGET_ALTIVEC")
660 (V4SF "TARGET_ALTIVEC")
661 (V2DI "TARGET_ALTIVEC")
662 (V2DF "TARGET_ALTIVEC")
663 (V1TI "TARGET_ALTIVEC")])
665 ;; For the GPRs we use 3 constraints for register outputs, two that are the
666 ;; same as the output register, and a third where the output register is an
667 ;; early clobber, so we don't have to deal with register overlaps. For the
668 ;; vector types, we prefer to use the vector registers. For TI mode, allow
671 ;; Mode attribute for boolean operation register constraints for output
672 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
674 (V16QI "wa,v,&?r,?r,?r")
675 (V8HI "wa,v,&?r,?r,?r")
676 (V4SI "wa,v,&?r,?r,?r")
677 (V4SF "wa,v,&?r,?r,?r")
678 (V2DI "wa,v,&?r,?r,?r")
679 (V2DF "wa,v,&?r,?r,?r")
680 (V1TI "wa,v,&?r,?r,?r")])
682 ;; Mode attribute for boolean operation register constraints for operand1
683 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
691 (V1TI "wa,v,r,0,r")])
693 ;; Mode attribute for boolean operation register constraints for operand2
694 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
702 (V1TI "wa,v,r,r,0")])
704 ;; Mode attribute for boolean operation register constraints for operand1
705 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
706 ;; is used for operand1 or operand2
707 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
715 (V1TI "wa,v,r,0,0")])
717 ;; Reload iterator for creating the function to allocate a base register to
718 ;; supplement addressing modes.
719 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
720 SF SD SI DF DD DI TI PTI KF IF TF])
722 ;; Iterate over smin, smax
723 (define_code_iterator fp_minmax [smin smax])
725 (define_code_attr minmax [(smin "min")
728 (define_code_attr SMINMAX [(smin "SMIN")
732 ;; Start with fixed-point load and store insns. Here we put only the more
733 ;; complex forms. Basic data transfer is done later.
735 (define_insn "zero_extendqi<mode>2"
736 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
737 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
744 [(set_attr "type" "load,shift,fpload,vecperm")])
746 (define_insn_and_split "*zero_extendqi<mode>2_dot"
747 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
748 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
750 (clobber (match_scratch:EXTQI 0 "=r,r"))]
751 "rs6000_gen_cell_microcode"
755 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
757 (zero_extend:EXTQI (match_dup 1)))
759 (compare:CC (match_dup 0)
762 [(set_attr "type" "logical")
763 (set_attr "dot" "yes")
764 (set_attr "length" "4,8")])
766 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
767 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
768 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
770 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
771 (zero_extend:EXTQI (match_dup 1)))]
772 "rs6000_gen_cell_microcode"
776 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
778 (zero_extend:EXTQI (match_dup 1)))
780 (compare:CC (match_dup 0)
783 [(set_attr "type" "logical")
784 (set_attr "dot" "yes")
785 (set_attr "length" "4,8")])
788 (define_insn "zero_extendhi<mode>2"
789 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
790 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
794 rlwinm %0,%1,0,0xffff
797 [(set_attr "type" "load,shift,fpload,vecperm")])
799 (define_insn_and_split "*zero_extendhi<mode>2_dot"
800 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
801 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
803 (clobber (match_scratch:EXTHI 0 "=r,r"))]
804 "rs6000_gen_cell_microcode"
808 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
810 (zero_extend:EXTHI (match_dup 1)))
812 (compare:CC (match_dup 0)
815 [(set_attr "type" "logical")
816 (set_attr "dot" "yes")
817 (set_attr "length" "4,8")])
819 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
820 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
821 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
823 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
824 (zero_extend:EXTHI (match_dup 1)))]
825 "rs6000_gen_cell_microcode"
829 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
831 (zero_extend:EXTHI (match_dup 1)))
833 (compare:CC (match_dup 0)
836 [(set_attr "type" "logical")
837 (set_attr "dot" "yes")
838 (set_attr "length" "4,8")])
841 (define_insn "zero_extendsi<mode>2"
842 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
843 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
852 xxextractuw %x0,%x1,4"
853 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
855 (define_insn_and_split "*zero_extendsi<mode>2_dot"
856 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
857 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
859 (clobber (match_scratch:EXTSI 0 "=r,r"))]
860 "rs6000_gen_cell_microcode"
864 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
866 (zero_extend:DI (match_dup 1)))
868 (compare:CC (match_dup 0)
871 [(set_attr "type" "shift")
872 (set_attr "dot" "yes")
873 (set_attr "length" "4,8")])
875 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
876 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
877 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
879 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
880 (zero_extend:EXTSI (match_dup 1)))]
881 "rs6000_gen_cell_microcode"
885 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
887 (zero_extend:EXTSI (match_dup 1)))
889 (compare:CC (match_dup 0)
892 [(set_attr "type" "shift")
893 (set_attr "dot" "yes")
894 (set_attr "length" "4,8")])
897 (define_insn "extendqi<mode>2"
898 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
899 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
904 [(set_attr "type" "exts,vecperm")])
906 (define_insn_and_split "*extendqi<mode>2_dot"
907 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
910 (clobber (match_scratch:EXTQI 0 "=r,r"))]
911 "rs6000_gen_cell_microcode"
915 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
917 (sign_extend:EXTQI (match_dup 1)))
919 (compare:CC (match_dup 0)
922 [(set_attr "type" "exts")
923 (set_attr "dot" "yes")
924 (set_attr "length" "4,8")])
926 (define_insn_and_split "*extendqi<mode>2_dot2"
927 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
928 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
930 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
931 (sign_extend:EXTQI (match_dup 1)))]
932 "rs6000_gen_cell_microcode"
936 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
938 (sign_extend:EXTQI (match_dup 1)))
940 (compare:CC (match_dup 0)
943 [(set_attr "type" "exts")
944 (set_attr "dot" "yes")
945 (set_attr "length" "4,8")])
948 (define_expand "extendhi<mode>2"
949 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
950 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
954 (define_insn "*extendhi<mode>2"
955 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
956 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
957 "rs6000_gen_cell_microcode"
963 [(set_attr "type" "load,exts,fpload,vecperm")
964 (set_attr "sign_extend" "yes")
965 (set_attr "length" "4,4,8,4")])
968 [(set (match_operand:EXTHI 0 "altivec_register_operand")
970 (match_operand:HI 1 "indexed_or_indirect_operand")))]
971 "TARGET_P9_VECTOR && reload_completed"
975 (sign_extend:EXTHI (match_dup 2)))]
977 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
980 (define_insn "*extendhi<mode>2_noload"
981 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
982 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
983 "!rs6000_gen_cell_microcode"
985 [(set_attr "type" "exts")])
987 (define_insn_and_split "*extendhi<mode>2_dot"
988 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
989 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
991 (clobber (match_scratch:EXTHI 0 "=r,r"))]
992 "rs6000_gen_cell_microcode"
996 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
998 (sign_extend:EXTHI (match_dup 1)))
1000 (compare:CC (match_dup 0)
1003 [(set_attr "type" "exts")
1004 (set_attr "dot" "yes")
1005 (set_attr "length" "4,8")])
1007 (define_insn_and_split "*extendhi<mode>2_dot2"
1008 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1009 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1011 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1012 (sign_extend:EXTHI (match_dup 1)))]
1013 "rs6000_gen_cell_microcode"
1017 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1019 (sign_extend:EXTHI (match_dup 1)))
1021 (compare:CC (match_dup 0)
1024 [(set_attr "type" "exts")
1025 (set_attr "dot" "yes")
1026 (set_attr "length" "4,8")])
1029 (define_insn "extendsi<mode>2"
1030 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK")
1031 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK")))]
1040 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts")
1041 (set_attr "sign_extend" "yes")])
1043 (define_insn_and_split "*extendsi<mode>2_dot"
1044 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1045 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1047 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1048 "rs6000_gen_cell_microcode"
1052 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1054 (sign_extend:EXTSI (match_dup 1)))
1056 (compare:CC (match_dup 0)
1059 [(set_attr "type" "exts")
1060 (set_attr "dot" "yes")
1061 (set_attr "length" "4,8")])
1063 (define_insn_and_split "*extendsi<mode>2_dot2"
1064 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1065 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1067 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1068 (sign_extend:EXTSI (match_dup 1)))]
1069 "rs6000_gen_cell_microcode"
1073 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1075 (sign_extend:EXTSI (match_dup 1)))
1077 (compare:CC (match_dup 0)
1080 [(set_attr "type" "exts")
1081 (set_attr "dot" "yes")
1082 (set_attr "length" "4,8")])
1084 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1086 (define_insn "*macchwc"
1087 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1088 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1089 (match_operand:SI 2 "gpc_reg_operand" "r")
1092 (match_operand:HI 1 "gpc_reg_operand" "r")))
1093 (match_operand:SI 4 "gpc_reg_operand" "0"))
1095 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1096 (plus:SI (mult:SI (ashiftrt:SI
1104 [(set_attr "type" "halfmul")])
1106 (define_insn "*macchw"
1107 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1108 (plus:SI (mult:SI (ashiftrt:SI
1109 (match_operand:SI 2 "gpc_reg_operand" "r")
1112 (match_operand:HI 1 "gpc_reg_operand" "r")))
1113 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1116 [(set_attr "type" "halfmul")])
1118 (define_insn "*macchwuc"
1119 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1120 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1121 (match_operand:SI 2 "gpc_reg_operand" "r")
1124 (match_operand:HI 1 "gpc_reg_operand" "r")))
1125 (match_operand:SI 4 "gpc_reg_operand" "0"))
1127 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1128 (plus:SI (mult:SI (lshiftrt:SI
1136 [(set_attr "type" "halfmul")])
1138 (define_insn "*macchwu"
1139 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1140 (plus:SI (mult:SI (lshiftrt:SI
1141 (match_operand:SI 2 "gpc_reg_operand" "r")
1144 (match_operand:HI 1 "gpc_reg_operand" "r")))
1145 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1148 [(set_attr "type" "halfmul")])
1150 (define_insn "*machhwc"
1151 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1152 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1153 (match_operand:SI 1 "gpc_reg_operand" "%r")
1156 (match_operand:SI 2 "gpc_reg_operand" "r")
1158 (match_operand:SI 4 "gpc_reg_operand" "0"))
1160 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1161 (plus:SI (mult:SI (ashiftrt:SI
1170 [(set_attr "type" "halfmul")])
1172 (define_insn "*machhw"
1173 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1174 (plus:SI (mult:SI (ashiftrt:SI
1175 (match_operand:SI 1 "gpc_reg_operand" "%r")
1178 (match_operand:SI 2 "gpc_reg_operand" "r")
1180 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1183 [(set_attr "type" "halfmul")])
1185 (define_insn "*machhwuc"
1186 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1187 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1188 (match_operand:SI 1 "gpc_reg_operand" "%r")
1191 (match_operand:SI 2 "gpc_reg_operand" "r")
1193 (match_operand:SI 4 "gpc_reg_operand" "0"))
1195 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1196 (plus:SI (mult:SI (lshiftrt:SI
1205 [(set_attr "type" "halfmul")])
1207 (define_insn "*machhwu"
1208 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1209 (plus:SI (mult:SI (lshiftrt:SI
1210 (match_operand:SI 1 "gpc_reg_operand" "%r")
1213 (match_operand:SI 2 "gpc_reg_operand" "r")
1215 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1218 [(set_attr "type" "halfmul")])
1220 (define_insn "*maclhwc"
1221 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1222 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1223 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1225 (match_operand:HI 2 "gpc_reg_operand" "r")))
1226 (match_operand:SI 4 "gpc_reg_operand" "0"))
1228 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1229 (plus:SI (mult:SI (sign_extend:SI
1236 [(set_attr "type" "halfmul")])
1238 (define_insn "*maclhw"
1239 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1240 (plus:SI (mult:SI (sign_extend:SI
1241 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1243 (match_operand:HI 2 "gpc_reg_operand" "r")))
1244 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1247 [(set_attr "type" "halfmul")])
1249 (define_insn "*maclhwuc"
1250 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1251 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1252 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1254 (match_operand:HI 2 "gpc_reg_operand" "r")))
1255 (match_operand:SI 4 "gpc_reg_operand" "0"))
1257 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1258 (plus:SI (mult:SI (zero_extend:SI
1265 [(set_attr "type" "halfmul")])
1267 (define_insn "*maclhwu"
1268 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1269 (plus:SI (mult:SI (zero_extend:SI
1270 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1272 (match_operand:HI 2 "gpc_reg_operand" "r")))
1273 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1276 [(set_attr "type" "halfmul")])
1278 (define_insn "*nmacchwc"
1279 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1280 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1281 (mult:SI (ashiftrt:SI
1282 (match_operand:SI 2 "gpc_reg_operand" "r")
1285 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1287 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1288 (minus:SI (match_dup 4)
1289 (mult:SI (ashiftrt:SI
1296 [(set_attr "type" "halfmul")])
1298 (define_insn "*nmacchw"
1299 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1300 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1301 (mult:SI (ashiftrt:SI
1302 (match_operand:SI 2 "gpc_reg_operand" "r")
1305 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1308 [(set_attr "type" "halfmul")])
1310 (define_insn "*nmachhwc"
1311 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1312 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1313 (mult:SI (ashiftrt:SI
1314 (match_operand:SI 1 "gpc_reg_operand" "%r")
1317 (match_operand:SI 2 "gpc_reg_operand" "r")
1320 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1321 (minus:SI (match_dup 4)
1322 (mult:SI (ashiftrt:SI
1330 [(set_attr "type" "halfmul")])
1332 (define_insn "*nmachhw"
1333 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1334 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1335 (mult:SI (ashiftrt:SI
1336 (match_operand:SI 1 "gpc_reg_operand" "%r")
1339 (match_operand:SI 2 "gpc_reg_operand" "r")
1343 [(set_attr "type" "halfmul")])
1345 (define_insn "*nmaclhwc"
1346 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1347 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1348 (mult:SI (sign_extend:SI
1349 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1351 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1353 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1354 (minus:SI (match_dup 4)
1355 (mult:SI (sign_extend:SI
1361 [(set_attr "type" "halfmul")])
1363 (define_insn "*nmaclhw"
1364 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1365 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1366 (mult:SI (sign_extend:SI
1367 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1369 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1372 [(set_attr "type" "halfmul")])
1374 (define_insn "*mulchwc"
1375 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1376 (compare:CC (mult:SI (ashiftrt:SI
1377 (match_operand:SI 2 "gpc_reg_operand" "r")
1380 (match_operand:HI 1 "gpc_reg_operand" "r")))
1382 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1383 (mult:SI (ashiftrt:SI
1390 [(set_attr "type" "halfmul")])
1392 (define_insn "*mulchw"
1393 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1394 (mult:SI (ashiftrt:SI
1395 (match_operand:SI 2 "gpc_reg_operand" "r")
1398 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1401 [(set_attr "type" "halfmul")])
1403 (define_insn "*mulchwuc"
1404 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1405 (compare:CC (mult:SI (lshiftrt:SI
1406 (match_operand:SI 2 "gpc_reg_operand" "r")
1409 (match_operand:HI 1 "gpc_reg_operand" "r")))
1411 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1412 (mult:SI (lshiftrt:SI
1419 [(set_attr "type" "halfmul")])
1421 (define_insn "*mulchwu"
1422 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1423 (mult:SI (lshiftrt:SI
1424 (match_operand:SI 2 "gpc_reg_operand" "r")
1427 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1430 [(set_attr "type" "halfmul")])
1432 (define_insn "*mulhhwc"
1433 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1434 (compare:CC (mult:SI (ashiftrt:SI
1435 (match_operand:SI 1 "gpc_reg_operand" "%r")
1438 (match_operand:SI 2 "gpc_reg_operand" "r")
1441 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1442 (mult:SI (ashiftrt:SI
1450 [(set_attr "type" "halfmul")])
1452 (define_insn "*mulhhw"
1453 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1454 (mult:SI (ashiftrt:SI
1455 (match_operand:SI 1 "gpc_reg_operand" "%r")
1458 (match_operand:SI 2 "gpc_reg_operand" "r")
1462 [(set_attr "type" "halfmul")])
1464 (define_insn "*mulhhwuc"
1465 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1466 (compare:CC (mult:SI (lshiftrt:SI
1467 (match_operand:SI 1 "gpc_reg_operand" "%r")
1470 (match_operand:SI 2 "gpc_reg_operand" "r")
1473 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1474 (mult:SI (lshiftrt:SI
1482 [(set_attr "type" "halfmul")])
1484 (define_insn "*mulhhwu"
1485 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1486 (mult:SI (lshiftrt:SI
1487 (match_operand:SI 1 "gpc_reg_operand" "%r")
1490 (match_operand:SI 2 "gpc_reg_operand" "r")
1494 [(set_attr "type" "halfmul")])
1496 (define_insn "*mullhwc"
1497 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1498 (compare:CC (mult:SI (sign_extend:SI
1499 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1501 (match_operand:HI 2 "gpc_reg_operand" "r")))
1503 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1504 (mult:SI (sign_extend:SI
1510 [(set_attr "type" "halfmul")])
1512 (define_insn "*mullhw"
1513 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1514 (mult:SI (sign_extend:SI
1515 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1517 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1520 [(set_attr "type" "halfmul")])
1522 (define_insn "*mullhwuc"
1523 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1524 (compare:CC (mult:SI (zero_extend:SI
1525 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1527 (match_operand:HI 2 "gpc_reg_operand" "r")))
1529 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1530 (mult:SI (zero_extend:SI
1536 [(set_attr "type" "halfmul")])
1538 (define_insn "*mullhwu"
1539 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1540 (mult:SI (zero_extend:SI
1541 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1543 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1546 [(set_attr "type" "halfmul")])
1548 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1549 (define_insn "dlmzb"
1550 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1551 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1552 (match_operand:SI 2 "gpc_reg_operand" "r")]
1554 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1555 (unspec:SI [(match_dup 1)
1561 (define_expand "strlensi"
1562 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1563 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1564 (match_operand:QI 2 "const_int_operand" "")
1565 (match_operand 3 "const_int_operand" "")]
1566 UNSPEC_DLMZB_STRLEN))
1567 (clobber (match_scratch:CC 4 "=x"))]
1568 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1570 rtx result = operands[0];
1571 rtx src = operands[1];
1572 rtx search_char = operands[2];
1573 rtx align = operands[3];
1574 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1575 rtx loop_label, end_label, mem, cr0, cond;
1576 if (search_char != const0_rtx
1577 || GET_CODE (align) != CONST_INT
1578 || INTVAL (align) < 8)
1580 word1 = gen_reg_rtx (SImode);
1581 word2 = gen_reg_rtx (SImode);
1582 scratch_dlmzb = gen_reg_rtx (SImode);
1583 scratch_string = gen_reg_rtx (Pmode);
1584 loop_label = gen_label_rtx ();
1585 end_label = gen_label_rtx ();
1586 addr = force_reg (Pmode, XEXP (src, 0));
1587 emit_move_insn (scratch_string, addr);
1588 emit_label (loop_label);
1589 mem = change_address (src, SImode, scratch_string);
1590 emit_move_insn (word1, mem);
1591 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1592 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1593 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1594 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1595 emit_jump_insn (gen_rtx_SET (pc_rtx,
1596 gen_rtx_IF_THEN_ELSE (VOIDmode,
1602 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1603 emit_jump_insn (gen_rtx_SET (pc_rtx,
1604 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1606 emit_label (end_label);
1607 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1608 emit_insn (gen_subsi3 (result, scratch_string, addr));
1609 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1613 ;; Fixed-point arithmetic insns.
1615 (define_expand "add<mode>3"
1616 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1617 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1618 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1621 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1623 rtx lo0 = gen_lowpart (SImode, operands[0]);
1624 rtx lo1 = gen_lowpart (SImode, operands[1]);
1625 rtx lo2 = gen_lowpart (SImode, operands[2]);
1626 rtx hi0 = gen_highpart (SImode, operands[0]);
1627 rtx hi1 = gen_highpart (SImode, operands[1]);
1628 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1630 if (!reg_or_short_operand (lo2, SImode))
1631 lo2 = force_reg (SImode, lo2);
1632 if (!adde_operand (hi2, SImode))
1633 hi2 = force_reg (SImode, hi2);
1635 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1636 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1640 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1642 rtx tmp = ((!can_create_pseudo_p ()
1643 || rtx_equal_p (operands[0], operands[1]))
1644 ? operands[0] : gen_reg_rtx (<MODE>mode));
1646 HOST_WIDE_INT val = INTVAL (operands[2]);
1647 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1648 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1650 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1653 /* The ordering here is important for the prolog expander.
1654 When space is allocated from the stack, adding 'low' first may
1655 produce a temporary deallocation (which would be bad). */
1656 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1657 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1662 (define_insn "*add<mode>3"
1663 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1664 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1665 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1671 [(set_attr "type" "add")])
1673 (define_insn "addsi3_high"
1674 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1675 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1676 (high:SI (match_operand 2 "" ""))))]
1677 "TARGET_MACHO && !TARGET_64BIT"
1678 "addis %0,%1,ha16(%2)"
1679 [(set_attr "type" "add")])
1681 (define_insn_and_split "*add<mode>3_dot"
1682 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1683 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1684 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1686 (clobber (match_scratch:GPR 0 "=r,r"))]
1687 "<MODE>mode == Pmode"
1691 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1693 (plus:GPR (match_dup 1)
1696 (compare:CC (match_dup 0)
1699 [(set_attr "type" "add")
1700 (set_attr "dot" "yes")
1701 (set_attr "length" "4,8")])
1703 (define_insn_and_split "*add<mode>3_dot2"
1704 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1705 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1706 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1708 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1709 (plus:GPR (match_dup 1)
1711 "<MODE>mode == Pmode"
1715 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1717 (plus:GPR (match_dup 1)
1720 (compare:CC (match_dup 0)
1723 [(set_attr "type" "add")
1724 (set_attr "dot" "yes")
1725 (set_attr "length" "4,8")])
1727 (define_insn_and_split "*add<mode>3_imm_dot"
1728 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1729 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1730 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1732 (clobber (match_scratch:GPR 0 "=r,r"))
1733 (clobber (reg:GPR CA_REGNO))]
1734 "<MODE>mode == Pmode"
1738 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1740 (plus:GPR (match_dup 1)
1743 (compare:CC (match_dup 0)
1746 [(set_attr "type" "add")
1747 (set_attr "dot" "yes")
1748 (set_attr "length" "4,8")])
1750 (define_insn_and_split "*add<mode>3_imm_dot2"
1751 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1752 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1753 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1755 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1756 (plus:GPR (match_dup 1)
1758 (clobber (reg:GPR CA_REGNO))]
1759 "<MODE>mode == Pmode"
1763 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1765 (plus:GPR (match_dup 1)
1768 (compare:CC (match_dup 0)
1771 [(set_attr "type" "add")
1772 (set_attr "dot" "yes")
1773 (set_attr "length" "4,8")])
1775 ;; Split an add that we can't do in one insn into two insns, each of which
1776 ;; does one 16-bit part. This is used by combine. Note that the low-order
1777 ;; add should be last in case the result gets used in an address.
1780 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1781 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1782 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1784 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1785 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1787 HOST_WIDE_INT val = INTVAL (operands[2]);
1788 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1789 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1791 operands[4] = GEN_INT (low);
1792 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1793 operands[3] = GEN_INT (rest);
1794 else if (can_create_pseudo_p ())
1796 operands[3] = gen_reg_rtx (DImode);
1797 emit_move_insn (operands[3], operands[2]);
1798 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1806 (define_insn "add<mode>3_carry"
1807 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1808 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1809 (match_operand:P 2 "reg_or_short_operand" "rI")))
1810 (set (reg:P CA_REGNO)
1811 (ltu:P (plus:P (match_dup 1)
1816 [(set_attr "type" "add")])
1818 (define_insn "*add<mode>3_imm_carry_pos"
1819 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1820 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1821 (match_operand:P 2 "short_cint_operand" "n")))
1822 (set (reg:P CA_REGNO)
1823 (geu:P (match_dup 1)
1824 (match_operand:P 3 "const_int_operand" "n")))]
1825 "INTVAL (operands[2]) > 0
1826 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1828 [(set_attr "type" "add")])
1830 (define_insn "*add<mode>3_imm_carry_0"
1831 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1832 (match_operand:P 1 "gpc_reg_operand" "r"))
1833 (set (reg:P CA_REGNO)
1837 [(set_attr "type" "add")])
1839 (define_insn "*add<mode>3_imm_carry_m1"
1840 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1841 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1843 (set (reg:P CA_REGNO)
1848 [(set_attr "type" "add")])
1850 (define_insn "*add<mode>3_imm_carry_neg"
1851 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1852 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1853 (match_operand:P 2 "short_cint_operand" "n")))
1854 (set (reg:P CA_REGNO)
1855 (gtu:P (match_dup 1)
1856 (match_operand:P 3 "const_int_operand" "n")))]
1857 "INTVAL (operands[2]) < 0
1858 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1860 [(set_attr "type" "add")])
1863 (define_expand "add<mode>3_carry_in"
1865 (set (match_operand:GPR 0 "gpc_reg_operand")
1866 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1867 (match_operand:GPR 2 "adde_operand"))
1868 (reg:GPR CA_REGNO)))
1869 (clobber (reg:GPR CA_REGNO))])]
1872 if (operands[2] == const0_rtx)
1874 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1877 if (operands[2] == constm1_rtx)
1879 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1884 (define_insn "*add<mode>3_carry_in_internal"
1885 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1886 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1887 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1888 (reg:GPR CA_REGNO)))
1889 (clobber (reg:GPR CA_REGNO))]
1892 [(set_attr "type" "add")])
1894 (define_insn "add<mode>3_carry_in_0"
1895 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1896 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1897 (reg:GPR CA_REGNO)))
1898 (clobber (reg:GPR CA_REGNO))]
1901 [(set_attr "type" "add")])
1903 (define_insn "add<mode>3_carry_in_m1"
1904 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1905 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1908 (clobber (reg:GPR CA_REGNO))]
1911 [(set_attr "type" "add")])
1914 (define_expand "one_cmpl<mode>2"
1915 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1916 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1919 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1921 rs6000_split_logical (operands, NOT, false, false, false);
1926 (define_insn "*one_cmpl<mode>2"
1927 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1928 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1932 (define_insn_and_split "*one_cmpl<mode>2_dot"
1933 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1934 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1936 (clobber (match_scratch:GPR 0 "=r,r"))]
1937 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1941 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1943 (not:GPR (match_dup 1)))
1945 (compare:CC (match_dup 0)
1948 [(set_attr "type" "logical")
1949 (set_attr "dot" "yes")
1950 (set_attr "length" "4,8")])
1952 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1953 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1954 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1956 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1957 (not:GPR (match_dup 1)))]
1958 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1962 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1964 (not:GPR (match_dup 1)))
1966 (compare:CC (match_dup 0)
1969 [(set_attr "type" "logical")
1970 (set_attr "dot" "yes")
1971 (set_attr "length" "4,8")])
1974 (define_expand "sub<mode>3"
1975 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1976 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1977 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1980 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1982 rtx lo0 = gen_lowpart (SImode, operands[0]);
1983 rtx lo1 = gen_lowpart (SImode, operands[1]);
1984 rtx lo2 = gen_lowpart (SImode, operands[2]);
1985 rtx hi0 = gen_highpart (SImode, operands[0]);
1986 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1987 rtx hi2 = gen_highpart (SImode, operands[2]);
1989 if (!reg_or_short_operand (lo1, SImode))
1990 lo1 = force_reg (SImode, lo1);
1991 if (!adde_operand (hi1, SImode))
1992 hi1 = force_reg (SImode, hi1);
1994 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1995 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1999 if (short_cint_operand (operands[1], <MODE>mode))
2001 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2006 (define_insn "*subf<mode>3"
2007 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2008 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2009 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2012 [(set_attr "type" "add")])
2014 (define_insn_and_split "*subf<mode>3_dot"
2015 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2016 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2017 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2019 (clobber (match_scratch:GPR 0 "=r,r"))]
2020 "<MODE>mode == Pmode"
2024 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2026 (minus:GPR (match_dup 2)
2029 (compare:CC (match_dup 0)
2032 [(set_attr "type" "add")
2033 (set_attr "dot" "yes")
2034 (set_attr "length" "4,8")])
2036 (define_insn_and_split "*subf<mode>3_dot2"
2037 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2038 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2039 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2041 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2042 (minus:GPR (match_dup 2)
2044 "<MODE>mode == Pmode"
2048 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2050 (minus:GPR (match_dup 2)
2053 (compare:CC (match_dup 0)
2056 [(set_attr "type" "add")
2057 (set_attr "dot" "yes")
2058 (set_attr "length" "4,8")])
2060 (define_insn "subf<mode>3_imm"
2061 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2062 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2063 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2064 (clobber (reg:GPR CA_REGNO))]
2067 [(set_attr "type" "add")])
2069 (define_insn_and_split "subf<mode>3_carry_dot2"
2070 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2071 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2072 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2074 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2075 (minus:P (match_dup 2)
2077 (set (reg:P CA_REGNO)
2078 (leu:P (match_dup 1)
2080 "<MODE>mode == Pmode"
2084 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2085 [(parallel [(set (match_dup 0)
2086 (minus:P (match_dup 2)
2088 (set (reg:P CA_REGNO)
2089 (leu:P (match_dup 1)
2092 (compare:CC (match_dup 0)
2095 [(set_attr "type" "add")
2096 (set_attr "dot" "yes")
2097 (set_attr "length" "4,8")])
2099 (define_insn "subf<mode>3_carry"
2100 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2101 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2102 (match_operand:P 1 "gpc_reg_operand" "r")))
2103 (set (reg:P CA_REGNO)
2104 (leu:P (match_dup 1)
2108 [(set_attr "type" "add")])
2110 (define_insn "*subf<mode>3_imm_carry_0"
2111 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2112 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2113 (set (reg:P CA_REGNO)
2118 [(set_attr "type" "add")])
2120 (define_insn "*subf<mode>3_imm_carry_m1"
2121 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2122 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2123 (set (reg:P CA_REGNO)
2127 [(set_attr "type" "add")])
2130 (define_expand "subf<mode>3_carry_in"
2132 (set (match_operand:GPR 0 "gpc_reg_operand")
2133 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2135 (match_operand:GPR 2 "adde_operand")))
2136 (clobber (reg:GPR CA_REGNO))])]
2139 if (operands[2] == const0_rtx)
2141 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2144 if (operands[2] == constm1_rtx)
2146 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2151 (define_insn "*subf<mode>3_carry_in_internal"
2152 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2153 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2155 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2156 (clobber (reg:GPR CA_REGNO))]
2159 [(set_attr "type" "add")])
2161 (define_insn "subf<mode>3_carry_in_0"
2162 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2163 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2164 (reg:GPR CA_REGNO)))
2165 (clobber (reg:GPR CA_REGNO))]
2168 [(set_attr "type" "add")])
2170 (define_insn "subf<mode>3_carry_in_m1"
2171 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2172 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2173 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2175 (clobber (reg:GPR CA_REGNO))]
2178 [(set_attr "type" "add")])
2180 (define_insn "subf<mode>3_carry_in_xx"
2181 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2182 (plus:GPR (reg:GPR CA_REGNO)
2184 (clobber (reg:GPR CA_REGNO))]
2187 [(set_attr "type" "add")])
2190 (define_insn "neg<mode>2"
2191 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2192 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2195 [(set_attr "type" "add")])
2197 (define_insn_and_split "*neg<mode>2_dot"
2198 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2199 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2201 (clobber (match_scratch:GPR 0 "=r,r"))]
2202 "<MODE>mode == Pmode"
2206 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2208 (neg:GPR (match_dup 1)))
2210 (compare:CC (match_dup 0)
2213 [(set_attr "type" "add")
2214 (set_attr "dot" "yes")
2215 (set_attr "length" "4,8")])
2217 (define_insn_and_split "*neg<mode>2_dot2"
2218 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2219 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2221 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2222 (neg:GPR (match_dup 1)))]
2223 "<MODE>mode == Pmode"
2227 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2229 (neg:GPR (match_dup 1)))
2231 (compare:CC (match_dup 0)
2234 [(set_attr "type" "add")
2235 (set_attr "dot" "yes")
2236 (set_attr "length" "4,8")])
2239 (define_insn "clz<mode>2"
2240 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2241 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2244 [(set_attr "type" "cntlz")])
2246 (define_expand "ctz<mode>2"
2247 [(set (match_operand:GPR 0 "gpc_reg_operand")
2248 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2253 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2257 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2258 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2259 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2263 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2264 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2265 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2266 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2270 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2271 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2272 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2273 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2279 (define_insn "ctz<mode>2_hw"
2280 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2281 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2284 [(set_attr "type" "cntlz")])
2286 (define_expand "ffs<mode>2"
2287 [(set (match_operand:GPR 0 "gpc_reg_operand")
2288 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2291 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2292 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2293 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2294 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2295 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2296 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2297 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2302 (define_expand "popcount<mode>2"
2303 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2304 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2305 "TARGET_POPCNTB || TARGET_POPCNTD"
2307 rs6000_emit_popcount (operands[0], operands[1]);
2311 (define_insn "popcntb<mode>2"
2312 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2313 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2317 [(set_attr "type" "popcnt")])
2319 (define_insn "popcntd<mode>2"
2320 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2321 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2324 [(set_attr "type" "popcnt")])
2327 (define_expand "parity<mode>2"
2328 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2329 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2332 rs6000_emit_parity (operands[0], operands[1]);
2336 (define_insn "parity<mode>2_cmpb"
2337 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2338 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2339 "TARGET_CMPB && TARGET_POPCNTB"
2341 [(set_attr "type" "popcnt")])
2343 (define_insn "cmpb<mode>3"
2344 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2345 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2346 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2349 [(set_attr "type" "cmp")])
2351 ;; Since the hardware zeros the upper part of the register, save generating the
2352 ;; AND immediate if we are converting to unsigned
2353 (define_insn "*bswaphi2_extenddi"
2354 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2356 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2359 [(set_attr "length" "4")
2360 (set_attr "type" "load")])
2362 (define_insn "*bswaphi2_extendsi"
2363 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2365 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2368 [(set_attr "length" "4")
2369 (set_attr "type" "load")])
2371 (define_expand "bswaphi2"
2372 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2374 (match_operand:HI 1 "reg_or_mem_operand" "")))
2375 (clobber (match_scratch:SI 2 ""))])]
2378 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2379 operands[1] = force_reg (HImode, operands[1]);
2382 (define_insn "bswaphi2_internal"
2383 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2385 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2386 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2392 [(set_attr "length" "4,4,12")
2393 (set_attr "type" "load,store,*")])
2396 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2397 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2398 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2401 (and:SI (lshiftrt:SI (match_dup 4)
2405 (and:SI (ashift:SI (match_dup 4)
2407 (const_int 65280))) ;; 0xff00
2409 (ior:SI (match_dup 3)
2413 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2414 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2417 (define_insn "*bswapsi2_extenddi"
2418 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2420 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2423 [(set_attr "length" "4")
2424 (set_attr "type" "load")])
2426 (define_expand "bswapsi2"
2427 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2429 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2432 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2433 operands[1] = force_reg (SImode, operands[1]);
2436 (define_insn "*bswapsi2_internal"
2437 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2439 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2445 [(set_attr "length" "4,4,12")
2446 (set_attr "type" "load,store,*")])
2448 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2449 ;; zero_extract insns do not change for -mlittle.
2451 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2452 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2454 [(set (match_dup 0) ; DABC
2455 (rotate:SI (match_dup 1)
2457 (set (match_dup 0) ; DCBC
2458 (ior:SI (and:SI (ashift:SI (match_dup 1)
2460 (const_int 16711680))
2461 (and:SI (match_dup 0)
2462 (const_int -16711681))))
2463 (set (match_dup 0) ; DCBA
2464 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2467 (and:SI (match_dup 0)
2473 (define_expand "bswapdi2"
2474 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2476 (match_operand:DI 1 "reg_or_mem_operand" "")))
2477 (clobber (match_scratch:DI 2 ""))
2478 (clobber (match_scratch:DI 3 ""))])]
2481 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2482 operands[1] = force_reg (DImode, operands[1]);
2484 if (!TARGET_POWERPC64)
2486 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2487 that uses 64-bit registers needs the same scratch registers as 64-bit
2489 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2494 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2495 (define_insn "*bswapdi2_ldbrx"
2496 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2497 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2498 (clobber (match_scratch:DI 2 "=X,X,&r"))
2499 (clobber (match_scratch:DI 3 "=X,X,&r"))]
2500 "TARGET_POWERPC64 && TARGET_LDBRX
2501 && (REG_P (operands[0]) || REG_P (operands[1]))"
2506 [(set_attr "length" "4,4,36")
2507 (set_attr "type" "load,store,*")])
2509 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2510 (define_insn "*bswapdi2_64bit"
2511 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2512 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2513 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2514 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2515 "TARGET_POWERPC64 && !TARGET_LDBRX
2516 && (REG_P (operands[0]) || REG_P (operands[1]))
2517 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2518 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2520 [(set_attr "length" "16,12,36")])
2523 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2524 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2525 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2526 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2527 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2531 rtx dest = operands[0];
2532 rtx src = operands[1];
2533 rtx op2 = operands[2];
2534 rtx op3 = operands[3];
2535 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2536 BYTES_BIG_ENDIAN ? 4 : 0);
2537 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2538 BYTES_BIG_ENDIAN ? 4 : 0);
2544 addr1 = XEXP (src, 0);
2545 if (GET_CODE (addr1) == PLUS)
2547 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2548 if (TARGET_AVOID_XFORM)
2550 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2554 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2556 else if (TARGET_AVOID_XFORM)
2558 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2563 emit_move_insn (op2, GEN_INT (4));
2564 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2567 word1 = change_address (src, SImode, addr1);
2568 word2 = change_address (src, SImode, addr2);
2570 if (BYTES_BIG_ENDIAN)
2572 emit_insn (gen_bswapsi2 (op3_32, word2));
2573 emit_insn (gen_bswapsi2 (dest_32, word1));
2577 emit_insn (gen_bswapsi2 (op3_32, word1));
2578 emit_insn (gen_bswapsi2 (dest_32, word2));
2581 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2582 emit_insn (gen_iordi3 (dest, dest, op3));
2587 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2588 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2589 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2590 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2591 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2595 rtx dest = operands[0];
2596 rtx src = operands[1];
2597 rtx op2 = operands[2];
2598 rtx op3 = operands[3];
2599 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2600 BYTES_BIG_ENDIAN ? 4 : 0);
2601 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2602 BYTES_BIG_ENDIAN ? 4 : 0);
2608 addr1 = XEXP (dest, 0);
2609 if (GET_CODE (addr1) == PLUS)
2611 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2612 if (TARGET_AVOID_XFORM)
2614 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2618 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2620 else if (TARGET_AVOID_XFORM)
2622 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2627 emit_move_insn (op2, GEN_INT (4));
2628 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2631 word1 = change_address (dest, SImode, addr1);
2632 word2 = change_address (dest, SImode, addr2);
2634 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2636 if (BYTES_BIG_ENDIAN)
2638 emit_insn (gen_bswapsi2 (word1, src_si));
2639 emit_insn (gen_bswapsi2 (word2, op3_si));
2643 emit_insn (gen_bswapsi2 (word2, src_si));
2644 emit_insn (gen_bswapsi2 (word1, op3_si));
2650 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2651 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2652 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2653 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2654 "TARGET_POWERPC64 && reload_completed"
2658 rtx dest = operands[0];
2659 rtx src = operands[1];
2660 rtx op2 = operands[2];
2661 rtx op3 = operands[3];
2662 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2663 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2664 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2665 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2666 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2668 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2669 emit_insn (gen_bswapsi2 (dest_si, src_si));
2670 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2671 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2672 emit_insn (gen_iordi3 (dest, dest, op3));
2676 (define_insn "bswapdi2_32bit"
2677 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2678 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2679 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2680 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2682 [(set_attr "length" "16,12,36")])
2685 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2686 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2687 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2688 "!TARGET_POWERPC64 && reload_completed"
2692 rtx dest = operands[0];
2693 rtx src = operands[1];
2694 rtx op2 = operands[2];
2695 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2696 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2702 addr1 = XEXP (src, 0);
2703 if (GET_CODE (addr1) == PLUS)
2705 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2706 if (TARGET_AVOID_XFORM
2707 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2709 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2713 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2715 else if (TARGET_AVOID_XFORM
2716 || REGNO (addr1) == REGNO (dest2))
2718 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2723 emit_move_insn (op2, GEN_INT (4));
2724 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2727 word1 = change_address (src, SImode, addr1);
2728 word2 = change_address (src, SImode, addr2);
2730 emit_insn (gen_bswapsi2 (dest2, word1));
2731 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2732 thus allowing us to omit an early clobber on the output. */
2733 emit_insn (gen_bswapsi2 (dest1, word2));
2738 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2739 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2740 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2741 "!TARGET_POWERPC64 && reload_completed"
2745 rtx dest = operands[0];
2746 rtx src = operands[1];
2747 rtx op2 = operands[2];
2748 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2749 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2755 addr1 = XEXP (dest, 0);
2756 if (GET_CODE (addr1) == PLUS)
2758 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2759 if (TARGET_AVOID_XFORM)
2761 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2765 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2767 else if (TARGET_AVOID_XFORM)
2769 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2774 emit_move_insn (op2, GEN_INT (4));
2775 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2778 word1 = change_address (dest, SImode, addr1);
2779 word2 = change_address (dest, SImode, addr2);
2781 emit_insn (gen_bswapsi2 (word2, src1));
2782 emit_insn (gen_bswapsi2 (word1, src2));
2787 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2788 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2789 (clobber (match_operand:SI 2 "" ""))]
2790 "!TARGET_POWERPC64 && reload_completed"
2794 rtx dest = operands[0];
2795 rtx src = operands[1];
2796 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2797 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2798 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2799 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2801 emit_insn (gen_bswapsi2 (dest1, src2));
2802 emit_insn (gen_bswapsi2 (dest2, src1));
2807 (define_insn "mul<mode>3"
2808 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2809 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2810 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2815 [(set_attr "type" "mul")
2817 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2819 (match_operand:GPR 2 "short_cint_operand" "")
2820 (const_string "16")]
2821 (const_string "<bits>")))])
2823 (define_insn_and_split "*mul<mode>3_dot"
2824 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2825 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2826 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2828 (clobber (match_scratch:GPR 0 "=r,r"))]
2829 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2833 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2835 (mult:GPR (match_dup 1)
2838 (compare:CC (match_dup 0)
2841 [(set_attr "type" "mul")
2842 (set_attr "size" "<bits>")
2843 (set_attr "dot" "yes")
2844 (set_attr "length" "4,8")])
2846 (define_insn_and_split "*mul<mode>3_dot2"
2847 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2848 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2849 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2851 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2852 (mult:GPR (match_dup 1)
2854 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2858 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2860 (mult:GPR (match_dup 1)
2863 (compare:CC (match_dup 0)
2866 [(set_attr "type" "mul")
2867 (set_attr "size" "<bits>")
2868 (set_attr "dot" "yes")
2869 (set_attr "length" "4,8")])
2872 (define_expand "<su>mul<mode>3_highpart"
2873 [(set (match_operand:GPR 0 "gpc_reg_operand")
2875 (mult:<DMODE> (any_extend:<DMODE>
2876 (match_operand:GPR 1 "gpc_reg_operand"))
2878 (match_operand:GPR 2 "gpc_reg_operand")))
2882 if (<MODE>mode == SImode && TARGET_POWERPC64)
2884 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2889 if (!WORDS_BIG_ENDIAN)
2891 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2897 (define_insn "*<su>mul<mode>3_highpart"
2898 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2900 (mult:<DMODE> (any_extend:<DMODE>
2901 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2903 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2905 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2906 "mulh<wd><u> %0,%1,%2"
2907 [(set_attr "type" "mul")
2908 (set_attr "size" "<bits>")])
2910 (define_insn "<su>mulsi3_highpart_le"
2911 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2913 (mult:DI (any_extend:DI
2914 (match_operand:SI 1 "gpc_reg_operand" "r"))
2916 (match_operand:SI 2 "gpc_reg_operand" "r")))
2918 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2920 [(set_attr "type" "mul")])
2922 (define_insn "<su>muldi3_highpart_le"
2923 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2925 (mult:TI (any_extend:TI
2926 (match_operand:DI 1 "gpc_reg_operand" "r"))
2928 (match_operand:DI 2 "gpc_reg_operand" "r")))
2930 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2932 [(set_attr "type" "mul")
2933 (set_attr "size" "64")])
2935 (define_insn "<su>mulsi3_highpart_64"
2936 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2939 (mult:DI (any_extend:DI
2940 (match_operand:SI 1 "gpc_reg_operand" "r"))
2942 (match_operand:SI 2 "gpc_reg_operand" "r")))
2946 [(set_attr "type" "mul")])
2948 (define_expand "<u>mul<mode><dmode>3"
2949 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2950 (mult:<DMODE> (any_extend:<DMODE>
2951 (match_operand:GPR 1 "gpc_reg_operand"))
2953 (match_operand:GPR 2 "gpc_reg_operand"))))]
2954 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2956 rtx l = gen_reg_rtx (<MODE>mode);
2957 rtx h = gen_reg_rtx (<MODE>mode);
2958 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2959 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2960 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2961 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2965 (define_insn "*maddld4"
2966 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2967 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2968 (match_operand:DI 2 "gpc_reg_operand" "r"))
2969 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2971 "maddld %0,%1,%2,%3"
2972 [(set_attr "type" "mul")])
2974 (define_insn "udiv<mode>3"
2975 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2976 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2977 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2980 [(set_attr "type" "div")
2981 (set_attr "size" "<bits>")])
2984 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2985 ;; modulus. If it isn't a power of two, force operands into register and do
2987 (define_expand "div<mode>3"
2988 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2989 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2990 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2993 if (CONST_INT_P (operands[2])
2994 && INTVAL (operands[2]) > 0
2995 && exact_log2 (INTVAL (operands[2])) >= 0)
2997 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3001 operands[2] = force_reg (<MODE>mode, operands[2]);
3004 (define_insn "*div<mode>3"
3005 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3006 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3007 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3010 [(set_attr "type" "div")
3011 (set_attr "size" "<bits>")])
3013 (define_insn "div<mode>3_sra"
3014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3015 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3016 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3017 (clobber (reg:GPR CA_REGNO))]
3019 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3020 [(set_attr "type" "two")
3021 (set_attr "length" "8")])
3023 (define_insn_and_split "*div<mode>3_sra_dot"
3024 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3025 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3026 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3028 (clobber (match_scratch:GPR 0 "=r,r"))
3029 (clobber (reg:GPR CA_REGNO))]
3030 "<MODE>mode == Pmode"
3032 sra<wd>i %0,%1,%p2\;addze. %0,%0
3034 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3035 [(parallel [(set (match_dup 0)
3036 (div:GPR (match_dup 1)
3038 (clobber (reg:GPR CA_REGNO))])
3040 (compare:CC (match_dup 0)
3043 [(set_attr "type" "two")
3044 (set_attr "length" "8,12")
3045 (set_attr "cell_micro" "not")])
3047 (define_insn_and_split "*div<mode>3_sra_dot2"
3048 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3049 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3050 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3052 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3053 (div:GPR (match_dup 1)
3055 (clobber (reg:GPR CA_REGNO))]
3056 "<MODE>mode == Pmode"
3058 sra<wd>i %0,%1,%p2\;addze. %0,%0
3060 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3061 [(parallel [(set (match_dup 0)
3062 (div:GPR (match_dup 1)
3064 (clobber (reg:GPR CA_REGNO))])
3066 (compare:CC (match_dup 0)
3069 [(set_attr "type" "two")
3070 (set_attr "length" "8,12")
3071 (set_attr "cell_micro" "not")])
3073 (define_expand "mod<mode>3"
3074 [(set (match_operand:GPR 0 "gpc_reg_operand")
3075 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3076 (match_operand:GPR 2 "reg_or_cint_operand")))]
3083 if (GET_CODE (operands[2]) != CONST_INT
3084 || INTVAL (operands[2]) <= 0
3085 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3090 operands[2] = force_reg (<MODE>mode, operands[2]);
3094 temp1 = gen_reg_rtx (<MODE>mode);
3095 temp2 = gen_reg_rtx (<MODE>mode);
3097 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3098 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3099 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3104 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3105 ;; mod, prefer putting the result of mod into a different register
3106 (define_insn "*mod<mode>3"
3107 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3108 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3109 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3112 [(set_attr "type" "div")
3113 (set_attr "size" "<bits>")])
3116 (define_insn "umod<mode>3"
3117 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3118 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3119 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3122 [(set_attr "type" "div")
3123 (set_attr "size" "<bits>")])
3125 ;; On machines with modulo support, do a combined div/mod the old fashioned
3126 ;; method, since the multiply/subtract is faster than doing the mod instruction
3130 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3131 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3132 (match_operand:GPR 2 "gpc_reg_operand" "")))
3133 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3134 (mod:GPR (match_dup 1)
3137 && ! reg_mentioned_p (operands[0], operands[1])
3138 && ! reg_mentioned_p (operands[0], operands[2])
3139 && ! reg_mentioned_p (operands[3], operands[1])
3140 && ! reg_mentioned_p (operands[3], operands[2])"
3142 (div:GPR (match_dup 1)
3145 (mult:GPR (match_dup 0)
3148 (minus:GPR (match_dup 1)
3152 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3153 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3154 (match_operand:GPR 2 "gpc_reg_operand" "")))
3155 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3156 (umod:GPR (match_dup 1)
3159 && ! reg_mentioned_p (operands[0], operands[1])
3160 && ! reg_mentioned_p (operands[0], operands[2])
3161 && ! reg_mentioned_p (operands[3], operands[1])
3162 && ! reg_mentioned_p (operands[3], operands[2])"
3164 (div:GPR (match_dup 1)
3167 (mult:GPR (match_dup 0)
3170 (minus:GPR (match_dup 1)
3174 ;; Logical instructions
3175 ;; The logical instructions are mostly combined by using match_operator,
3176 ;; but the plain AND insns are somewhat different because there is no
3177 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3178 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3180 (define_expand "and<mode>3"
3181 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3182 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3183 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3186 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3188 rs6000_split_logical (operands, AND, false, false, false);
3192 if (CONST_INT_P (operands[2]))
3194 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3196 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3200 if (logical_const_operand (operands[2], <MODE>mode)
3201 && rs6000_gen_cell_microcode)
3203 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3207 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3209 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3213 operands[2] = force_reg (<MODE>mode, operands[2]);
3218 (define_insn "and<mode>3_imm"
3219 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3220 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3221 (match_operand:GPR 2 "logical_const_operand" "n")))
3222 (clobber (match_scratch:CC 3 "=x"))]
3223 "rs6000_gen_cell_microcode
3224 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3225 "andi%e2. %0,%1,%u2"
3226 [(set_attr "type" "logical")
3227 (set_attr "dot" "yes")])
3229 (define_insn_and_split "*and<mode>3_imm_dot"
3230 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3231 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3232 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3234 (clobber (match_scratch:GPR 0 "=r,r"))
3235 (clobber (match_scratch:CC 4 "=X,x"))]
3236 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3237 && rs6000_gen_cell_microcode
3238 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3242 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3243 [(parallel [(set (match_dup 0)
3244 (and:GPR (match_dup 1)
3246 (clobber (match_dup 4))])
3248 (compare:CC (match_dup 0)
3251 [(set_attr "type" "logical")
3252 (set_attr "dot" "yes")
3253 (set_attr "length" "4,8")])
3255 (define_insn_and_split "*and<mode>3_imm_dot2"
3256 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3257 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3258 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3260 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3261 (and:GPR (match_dup 1)
3263 (clobber (match_scratch:CC 4 "=X,x"))]
3264 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3265 && rs6000_gen_cell_microcode
3266 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3270 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3271 [(parallel [(set (match_dup 0)
3272 (and:GPR (match_dup 1)
3274 (clobber (match_dup 4))])
3276 (compare:CC (match_dup 0)
3279 [(set_attr "type" "logical")
3280 (set_attr "dot" "yes")
3281 (set_attr "length" "4,8")])
3283 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3284 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3285 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3286 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3288 (clobber (match_scratch:GPR 0 "=r,r"))]
3289 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3290 && rs6000_gen_cell_microcode
3291 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3295 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3297 (and:GPR (match_dup 1)
3300 (compare:CC (match_dup 0)
3303 [(set_attr "type" "logical")
3304 (set_attr "dot" "yes")
3305 (set_attr "length" "4,8")])
3307 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3308 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3309 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3310 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3312 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3313 (and:GPR (match_dup 1)
3315 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3316 && rs6000_gen_cell_microcode
3317 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3321 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3323 (and:GPR (match_dup 1)
3326 (compare:CC (match_dup 0)
3329 [(set_attr "type" "logical")
3330 (set_attr "dot" "yes")
3331 (set_attr "length" "4,8")])
3333 (define_insn "*and<mode>3_imm_dot_shifted"
3334 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3337 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3338 (match_operand:SI 4 "const_int_operand" "n"))
3339 (match_operand:GPR 2 "const_int_operand" "n"))
3341 (clobber (match_scratch:GPR 0 "=r"))]
3342 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3343 << INTVAL (operands[4])),
3345 && (<MODE>mode == Pmode
3346 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3347 && rs6000_gen_cell_microcode"
3349 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3350 return "andi%e2. %0,%1,%u2";
3352 [(set_attr "type" "logical")
3353 (set_attr "dot" "yes")])
3356 (define_insn "and<mode>3_mask"
3357 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3358 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3359 (match_operand:GPR 2 "const_int_operand" "n")))]
3360 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3362 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3364 [(set_attr "type" "shift")])
3366 (define_insn_and_split "*and<mode>3_mask_dot"
3367 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3368 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3369 (match_operand:GPR 2 "const_int_operand" "n,n"))
3371 (clobber (match_scratch:GPR 0 "=r,r"))]
3372 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3373 && rs6000_gen_cell_microcode
3374 && !logical_const_operand (operands[2], <MODE>mode)
3375 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3377 if (which_alternative == 0)
3378 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3382 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3384 (and:GPR (match_dup 1)
3387 (compare:CC (match_dup 0)
3390 [(set_attr "type" "shift")
3391 (set_attr "dot" "yes")
3392 (set_attr "length" "4,8")])
3394 (define_insn_and_split "*and<mode>3_mask_dot2"
3395 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3396 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3397 (match_operand:GPR 2 "const_int_operand" "n,n"))
3399 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3400 (and:GPR (match_dup 1)
3402 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3403 && rs6000_gen_cell_microcode
3404 && !logical_const_operand (operands[2], <MODE>mode)
3405 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3407 if (which_alternative == 0)
3408 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3412 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3414 (and:GPR (match_dup 1)
3417 (compare:CC (match_dup 0)
3420 [(set_attr "type" "shift")
3421 (set_attr "dot" "yes")
3422 (set_attr "length" "4,8")])
3425 (define_insn_and_split "*and<mode>3_2insn"
3426 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3427 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3428 (match_operand:GPR 2 "const_int_operand" "n")))]
3429 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3430 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3431 || (logical_const_operand (operands[2], <MODE>mode)
3432 && rs6000_gen_cell_microcode))"
3437 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3440 [(set_attr "type" "shift")
3441 (set_attr "length" "8")])
3443 (define_insn_and_split "*and<mode>3_2insn_dot"
3444 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3445 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3446 (match_operand:GPR 2 "const_int_operand" "n,n"))
3448 (clobber (match_scratch:GPR 0 "=r,r"))]
3449 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3450 && rs6000_gen_cell_microcode
3451 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3452 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3453 || (logical_const_operand (operands[2], <MODE>mode)
3454 && rs6000_gen_cell_microcode))"
3456 "&& reload_completed"
3459 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3462 [(set_attr "type" "shift")
3463 (set_attr "dot" "yes")
3464 (set_attr "length" "8,12")])
3466 (define_insn_and_split "*and<mode>3_2insn_dot2"
3467 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3468 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3469 (match_operand:GPR 2 "const_int_operand" "n,n"))
3471 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3472 (and:GPR (match_dup 1)
3474 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3475 && rs6000_gen_cell_microcode
3476 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3477 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3478 || (logical_const_operand (operands[2], <MODE>mode)
3479 && rs6000_gen_cell_microcode))"
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 && rs6000_gen_cell_microcode"
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 && rs6000_gen_cell_microcode"
3599 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3603 (compare:CC (match_dup 0)
3606 [(set_attr "type" "logical")
3607 (set_attr "dot" "yes")
3608 (set_attr "length" "4,8")])
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 && rs6000_gen_cell_microcode"
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 && rs6000_gen_cell_microcode"
3654 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3658 (compare:CC (match_dup 0)
3661 [(set_attr "type" "logical")
3662 (set_attr "dot" "yes")
3663 (set_attr "length" "4,8")])
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 && rs6000_gen_cell_microcode"
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 && rs6000_gen_cell_microcode"
3709 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3713 (compare:CC (match_dup 0)
3716 [(set_attr "type" "logical")
3717 (set_attr "dot" "yes")
3718 (set_attr "length" "4,8")])
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_gen_cell_microcode
3756 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3758 if (which_alternative == 0)
3759 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3763 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3765 (and:GPR (match_dup 4)
3768 (compare:CC (match_dup 0)
3771 [(set_attr "type" "shift")
3772 (set_attr "maybe_var_shift" "yes")
3773 (set_attr "dot" "yes")
3774 (set_attr "length" "4,8")])
3776 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3777 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3779 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3780 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3781 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3782 (match_operand:GPR 3 "const_int_operand" "n,n"))
3784 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3785 (and:GPR (match_dup 4)
3787 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3788 && rs6000_gen_cell_microcode
3789 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3791 if (which_alternative == 0)
3792 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3796 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3798 (and:GPR (match_dup 4)
3801 (compare:CC (match_dup 0)
3804 [(set_attr "type" "shift")
3805 (set_attr "maybe_var_shift" "yes")
3806 (set_attr "dot" "yes")
3807 (set_attr "length" "4,8")])
3809 ; Special case for less-than-0. We can do it with just one machine
3810 ; instruction, but the generic optimizers do not realise it is cheap.
3811 (define_insn "*lt0_disi"
3812 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3813 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3816 "rlwinm %0,%1,1,31,31"
3817 [(set_attr "type" "shift")])
3821 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3822 ; both are an AND so are the same precedence).
3823 (define_insn "*rotl<mode>3_insert"
3824 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3825 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3826 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3827 (match_operand:SI 2 "const_int_operand" "n")])
3828 (match_operand:GPR 3 "const_int_operand" "n"))
3829 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3830 (match_operand:GPR 6 "const_int_operand" "n"))))]
3831 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3832 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3834 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3836 [(set_attr "type" "insert")])
3837 ; FIXME: this needs an attr "size", so that the scheduler can see the
3838 ; difference between rlwimi and rldimi. We also might want dot forms,
3839 ; but not for rlwimi on POWER4 and similar processors.
3841 (define_insn "*rotl<mode>3_insert_2"
3842 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3843 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3844 (match_operand:GPR 6 "const_int_operand" "n"))
3845 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3846 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3847 (match_operand:SI 2 "const_int_operand" "n")])
3848 (match_operand:GPR 3 "const_int_operand" "n"))))]
3849 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3850 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3852 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3854 [(set_attr "type" "insert")])
3856 ; There are also some forms without one of the ANDs.
3857 (define_insn "*rotl<mode>3_insert_3"
3858 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3859 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3860 (match_operand:GPR 4 "const_int_operand" "n"))
3861 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3862 (match_operand:SI 2 "const_int_operand" "n"))))]
3863 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3865 if (<MODE>mode == SImode)
3866 return "rlwimi %0,%1,%h2,0,31-%h2";
3868 return "rldimi %0,%1,%H2,0";
3870 [(set_attr "type" "insert")])
3872 (define_insn "*rotl<mode>3_insert_4"
3873 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3874 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3875 (match_operand:GPR 4 "const_int_operand" "n"))
3876 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3877 (match_operand:SI 2 "const_int_operand" "n"))))]
3878 "<MODE>mode == SImode &&
3879 GET_MODE_PRECISION (<MODE>mode)
3880 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3882 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3883 - INTVAL (operands[2]));
3884 if (<MODE>mode == SImode)
3885 return "rlwimi %0,%1,%h2,32-%h2,31";
3887 return "rldimi %0,%1,%H2,64-%H2";
3889 [(set_attr "type" "insert")])
3891 (define_insn "*rotlsi3_insert_5"
3892 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3893 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3894 (match_operand:SI 2 "const_int_operand" "n,n"))
3895 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3896 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3897 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3898 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3899 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3903 [(set_attr "type" "insert")])
3905 (define_insn "*rotldi3_insert_6"
3906 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3907 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3908 (match_operand:DI 2 "const_int_operand" "n"))
3909 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3910 (match_operand:DI 4 "const_int_operand" "n"))))]
3911 "exact_log2 (-UINTVAL (operands[2])) > 0
3912 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3914 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3915 return "rldimi %0,%3,0,%5";
3917 [(set_attr "type" "insert")
3918 (set_attr "size" "64")])
3920 (define_insn "*rotldi3_insert_7"
3921 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3922 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3923 (match_operand:DI 4 "const_int_operand" "n"))
3924 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3925 (match_operand:DI 2 "const_int_operand" "n"))))]
3926 "exact_log2 (-UINTVAL (operands[2])) > 0
3927 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3929 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3930 return "rldimi %0,%3,0,%5";
3932 [(set_attr "type" "insert")
3933 (set_attr "size" "64")])
3936 ; This handles the important case of multiple-precision shifts. There is
3937 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3939 [(set (match_operand:GPR 0 "gpc_reg_operand")
3940 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3941 (match_operand:SI 3 "const_int_operand"))
3942 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3943 (match_operand:SI 4 "const_int_operand"))))]
3944 "can_create_pseudo_p ()
3945 && INTVAL (operands[3]) + INTVAL (operands[4])
3946 >= GET_MODE_PRECISION (<MODE>mode)"
3948 (lshiftrt:GPR (match_dup 2)
3951 (ior:GPR (and:GPR (match_dup 5)
3953 (ashift:GPR (match_dup 1)
3956 unsigned HOST_WIDE_INT mask = 1;
3957 mask = (mask << INTVAL (operands[3])) - 1;
3958 operands[5] = gen_reg_rtx (<MODE>mode);
3959 operands[6] = GEN_INT (mask);
3963 [(set (match_operand:GPR 0 "gpc_reg_operand")
3964 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3965 (match_operand:SI 4 "const_int_operand"))
3966 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3967 (match_operand:SI 3 "const_int_operand"))))]
3968 "can_create_pseudo_p ()
3969 && INTVAL (operands[3]) + INTVAL (operands[4])
3970 >= GET_MODE_PRECISION (<MODE>mode)"
3972 (lshiftrt:GPR (match_dup 2)
3975 (ior:GPR (and:GPR (match_dup 5)
3977 (ashift:GPR (match_dup 1)
3980 unsigned HOST_WIDE_INT mask = 1;
3981 mask = (mask << INTVAL (operands[3])) - 1;
3982 operands[5] = gen_reg_rtx (<MODE>mode);
3983 operands[6] = GEN_INT (mask);
3987 ; Another important case is setting some bits to 1; we can do that with
3988 ; an insert instruction, in many cases.
3989 (define_insn_and_split "*ior<mode>_mask"
3990 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3991 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3992 (match_operand:GPR 2 "const_int_operand" "n")))
3993 (clobber (match_scratch:GPR 3 "=r"))]
3994 "!logical_const_operand (operands[2], <MODE>mode)
3995 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4001 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4004 (and:GPR (match_dup 1)
4008 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4009 if (GET_CODE (operands[3]) == SCRATCH)
4010 operands[3] = gen_reg_rtx (<MODE>mode);
4011 operands[4] = GEN_INT (ne);
4012 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4014 [(set_attr "type" "two")
4015 (set_attr "length" "8")])
4018 ;; Now the simple shifts.
4020 (define_insn "rotl<mode>3"
4021 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4022 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4023 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4025 "rotl<wd>%I2 %0,%1,%<hH>2"
4026 [(set_attr "type" "shift")
4027 (set_attr "maybe_var_shift" "yes")])
4029 (define_insn "*rotlsi3_64"
4030 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4032 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4033 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4035 "rotlw%I2 %0,%1,%h2"
4036 [(set_attr "type" "shift")
4037 (set_attr "maybe_var_shift" "yes")])
4039 (define_insn_and_split "*rotl<mode>3_dot"
4040 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4041 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4042 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4044 (clobber (match_scratch:GPR 0 "=r,r"))]
4045 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4047 rotl<wd>%I2. %0,%1,%<hH>2
4049 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4051 (rotate:GPR (match_dup 1)
4054 (compare:CC (match_dup 0)
4057 [(set_attr "type" "shift")
4058 (set_attr "maybe_var_shift" "yes")
4059 (set_attr "dot" "yes")
4060 (set_attr "length" "4,8")])
4062 (define_insn_and_split "*rotl<mode>3_dot2"
4063 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4064 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4065 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4067 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4068 (rotate:GPR (match_dup 1)
4070 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4072 rotl<wd>%I2. %0,%1,%<hH>2
4074 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4076 (rotate:GPR (match_dup 1)
4079 (compare:CC (match_dup 0)
4082 [(set_attr "type" "shift")
4083 (set_attr "maybe_var_shift" "yes")
4084 (set_attr "dot" "yes")
4085 (set_attr "length" "4,8")])
4088 (define_insn "ashl<mode>3"
4089 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4090 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4091 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4093 "sl<wd>%I2 %0,%1,%<hH>2"
4094 [(set_attr "type" "shift")
4095 (set_attr "maybe_var_shift" "yes")])
4097 (define_insn "*ashlsi3_64"
4098 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4100 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4101 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4104 [(set_attr "type" "shift")
4105 (set_attr "maybe_var_shift" "yes")])
4107 (define_insn_and_split "*ashl<mode>3_dot"
4108 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4109 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4110 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4112 (clobber (match_scratch:GPR 0 "=r,r"))]
4113 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4115 sl<wd>%I2. %0,%1,%<hH>2
4117 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4119 (ashift:GPR (match_dup 1)
4122 (compare:CC (match_dup 0)
4125 [(set_attr "type" "shift")
4126 (set_attr "maybe_var_shift" "yes")
4127 (set_attr "dot" "yes")
4128 (set_attr "length" "4,8")])
4130 (define_insn_and_split "*ashl<mode>3_dot2"
4131 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4132 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4133 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4135 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4136 (ashift:GPR (match_dup 1)
4138 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4140 sl<wd>%I2. %0,%1,%<hH>2
4142 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4144 (ashift:GPR (match_dup 1)
4147 (compare:CC (match_dup 0)
4150 [(set_attr "type" "shift")
4151 (set_attr "maybe_var_shift" "yes")
4152 (set_attr "dot" "yes")
4153 (set_attr "length" "4,8")])
4155 ;; Pretend we have a memory form of extswsli until register allocation is done
4156 ;; so that we use LWZ to load the value from memory, instead of LWA.
4157 (define_insn_and_split "ashdi3_extswsli"
4158 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4160 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4161 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4166 "&& reload_completed && MEM_P (operands[1])"
4170 (ashift:DI (sign_extend:DI (match_dup 3))
4173 operands[3] = gen_lowpart (SImode, operands[0]);
4175 [(set_attr "type" "shift")
4176 (set_attr "maybe_var_shift" "no")])
4179 (define_insn_and_split "ashdi3_extswsli_dot"
4180 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4183 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4184 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4186 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4193 "&& reload_completed
4194 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4195 || memory_operand (operands[1], SImode))"
4198 rtx dest = operands[0];
4199 rtx src = operands[1];
4200 rtx shift = operands[2];
4201 rtx cr = operands[3];
4208 src2 = gen_lowpart (SImode, dest);
4209 emit_move_insn (src2, src);
4212 if (REGNO (cr) == CR0_REGNO)
4214 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4218 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4219 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4222 [(set_attr "type" "shift")
4223 (set_attr "maybe_var_shift" "no")
4224 (set_attr "dot" "yes")
4225 (set_attr "length" "4,8,8,12")])
4227 (define_insn_and_split "ashdi3_extswsli_dot2"
4228 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4231 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4232 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4234 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4235 (ashift:DI (sign_extend:DI (match_dup 1))
4243 "&& reload_completed
4244 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4245 || memory_operand (operands[1], SImode))"
4248 rtx dest = operands[0];
4249 rtx src = operands[1];
4250 rtx shift = operands[2];
4251 rtx cr = operands[3];
4258 src2 = gen_lowpart (SImode, dest);
4259 emit_move_insn (src2, src);
4262 if (REGNO (cr) == CR0_REGNO)
4264 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4268 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4269 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4272 [(set_attr "type" "shift")
4273 (set_attr "maybe_var_shift" "no")
4274 (set_attr "dot" "yes")
4275 (set_attr "length" "4,8,8,12")])
4277 (define_insn "lshr<mode>3"
4278 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4279 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4280 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4282 "sr<wd>%I2 %0,%1,%<hH>2"
4283 [(set_attr "type" "shift")
4284 (set_attr "maybe_var_shift" "yes")])
4286 (define_insn "*lshrsi3_64"
4287 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4289 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4290 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4293 [(set_attr "type" "shift")
4294 (set_attr "maybe_var_shift" "yes")])
4296 (define_insn_and_split "*lshr<mode>3_dot"
4297 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4298 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4299 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4301 (clobber (match_scratch:GPR 0 "=r,r"))]
4302 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4304 sr<wd>%I2. %0,%1,%<hH>2
4306 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4308 (lshiftrt:GPR (match_dup 1)
4311 (compare:CC (match_dup 0)
4314 [(set_attr "type" "shift")
4315 (set_attr "maybe_var_shift" "yes")
4316 (set_attr "dot" "yes")
4317 (set_attr "length" "4,8")])
4319 (define_insn_and_split "*lshr<mode>3_dot2"
4320 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4321 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4322 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4324 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4325 (lshiftrt:GPR (match_dup 1)
4327 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4329 sr<wd>%I2. %0,%1,%<hH>2
4331 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4333 (lshiftrt:GPR (match_dup 1)
4336 (compare:CC (match_dup 0)
4339 [(set_attr "type" "shift")
4340 (set_attr "maybe_var_shift" "yes")
4341 (set_attr "dot" "yes")
4342 (set_attr "length" "4,8")])
4345 (define_insn "ashr<mode>3"
4346 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4347 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4348 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4349 (clobber (reg:GPR CA_REGNO))]
4351 "sra<wd>%I2 %0,%1,%<hH>2"
4352 [(set_attr "type" "shift")
4353 (set_attr "maybe_var_shift" "yes")])
4355 (define_insn "*ashrsi3_64"
4356 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4358 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4359 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4360 (clobber (reg:SI CA_REGNO))]
4363 [(set_attr "type" "shift")
4364 (set_attr "maybe_var_shift" "yes")])
4366 (define_insn_and_split "*ashr<mode>3_dot"
4367 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4368 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4369 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4371 (clobber (match_scratch:GPR 0 "=r,r"))
4372 (clobber (reg:GPR CA_REGNO))]
4373 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4375 sra<wd>%I2. %0,%1,%<hH>2
4377 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4378 [(parallel [(set (match_dup 0)
4379 (ashiftrt:GPR (match_dup 1)
4381 (clobber (reg:GPR CA_REGNO))])
4383 (compare:CC (match_dup 0)
4386 [(set_attr "type" "shift")
4387 (set_attr "maybe_var_shift" "yes")
4388 (set_attr "dot" "yes")
4389 (set_attr "length" "4,8")])
4391 (define_insn_and_split "*ashr<mode>3_dot2"
4392 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4393 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4394 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4396 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4397 (ashiftrt:GPR (match_dup 1)
4399 (clobber (reg:GPR CA_REGNO))]
4400 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4402 sra<wd>%I2. %0,%1,%<hH>2
4404 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4405 [(parallel [(set (match_dup 0)
4406 (ashiftrt:GPR (match_dup 1)
4408 (clobber (reg:GPR CA_REGNO))])
4410 (compare:CC (match_dup 0)
4413 [(set_attr "type" "shift")
4414 (set_attr "maybe_var_shift" "yes")
4415 (set_attr "dot" "yes")
4416 (set_attr "length" "4,8")])
4418 ;; Builtins to replace a division to generate FRE reciprocal estimate
4419 ;; instructions and the necessary fixup instructions
4420 (define_expand "recip<mode>3"
4421 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4422 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4423 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4424 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4426 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4430 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4431 ;; hardware division. This is only done before register allocation and with
4432 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4433 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4434 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4436 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4437 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4438 (match_operand 2 "gpc_reg_operand" "")))]
4439 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4440 && can_create_pseudo_p () && flag_finite_math_only
4441 && !flag_trapping_math && flag_reciprocal_math"
4444 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4448 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4449 ;; appropriate fixup.
4450 (define_expand "rsqrt<mode>2"
4451 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4452 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4453 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4455 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4459 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4460 ;; modes here, and also add in conditional vsx/power8-vector support to access
4461 ;; values in the traditional Altivec registers if the appropriate
4462 ;; -mupper-regs-{df,sf} option is enabled.
4464 (define_expand "abs<mode>2"
4465 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4466 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4467 "TARGET_<MODE>_INSN"
4470 (define_insn "*abs<mode>2_fpr"
4471 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4472 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4477 [(set_attr "type" "fpsimple")
4478 (set_attr "fp_type" "fp_addsub_<Fs>")])
4480 (define_insn "*nabs<mode>2_fpr"
4481 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4484 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4489 [(set_attr "type" "fpsimple")
4490 (set_attr "fp_type" "fp_addsub_<Fs>")])
4492 (define_expand "neg<mode>2"
4493 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4494 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4495 "TARGET_<MODE>_INSN"
4498 (define_insn "*neg<mode>2_fpr"
4499 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4500 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4505 [(set_attr "type" "fpsimple")
4506 (set_attr "fp_type" "fp_addsub_<Fs>")])
4508 (define_expand "add<mode>3"
4509 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4510 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4511 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4512 "TARGET_<MODE>_INSN"
4515 (define_insn "*add<mode>3_fpr"
4516 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4517 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4518 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4521 fadd<Ftrad> %0,%1,%2
4522 xsadd<Fvsx> %x0,%x1,%x2"
4523 [(set_attr "type" "fp")
4524 (set_attr "fp_type" "fp_addsub_<Fs>")])
4526 (define_expand "sub<mode>3"
4527 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4528 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4529 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4530 "TARGET_<MODE>_INSN"
4533 (define_insn "*sub<mode>3_fpr"
4534 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4535 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4536 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4539 fsub<Ftrad> %0,%1,%2
4540 xssub<Fvsx> %x0,%x1,%x2"
4541 [(set_attr "type" "fp")
4542 (set_attr "fp_type" "fp_addsub_<Fs>")])
4544 (define_expand "mul<mode>3"
4545 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4546 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4547 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4548 "TARGET_<MODE>_INSN"
4551 (define_insn "*mul<mode>3_fpr"
4552 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4553 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4554 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4557 fmul<Ftrad> %0,%1,%2
4558 xsmul<Fvsx> %x0,%x1,%x2"
4559 [(set_attr "type" "dmul")
4560 (set_attr "fp_type" "fp_mul_<Fs>")])
4562 (define_expand "div<mode>3"
4563 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4564 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4565 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4566 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4568 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4569 && can_create_pseudo_p () && flag_finite_math_only
4570 && !flag_trapping_math && flag_reciprocal_math)
4572 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4577 (define_insn "*div<mode>3_fpr"
4578 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4579 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4580 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4581 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4583 fdiv<Ftrad> %0,%1,%2
4584 xsdiv<Fvsx> %x0,%x1,%x2"
4585 [(set_attr "type" "<Fs>div")
4586 (set_attr "fp_type" "fp_div_<Fs>")])
4588 (define_insn "*sqrt<mode>2_internal"
4589 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4590 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4591 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4592 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4595 xssqrt<Fvsx> %x0,%x1"
4596 [(set_attr "type" "<Fs>sqrt")
4597 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4599 (define_expand "sqrt<mode>2"
4600 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4601 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4602 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4603 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4605 if (<MODE>mode == SFmode
4606 && TARGET_RECIP_PRECISION
4607 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4608 && !optimize_function_for_size_p (cfun)
4609 && flag_finite_math_only && !flag_trapping_math
4610 && flag_unsafe_math_optimizations)
4612 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4617 ;; Floating point reciprocal approximation
4618 (define_insn "fre<Fs>"
4619 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4620 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4626 [(set_attr "type" "fp")])
4628 (define_insn "*rsqrt<mode>2"
4629 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4630 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4632 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4634 frsqrte<Ftrad> %0,%1
4635 xsrsqrte<Fvsx> %x0,%x1"
4636 [(set_attr "type" "fp")])
4638 ;; Floating point comparisons
4639 (define_insn "*cmp<mode>_fpr"
4640 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4641 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4642 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4646 xscmpudp %0,%x1,%x2"
4647 [(set_attr "type" "fpcompare")])
4649 ;; Floating point conversions
4650 (define_expand "extendsfdf2"
4651 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4652 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4653 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4656 (define_insn_and_split "*extendsfdf2_fpr"
4657 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4658 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4659 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4665 xscpsgndp %x0,%x1,%x1
4668 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4671 emit_note (NOTE_INSN_DELETED);
4674 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4676 (define_expand "truncdfsf2"
4677 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4678 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4679 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4682 (define_insn "*truncdfsf2_fpr"
4683 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4684 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4685 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4689 [(set_attr "type" "fp")])
4691 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4692 ;; builtins.c and optabs.c that are not correct for IBM long double
4693 ;; when little-endian.
4694 (define_expand "signbit<mode>2"
4696 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4698 (subreg:DI (match_dup 2) 0))
4701 (set (match_operand:SI 0 "gpc_reg_operand" "")
4704 && (TARGET_FPRS || TARGET_E500_DOUBLE)
4705 && (!FLOAT128_IEEE_P (<MODE>mode)
4706 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4708 if (FLOAT128_IEEE_P (<MODE>mode))
4710 if (<MODE>mode == KFmode)
4711 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4712 else if (<MODE>mode == TFmode)
4713 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4718 operands[2] = gen_reg_rtx (DFmode);
4719 operands[3] = gen_reg_rtx (DImode);
4720 if (TARGET_POWERPC64)
4722 operands[4] = gen_reg_rtx (DImode);
4723 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4724 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4725 WORDS_BIG_ENDIAN ? 4 : 0);
4729 operands[4] = gen_reg_rtx (SImode);
4730 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4731 WORDS_BIG_ENDIAN ? 0 : 4);
4732 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4736 (define_expand "copysign<mode>3"
4738 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4740 (neg:SFDF (abs:SFDF (match_dup 1))))
4741 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4742 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4746 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4747 && ((TARGET_PPC_GFXOPT
4748 && !HONOR_NANS (<MODE>mode)
4749 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4751 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4753 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4755 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4760 operands[3] = gen_reg_rtx (<MODE>mode);
4761 operands[4] = gen_reg_rtx (<MODE>mode);
4762 operands[5] = CONST0_RTX (<MODE>mode);
4765 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4767 (define_insn_and_split "signbit<mode>2_dm"
4768 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4770 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4772 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4774 "&& reload_completed"
4777 rs6000_split_signbit (operands[0], operands[1]);
4780 [(set_attr "length" "8,8,4")
4781 (set_attr "type" "mftgpr,load,integer")])
4783 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4784 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4787 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4789 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4791 "&& reload_completed"
4794 rs6000_split_signbit (operands[0], operands[1]);
4797 [(set_attr "length" "8,8,4")
4798 (set_attr "type" "mftgpr,load,integer")])
4800 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4801 ;; point types, which makes normal SUBREG's problematical. Instead use a
4802 ;; special pattern to avoid using a normal movdi.
4803 (define_insn "signbit<mode>2_dm2"
4804 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4805 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4808 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4810 [(set_attr "type" "mftgpr")])
4813 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4814 ;; compiler from optimizing -0.0
4815 (define_insn "copysign<mode>3_fcpsgn"
4816 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4817 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4818 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4820 "TARGET_<MODE>_FPR && TARGET_CMPB"
4823 xscpsgndp %x0,%x2,%x1"
4824 [(set_attr "type" "fpsimple")])
4826 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4827 ;; fsel instruction and some auxiliary computations. Then we just have a
4828 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4830 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4831 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4832 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4833 ;; define_splits to make them if made by combine. On VSX machines we have the
4834 ;; min/max instructions.
4836 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4837 ;; to allow either DF/SF to use only traditional registers.
4839 (define_expand "s<minmax><mode>3"
4840 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4841 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4842 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4843 "TARGET_MINMAX_<MODE>"
4845 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4849 (define_insn "*s<minmax><mode>3_vsx"
4850 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4851 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4852 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4853 "TARGET_VSX && TARGET_<MODE>_FPR"
4855 return (TARGET_P9_MINMAX
4856 ? "xs<minmax>cdp %x0,%x1,%x2"
4857 : "xs<minmax>dp %x0,%x1,%x2");
4859 [(set_attr "type" "fp")])
4861 ;; The conditional move instructions allow us to perform max and min operations
4862 ;; even when we don't have the appropriate max/min instruction using the FSEL
4865 (define_insn_and_split "*s<minmax><mode>3_fpr"
4866 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4867 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4868 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4869 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4874 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4878 (define_expand "mov<mode>cc"
4879 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4880 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4881 (match_operand:GPR 2 "gpc_reg_operand" "")
4882 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4886 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4892 ;; We use the BASE_REGS for the isel input operands because, if rA is
4893 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4894 ;; because we may switch the operands and rB may end up being rA.
4896 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4897 ;; leave out the mode in operand 4 and use one pattern, but reload can
4898 ;; change the mode underneath our feet and then gets confused trying
4899 ;; to reload the value.
4900 (define_insn "isel_signed_<mode>"
4901 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4903 (match_operator 1 "scc_comparison_operator"
4904 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4906 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4907 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4910 { return output_isel (operands); }"
4911 [(set_attr "type" "isel")
4912 (set_attr "length" "4")])
4914 (define_insn "isel_unsigned_<mode>"
4915 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4917 (match_operator 1 "scc_comparison_operator"
4918 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4920 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4921 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4924 { return output_isel (operands); }"
4925 [(set_attr "type" "isel")
4926 (set_attr "length" "4")])
4928 ;; These patterns can be useful for combine; they let combine know that
4929 ;; isel can handle reversed comparisons so long as the operands are
4932 (define_insn "*isel_reversed_signed_<mode>"
4933 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4935 (match_operator 1 "scc_rev_comparison_operator"
4936 [(match_operand:CC 4 "cc_reg_operand" "y")
4938 (match_operand:GPR 2 "gpc_reg_operand" "b")
4939 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4942 { return output_isel (operands); }"
4943 [(set_attr "type" "isel")
4944 (set_attr "length" "4")])
4946 (define_insn "*isel_reversed_unsigned_<mode>"
4947 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4949 (match_operator 1 "scc_rev_comparison_operator"
4950 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4952 (match_operand:GPR 2 "gpc_reg_operand" "b")
4953 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4956 { return output_isel (operands); }"
4957 [(set_attr "type" "isel")
4958 (set_attr "length" "4")])
4960 ;; Floating point conditional move
4961 (define_expand "mov<mode>cc"
4962 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4963 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4964 (match_operand:SFDF 2 "gpc_reg_operand" "")
4965 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4966 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4969 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4975 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4976 [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4978 (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4979 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4980 (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4981 (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4982 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4984 [(set_attr "type" "fp")])
4986 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4987 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4989 (match_operator:CCFP 1 "fpmask_comparison_operator"
4990 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4991 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4992 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4993 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4994 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4999 (if_then_else:V2DI (match_dup 1)
5003 (if_then_else:SFDF (ne (match_dup 6)
5008 if (GET_CODE (operands[6]) == SCRATCH)
5009 operands[6] = gen_reg_rtx (V2DImode);
5011 operands[7] = CONSTM1_RTX (V2DImode);
5012 operands[8] = CONST0_RTX (V2DImode);
5014 [(set_attr "length" "8")
5015 (set_attr "type" "vecperm")])
5017 ;; Handle inverting the fpmask comparisons.
5018 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5019 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5021 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5022 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5023 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5024 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5025 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5026 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5031 (if_then_else:V2DI (match_dup 9)
5035 (if_then_else:SFDF (ne (match_dup 6)
5040 rtx op1 = operands[1];
5041 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5043 if (GET_CODE (operands[6]) == SCRATCH)
5044 operands[6] = gen_reg_rtx (V2DImode);
5046 operands[7] = CONSTM1_RTX (V2DImode);
5047 operands[8] = CONST0_RTX (V2DImode);
5049 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5051 [(set_attr "length" "8")
5052 (set_attr "type" "vecperm")])
5054 (define_insn "*fpmask<mode>"
5055 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5057 (match_operator:CCFP 1 "fpmask_comparison_operator"
5058 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5059 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5060 (match_operand:V2DI 4 "all_ones_constant" "")
5061 (match_operand:V2DI 5 "zero_constant" "")))]
5063 "xscmp%V1dp %x0,%x2,%x3"
5064 [(set_attr "type" "fpcompare")])
5066 (define_insn "*xxsel<mode>"
5067 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5068 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5069 (match_operand:V2DI 2 "zero_constant" ""))
5070 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5071 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5073 "xxsel %x0,%x4,%x3,%x1"
5074 [(set_attr "type" "vecmove")])
5077 ;; Conversions to and from floating-point.
5079 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5080 ; don't want to support putting SImode in FPR registers.
5081 (define_insn "lfiwax"
5082 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5083 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5085 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5091 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5093 ; This split must be run before register allocation because it allocates the
5094 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5095 ; it earlier to allow for the combiner to merge insns together where it might
5096 ; not be needed and also in case the insns are deleted as dead code.
5098 (define_insn_and_split "floatsi<mode>2_lfiwax"
5099 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5100 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5101 (clobber (match_scratch:DI 2 "=wi"))]
5102 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5103 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5109 rtx dest = operands[0];
5110 rtx src = operands[1];
5113 if (!MEM_P (src) && TARGET_POWERPC64
5114 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5115 tmp = convert_to_mode (DImode, src, false);
5119 if (GET_CODE (tmp) == SCRATCH)
5120 tmp = gen_reg_rtx (DImode);
5123 src = rs6000_address_for_fpconvert (src);
5124 emit_insn (gen_lfiwax (tmp, src));
5128 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5129 emit_move_insn (stack, src);
5130 emit_insn (gen_lfiwax (tmp, stack));
5133 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5136 [(set_attr "length" "12")
5137 (set_attr "type" "fpload")])
5139 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5140 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5143 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5144 (clobber (match_scratch:DI 2 "=wi"))]
5145 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5152 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5153 if (GET_CODE (operands[2]) == SCRATCH)
5154 operands[2] = gen_reg_rtx (DImode);
5155 if (TARGET_VSX_SMALL_INTEGER)
5156 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5158 emit_insn (gen_lfiwax (operands[2], operands[1]));
5159 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5162 [(set_attr "length" "8")
5163 (set_attr "type" "fpload")])
5165 (define_insn "lfiwzx"
5166 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5167 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5169 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5174 xxextractuw %x0,%x1,4"
5175 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5177 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5178 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5179 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5180 (clobber (match_scratch:DI 2 "=wi"))]
5181 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5188 rtx dest = operands[0];
5189 rtx src = operands[1];
5192 if (!MEM_P (src) && TARGET_POWERPC64
5193 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5194 tmp = convert_to_mode (DImode, src, true);
5198 if (GET_CODE (tmp) == SCRATCH)
5199 tmp = gen_reg_rtx (DImode);
5202 src = rs6000_address_for_fpconvert (src);
5203 emit_insn (gen_lfiwzx (tmp, src));
5207 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5208 emit_move_insn (stack, src);
5209 emit_insn (gen_lfiwzx (tmp, stack));
5212 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5215 [(set_attr "length" "12")
5216 (set_attr "type" "fpload")])
5218 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5219 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5220 (unsigned_float:SFDF
5222 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5223 (clobber (match_scratch:DI 2 "=wi"))]
5224 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5231 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5232 if (GET_CODE (operands[2]) == SCRATCH)
5233 operands[2] = gen_reg_rtx (DImode);
5234 if (TARGET_VSX_SMALL_INTEGER)
5235 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5237 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5238 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5241 [(set_attr "length" "8")
5242 (set_attr "type" "fpload")])
5244 ; For each of these conversions, there is a define_expand, a define_insn
5245 ; with a '#' template, and a define_split (with C code). The idea is
5246 ; to allow constant folding with the template of the define_insn,
5247 ; then to have the insns split later (between sched1 and final).
5249 (define_expand "floatsidf2"
5250 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5251 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5254 (clobber (match_dup 4))
5255 (clobber (match_dup 5))
5256 (clobber (match_dup 6))])]
5258 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5261 if (TARGET_E500_DOUBLE)
5263 if (!REG_P (operands[1]))
5264 operands[1] = force_reg (SImode, operands[1]);
5265 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5268 else if (TARGET_LFIWAX && TARGET_FCFID)
5270 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5273 else if (TARGET_FCFID)
5275 rtx dreg = operands[1];
5277 dreg = force_reg (SImode, dreg);
5278 dreg = convert_to_mode (DImode, dreg, false);
5279 emit_insn (gen_floatdidf2 (operands[0], dreg));
5283 if (!REG_P (operands[1]))
5284 operands[1] = force_reg (SImode, operands[1]);
5285 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5286 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5287 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5288 operands[5] = gen_reg_rtx (DFmode);
5289 operands[6] = gen_reg_rtx (SImode);
5292 (define_insn_and_split "*floatsidf2_internal"
5293 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5294 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5295 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5296 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5297 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5298 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5299 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5300 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5306 rtx lowword, highword;
5307 gcc_assert (MEM_P (operands[4]));
5308 highword = adjust_address (operands[4], SImode, 0);
5309 lowword = adjust_address (operands[4], SImode, 4);
5310 if (! WORDS_BIG_ENDIAN)
5311 std::swap (lowword, highword);
5313 emit_insn (gen_xorsi3 (operands[6], operands[1],
5314 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5315 emit_move_insn (lowword, operands[6]);
5316 emit_move_insn (highword, operands[2]);
5317 emit_move_insn (operands[5], operands[4]);
5318 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5321 [(set_attr "length" "24")
5322 (set_attr "type" "fp")])
5324 ;; If we don't have a direct conversion to single precision, don't enable this
5325 ;; conversion for 32-bit without fast math, because we don't have the insn to
5326 ;; generate the fixup swizzle to avoid double rounding problems.
5327 (define_expand "floatunssisf2"
5328 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5329 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5330 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5333 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5334 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5335 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5340 if (!REG_P (operands[1]))
5341 operands[1] = force_reg (SImode, operands[1]);
5343 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5345 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5350 rtx dreg = operands[1];
5352 dreg = force_reg (SImode, dreg);
5353 dreg = convert_to_mode (DImode, dreg, true);
5354 emit_insn (gen_floatdisf2 (operands[0], dreg));
5359 (define_expand "floatunssidf2"
5360 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5361 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5364 (clobber (match_dup 4))
5365 (clobber (match_dup 5))])]
5367 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5370 if (TARGET_E500_DOUBLE)
5372 if (!REG_P (operands[1]))
5373 operands[1] = force_reg (SImode, operands[1]);
5374 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5377 else if (TARGET_LFIWZX && TARGET_FCFID)
5379 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5382 else if (TARGET_FCFID)
5384 rtx dreg = operands[1];
5386 dreg = force_reg (SImode, dreg);
5387 dreg = convert_to_mode (DImode, dreg, true);
5388 emit_insn (gen_floatdidf2 (operands[0], dreg));
5392 if (!REG_P (operands[1]))
5393 operands[1] = force_reg (SImode, operands[1]);
5394 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5395 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5396 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5397 operands[5] = gen_reg_rtx (DFmode);
5400 (define_insn_and_split "*floatunssidf2_internal"
5401 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5402 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5403 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5404 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5405 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5406 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5407 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5408 && !(TARGET_FCFID && TARGET_POWERPC64)"
5414 rtx lowword, highword;
5415 gcc_assert (MEM_P (operands[4]));
5416 highword = adjust_address (operands[4], SImode, 0);
5417 lowword = adjust_address (operands[4], SImode, 4);
5418 if (! WORDS_BIG_ENDIAN)
5419 std::swap (lowword, highword);
5421 emit_move_insn (lowword, operands[1]);
5422 emit_move_insn (highword, operands[2]);
5423 emit_move_insn (operands[5], operands[4]);
5424 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5427 [(set_attr "length" "20")
5428 (set_attr "type" "fp")])
5430 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5431 ;; vector registers. These insns favor doing the sign/zero extension in
5432 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5433 ;; extension and then a direct move.
5435 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5436 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5438 (match_operand:QHI 1 "input_operand")))
5439 (clobber (match_scratch:DI 2))
5440 (clobber (match_scratch:DI 3))
5441 (clobber (match_scratch:<QHI:MODE> 4))])]
5442 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5443 && TARGET_VSX_SMALL_INTEGER"
5445 if (MEM_P (operands[1]))
5446 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5449 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5450 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5452 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5453 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5454 (clobber (match_scratch:DI 3 "=X,r,X"))
5455 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5456 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5457 && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5459 "&& reload_completed"
5462 rtx result = operands[0];
5463 rtx input = operands[1];
5464 rtx di = operands[2];
5468 rtx tmp = operands[3];
5469 if (altivec_register_operand (input, <QHI:MODE>mode))
5470 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5471 else if (GET_CODE (tmp) == SCRATCH)
5472 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5475 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5476 emit_move_insn (di, tmp);
5481 rtx tmp = operands[4];
5482 emit_move_insn (tmp, input);
5483 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5486 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5490 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5491 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5492 (unsigned_float:FP_ISA3
5493 (match_operand:QHI 1 "input_operand" "")))
5494 (clobber (match_scratch:DI 2 ""))
5495 (clobber (match_scratch:DI 3 ""))])]
5496 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5497 && TARGET_VSX_SMALL_INTEGER"
5499 if (MEM_P (operands[1]))
5500 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5503 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5504 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5505 (unsigned_float:FP_ISA3
5506 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5507 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5508 (clobber (match_scratch:DI 3 "=X,r,X"))]
5509 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5510 && TARGET_VSX_SMALL_INTEGER"
5512 "&& reload_completed"
5515 rtx result = operands[0];
5516 rtx input = operands[1];
5517 rtx di = operands[2];
5519 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5520 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5523 rtx tmp = operands[3];
5524 if (GET_CODE (tmp) == SCRATCH)
5525 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5528 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5529 emit_move_insn (di, tmp);
5533 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5537 (define_expand "fix_trunc<mode>si2"
5538 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5539 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5540 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5543 if (!<E500_CONVERT>)
5545 rtx src = force_reg (<MODE>mode, operands[1]);
5548 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5551 rtx tmp = gen_reg_rtx (DImode);
5552 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5553 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5560 ; Like the convert to float patterns, this insn must be split before
5561 ; register allocation so that it can allocate the memory slot if it
5563 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5564 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5565 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5566 (clobber (match_scratch:DI 2 "=d"))]
5567 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5568 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5569 && TARGET_STFIWX && can_create_pseudo_p ()"
5574 rtx dest = operands[0];
5575 rtx src = operands[1];
5576 rtx tmp = operands[2];
5578 if (GET_CODE (tmp) == SCRATCH)
5579 tmp = gen_reg_rtx (DImode);
5581 emit_insn (gen_fctiwz_<mode> (tmp, src));
5584 dest = rs6000_address_for_fpconvert (dest);
5585 emit_insn (gen_stfiwx (dest, tmp));
5588 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5590 dest = gen_lowpart (DImode, dest);
5591 emit_move_insn (dest, tmp);
5596 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5597 emit_insn (gen_stfiwx (stack, tmp));
5598 emit_move_insn (dest, stack);
5602 [(set_attr "length" "12")
5603 (set_attr "type" "fp")])
5605 (define_insn_and_split "fix_trunc<mode>si2_internal"
5606 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5607 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5608 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5609 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5610 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5617 gcc_assert (MEM_P (operands[3]));
5618 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5620 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5621 emit_move_insn (operands[3], operands[2]);
5622 emit_move_insn (operands[0], lowword);
5625 [(set_attr "length" "16")
5626 (set_attr "type" "fp")])
5628 (define_expand "fix_trunc<mode>di2"
5629 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5630 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5631 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5635 (define_insn "*fix_trunc<mode>di2_fctidz"
5636 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5637 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5638 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5643 [(set_attr "type" "fp")])
5645 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5646 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5647 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5648 (clobber (match_scratch:DI 2))])]
5649 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5650 && TARGET_VSX_SMALL_INTEGER"
5652 if (MEM_P (operands[0]))
5653 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5656 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5657 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5659 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5660 (clobber (match_scratch:DI 2 "=X,wi"))]
5661 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5662 && TARGET_VSX_SMALL_INTEGER"
5664 "&& reload_completed"
5667 rtx dest = operands[0];
5668 rtx src = operands[1];
5670 if (vsx_register_operand (dest, <QHI:MODE>mode))
5672 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5673 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5677 rtx tmp = operands[2];
5678 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5680 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5681 emit_move_insn (dest, tmp2);
5686 (define_expand "fixuns_trunc<mode>si2"
5687 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5688 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5690 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5694 if (!<E500_CONVERT>)
5696 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5701 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5702 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5703 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5704 (clobber (match_scratch:DI 2 "=d"))]
5705 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5706 && TARGET_STFIWX && can_create_pseudo_p ()"
5711 rtx dest = operands[0];
5712 rtx src = operands[1];
5713 rtx tmp = operands[2];
5715 if (GET_CODE (tmp) == SCRATCH)
5716 tmp = gen_reg_rtx (DImode);
5718 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5721 dest = rs6000_address_for_fpconvert (dest);
5722 emit_insn (gen_stfiwx (dest, tmp));
5725 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5727 dest = gen_lowpart (DImode, dest);
5728 emit_move_insn (dest, tmp);
5733 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5734 emit_insn (gen_stfiwx (stack, tmp));
5735 emit_move_insn (dest, stack);
5739 [(set_attr "length" "12")
5740 (set_attr "type" "fp")])
5742 (define_insn "fixuns_trunc<mode>di2"
5743 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5744 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5745 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ"
5749 [(set_attr "type" "fp")])
5751 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5752 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5753 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5754 (clobber (match_scratch:DI 2))])]
5755 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5756 && TARGET_VSX_SMALL_INTEGER"
5758 if (MEM_P (operands[0]))
5759 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5762 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5763 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5765 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5766 (clobber (match_scratch:DI 2 "=X,wi"))]
5767 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5768 && TARGET_VSX_SMALL_INTEGER"
5770 "&& reload_completed"
5773 rtx dest = operands[0];
5774 rtx src = operands[1];
5776 if (vsx_register_operand (dest, <QHI:MODE>mode))
5778 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5779 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5783 rtx tmp = operands[2];
5784 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5786 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5787 emit_move_insn (dest, tmp2);
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")
5797 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5799 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5803 [(set_attr "type" "fp")])
5805 (define_insn "fctiwuz_<mode>"
5806 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5807 (unspec:DI [(unsigned_fix:SI
5808 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5810 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5814 [(set_attr "type" "fp")])
5816 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5817 ;; since the friz instruction does not truncate the value if the floating
5818 ;; point value is < LONG_MIN or > LONG_MAX.
5819 (define_insn "*friz"
5820 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5821 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5822 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5823 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5827 [(set_attr "type" "fp")])
5829 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5830 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5831 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5832 ;; extend it, store it back on the stack from the GPR, load it back into the
5833 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5834 ;; disable using store and load to sign/zero extend the value.
5835 (define_insn_and_split "*round32<mode>2_fprs"
5836 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5838 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5839 (clobber (match_scratch:DI 2 "=d"))
5840 (clobber (match_scratch:DI 3 "=d"))]
5841 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5842 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5843 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5848 rtx dest = operands[0];
5849 rtx src = operands[1];
5850 rtx tmp1 = operands[2];
5851 rtx tmp2 = operands[3];
5852 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5854 if (GET_CODE (tmp1) == SCRATCH)
5855 tmp1 = gen_reg_rtx (DImode);
5856 if (GET_CODE (tmp2) == SCRATCH)
5857 tmp2 = gen_reg_rtx (DImode);
5859 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5860 emit_insn (gen_stfiwx (stack, tmp1));
5861 emit_insn (gen_lfiwax (tmp2, stack));
5862 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5865 [(set_attr "type" "fpload")
5866 (set_attr "length" "16")])
5868 (define_insn_and_split "*roundu32<mode>2_fprs"
5869 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5870 (unsigned_float:SFDF
5871 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5872 (clobber (match_scratch:DI 2 "=d"))
5873 (clobber (match_scratch:DI 3 "=d"))]
5874 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5875 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5876 && can_create_pseudo_p ()"
5881 rtx dest = operands[0];
5882 rtx src = operands[1];
5883 rtx tmp1 = operands[2];
5884 rtx tmp2 = operands[3];
5885 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5887 if (GET_CODE (tmp1) == SCRATCH)
5888 tmp1 = gen_reg_rtx (DImode);
5889 if (GET_CODE (tmp2) == SCRATCH)
5890 tmp2 = gen_reg_rtx (DImode);
5892 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5893 emit_insn (gen_stfiwx (stack, tmp1));
5894 emit_insn (gen_lfiwzx (tmp2, stack));
5895 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5898 [(set_attr "type" "fpload")
5899 (set_attr "length" "16")])
5901 ;; No VSX equivalent to fctid
5902 (define_insn "lrint<mode>di2"
5903 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5904 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5906 "TARGET_<MODE>_FPR && TARGET_FPRND"
5908 [(set_attr "type" "fp")])
5910 (define_insn "btrunc<mode>2"
5911 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5912 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5914 "TARGET_<MODE>_FPR && TARGET_FPRND"
5918 [(set_attr "type" "fp")
5919 (set_attr "fp_type" "fp_addsub_<Fs>")])
5921 (define_insn "ceil<mode>2"
5922 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5923 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5925 "TARGET_<MODE>_FPR && TARGET_FPRND"
5929 [(set_attr "type" "fp")
5930 (set_attr "fp_type" "fp_addsub_<Fs>")])
5932 (define_insn "floor<mode>2"
5933 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5934 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5936 "TARGET_<MODE>_FPR && TARGET_FPRND"
5940 [(set_attr "type" "fp")
5941 (set_attr "fp_type" "fp_addsub_<Fs>")])
5943 ;; No VSX equivalent to frin
5944 (define_insn "round<mode>2"
5945 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5946 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5948 "TARGET_<MODE>_FPR && TARGET_FPRND"
5950 [(set_attr "type" "fp")
5951 (set_attr "fp_type" "fp_addsub_<Fs>")])
5953 (define_insn "*xsrdpi<mode>2"
5954 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5955 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5957 "TARGET_<MODE>_FPR && TARGET_VSX"
5959 [(set_attr "type" "fp")
5960 (set_attr "fp_type" "fp_addsub_<Fs>")])
5962 (define_expand "lround<mode>di2"
5964 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5966 (set (match_operand:DI 0 "gpc_reg_operand" "")
5967 (unspec:DI [(match_dup 2)]
5969 "TARGET_<MODE>_FPR && TARGET_VSX"
5971 operands[2] = gen_reg_rtx (<MODE>mode);
5974 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5975 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5976 ; is only generated for Power8 or later.
5977 (define_insn "stfiwx"
5978 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5979 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5985 [(set_attr "type" "fpstore")])
5987 ;; If we don't have a direct conversion to single precision, don't enable this
5988 ;; conversion for 32-bit without fast math, because we don't have the insn to
5989 ;; generate the fixup swizzle to avoid double rounding problems.
5990 (define_expand "floatsisf2"
5991 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5992 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5993 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5996 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5997 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5998 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
6003 if (!REG_P (operands[1]))
6004 operands[1] = force_reg (SImode, operands[1]);
6006 else if (TARGET_FCFIDS && TARGET_LFIWAX)
6008 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6011 else if (TARGET_FCFID && TARGET_LFIWAX)
6013 rtx dfreg = gen_reg_rtx (DFmode);
6014 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6015 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6020 rtx dreg = operands[1];
6022 dreg = force_reg (SImode, dreg);
6023 dreg = convert_to_mode (DImode, dreg, false);
6024 emit_insn (gen_floatdisf2 (operands[0], dreg));
6029 (define_expand "floatdidf2"
6030 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6031 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6032 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6035 (define_insn "*floatdidf2_fpr"
6036 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6037 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6038 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6042 [(set_attr "type" "fp")])
6044 ; Allow the combiner to merge source memory operands to the conversion so that
6045 ; the optimizer/register allocator doesn't try to load the value too early in a
6046 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6047 ; hit. We will split after reload to avoid the trip through the GPRs
6049 (define_insn_and_split "*floatdidf2_mem"
6050 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6051 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6052 (clobber (match_scratch:DI 2 "=d,wi"))]
6053 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6055 "&& reload_completed"
6056 [(set (match_dup 2) (match_dup 1))
6057 (set (match_dup 0) (float:DF (match_dup 2)))]
6059 [(set_attr "length" "8")
6060 (set_attr "type" "fpload")])
6062 (define_expand "floatunsdidf2"
6063 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6065 (match_operand:DI 1 "gpc_reg_operand" "")))]
6066 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6069 (define_insn "*floatunsdidf2_fcfidu"
6070 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6071 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6072 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6076 [(set_attr "type" "fp")
6077 (set_attr "length" "4")])
6079 (define_insn_and_split "*floatunsdidf2_mem"
6080 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6081 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6082 (clobber (match_scratch:DI 2 "=d,wi"))]
6083 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6085 "&& reload_completed"
6086 [(set (match_dup 2) (match_dup 1))
6087 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6089 [(set_attr "length" "8")
6090 (set_attr "type" "fpload")])
6092 (define_expand "floatdisf2"
6093 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6094 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6095 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6096 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6101 rtx val = operands[1];
6102 if (!flag_unsafe_math_optimizations)
6104 rtx label = gen_label_rtx ();
6105 val = gen_reg_rtx (DImode);
6106 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6109 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6114 (define_insn "floatdisf2_fcfids"
6115 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6116 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6117 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6118 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6122 [(set_attr "type" "fp")])
6124 (define_insn_and_split "*floatdisf2_mem"
6125 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6126 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6127 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6128 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6129 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6131 "&& reload_completed"
6135 emit_move_insn (operands[2], operands[1]);
6136 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6139 [(set_attr "length" "8")])
6141 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6142 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6143 ;; from double rounding.
6144 ;; Instead of creating a new cpu type for two FP operations, just use fp
6145 (define_insn_and_split "floatdisf2_internal1"
6146 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6147 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6148 (clobber (match_scratch:DF 2 "=d"))]
6149 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6152 "&& reload_completed"
6154 (float:DF (match_dup 1)))
6156 (float_truncate:SF (match_dup 2)))]
6158 [(set_attr "length" "8")
6159 (set_attr "type" "fp")])
6161 ;; Twiddles bits to avoid double rounding.
6162 ;; Bits that might be truncated when converting to DFmode are replaced
6163 ;; by a bit that won't be lost at that stage, but is below the SFmode
6164 ;; rounding position.
6165 (define_expand "floatdisf2_internal2"
6166 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6168 (clobber (reg:DI CA_REGNO))])
6169 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6171 (set (match_dup 3) (plus:DI (match_dup 3)
6173 (set (match_dup 0) (plus:DI (match_dup 0)
6175 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6177 (set (match_dup 0) (ior:DI (match_dup 0)
6179 (set (match_dup 0) (and:DI (match_dup 0)
6181 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6182 (label_ref (match_operand:DI 2 "" ""))
6184 (set (match_dup 0) (match_dup 1))]
6185 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6189 operands[3] = gen_reg_rtx (DImode);
6190 operands[4] = gen_reg_rtx (CCUNSmode);
6193 (define_expand "floatunsdisf2"
6194 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6195 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6196 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6197 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6200 (define_insn "floatunsdisf2_fcfidus"
6201 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6202 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6203 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6204 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6208 [(set_attr "type" "fp")])
6210 (define_insn_and_split "*floatunsdisf2_mem"
6211 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6212 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6213 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6214 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6215 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6217 "&& reload_completed"
6221 emit_move_insn (operands[2], operands[1]);
6222 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6225 [(set_attr "length" "8")
6226 (set_attr "type" "fpload")])
6228 ;; Define the TImode operations that can be done in a small number
6229 ;; of instructions. The & constraints are to prevent the register
6230 ;; allocator from allocating registers that overlap with the inputs
6231 ;; (for example, having an input in 7,8 and an output in 6,7). We
6232 ;; also allow for the output being the same as one of the inputs.
6234 (define_expand "addti3"
6235 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6236 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6237 (match_operand:TI 2 "reg_or_short_operand" "")))]
6240 rtx lo0 = gen_lowpart (DImode, operands[0]);
6241 rtx lo1 = gen_lowpart (DImode, operands[1]);
6242 rtx lo2 = gen_lowpart (DImode, operands[2]);
6243 rtx hi0 = gen_highpart (DImode, operands[0]);
6244 rtx hi1 = gen_highpart (DImode, operands[1]);
6245 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6247 if (!reg_or_short_operand (lo2, DImode))
6248 lo2 = force_reg (DImode, lo2);
6249 if (!adde_operand (hi2, DImode))
6250 hi2 = force_reg (DImode, hi2);
6252 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6253 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6257 (define_expand "subti3"
6258 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6259 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6260 (match_operand:TI 2 "gpc_reg_operand" "")))]
6263 rtx lo0 = gen_lowpart (DImode, operands[0]);
6264 rtx lo1 = gen_lowpart (DImode, operands[1]);
6265 rtx lo2 = gen_lowpart (DImode, operands[2]);
6266 rtx hi0 = gen_highpart (DImode, operands[0]);
6267 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6268 rtx hi2 = gen_highpart (DImode, operands[2]);
6270 if (!reg_or_short_operand (lo1, DImode))
6271 lo1 = force_reg (DImode, lo1);
6272 if (!adde_operand (hi1, DImode))
6273 hi1 = force_reg (DImode, hi1);
6275 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6276 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6280 ;; 128-bit logical operations expanders
6282 (define_expand "and<mode>3"
6283 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6284 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6285 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6289 (define_expand "ior<mode>3"
6290 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6291 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6292 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6296 (define_expand "xor<mode>3"
6297 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6298 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6299 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6303 (define_expand "one_cmpl<mode>2"
6304 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6305 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6309 (define_expand "nor<mode>3"
6310 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6312 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6313 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6317 (define_expand "andc<mode>3"
6318 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6320 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6321 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6325 ;; Power8 vector logical instructions.
6326 (define_expand "eqv<mode>3"
6327 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6329 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6330 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6331 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6334 ;; Rewrite nand into canonical form
6335 (define_expand "nand<mode>3"
6336 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6338 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6339 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6340 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6343 ;; The canonical form is to have the negated element first, so we need to
6344 ;; reverse arguments.
6345 (define_expand "orc<mode>3"
6346 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6348 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6349 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6350 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6353 ;; 128-bit logical operations insns and split operations
6354 (define_insn_and_split "*and<mode>3_internal"
6355 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6357 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6358 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6361 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6362 return "xxland %x0,%x1,%x2";
6364 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6365 return "vand %0,%1,%2";
6369 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6372 rs6000_split_logical (operands, AND, false, false, false);
6377 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6378 (const_string "veclogical")
6379 (const_string "integer")))
6380 (set (attr "length")
6382 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6385 (match_test "TARGET_POWERPC64")
6387 (const_string "16"))))])
6390 (define_insn_and_split "*bool<mode>3_internal"
6391 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6392 (match_operator:BOOL_128 3 "boolean_or_operator"
6393 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6394 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6397 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6398 return "xxl%q3 %x0,%x1,%x2";
6400 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6401 return "v%q3 %0,%1,%2";
6405 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6408 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6413 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6414 (const_string "veclogical")
6415 (const_string "integer")))
6416 (set (attr "length")
6418 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6421 (match_test "TARGET_POWERPC64")
6423 (const_string "16"))))])
6426 (define_insn_and_split "*boolc<mode>3_internal1"
6427 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6428 (match_operator:BOOL_128 3 "boolean_operator"
6430 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6431 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6432 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6434 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6435 return "xxl%q3 %x0,%x1,%x2";
6437 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6438 return "v%q3 %0,%1,%2";
6442 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6443 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6446 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6451 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6452 (const_string "veclogical")
6453 (const_string "integer")))
6454 (set (attr "length")
6456 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6459 (match_test "TARGET_POWERPC64")
6461 (const_string "16"))))])
6463 (define_insn_and_split "*boolc<mode>3_internal2"
6464 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6465 (match_operator:TI2 3 "boolean_operator"
6467 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6468 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6469 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6471 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6474 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6477 [(set_attr "type" "integer")
6478 (set (attr "length")
6480 (match_test "TARGET_POWERPC64")
6482 (const_string "16")))])
6485 (define_insn_and_split "*boolcc<mode>3_internal1"
6486 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6487 (match_operator:BOOL_128 3 "boolean_operator"
6489 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6491 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6492 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6494 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6495 return "xxl%q3 %x0,%x1,%x2";
6497 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6498 return "v%q3 %0,%1,%2";
6502 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6503 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6506 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6511 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6512 (const_string "veclogical")
6513 (const_string "integer")))
6514 (set (attr "length")
6516 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6519 (match_test "TARGET_POWERPC64")
6521 (const_string "16"))))])
6523 (define_insn_and_split "*boolcc<mode>3_internal2"
6524 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6525 (match_operator:TI2 3 "boolean_operator"
6527 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6529 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6530 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6532 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6535 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6538 [(set_attr "type" "integer")
6539 (set (attr "length")
6541 (match_test "TARGET_POWERPC64")
6543 (const_string "16")))])
6547 (define_insn_and_split "*eqv<mode>3_internal1"
6548 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6551 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6552 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6555 if (vsx_register_operand (operands[0], <MODE>mode))
6556 return "xxleqv %x0,%x1,%x2";
6560 "TARGET_P8_VECTOR && reload_completed
6561 && int_reg_operand (operands[0], <MODE>mode)"
6564 rs6000_split_logical (operands, XOR, true, false, false);
6569 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6570 (const_string "veclogical")
6571 (const_string "integer")))
6572 (set (attr "length")
6574 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6577 (match_test "TARGET_POWERPC64")
6579 (const_string "16"))))])
6581 (define_insn_and_split "*eqv<mode>3_internal2"
6582 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6585 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6586 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6589 "reload_completed && !TARGET_P8_VECTOR"
6592 rs6000_split_logical (operands, XOR, true, false, false);
6595 [(set_attr "type" "integer")
6596 (set (attr "length")
6598 (match_test "TARGET_POWERPC64")
6600 (const_string "16")))])
6602 ;; 128-bit one's complement
6603 (define_insn_and_split "*one_cmpl<mode>3_internal"
6604 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6606 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6609 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6610 return "xxlnor %x0,%x1,%x1";
6612 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6613 return "vnor %0,%1,%1";
6617 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6620 rs6000_split_logical (operands, NOT, false, false, false);
6625 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6626 (const_string "veclogical")
6627 (const_string "integer")))
6628 (set (attr "length")
6630 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6633 (match_test "TARGET_POWERPC64")
6635 (const_string "16"))))])
6638 ;; Now define ways of moving data around.
6640 ;; Set up a register with a value from the GOT table
6642 (define_expand "movsi_got"
6643 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6644 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6645 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6646 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6649 if (GET_CODE (operands[1]) == CONST)
6651 rtx offset = const0_rtx;
6652 HOST_WIDE_INT value;
6654 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6655 value = INTVAL (offset);
6658 rtx tmp = (!can_create_pseudo_p ()
6660 : gen_reg_rtx (Pmode));
6661 emit_insn (gen_movsi_got (tmp, operands[1]));
6662 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6667 operands[2] = rs6000_got_register (operands[1]);
6670 (define_insn "*movsi_got_internal"
6671 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6672 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6673 (match_operand:SI 2 "gpc_reg_operand" "b")]
6675 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6676 "lwz %0,%a1@got(%2)"
6677 [(set_attr "type" "load")])
6679 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6680 ;; didn't get allocated to a hard register.
6682 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6683 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6684 (match_operand:SI 2 "memory_operand" "")]
6686 "DEFAULT_ABI == ABI_V4
6688 && (reload_in_progress || reload_completed)"
6689 [(set (match_dup 0) (match_dup 2))
6690 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6694 ;; For SI, we special-case integers that can't be loaded in one insn. We
6695 ;; do the load 16-bits at a time. We could do this by loading from memory,
6696 ;; and this is even supposed to be faster, but it is simpler not to get
6697 ;; integers in the TOC.
6698 (define_insn "movsi_low"
6699 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6700 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6701 (match_operand 2 "" ""))))]
6702 "TARGET_MACHO && ! TARGET_64BIT"
6703 "lwz %0,lo16(%2)(%1)"
6704 [(set_attr "type" "load")
6705 (set_attr "length" "4")])
6707 ;; MR LA LWZ LFIWZX LXSIWZX
6708 ;; STW STFIWX STXSIWX LI LIS
6709 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6710 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6711 ;; MF%1 MT%0 MT%0 NOP
6712 (define_insn "*movsi_internal1"
6713 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6714 "=r, r, r, ?*wI, ?*wH,
6716 r, ?*wIwH, ?*wJwK, ?*wK, ?*wJwK,
6717 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6720 (match_operand:SI 1 "input_operand"
6727 "!TARGET_SINGLE_FPU &&
6728 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6755 "*, *, load, fpload, fpload,
6756 store, fpstore, fpstore, *, *,
6757 *, veclogical, vecsimple, vecsimple, vecsimple,
6758 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6768 (define_insn "*movsi_internal1_single"
6769 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6770 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6771 "TARGET_SINGLE_FPU &&
6772 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6787 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6788 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6790 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6791 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6793 ;; Because SF values are actually stored as DF values within the vector
6794 ;; registers, we need to convert the value to the vector SF format when
6795 ;; we need to use the bits in a union or similar cases. We only need
6796 ;; to do this transformation when the value is a vector register. Loads,
6797 ;; stores, and transfers within GPRs are assumed to be safe.
6799 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6800 ;; no alternatives, because the call is created as part of secondary_reload,
6801 ;; and operand #2's register class is used to allocate the temporary register.
6802 ;; This function is called before reload, and it creates the temporary as
6805 ;; MR LWZ LFIWZX LXSIWZX STW
6806 ;; STFS STXSSP STXSSPX VSX->GPR MTVSRWZ
6809 (define_insn_and_split "movsi_from_sf"
6810 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6811 "=r, r, ?*wI, ?*wH, m,
6815 (unspec:SI [(match_operand:SF 1 "input_operand"
6821 (clobber (match_scratch:V4SF 2
6826 "TARGET_NO_SF_SUBREG
6827 && (register_operand (operands[0], SImode)
6828 || register_operand (operands[1], SFmode))"
6841 "&& reload_completed
6842 && register_operand (operands[0], SImode)
6843 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6846 rtx op0 = operands[0];
6847 rtx op1 = operands[1];
6848 rtx op2 = operands[2];
6849 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6851 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6853 if (int_reg_operand (op0, SImode))
6855 emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6856 emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6860 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6861 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6862 emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6868 "*, load, fpload, fpload, store,
6869 fpstore, fpstore, fpstore, mftgpr, mffgpr,
6877 ;; movsi_from_sf with zero extension
6879 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6882 (define_insn_and_split "*movdi_from_sf_zero_ext"
6883 [(set (match_operand:DI 0 "gpc_reg_operand"
6884 "=r, r, ?*wI, ?*wH, r,
6888 (unspec:SI [(match_operand:SF 1 "input_operand"
6891 UNSPEC_SI_FROM_SF)))
6893 (clobber (match_scratch:V4SF 2
6897 "TARGET_DIRECT_MOVE_64BIT
6898 && (register_operand (operands[0], DImode)
6899 || register_operand (operands[1], SImode))"
6908 "&& reload_completed
6909 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6912 rtx op0 = operands[0];
6913 rtx op1 = operands[1];
6914 rtx op2 = operands[2];
6916 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6918 if (int_reg_operand (op0, DImode))
6920 emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6921 emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6925 rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6926 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6927 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6928 emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
6934 "*, load, fpload, fpload, mftgpr,
6935 mffgpr, veclogical")
6941 ;; Split a load of a large constant into the appropriate two-insn
6945 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6946 (match_operand:SI 1 "const_int_operand" ""))]
6947 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6948 && (INTVAL (operands[1]) & 0xffff) != 0"
6952 (ior:SI (match_dup 0)
6956 if (rs6000_emit_set_const (operands[0], operands[1]))
6962 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6964 [(set (match_operand:DI 0 "altivec_register_operand")
6965 (match_operand:DI 1 "xxspltib_constant_split"))]
6966 "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
6969 rtx op0 = operands[0];
6970 rtx op1 = operands[1];
6971 int r = REGNO (op0);
6972 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6974 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6975 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6979 (define_insn "*mov<mode>_internal2"
6980 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6981 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6983 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6989 [(set_attr "type" "cmp,logical,cmp")
6990 (set_attr "dot" "yes")
6991 (set_attr "length" "4,4,8")])
6994 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6995 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6997 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6999 [(set (match_dup 0) (match_dup 1))
7001 (compare:CC (match_dup 0)
7005 (define_expand "mov<mode>"
7006 [(set (match_operand:INT 0 "general_operand" "")
7007 (match_operand:INT 1 "any_operand" ""))]
7009 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7011 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7012 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7013 ;; MTVSRWZ MF%1 MT%1 NOP
7014 (define_insn "*mov<mode>_internal"
7015 [(set (match_operand:QHI 0 "nonimmediate_operand"
7016 "=r, r, ?*wJwK, m, Z, r,
7017 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7018 ?*wJwK, r, *c*l, *h")
7020 (match_operand:QHI 1 "input_operand"
7021 "r, m, Z, r, wJwK, i,
7022 wJwK, O, wM, wB, wS, ?*wJwK,
7025 "gpc_reg_operand (operands[0], <MODE>mode)
7026 || gpc_reg_operand (operands[1], <MODE>mode)"
7045 "*, load, fpload, store, fpstore, *,
7046 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7047 mffgpr, mfjmpr, mtjmpr, *")
7055 ;; Here is how to move condition codes around. When we store CC data in
7056 ;; an integer register or memory, we store just the high-order 4 bits.
7057 ;; This lets us not shift in the most common case of CR0.
7058 (define_expand "movcc"
7059 [(set (match_operand:CC 0 "nonimmediate_operand" "")
7060 (match_operand:CC 1 "nonimmediate_operand" ""))]
7064 (define_insn "*movcc_internal1"
7065 [(set (match_operand:CC 0 "nonimmediate_operand"
7066 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7067 (match_operand:CC 1 "general_operand"
7068 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7069 "register_operand (operands[0], CCmode)
7070 || register_operand (operands[1], CCmode)"
7074 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7077 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7085 (cond [(eq_attr "alternative" "0,3")
7086 (const_string "cr_logical")
7087 (eq_attr "alternative" "1,2")
7088 (const_string "mtcr")
7089 (eq_attr "alternative" "6,7")
7090 (const_string "integer")
7091 (eq_attr "alternative" "8")
7092 (const_string "mfjmpr")
7093 (eq_attr "alternative" "9")
7094 (const_string "mtjmpr")
7095 (eq_attr "alternative" "10")
7096 (const_string "load")
7097 (eq_attr "alternative" "11")
7098 (const_string "store")
7099 (match_test "TARGET_MFCRF")
7100 (const_string "mfcrf")
7102 (const_string "mfcr")))
7103 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7105 ;; For floating-point, we normally deal with the floating-point registers
7106 ;; unless -msoft-float is used. The sole exception is that parameter passing
7107 ;; can produce floating-point values in fixed-point registers. Unless the
7108 ;; value is a simple constant or already in memory, we deal with this by
7109 ;; allocating memory and copying the value explicitly via that memory location.
7111 ;; Move 32-bit binary/decimal floating point
7112 (define_expand "mov<mode>"
7113 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7114 (match_operand:FMOVE32 1 "any_operand" ""))]
7116 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7119 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7120 (match_operand:FMOVE32 1 "const_double_operand" ""))]
7122 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7123 || (GET_CODE (operands[0]) == SUBREG
7124 && GET_CODE (SUBREG_REG (operands[0])) == REG
7125 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7126 [(set (match_dup 2) (match_dup 3))]
7131 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7133 if (! TARGET_POWERPC64)
7134 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7136 operands[2] = gen_lowpart (SImode, operands[0]);
7138 operands[3] = gen_int_mode (l, SImode);
7141 (define_insn "mov<mode>_hardfloat"
7142 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7143 "=!r, <f32_lr>, <f32_lr2>, <f32_av>, m, <f32_sm>,
7144 <f32_sm2>, Z, <f32_vsx>, !r, ?<f32_dm>, ?r,
7145 f, <f32_vsx>, !r, *c*l, !r, *h")
7146 (match_operand:FMOVE32 1 "input_operand"
7147 "m, <f32_lm>, <f32_lm2>, Z, r, <f32_sr>,
7148 <f32_sr2>, <f32_av>, <zero_fp>, <zero_fp>, r, <f32_dm>,
7149 f, <f32_vsx>, r, r, *h, 0"))]
7150 "(register_operand (operands[0], <MODE>mode)
7151 || register_operand (operands[1], <MODE>mode))
7152 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7153 && (TARGET_ALLOW_SF_SUBREG
7154 || valid_sf_si_move (operands[0], operands[1], <MODE>mode))"
7169 xscpsgndp %x0,%x1,%x1
7174 [(set_attr "type" "load,fpload,fpload,fpload,store,fpstore,fpstore,fpstore,veclogical,integer,mffgpr,mftgpr,fpsimple,fpsimple,*,mtjmpr,mfjmpr,*")])
7176 (define_insn "*mov<mode>_softfloat"
7177 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7178 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7179 "(gpc_reg_operand (operands[0], <MODE>mode)
7180 || gpc_reg_operand (operands[1], <MODE>mode))
7181 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7193 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7194 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7196 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7197 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7199 ;; Because SF values are actually stored as DF values within the vector
7200 ;; registers, we need to convert the value to the vector SF format when
7201 ;; we need to use the bits in a union or similar cases. We only need
7202 ;; to do this transformation when the value is a vector register. Loads,
7203 ;; stores, and transfers within GPRs are assumed to be safe.
7205 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7206 ;; no alternatives, because the call is created as part of secondary_reload,
7207 ;; and operand #2's register class is used to allocate the temporary register.
7208 ;; This function is called before reload, and it creates the temporary as
7211 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7212 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7213 (define_insn_and_split "movsf_from_si"
7214 [(set (match_operand:SF 0 "rs6000_nonimmediate_operand"
7215 "=!r, f, wb, wu, m, Z,
7218 (unspec:SF [(match_operand:SI 1 "input_operand"
7223 (clobber (match_scratch:DI 2
7227 "TARGET_NO_SF_SUBREG
7228 && (register_operand (operands[0], SFmode)
7229 || register_operand (operands[1], SImode))"
7242 "&& reload_completed
7243 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7244 && int_reg_operand_not_pseudo (operands[1], SImode)"
7247 rtx op0 = operands[0];
7248 rtx op1 = operands[1];
7249 rtx op2 = operands[2];
7250 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7252 /* Move SF value to upper 32-bits for xscvspdpn. */
7253 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7254 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7255 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7262 "load, fpload, fpload, fpload, store, fpstore,
7263 fpstore, vecfloat, mffgpr, *")])
7266 ;; Move 64-bit binary/decimal floating point
7267 (define_expand "mov<mode>"
7268 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7269 (match_operand:FMOVE64 1 "any_operand" ""))]
7271 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7274 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7275 (match_operand:FMOVE64 1 "const_int_operand" ""))]
7276 "! TARGET_POWERPC64 && reload_completed
7277 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7278 || (GET_CODE (operands[0]) == SUBREG
7279 && GET_CODE (SUBREG_REG (operands[0])) == REG
7280 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7281 [(set (match_dup 2) (match_dup 4))
7282 (set (match_dup 3) (match_dup 1))]
7285 int endian = (WORDS_BIG_ENDIAN == 0);
7286 HOST_WIDE_INT value = INTVAL (operands[1]);
7288 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7289 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7290 operands[4] = GEN_INT (value >> 32);
7291 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7295 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7296 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7297 "! TARGET_POWERPC64 && reload_completed
7298 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7299 || (GET_CODE (operands[0]) == SUBREG
7300 && GET_CODE (SUBREG_REG (operands[0])) == REG
7301 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7302 [(set (match_dup 2) (match_dup 4))
7303 (set (match_dup 3) (match_dup 5))]
7306 int endian = (WORDS_BIG_ENDIAN == 0);
7309 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7311 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7312 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7313 operands[4] = gen_int_mode (l[endian], SImode);
7314 operands[5] = gen_int_mode (l[1 - endian], SImode);
7318 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7319 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7320 "TARGET_POWERPC64 && reload_completed
7321 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7322 || (GET_CODE (operands[0]) == SUBREG
7323 && GET_CODE (SUBREG_REG (operands[0])) == REG
7324 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7325 [(set (match_dup 2) (match_dup 3))]
7328 int endian = (WORDS_BIG_ENDIAN == 0);
7332 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7334 operands[2] = gen_lowpart (DImode, operands[0]);
7335 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7336 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7337 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7339 operands[3] = gen_int_mode (val, DImode);
7342 ;; Don't have reload use general registers to load a constant. It is
7343 ;; less efficient than loading the constant into an FP register, since
7344 ;; it will probably be used there.
7346 ;; The move constraints are ordered to prefer floating point registers before
7347 ;; general purpose registers to avoid doing a store and a load to get the value
7348 ;; into a floating point register when it is needed for a floating point
7349 ;; operation. Prefer traditional floating point registers over VSX registers,
7350 ;; since the D-form version of the memory instructions does not need a GPR for
7351 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7354 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7355 ;; except for 0.0 which can be created on VSX with an xor instruction.
7357 (define_insn "*mov<mode>_hardfloat32"
7358 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7359 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7360 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7361 && (gpc_reg_operand (operands[0], <MODE>mode)
7362 || gpc_reg_operand (operands[1], <MODE>mode))"
7377 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7378 (set_attr "size" "64")
7379 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7381 (define_insn "*mov<mode>_softfloat32"
7382 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7383 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7385 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
7386 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7387 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7388 && (gpc_reg_operand (operands[0], <MODE>mode)
7389 || gpc_reg_operand (operands[1], <MODE>mode))"
7391 [(set_attr "type" "store,load,two,*,*,*")
7392 (set_attr "length" "8,8,8,8,12,16")])
7394 ; ld/std require word-aligned displacements -> 'Y' constraint.
7395 ; List Y->r and r->Y before r->r for reload.
7396 (define_insn "*mov<mode>_hardfloat64"
7397 [(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>")
7398 (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"))]
7399 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7400 && (gpc_reg_operand (operands[0], <MODE>mode)
7401 || gpc_reg_operand (operands[1], <MODE>mode))"
7423 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7424 (set_attr "size" "64")
7425 (set_attr "length" "4")])
7427 (define_insn "*mov<mode>_softfloat64"
7428 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7429 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7430 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7431 && (gpc_reg_operand (operands[0], <MODE>mode)
7432 || gpc_reg_operand (operands[1], <MODE>mode))"
7443 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7444 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7446 (define_expand "mov<mode>"
7447 [(set (match_operand:FMOVE128 0 "general_operand" "")
7448 (match_operand:FMOVE128 1 "any_operand" ""))]
7450 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7452 ;; It's important to list Y->r and r->Y before r->r because otherwise
7453 ;; reload, given m->r, will try to pick r->r and reload it, which
7454 ;; doesn't make progress.
7456 ;; We can't split little endian direct moves of TDmode, because the words are
7457 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7458 ;; problematical. Don't allow direct move for this case.
7460 (define_insn_and_split "*mov<mode>_64bit_dm"
7461 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7462 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7463 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7464 && FLOAT128_2REG_P (<MODE>mode)
7465 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7466 && (gpc_reg_operand (operands[0], <MODE>mode)
7467 || gpc_reg_operand (operands[1], <MODE>mode))"
7469 "&& reload_completed"
7471 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7472 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7474 (define_insn_and_split "*movtd_64bit_nodm"
7475 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7476 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7477 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7478 && (gpc_reg_operand (operands[0], TDmode)
7479 || gpc_reg_operand (operands[1], TDmode))"
7481 "&& reload_completed"
7483 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7484 [(set_attr "length" "8,8,8,12,12,8")])
7486 (define_insn_and_split "*mov<mode>_32bit"
7487 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7488 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7489 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7490 && (FLOAT128_2REG_P (<MODE>mode)
7491 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7492 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7493 && (gpc_reg_operand (operands[0], <MODE>mode)
7494 || gpc_reg_operand (operands[1], <MODE>mode))"
7496 "&& reload_completed"
7498 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7499 [(set_attr "length" "8,8,8,8,20,20,16")])
7501 (define_insn_and_split "*mov<mode>_softfloat"
7502 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7503 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7504 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7505 && (gpc_reg_operand (operands[0], <MODE>mode)
7506 || gpc_reg_operand (operands[1], <MODE>mode))"
7508 "&& reload_completed"
7510 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7511 [(set_attr "length" "20,20,16")])
7513 (define_expand "extenddf<mode>2"
7514 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7515 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7516 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7517 && TARGET_LONG_DOUBLE_128"
7519 if (FLOAT128_IEEE_P (<MODE>mode))
7520 rs6000_expand_float128_convert (operands[0], operands[1], false);
7521 else if (TARGET_E500_DOUBLE)
7523 gcc_assert (<MODE>mode == TFmode);
7524 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7526 else if (TARGET_VSX)
7528 if (<MODE>mode == TFmode)
7529 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7530 else if (<MODE>mode == IFmode)
7531 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7537 rtx zero = gen_reg_rtx (DFmode);
7538 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7540 if (<MODE>mode == TFmode)
7541 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7542 else if (<MODE>mode == IFmode)
7543 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7550 ;; Allow memory operands for the source to be created by the combiner.
7551 (define_insn_and_split "extenddf<mode>2_fprs"
7552 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7553 (float_extend:IBM128
7554 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7555 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7556 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7557 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7559 "&& reload_completed"
7560 [(set (match_dup 3) (match_dup 1))
7561 (set (match_dup 4) (match_dup 2))]
7563 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7564 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7566 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7567 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7570 (define_insn_and_split "extenddf<mode>2_vsx"
7571 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7572 (float_extend:IBM128
7573 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7574 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7576 "&& reload_completed"
7577 [(set (match_dup 2) (match_dup 1))
7578 (set (match_dup 3) (match_dup 4))]
7580 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7581 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7583 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7584 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7585 operands[4] = CONST0_RTX (DFmode);
7588 (define_expand "extendsf<mode>2"
7589 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7590 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7592 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7593 && TARGET_LONG_DOUBLE_128"
7595 if (FLOAT128_IEEE_P (<MODE>mode))
7596 rs6000_expand_float128_convert (operands[0], operands[1], false);
7599 rtx tmp = gen_reg_rtx (DFmode);
7600 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7601 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7606 (define_expand "trunc<mode>df2"
7607 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7608 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7610 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7611 && TARGET_LONG_DOUBLE_128"
7613 if (FLOAT128_IEEE_P (<MODE>mode))
7615 rs6000_expand_float128_convert (operands[0], operands[1], false);
7620 (define_insn_and_split "trunc<mode>df2_internal1"
7621 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7623 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7624 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7625 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7629 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7632 emit_note (NOTE_INSN_DELETED);
7635 [(set_attr "type" "fpsimple")])
7637 (define_insn "trunc<mode>df2_internal2"
7638 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7639 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7640 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7641 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7643 [(set_attr "type" "fp")
7644 (set_attr "fp_type" "fp_addsub_d")])
7646 (define_expand "trunc<mode>sf2"
7647 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7648 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7650 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7651 && TARGET_LONG_DOUBLE_128"
7653 if (FLOAT128_IEEE_P (<MODE>mode))
7654 rs6000_expand_float128_convert (operands[0], operands[1], false);
7655 else if (TARGET_E500_DOUBLE)
7657 gcc_assert (<MODE>mode == TFmode);
7658 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7660 else if (<MODE>mode == TFmode)
7661 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7662 else if (<MODE>mode == IFmode)
7663 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7669 (define_insn_and_split "trunc<mode>sf2_fprs"
7670 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7671 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7672 (clobber (match_scratch:DF 2 "=d"))]
7673 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7674 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7676 "&& reload_completed"
7678 (float_truncate:DF (match_dup 1)))
7680 (float_truncate:SF (match_dup 2)))]
7683 (define_expand "floatsi<mode>2"
7684 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7685 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7686 (clobber (match_scratch:DI 2))])]
7688 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7689 && TARGET_LONG_DOUBLE_128"
7691 rtx op0 = operands[0];
7692 rtx op1 = operands[1];
7694 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7696 else if (FLOAT128_IEEE_P (<MODE>mode))
7698 rs6000_expand_float128_convert (op0, op1, false);
7703 rtx tmp = gen_reg_rtx (DFmode);
7704 expand_float (tmp, op1, false);
7705 if (<MODE>mode == TFmode)
7706 emit_insn (gen_extenddftf2 (op0, tmp));
7707 else if (<MODE>mode == IFmode)
7708 emit_insn (gen_extenddfif2 (op0, tmp));
7715 ; fadd, but rounding towards zero.
7716 ; This is probably not the optimal code sequence.
7717 (define_insn "fix_trunc_helper<mode>"
7718 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7719 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7720 UNSPEC_FIX_TRUNC_TF))
7721 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7722 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7723 && FLOAT128_IBM_P (<MODE>mode)"
7724 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7725 [(set_attr "type" "fp")
7726 (set_attr "length" "20")])
7728 (define_expand "fix_trunc<mode>si2"
7729 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7730 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7732 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7734 rtx op0 = operands[0];
7735 rtx op1 = operands[1];
7737 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7741 if (FLOAT128_IEEE_P (<MODE>mode))
7742 rs6000_expand_float128_convert (op0, op1, false);
7743 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7744 emit_insn (gen_spe_fix_trunctfsi2 (op0, op1));
7745 else if (<MODE>mode == TFmode)
7746 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7747 else if (<MODE>mode == IFmode)
7748 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7755 (define_expand "fix_trunc<mode>si2_fprs"
7756 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7757 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7758 (clobber (match_dup 2))
7759 (clobber (match_dup 3))
7760 (clobber (match_dup 4))
7761 (clobber (match_dup 5))])]
7762 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7764 operands[2] = gen_reg_rtx (DFmode);
7765 operands[3] = gen_reg_rtx (DFmode);
7766 operands[4] = gen_reg_rtx (DImode);
7767 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7770 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7771 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7772 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7773 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7774 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7775 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7776 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7777 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7783 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7786 gcc_assert (MEM_P (operands[5]));
7787 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7789 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7790 emit_move_insn (operands[5], operands[4]);
7791 emit_move_insn (operands[0], lowword);
7795 (define_expand "fix_trunc<mode>di2"
7796 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7797 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7798 "TARGET_FLOAT128_TYPE"
7800 if (!TARGET_FLOAT128_HW)
7802 rs6000_expand_float128_convert (operands[0], operands[1], false);
7807 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7808 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7809 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7810 "TARGET_FLOAT128_TYPE"
7812 rs6000_expand_float128_convert (operands[0], operands[1], true);
7816 (define_expand "floatdi<mode>2"
7817 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7818 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7819 "TARGET_FLOAT128_TYPE"
7821 if (!TARGET_FLOAT128_HW)
7823 rs6000_expand_float128_convert (operands[0], operands[1], false);
7828 (define_expand "floatunsdi<IEEE128:mode>2"
7829 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7830 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7831 "TARGET_FLOAT128_TYPE"
7833 if (!TARGET_FLOAT128_HW)
7835 rs6000_expand_float128_convert (operands[0], operands[1], true);
7840 (define_expand "floatuns<IEEE128:mode>2"
7841 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7842 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7843 "TARGET_FLOAT128_TYPE"
7845 rtx op0 = operands[0];
7846 rtx op1 = operands[1];
7848 if (TARGET_FLOAT128_HW)
7849 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7851 rs6000_expand_float128_convert (op0, op1, true);
7855 (define_expand "neg<mode>2"
7856 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7857 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7858 "FLOAT128_IEEE_P (<MODE>mode)
7859 || (FLOAT128_IBM_P (<MODE>mode)
7860 && TARGET_HARD_FLOAT
7861 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7864 if (FLOAT128_IEEE_P (<MODE>mode))
7866 if (TARGET_FLOAT128_HW)
7868 if (<MODE>mode == TFmode)
7869 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7870 else if (<MODE>mode == KFmode)
7871 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7875 else if (TARGET_FLOAT128_TYPE)
7877 if (<MODE>mode == TFmode)
7878 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7879 else if (<MODE>mode == KFmode)
7880 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7886 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7887 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7889 operands[1], <MODE>mode);
7891 if (target && !rtx_equal_p (target, operands[0]))
7892 emit_move_insn (operands[0], target);
7898 (define_insn "neg<mode>2_internal"
7899 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7900 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7901 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7904 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7905 return \"fneg %L0,%L1\;fneg %0,%1\";
7907 return \"fneg %0,%1\;fneg %L0,%L1\";
7909 [(set_attr "type" "fpsimple")
7910 (set_attr "length" "8")])
7912 (define_expand "abs<mode>2"
7913 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7914 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7915 "FLOAT128_IEEE_P (<MODE>mode)
7916 || (FLOAT128_IBM_P (<MODE>mode)
7917 && TARGET_HARD_FLOAT
7918 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7923 if (FLOAT128_IEEE_P (<MODE>mode))
7925 if (TARGET_FLOAT128_HW)
7927 if (<MODE>mode == TFmode)
7928 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7929 else if (<MODE>mode == KFmode)
7930 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7935 else if (TARGET_FLOAT128_TYPE)
7937 if (<MODE>mode == TFmode)
7938 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7939 else if (<MODE>mode == KFmode)
7940 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7949 label = gen_label_rtx ();
7950 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7952 if (flag_finite_math_only && !flag_trapping_math)
7953 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7955 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7957 else if (<MODE>mode == TFmode)
7958 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7959 else if (<MODE>mode == TFmode)
7960 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7967 (define_expand "abs<mode>2_internal"
7968 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7969 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7970 (set (match_dup 3) (match_dup 5))
7971 (set (match_dup 5) (abs:DF (match_dup 5)))
7972 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7973 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7974 (label_ref (match_operand 2 "" ""))
7976 (set (match_dup 6) (neg:DF (match_dup 6)))]
7977 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7978 && TARGET_LONG_DOUBLE_128"
7981 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7982 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7983 operands[3] = gen_reg_rtx (DFmode);
7984 operands[4] = gen_reg_rtx (CCFPmode);
7985 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7986 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7990 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7993 (define_expand "ieee_128bit_negative_zero"
7994 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7995 "TARGET_FLOAT128_TYPE"
7997 rtvec v = rtvec_alloc (16);
8000 for (i = 0; i < 16; i++)
8001 RTVEC_ELT (v, i) = const0_rtx;
8003 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8004 RTVEC_ELT (v, high) = GEN_INT (0x80);
8006 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8010 ;; IEEE 128-bit negate
8012 ;; We have 2 insns here for negate and absolute value. The first uses
8013 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8014 ;; insns, and second insn after the first split pass loads up the bit to
8015 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8016 ;; neg/abs to create the constant just once.
8018 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8019 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8020 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8021 (clobber (match_scratch:V16QI 2 "=v"))]
8022 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8025 [(parallel [(set (match_dup 0)
8026 (neg:IEEE128 (match_dup 1)))
8027 (use (match_dup 2))])]
8029 if (GET_CODE (operands[2]) == SCRATCH)
8030 operands[2] = gen_reg_rtx (V16QImode);
8032 operands[3] = gen_reg_rtx (V16QImode);
8033 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8035 [(set_attr "length" "8")
8036 (set_attr "type" "vecsimple")])
8038 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8039 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8040 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8041 (use (match_operand:V16QI 2 "register_operand" "v"))]
8042 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8043 "xxlxor %x0,%x1,%x2"
8044 [(set_attr "type" "veclogical")])
8046 ;; IEEE 128-bit absolute value
8047 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8048 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8049 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8050 (clobber (match_scratch:V16QI 2 "=v"))]
8051 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8054 [(parallel [(set (match_dup 0)
8055 (abs:IEEE128 (match_dup 1)))
8056 (use (match_dup 2))])]
8058 if (GET_CODE (operands[2]) == SCRATCH)
8059 operands[2] = gen_reg_rtx (V16QImode);
8061 operands[3] = gen_reg_rtx (V16QImode);
8062 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8064 [(set_attr "length" "8")
8065 (set_attr "type" "vecsimple")])
8067 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8068 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8069 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8070 (use (match_operand:V16QI 2 "register_operand" "v"))]
8071 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8072 "xxlandc %x0,%x1,%x2"
8073 [(set_attr "type" "veclogical")])
8075 ;; IEEE 128-bit negative absolute value
8076 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8077 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8080 (match_operand:IEEE128 1 "register_operand" "wa"))))
8081 (clobber (match_scratch:V16QI 2 "=v"))]
8082 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8083 && FLOAT128_IEEE_P (<MODE>mode)"
8086 [(parallel [(set (match_dup 0)
8087 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8088 (use (match_dup 2))])]
8090 if (GET_CODE (operands[2]) == SCRATCH)
8091 operands[2] = gen_reg_rtx (V16QImode);
8093 operands[3] = gen_reg_rtx (V16QImode);
8094 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8096 [(set_attr "length" "8")
8097 (set_attr "type" "vecsimple")])
8099 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8100 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8103 (match_operand:IEEE128 1 "register_operand" "wa"))))
8104 (use (match_operand:V16QI 2 "register_operand" "v"))]
8105 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8107 [(set_attr "type" "veclogical")])
8109 ;; Float128 conversion functions. These expand to library function calls.
8110 ;; We use expand to convert from IBM double double to IEEE 128-bit
8111 ;; and trunc for the opposite.
8112 (define_expand "extendiftf2"
8113 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8114 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8115 "TARGET_FLOAT128_TYPE"
8117 rs6000_expand_float128_convert (operands[0], operands[1], false);
8121 (define_expand "extendifkf2"
8122 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8123 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8124 "TARGET_FLOAT128_TYPE"
8126 rs6000_expand_float128_convert (operands[0], operands[1], false);
8130 (define_expand "extendtfkf2"
8131 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8132 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8133 "TARGET_FLOAT128_TYPE"
8135 rs6000_expand_float128_convert (operands[0], operands[1], false);
8139 (define_expand "trunciftf2"
8140 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8141 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8142 "TARGET_FLOAT128_TYPE"
8144 rs6000_expand_float128_convert (operands[0], operands[1], false);
8148 (define_expand "truncifkf2"
8149 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8150 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8151 "TARGET_FLOAT128_TYPE"
8153 rs6000_expand_float128_convert (operands[0], operands[1], false);
8157 (define_expand "trunckftf2"
8158 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8159 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8160 "TARGET_FLOAT128_TYPE"
8162 rs6000_expand_float128_convert (operands[0], operands[1], false);
8166 (define_expand "trunctfif2"
8167 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8168 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8169 "TARGET_FLOAT128_TYPE"
8171 rs6000_expand_float128_convert (operands[0], operands[1], false);
8176 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8177 ;; must have 3 arguments, and scratch register constraint must be a single
8180 ;; Reload patterns to support gpr load/store with misaligned mem.
8181 ;; and multiple gpr load/store at offset >= 0xfffc
8182 (define_expand "reload_<mode>_store"
8183 [(parallel [(match_operand 0 "memory_operand" "=m")
8184 (match_operand 1 "gpc_reg_operand" "r")
8185 (match_operand:GPR 2 "register_operand" "=&b")])]
8188 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8192 (define_expand "reload_<mode>_load"
8193 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8194 (match_operand 1 "memory_operand" "m")
8195 (match_operand:GPR 2 "register_operand" "=b")])]
8198 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8203 ;; Reload patterns for various types using the vector registers. We may need
8204 ;; an additional base register to convert the reg+offset addressing to reg+reg
8205 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8206 ;; index register for gpr registers.
8207 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8208 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8209 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8210 (match_operand:P 2 "register_operand" "=b")])]
8213 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8217 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8218 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8219 (match_operand:RELOAD 1 "memory_operand" "m")
8220 (match_operand:P 2 "register_operand" "=b")])]
8223 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8228 ;; Reload sometimes tries to move the address to a GPR, and can generate
8229 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8230 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8232 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8233 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8234 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8235 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8237 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
8239 "&& reload_completed"
8241 (plus:P (match_dup 1)
8244 (and:P (match_dup 0)
8247 ;; Power8 merge instructions to allow direct move to/from floating point
8248 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8249 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8250 ;; value, since it is allocated in reload and not all of the flow information
8251 ;; is setup for it. We have two patterns to do the two moves between gprs and
8252 ;; fprs. There isn't a dependancy between the two, but we could potentially
8253 ;; schedule other instructions between the two instructions.
8255 (define_insn "p8_fmrgow_<mode>"
8256 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8258 (match_operand:DF 1 "register_operand" "d")
8259 (match_operand:DF 2 "register_operand" "d")]
8260 UNSPEC_P8V_FMRGOW))]
8261 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8263 [(set_attr "type" "fpsimple")])
8265 (define_insn "p8_mtvsrwz"
8266 [(set (match_operand:DF 0 "register_operand" "=d")
8267 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8268 UNSPEC_P8V_MTVSRWZ))]
8269 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8271 [(set_attr "type" "mftgpr")])
8273 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8274 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8275 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8276 UNSPEC_P8V_RELOAD_FROM_GPR))
8277 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8278 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8280 "&& reload_completed"
8283 rtx dest = operands[0];
8284 rtx src = operands[1];
8285 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8286 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8287 rtx gpr_hi_reg = gen_highpart (SImode, src);
8288 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8290 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8291 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8292 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8295 [(set_attr "length" "12")
8296 (set_attr "type" "three")])
8298 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8299 (define_insn "p8_mtvsrd_df"
8300 [(set (match_operand:DF 0 "register_operand" "=wa")
8301 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8302 UNSPEC_P8V_MTVSRD))]
8303 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8305 [(set_attr "type" "mftgpr")])
8307 (define_insn "p8_xxpermdi_<mode>"
8308 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8309 (unspec:FMOVE128_GPR [
8310 (match_operand:DF 1 "register_operand" "wa")
8311 (match_operand:DF 2 "register_operand" "wa")]
8312 UNSPEC_P8V_XXPERMDI))]
8313 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8314 "xxpermdi %x0,%x1,%x2,0"
8315 [(set_attr "type" "vecperm")])
8317 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8318 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8319 (unspec:FMOVE128_GPR
8320 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8321 UNSPEC_P8V_RELOAD_FROM_GPR))
8322 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8323 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8325 "&& reload_completed"
8328 rtx dest = operands[0];
8329 rtx src = operands[1];
8330 /* You might think that we could use op0 as one temp and a DF clobber
8331 as op2, but you'd be wrong. Secondary reload move patterns don't
8332 check for overlap of the clobber and the destination. */
8333 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8334 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8335 rtx gpr_hi_reg = gen_highpart (DImode, src);
8336 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8338 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8339 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8340 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8343 [(set_attr "length" "12")
8344 (set_attr "type" "three")])
8347 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8348 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8350 && (int_reg_operand (operands[0], <MODE>mode)
8351 || int_reg_operand (operands[1], <MODE>mode))
8352 && (!TARGET_DIRECT_MOVE_128
8353 || (!vsx_register_operand (operands[0], <MODE>mode)
8354 && !vsx_register_operand (operands[1], <MODE>mode)))"
8356 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8358 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8359 ;; type is stored internally as double precision in the VSX registers, we have
8360 ;; to convert it from the vector format.
8361 (define_insn "p8_mtvsrd_sf"
8362 [(set (match_operand:SF 0 "register_operand" "=wa")
8363 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8364 UNSPEC_P8V_MTVSRD))]
8365 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8367 [(set_attr "type" "mftgpr")])
8369 (define_insn_and_split "reload_vsx_from_gprsf"
8370 [(set (match_operand:SF 0 "register_operand" "=wa")
8371 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8372 UNSPEC_P8V_RELOAD_FROM_GPR))
8373 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8374 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8376 "&& reload_completed"
8379 rtx op0 = operands[0];
8380 rtx op1 = operands[1];
8381 rtx op2 = operands[2];
8382 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8384 /* Move SF value to upper 32-bits for xscvspdpn. */
8385 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8386 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8387 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8390 [(set_attr "length" "8")
8391 (set_attr "type" "two")])
8393 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8394 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8395 ;; and then doing a move of that.
8396 (define_insn "p8_mfvsrd_3_<mode>"
8397 [(set (match_operand:DF 0 "register_operand" "=r")
8398 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8399 UNSPEC_P8V_RELOAD_FROM_VSX))]
8400 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8402 [(set_attr "type" "mftgpr")])
8404 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8405 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8406 (unspec:FMOVE128_GPR
8407 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8408 UNSPEC_P8V_RELOAD_FROM_VSX))
8409 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8410 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8412 "&& reload_completed"
8415 rtx dest = operands[0];
8416 rtx src = operands[1];
8417 rtx tmp = operands[2];
8418 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8419 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8421 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8422 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
8423 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8426 [(set_attr "length" "12")
8427 (set_attr "type" "three")])
8429 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8430 ;; type is stored internally as double precision, we have to convert it to the
8433 (define_insn_and_split "reload_gpr_from_vsxsf"
8434 [(set (match_operand:SF 0 "register_operand" "=r")
8435 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8436 UNSPEC_P8V_RELOAD_FROM_VSX))
8437 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8438 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8440 "&& reload_completed"
8443 rtx op0 = operands[0];
8444 rtx op1 = operands[1];
8445 rtx op2 = operands[2];
8446 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8448 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8449 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8450 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8453 [(set_attr "length" "12")
8454 (set_attr "type" "three")])
8456 (define_insn "p8_mfvsrd_4_disf"
8457 [(set (match_operand:DI 0 "register_operand" "=r")
8458 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8459 UNSPEC_P8V_RELOAD_FROM_VSX))]
8460 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8462 [(set_attr "type" "mftgpr")])
8465 ;; Next come the multi-word integer load and store and the load and store
8468 ;; List r->r after r->Y, otherwise reload will try to reload a
8469 ;; non-offsettable address by using r->r which won't make progress.
8470 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8471 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8473 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8474 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8475 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8478 (define_insn "*movdi_internal32"
8479 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8480 "=Y, r, r, ^m, ^d, ^d,
8481 r, ^wY, $Z, ^wb, $wv, ^wi,
8482 *wo, *wo, *wv, *wi, *wi, *wv,
8485 (match_operand:DI 1 "input_operand"
8487 IJKnGHF, wb, wv, wY, Z, wi,
8488 Oj, wM, OjwM, Oj, wM, wS,
8492 && (gpc_reg_operand (operands[0], DImode)
8493 || gpc_reg_operand (operands[1], DImode))"
8515 "store, load, *, fpstore, fpload, fpsimple,
8516 *, fpstore, fpstore, fpload, fpload, veclogical,
8517 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8519 (set_attr "size" "64")])
8522 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8523 (match_operand:DI 1 "const_int_operand" ""))]
8524 "! TARGET_POWERPC64 && reload_completed
8525 && gpr_or_gpr_p (operands[0], operands[1])
8526 && !direct_move_p (operands[0], operands[1])"
8527 [(set (match_dup 2) (match_dup 4))
8528 (set (match_dup 3) (match_dup 1))]
8531 HOST_WIDE_INT value = INTVAL (operands[1]);
8532 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8534 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8536 operands[4] = GEN_INT (value >> 32);
8537 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8541 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8542 (match_operand:DIFD 1 "input_operand" ""))]
8543 "reload_completed && !TARGET_POWERPC64
8544 && gpr_or_gpr_p (operands[0], operands[1])
8545 && !direct_move_p (operands[0], operands[1])"
8547 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8549 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8550 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8551 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8552 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8553 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8554 (define_insn "*movdi_internal64"
8555 [(set (match_operand:DI 0 "nonimmediate_operand"
8557 ^m, ^d, ^d, ^wY, $Z, $wb,
8558 $wv, ^wi, *wo, *wo, *wv, *wi,
8559 *wi, *wv, *wv, r, *h, *h,
8560 ?*r, ?*wg, ?*r, ?*wj")
8562 (match_operand:DI 1 "input_operand"
8564 d, m, d, wb, wv, wY,
8565 Z, wi, Oj, wM, OjwM, Oj,
8566 wM, wS, wB, *h, r, 0,
8570 && (gpc_reg_operand (operands[0], DImode)
8571 || gpc_reg_operand (operands[1], DImode))"
8602 "store, load, *, *, *, *,
8603 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8604 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8605 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8606 mftgpr, mffgpr, mftgpr, mffgpr")
8608 (set_attr "size" "64")
8616 ; Some DImode loads are best done as a load of -1 followed by a mask
8619 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8620 (match_operand:DI 1 "const_int_operand"))]
8622 && num_insns_constant (operands[1], DImode) > 1
8623 && rs6000_is_valid_and_mask (operands[1], DImode)"
8627 (and:DI (match_dup 0)
8631 ;; Split a load of a large constant into the appropriate five-instruction
8632 ;; sequence. Handle anything in a constant number of insns.
8633 ;; When non-easy constants can go in the TOC, this should use
8634 ;; easy_fp_constant predicate.
8636 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8637 (match_operand:DI 1 "const_int_operand" ""))]
8638 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8639 [(set (match_dup 0) (match_dup 2))
8640 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8643 if (rs6000_emit_set_const (operands[0], operands[1]))
8650 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8651 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8652 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8653 [(set (match_dup 0) (match_dup 2))
8654 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8657 if (rs6000_emit_set_const (operands[0], operands[1]))
8664 [(set (match_operand:DI 0 "altivec_register_operand" "")
8665 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8666 "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8669 rtx op0 = operands[0];
8670 rtx op1 = operands[1];
8671 int r = REGNO (op0);
8672 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8674 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8675 if (op1 != const0_rtx && op1 != constm1_rtx)
8677 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8678 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8683 ;; Split integer constants that can be loaded with XXSPLTIB and a
8684 ;; sign extend operation.
8686 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8687 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8688 "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8691 rtx op0 = operands[0];
8692 rtx op1 = operands[1];
8693 int r = REGNO (op0);
8694 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8696 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8697 if (<MODE>mode == DImode)
8698 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8699 else if (<MODE>mode == SImode)
8700 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8701 else if (<MODE>mode == HImode)
8703 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8704 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8710 ;; TImode/PTImode is similar, except that we usually want to compute the
8711 ;; address into a register and use lsi/stsi (the exception is during reload).
8713 (define_insn "*mov<mode>_string"
8714 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8715 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8717 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8718 && (gpc_reg_operand (operands[0], <MODE>mode)
8719 || gpc_reg_operand (operands[1], <MODE>mode))"
8722 switch (which_alternative)
8728 return \"stswi %1,%P0,16\";
8733 /* If the address is not used in the output, we can use lsi. Otherwise,
8734 fall through to generating four loads. */
8736 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8737 return \"lswi %0,%P1,16\";
8745 [(set_attr "type" "store,store,load,load,*,*")
8746 (set_attr "update" "yes")
8747 (set_attr "indexed" "yes")
8748 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8749 (const_string "always")
8750 (const_string "conditional")))])
8752 (define_insn "*mov<mode>_ppc64"
8753 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8754 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8755 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8756 && (gpc_reg_operand (operands[0], <MODE>mode)
8757 || gpc_reg_operand (operands[1], <MODE>mode)))"
8759 return rs6000_output_move_128bit (operands);
8761 [(set_attr "type" "store,store,load,load,*,*")
8762 (set_attr "length" "8")])
8765 [(set (match_operand:TI2 0 "int_reg_operand" "")
8766 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8768 && (VECTOR_MEM_NONE_P (<MODE>mode)
8769 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8770 [(set (match_dup 2) (match_dup 4))
8771 (set (match_dup 3) (match_dup 5))]
8774 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8776 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8778 if (CONST_WIDE_INT_P (operands[1]))
8780 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8781 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8783 else if (CONST_INT_P (operands[1]))
8785 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8786 operands[5] = operands[1];
8793 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8794 (match_operand:TI2 1 "input_operand" ""))]
8796 && gpr_or_gpr_p (operands[0], operands[1])
8797 && !direct_move_p (operands[0], operands[1])
8798 && !quad_load_store_p (operands[0], operands[1])"
8800 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8802 (define_expand "load_multiple"
8803 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8804 (match_operand:SI 1 "" ""))
8805 (use (match_operand:SI 2 "" ""))])]
8806 "TARGET_STRING && !TARGET_POWERPC64"
8814 /* Support only loading a constant number of fixed-point registers from
8815 memory and only bother with this if more than two; the machine
8816 doesn't support more than eight. */
8817 if (GET_CODE (operands[2]) != CONST_INT
8818 || INTVAL (operands[2]) <= 2
8819 || INTVAL (operands[2]) > 8
8820 || GET_CODE (operands[1]) != MEM
8821 || GET_CODE (operands[0]) != REG
8822 || REGNO (operands[0]) >= 32)
8825 count = INTVAL (operands[2]);
8826 regno = REGNO (operands[0]);
8828 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8829 op1 = replace_equiv_address (operands[1],
8830 force_reg (SImode, XEXP (operands[1], 0)));
8832 for (i = 0; i < count; i++)
8833 XVECEXP (operands[3], 0, i)
8834 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8835 adjust_address_nv (op1, SImode, i * 4));
8838 (define_insn "*ldmsi8"
8839 [(match_parallel 0 "load_multiple_operation"
8840 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8841 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8842 (set (match_operand:SI 3 "gpc_reg_operand" "")
8843 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8844 (set (match_operand:SI 4 "gpc_reg_operand" "")
8845 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8846 (set (match_operand:SI 5 "gpc_reg_operand" "")
8847 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8848 (set (match_operand:SI 6 "gpc_reg_operand" "")
8849 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8850 (set (match_operand:SI 7 "gpc_reg_operand" "")
8851 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8852 (set (match_operand:SI 8 "gpc_reg_operand" "")
8853 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8854 (set (match_operand:SI 9 "gpc_reg_operand" "")
8855 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8856 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8858 { return rs6000_output_load_multiple (operands); }"
8859 [(set_attr "type" "load")
8860 (set_attr "update" "yes")
8861 (set_attr "indexed" "yes")
8862 (set_attr "length" "32")])
8864 (define_insn "*ldmsi7"
8865 [(match_parallel 0 "load_multiple_operation"
8866 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8867 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8868 (set (match_operand:SI 3 "gpc_reg_operand" "")
8869 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8870 (set (match_operand:SI 4 "gpc_reg_operand" "")
8871 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8872 (set (match_operand:SI 5 "gpc_reg_operand" "")
8873 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8874 (set (match_operand:SI 6 "gpc_reg_operand" "")
8875 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8876 (set (match_operand:SI 7 "gpc_reg_operand" "")
8877 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8878 (set (match_operand:SI 8 "gpc_reg_operand" "")
8879 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8880 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8882 { return rs6000_output_load_multiple (operands); }"
8883 [(set_attr "type" "load")
8884 (set_attr "update" "yes")
8885 (set_attr "indexed" "yes")
8886 (set_attr "length" "32")])
8888 (define_insn "*ldmsi6"
8889 [(match_parallel 0 "load_multiple_operation"
8890 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8891 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8892 (set (match_operand:SI 3 "gpc_reg_operand" "")
8893 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8894 (set (match_operand:SI 4 "gpc_reg_operand" "")
8895 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8896 (set (match_operand:SI 5 "gpc_reg_operand" "")
8897 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8898 (set (match_operand:SI 6 "gpc_reg_operand" "")
8899 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8900 (set (match_operand:SI 7 "gpc_reg_operand" "")
8901 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8902 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8904 { return rs6000_output_load_multiple (operands); }"
8905 [(set_attr "type" "load")
8906 (set_attr "update" "yes")
8907 (set_attr "indexed" "yes")
8908 (set_attr "length" "32")])
8910 (define_insn "*ldmsi5"
8911 [(match_parallel 0 "load_multiple_operation"
8912 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8913 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8914 (set (match_operand:SI 3 "gpc_reg_operand" "")
8915 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8916 (set (match_operand:SI 4 "gpc_reg_operand" "")
8917 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8918 (set (match_operand:SI 5 "gpc_reg_operand" "")
8919 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8920 (set (match_operand:SI 6 "gpc_reg_operand" "")
8921 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8922 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8924 { return rs6000_output_load_multiple (operands); }"
8925 [(set_attr "type" "load")
8926 (set_attr "update" "yes")
8927 (set_attr "indexed" "yes")
8928 (set_attr "length" "32")])
8930 (define_insn "*ldmsi4"
8931 [(match_parallel 0 "load_multiple_operation"
8932 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8933 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8934 (set (match_operand:SI 3 "gpc_reg_operand" "")
8935 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8936 (set (match_operand:SI 4 "gpc_reg_operand" "")
8937 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8938 (set (match_operand:SI 5 "gpc_reg_operand" "")
8939 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8940 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8942 { return rs6000_output_load_multiple (operands); }"
8943 [(set_attr "type" "load")
8944 (set_attr "update" "yes")
8945 (set_attr "indexed" "yes")
8946 (set_attr "length" "32")])
8948 (define_insn "*ldmsi3"
8949 [(match_parallel 0 "load_multiple_operation"
8950 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8951 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8952 (set (match_operand:SI 3 "gpc_reg_operand" "")
8953 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8954 (set (match_operand:SI 4 "gpc_reg_operand" "")
8955 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8956 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8958 { return rs6000_output_load_multiple (operands); }"
8959 [(set_attr "type" "load")
8960 (set_attr "update" "yes")
8961 (set_attr "indexed" "yes")
8962 (set_attr "length" "32")])
8964 (define_expand "store_multiple"
8965 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8966 (match_operand:SI 1 "" ""))
8967 (clobber (scratch:SI))
8968 (use (match_operand:SI 2 "" ""))])]
8969 "TARGET_STRING && !TARGET_POWERPC64"
8978 /* Support only storing a constant number of fixed-point registers to
8979 memory and only bother with this if more than two; the machine
8980 doesn't support more than eight. */
8981 if (GET_CODE (operands[2]) != CONST_INT
8982 || INTVAL (operands[2]) <= 2
8983 || INTVAL (operands[2]) > 8
8984 || GET_CODE (operands[0]) != MEM
8985 || GET_CODE (operands[1]) != REG
8986 || REGNO (operands[1]) >= 32)
8989 count = INTVAL (operands[2]);
8990 regno = REGNO (operands[1]);
8992 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8993 to = force_reg (SImode, XEXP (operands[0], 0));
8994 op0 = replace_equiv_address (operands[0], to);
8996 XVECEXP (operands[3], 0, 0)
8997 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8998 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8999 gen_rtx_SCRATCH (SImode));
9001 for (i = 1; i < count; i++)
9002 XVECEXP (operands[3], 0, i + 1)
9003 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9004 gen_rtx_REG (SImode, regno + i));
9007 (define_insn "*stmsi8"
9008 [(match_parallel 0 "store_multiple_operation"
9009 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9010 (match_operand:SI 2 "gpc_reg_operand" "r"))
9011 (clobber (match_scratch:SI 3 "=X"))
9012 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9013 (match_operand:SI 4 "gpc_reg_operand" "r"))
9014 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9015 (match_operand:SI 5 "gpc_reg_operand" "r"))
9016 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9017 (match_operand:SI 6 "gpc_reg_operand" "r"))
9018 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9019 (match_operand:SI 7 "gpc_reg_operand" "r"))
9020 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9021 (match_operand:SI 8 "gpc_reg_operand" "r"))
9022 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9023 (match_operand:SI 9 "gpc_reg_operand" "r"))
9024 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9025 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9026 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9028 [(set_attr "type" "store")
9029 (set_attr "update" "yes")
9030 (set_attr "indexed" "yes")
9031 (set_attr "cell_micro" "always")])
9033 (define_insn "*stmsi7"
9034 [(match_parallel 0 "store_multiple_operation"
9035 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9036 (match_operand:SI 2 "gpc_reg_operand" "r"))
9037 (clobber (match_scratch:SI 3 "=X"))
9038 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9039 (match_operand:SI 4 "gpc_reg_operand" "r"))
9040 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9041 (match_operand:SI 5 "gpc_reg_operand" "r"))
9042 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9043 (match_operand:SI 6 "gpc_reg_operand" "r"))
9044 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9045 (match_operand:SI 7 "gpc_reg_operand" "r"))
9046 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9047 (match_operand:SI 8 "gpc_reg_operand" "r"))
9048 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9049 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9050 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9052 [(set_attr "type" "store")
9053 (set_attr "update" "yes")
9054 (set_attr "indexed" "yes")
9055 (set_attr "cell_micro" "always")])
9057 (define_insn "*stmsi6"
9058 [(match_parallel 0 "store_multiple_operation"
9059 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9060 (match_operand:SI 2 "gpc_reg_operand" "r"))
9061 (clobber (match_scratch:SI 3 "=X"))
9062 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9063 (match_operand:SI 4 "gpc_reg_operand" "r"))
9064 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9065 (match_operand:SI 5 "gpc_reg_operand" "r"))
9066 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9067 (match_operand:SI 6 "gpc_reg_operand" "r"))
9068 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9069 (match_operand:SI 7 "gpc_reg_operand" "r"))
9070 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9071 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9072 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9074 [(set_attr "type" "store")
9075 (set_attr "update" "yes")
9076 (set_attr "indexed" "yes")
9077 (set_attr "cell_micro" "always")])
9079 (define_insn "*stmsi5"
9080 [(match_parallel 0 "store_multiple_operation"
9081 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9082 (match_operand:SI 2 "gpc_reg_operand" "r"))
9083 (clobber (match_scratch:SI 3 "=X"))
9084 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9085 (match_operand:SI 4 "gpc_reg_operand" "r"))
9086 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9087 (match_operand:SI 5 "gpc_reg_operand" "r"))
9088 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9089 (match_operand:SI 6 "gpc_reg_operand" "r"))
9090 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9091 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9092 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9094 [(set_attr "type" "store")
9095 (set_attr "update" "yes")
9096 (set_attr "indexed" "yes")
9097 (set_attr "cell_micro" "always")])
9099 (define_insn "*stmsi4"
9100 [(match_parallel 0 "store_multiple_operation"
9101 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9102 (match_operand:SI 2 "gpc_reg_operand" "r"))
9103 (clobber (match_scratch:SI 3 "=X"))
9104 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9105 (match_operand:SI 4 "gpc_reg_operand" "r"))
9106 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9107 (match_operand:SI 5 "gpc_reg_operand" "r"))
9108 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9109 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9110 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9112 [(set_attr "type" "store")
9113 (set_attr "update" "yes")
9114 (set_attr "indexed" "yes")
9115 (set_attr "cell_micro" "always")])
9117 (define_insn "*stmsi3"
9118 [(match_parallel 0 "store_multiple_operation"
9119 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9120 (match_operand:SI 2 "gpc_reg_operand" "r"))
9121 (clobber (match_scratch:SI 3 "=X"))
9122 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9123 (match_operand:SI 4 "gpc_reg_operand" "r"))
9124 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9125 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9126 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9128 [(set_attr "type" "store")
9129 (set_attr "update" "yes")
9130 (set_attr "indexed" "yes")
9131 (set_attr "cell_micro" "always")])
9133 (define_expand "setmemsi"
9134 [(parallel [(set (match_operand:BLK 0 "" "")
9135 (match_operand 2 "const_int_operand" ""))
9136 (use (match_operand:SI 1 "" ""))
9137 (use (match_operand:SI 3 "" ""))])]
9141 /* If value to set is not zero, use the library routine. */
9142 if (operands[2] != const0_rtx)
9145 if (expand_block_clear (operands))
9151 ;; String compare N insn.
9152 ;; Argument 0 is the target (result)
9153 ;; Argument 1 is the destination
9154 ;; Argument 2 is the source
9155 ;; Argument 3 is the length
9156 ;; Argument 4 is the alignment
9158 (define_expand "cmpstrnsi"
9159 [(parallel [(set (match_operand:SI 0)
9160 (compare:SI (match_operand:BLK 1)
9161 (match_operand:BLK 2)))
9162 (use (match_operand:SI 3))
9163 (use (match_operand:SI 4))])]
9164 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9166 if (optimize_insn_for_size_p ())
9169 if (expand_strn_compare (operands, 0))
9175 ;; String compare insn.
9176 ;; Argument 0 is the target (result)
9177 ;; Argument 1 is the destination
9178 ;; Argument 2 is the source
9179 ;; Argument 3 is the alignment
9181 (define_expand "cmpstrsi"
9182 [(parallel [(set (match_operand:SI 0)
9183 (compare:SI (match_operand:BLK 1)
9184 (match_operand:BLK 2)))
9185 (use (match_operand:SI 3))])]
9186 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9188 if (optimize_insn_for_size_p ())
9191 if (expand_strn_compare (operands, 1))
9197 ;; Block compare insn.
9198 ;; Argument 0 is the target (result)
9199 ;; Argument 1 is the destination
9200 ;; Argument 2 is the source
9201 ;; Argument 3 is the length
9202 ;; Argument 4 is the alignment
9204 (define_expand "cmpmemsi"
9205 [(parallel [(set (match_operand:SI 0)
9206 (compare:SI (match_operand:BLK 1)
9207 (match_operand:BLK 2)))
9208 (use (match_operand:SI 3))
9209 (use (match_operand:SI 4))])]
9212 if (expand_block_compare (operands))
9218 ;; String/block move insn.
9219 ;; Argument 0 is the destination
9220 ;; Argument 1 is the source
9221 ;; Argument 2 is the length
9222 ;; Argument 3 is the alignment
9224 (define_expand "movmemsi"
9225 [(parallel [(set (match_operand:BLK 0 "" "")
9226 (match_operand:BLK 1 "" ""))
9227 (use (match_operand:SI 2 "" ""))
9228 (use (match_operand:SI 3 "" ""))])]
9232 if (expand_block_move (operands))
9238 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
9239 ;; register allocator doesn't have a clue about allocating 8 word registers.
9240 ;; rD/rS = r5 is preferred, efficient form.
9241 (define_expand "movmemsi_8reg"
9242 [(parallel [(set (match_operand 0 "" "")
9243 (match_operand 1 "" ""))
9244 (use (match_operand 2 "" ""))
9245 (use (match_operand 3 "" ""))
9246 (clobber (reg:SI 5))
9247 (clobber (reg:SI 6))
9248 (clobber (reg:SI 7))
9249 (clobber (reg:SI 8))
9250 (clobber (reg:SI 9))
9251 (clobber (reg:SI 10))
9252 (clobber (reg:SI 11))
9253 (clobber (reg:SI 12))
9254 (clobber (match_scratch:SI 4 ""))])]
9259 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9260 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9261 (use (match_operand:SI 2 "immediate_operand" "i"))
9262 (use (match_operand:SI 3 "immediate_operand" "i"))
9263 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9264 (clobber (reg:SI 6))
9265 (clobber (reg:SI 7))
9266 (clobber (reg:SI 8))
9267 (clobber (reg:SI 9))
9268 (clobber (reg:SI 10))
9269 (clobber (reg:SI 11))
9270 (clobber (reg:SI 12))
9271 (clobber (match_scratch:SI 5 "=X"))]
9273 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9274 || INTVAL (operands[2]) == 0)
9275 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9276 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9277 && REGNO (operands[4]) == 5"
9278 "lswi %4,%1,%2\;stswi %4,%0,%2"
9279 [(set_attr "type" "store")
9280 (set_attr "update" "yes")
9281 (set_attr "indexed" "yes")
9282 (set_attr "cell_micro" "always")
9283 (set_attr "length" "8")])
9285 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
9286 ;; register allocator doesn't have a clue about allocating 6 word registers.
9287 ;; rD/rS = r5 is preferred, efficient form.
9288 (define_expand "movmemsi_6reg"
9289 [(parallel [(set (match_operand 0 "" "")
9290 (match_operand 1 "" ""))
9291 (use (match_operand 2 "" ""))
9292 (use (match_operand 3 "" ""))
9293 (clobber (reg:SI 5))
9294 (clobber (reg:SI 6))
9295 (clobber (reg:SI 7))
9296 (clobber (reg:SI 8))
9297 (clobber (reg:SI 9))
9298 (clobber (reg:SI 10))
9299 (clobber (match_scratch:SI 4 ""))])]
9304 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9305 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9306 (use (match_operand:SI 2 "immediate_operand" "i"))
9307 (use (match_operand:SI 3 "immediate_operand" "i"))
9308 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9309 (clobber (reg:SI 6))
9310 (clobber (reg:SI 7))
9311 (clobber (reg:SI 8))
9312 (clobber (reg:SI 9))
9313 (clobber (reg:SI 10))
9314 (clobber (match_scratch:SI 5 "=X"))]
9316 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9317 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9318 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9319 && REGNO (operands[4]) == 5"
9320 "lswi %4,%1,%2\;stswi %4,%0,%2"
9321 [(set_attr "type" "store")
9322 (set_attr "update" "yes")
9323 (set_attr "indexed" "yes")
9324 (set_attr "cell_micro" "always")
9325 (set_attr "length" "8")])
9327 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9328 ;; problems with TImode.
9329 ;; rD/rS = r5 is preferred, efficient form.
9330 (define_expand "movmemsi_4reg"
9331 [(parallel [(set (match_operand 0 "" "")
9332 (match_operand 1 "" ""))
9333 (use (match_operand 2 "" ""))
9334 (use (match_operand 3 "" ""))
9335 (clobber (reg:SI 5))
9336 (clobber (reg:SI 6))
9337 (clobber (reg:SI 7))
9338 (clobber (reg:SI 8))
9339 (clobber (match_scratch:SI 4 ""))])]
9344 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9345 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9346 (use (match_operand:SI 2 "immediate_operand" "i"))
9347 (use (match_operand:SI 3 "immediate_operand" "i"))
9348 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9349 (clobber (reg:SI 6))
9350 (clobber (reg:SI 7))
9351 (clobber (reg:SI 8))
9352 (clobber (match_scratch:SI 5 "=X"))]
9354 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9355 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9356 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9357 && REGNO (operands[4]) == 5"
9358 "lswi %4,%1,%2\;stswi %4,%0,%2"
9359 [(set_attr "type" "store")
9360 (set_attr "update" "yes")
9361 (set_attr "indexed" "yes")
9362 (set_attr "cell_micro" "always")
9363 (set_attr "length" "8")])
9365 ;; Move up to 8 bytes at a time.
9366 (define_expand "movmemsi_2reg"
9367 [(parallel [(set (match_operand 0 "" "")
9368 (match_operand 1 "" ""))
9369 (use (match_operand 2 "" ""))
9370 (use (match_operand 3 "" ""))
9371 (clobber (match_scratch:DI 4 ""))
9372 (clobber (match_scratch:SI 5 ""))])]
9373 "TARGET_STRING && ! TARGET_POWERPC64"
9377 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9378 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9379 (use (match_operand:SI 2 "immediate_operand" "i"))
9380 (use (match_operand:SI 3 "immediate_operand" "i"))
9381 (clobber (match_scratch:DI 4 "=&r"))
9382 (clobber (match_scratch:SI 5 "=X"))]
9383 "TARGET_STRING && ! TARGET_POWERPC64
9384 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9385 "lswi %4,%1,%2\;stswi %4,%0,%2"
9386 [(set_attr "type" "store")
9387 (set_attr "update" "yes")
9388 (set_attr "indexed" "yes")
9389 (set_attr "cell_micro" "always")
9390 (set_attr "length" "8")])
9392 ;; Move up to 4 bytes at a time.
9393 (define_expand "movmemsi_1reg"
9394 [(parallel [(set (match_operand 0 "" "")
9395 (match_operand 1 "" ""))
9396 (use (match_operand 2 "" ""))
9397 (use (match_operand 3 "" ""))
9398 (clobber (match_scratch:SI 4 ""))
9399 (clobber (match_scratch:SI 5 ""))])]
9404 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9405 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9406 (use (match_operand:SI 2 "immediate_operand" "i"))
9407 (use (match_operand:SI 3 "immediate_operand" "i"))
9408 (clobber (match_scratch:SI 4 "=&r"))
9409 (clobber (match_scratch:SI 5 "=X"))]
9410 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9411 "lswi %4,%1,%2\;stswi %4,%0,%2"
9412 [(set_attr "type" "store")
9413 (set_attr "update" "yes")
9414 (set_attr "indexed" "yes")
9415 (set_attr "cell_micro" "always")
9416 (set_attr "length" "8")])
9418 ;; Define insns that do load or store with update. Some of these we can
9419 ;; get by using pre-decrement or pre-increment, but the hardware can also
9420 ;; do cases where the increment is not the size of the object.
9422 ;; In all these cases, we use operands 0 and 1 for the register being
9423 ;; incremented because those are the operands that local-alloc will
9424 ;; tie and these are the pair most likely to be tieable (and the ones
9425 ;; that will benefit the most).
9427 (define_insn "*movdi_update1"
9428 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9429 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9430 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9431 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9432 (plus:DI (match_dup 1) (match_dup 2)))]
9433 "TARGET_POWERPC64 && TARGET_UPDATE
9434 && (!avoiding_indexed_address_p (DImode)
9435 || !gpc_reg_operand (operands[2], DImode))"
9439 [(set_attr "type" "load")
9440 (set_attr "update" "yes")
9441 (set_attr "indexed" "yes,no")])
9443 (define_insn "movdi_<mode>_update"
9444 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9445 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9446 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9447 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9448 (plus:P (match_dup 1) (match_dup 2)))]
9449 "TARGET_POWERPC64 && TARGET_UPDATE
9450 && (!avoiding_indexed_address_p (Pmode)
9451 || !gpc_reg_operand (operands[2], Pmode)
9452 || (REG_P (operands[0])
9453 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9457 [(set_attr "type" "store")
9458 (set_attr "update" "yes")
9459 (set_attr "indexed" "yes,no")])
9461 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9462 ;; needed for stack allocation, even if the user passes -mno-update.
9463 (define_insn "movdi_<mode>_update_stack"
9464 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9465 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9466 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9467 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9468 (plus:P (match_dup 1) (match_dup 2)))]
9473 [(set_attr "type" "store")
9474 (set_attr "update" "yes")
9475 (set_attr "indexed" "yes,no")])
9477 (define_insn "*movsi_update1"
9478 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9479 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9480 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9481 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9482 (plus:SI (match_dup 1) (match_dup 2)))]
9484 && (!avoiding_indexed_address_p (SImode)
9485 || !gpc_reg_operand (operands[2], SImode))"
9489 [(set_attr "type" "load")
9490 (set_attr "update" "yes")
9491 (set_attr "indexed" "yes,no")])
9493 (define_insn "*movsi_update2"
9494 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9496 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9497 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9498 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9499 (plus:DI (match_dup 1) (match_dup 2)))]
9500 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9501 && !avoiding_indexed_address_p (DImode)"
9503 [(set_attr "type" "load")
9504 (set_attr "sign_extend" "yes")
9505 (set_attr "update" "yes")
9506 (set_attr "indexed" "yes")])
9508 (define_insn "movsi_update"
9509 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9510 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9511 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9512 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9513 (plus:SI (match_dup 1) (match_dup 2)))]
9515 && (!avoiding_indexed_address_p (SImode)
9516 || !gpc_reg_operand (operands[2], SImode)
9517 || (REG_P (operands[0])
9518 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9522 [(set_attr "type" "store")
9523 (set_attr "update" "yes")
9524 (set_attr "indexed" "yes,no")])
9526 ;; This is an unconditional pattern; needed for stack allocation, even
9527 ;; if the user passes -mno-update.
9528 (define_insn "movsi_update_stack"
9529 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9530 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9531 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9532 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9533 (plus:SI (match_dup 1) (match_dup 2)))]
9538 [(set_attr "type" "store")
9539 (set_attr "update" "yes")
9540 (set_attr "indexed" "yes,no")])
9542 (define_insn "*movhi_update1"
9543 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9544 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9545 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9546 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9547 (plus:SI (match_dup 1) (match_dup 2)))]
9549 && (!avoiding_indexed_address_p (SImode)
9550 || !gpc_reg_operand (operands[2], SImode))"
9554 [(set_attr "type" "load")
9555 (set_attr "update" "yes")
9556 (set_attr "indexed" "yes,no")])
9558 (define_insn "*movhi_update2"
9559 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9561 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9562 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9563 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9564 (plus:SI (match_dup 1) (match_dup 2)))]
9566 && (!avoiding_indexed_address_p (SImode)
9567 || !gpc_reg_operand (operands[2], SImode))"
9571 [(set_attr "type" "load")
9572 (set_attr "update" "yes")
9573 (set_attr "indexed" "yes,no")])
9575 (define_insn "*movhi_update3"
9576 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9578 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9579 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9580 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9581 (plus:SI (match_dup 1) (match_dup 2)))]
9582 "TARGET_UPDATE && rs6000_gen_cell_microcode
9583 && (!avoiding_indexed_address_p (SImode)
9584 || !gpc_reg_operand (operands[2], SImode))"
9588 [(set_attr "type" "load")
9589 (set_attr "sign_extend" "yes")
9590 (set_attr "update" "yes")
9591 (set_attr "indexed" "yes,no")])
9593 (define_insn "*movhi_update4"
9594 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9595 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9596 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9597 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9598 (plus:SI (match_dup 1) (match_dup 2)))]
9600 && (!avoiding_indexed_address_p (SImode)
9601 || !gpc_reg_operand (operands[2], SImode))"
9605 [(set_attr "type" "store")
9606 (set_attr "update" "yes")
9607 (set_attr "indexed" "yes,no")])
9609 (define_insn "*movqi_update1"
9610 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9611 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9612 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9613 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9614 (plus:SI (match_dup 1) (match_dup 2)))]
9616 && (!avoiding_indexed_address_p (SImode)
9617 || !gpc_reg_operand (operands[2], SImode))"
9621 [(set_attr "type" "load")
9622 (set_attr "update" "yes")
9623 (set_attr "indexed" "yes,no")])
9625 (define_insn "*movqi_update2"
9626 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9628 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9629 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9630 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9631 (plus:SI (match_dup 1) (match_dup 2)))]
9633 && (!avoiding_indexed_address_p (SImode)
9634 || !gpc_reg_operand (operands[2], SImode))"
9638 [(set_attr "type" "load")
9639 (set_attr "update" "yes")
9640 (set_attr "indexed" "yes,no")])
9642 (define_insn "*movqi_update3"
9643 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9644 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9645 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9646 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9647 (plus:SI (match_dup 1) (match_dup 2)))]
9649 && (!avoiding_indexed_address_p (SImode)
9650 || !gpc_reg_operand (operands[2], SImode))"
9654 [(set_attr "type" "store")
9655 (set_attr "update" "yes")
9656 (set_attr "indexed" "yes,no")])
9658 (define_insn "*movsf_update1"
9659 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9660 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9661 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9662 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9663 (plus:SI (match_dup 1) (match_dup 2)))]
9664 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9665 && (!avoiding_indexed_address_p (SImode)
9666 || !gpc_reg_operand (operands[2], SImode))"
9670 [(set_attr "type" "fpload")
9671 (set_attr "update" "yes")
9672 (set_attr "indexed" "yes,no")])
9674 (define_insn "*movsf_update2"
9675 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9676 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9677 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9678 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9679 (plus:SI (match_dup 1) (match_dup 2)))]
9680 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9681 && (!avoiding_indexed_address_p (SImode)
9682 || !gpc_reg_operand (operands[2], SImode))"
9686 [(set_attr "type" "fpstore")
9687 (set_attr "update" "yes")
9688 (set_attr "indexed" "yes,no")])
9690 (define_insn "*movsf_update3"
9691 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9692 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9693 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9694 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9695 (plus:SI (match_dup 1) (match_dup 2)))]
9696 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9697 && (!avoiding_indexed_address_p (SImode)
9698 || !gpc_reg_operand (operands[2], SImode))"
9702 [(set_attr "type" "load")
9703 (set_attr "update" "yes")
9704 (set_attr "indexed" "yes,no")])
9706 (define_insn "*movsf_update4"
9707 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9708 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9709 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9710 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9711 (plus:SI (match_dup 1) (match_dup 2)))]
9712 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9713 && (!avoiding_indexed_address_p (SImode)
9714 || !gpc_reg_operand (operands[2], SImode))"
9718 [(set_attr "type" "store")
9719 (set_attr "update" "yes")
9720 (set_attr "indexed" "yes,no")])
9722 (define_insn "*movdf_update1"
9723 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9724 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9725 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9726 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9727 (plus:SI (match_dup 1) (match_dup 2)))]
9728 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9729 && (!avoiding_indexed_address_p (SImode)
9730 || !gpc_reg_operand (operands[2], SImode))"
9734 [(set_attr "type" "fpload")
9735 (set_attr "update" "yes")
9736 (set_attr "indexed" "yes,no")
9737 (set_attr "size" "64")])
9739 (define_insn "*movdf_update2"
9740 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9741 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9742 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9743 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9744 (plus:SI (match_dup 1) (match_dup 2)))]
9745 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9746 && (!avoiding_indexed_address_p (SImode)
9747 || !gpc_reg_operand (operands[2], SImode))"
9751 [(set_attr "type" "fpstore")
9752 (set_attr "update" "yes")
9753 (set_attr "indexed" "yes,no")])
9756 ;; After inserting conditional returns we can sometimes have
9757 ;; unnecessary register moves. Unfortunately we cannot have a
9758 ;; modeless peephole here, because some single SImode sets have early
9759 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9760 ;; sequences, using get_attr_length here will smash the operands
9761 ;; array. Neither is there an early_cobbler_p predicate.
9762 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9763 ;; Also this optimization interferes with scalars going into
9764 ;; altivec registers (the code does reloading through the FPRs).
9766 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9767 (match_operand:DF 1 "any_operand" ""))
9768 (set (match_operand:DF 2 "gpc_reg_operand" "")
9770 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9771 && !TARGET_UPPER_REGS_DF
9772 && peep2_reg_dead_p (2, operands[0])"
9773 [(set (match_dup 2) (match_dup 1))])
9776 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9777 (match_operand:SF 1 "any_operand" ""))
9778 (set (match_operand:SF 2 "gpc_reg_operand" "")
9780 "!TARGET_UPPER_REGS_SF
9781 && peep2_reg_dead_p (2, operands[0])"
9782 [(set (match_dup 2) (match_dup 1))])
9787 ;; Mode attributes for different ABIs.
9788 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9789 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9790 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9791 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9793 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9794 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9795 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9796 (match_operand 4 "" "g")))
9797 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9798 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9800 (clobber (reg:SI LR_REGNO))]
9801 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9803 if (TARGET_CMODEL != CMODEL_SMALL)
9804 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9807 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9809 "&& TARGET_TLS_MARKERS"
9811 (unspec:TLSmode [(match_dup 1)
9814 (parallel [(set (match_dup 0)
9815 (call (mem:TLSmode (match_dup 3))
9817 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9818 (clobber (reg:SI LR_REGNO))])]
9820 [(set_attr "type" "two")
9821 (set (attr "length")
9822 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9826 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9827 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9828 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9829 (match_operand 4 "" "g")))
9830 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9831 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9833 (clobber (reg:SI LR_REGNO))]
9834 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9838 if (TARGET_SECURE_PLT && flag_pic == 2)
9839 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9841 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9844 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9846 "&& TARGET_TLS_MARKERS"
9848 (unspec:TLSmode [(match_dup 1)
9851 (parallel [(set (match_dup 0)
9852 (call (mem:TLSmode (match_dup 3))
9854 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9855 (clobber (reg:SI LR_REGNO))])]
9857 [(set_attr "type" "two")
9858 (set_attr "length" "8")])
9860 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9861 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9862 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9863 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9865 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9866 "addi %0,%1,%2@got@tlsgd"
9867 "&& TARGET_CMODEL != CMODEL_SMALL"
9870 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9872 (lo_sum:TLSmode (match_dup 3)
9873 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9876 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9878 [(set (attr "length")
9879 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9883 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9884 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9886 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9887 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9889 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9890 "addis %0,%1,%2@got@tlsgd@ha"
9891 [(set_attr "length" "4")])
9893 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9894 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9895 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9896 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9897 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9899 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9900 "addi %0,%1,%2@got@tlsgd@l"
9901 [(set_attr "length" "4")])
9903 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9904 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9905 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9906 (match_operand 2 "" "g")))
9907 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9909 (clobber (reg:SI LR_REGNO))]
9910 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9911 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9912 "bl %z1(%3@tlsgd)\;nop"
9913 [(set_attr "type" "branch")
9914 (set_attr "length" "8")])
9916 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9917 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9918 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9919 (match_operand 2 "" "g")))
9920 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9922 (clobber (reg:SI LR_REGNO))]
9923 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9927 if (TARGET_SECURE_PLT && flag_pic == 2)
9928 return "bl %z1+32768(%3@tlsgd)@plt";
9929 return "bl %z1(%3@tlsgd)@plt";
9931 return "bl %z1(%3@tlsgd)";
9933 [(set_attr "type" "branch")
9934 (set_attr "length" "4")])
9936 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9937 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9938 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9939 (match_operand 3 "" "g")))
9940 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9942 (clobber (reg:SI LR_REGNO))]
9943 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9945 if (TARGET_CMODEL != CMODEL_SMALL)
9946 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9949 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9951 "&& TARGET_TLS_MARKERS"
9953 (unspec:TLSmode [(match_dup 1)]
9955 (parallel [(set (match_dup 0)
9956 (call (mem:TLSmode (match_dup 2))
9958 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9959 (clobber (reg:SI LR_REGNO))])]
9961 [(set_attr "type" "two")
9962 (set (attr "length")
9963 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9967 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9968 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9969 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9970 (match_operand 3 "" "g")))
9971 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9973 (clobber (reg:SI LR_REGNO))]
9974 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9978 if (TARGET_SECURE_PLT && flag_pic == 2)
9979 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9981 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9984 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9986 "&& TARGET_TLS_MARKERS"
9988 (unspec:TLSmode [(match_dup 1)]
9990 (parallel [(set (match_dup 0)
9991 (call (mem:TLSmode (match_dup 2))
9993 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9994 (clobber (reg:SI LR_REGNO))])]
9996 [(set_attr "length" "8")])
9998 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9999 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10000 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10002 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10003 "addi %0,%1,%&@got@tlsld"
10004 "&& TARGET_CMODEL != CMODEL_SMALL"
10005 [(set (match_dup 2)
10007 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10009 (lo_sum:TLSmode (match_dup 2)
10010 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10013 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10015 [(set (attr "length")
10016 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10020 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10021 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10023 (unspec:TLSmode [(const_int 0)
10024 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10026 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10027 "addis %0,%1,%&@got@tlsld@ha"
10028 [(set_attr "length" "4")])
10030 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10031 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10032 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10033 (unspec:TLSmode [(const_int 0)
10034 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10036 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10037 "addi %0,%1,%&@got@tlsld@l"
10038 [(set_attr "length" "4")])
10040 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10041 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10042 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10043 (match_operand 2 "" "g")))
10044 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10045 (clobber (reg:SI LR_REGNO))]
10046 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10047 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10048 "bl %z1(%&@tlsld)\;nop"
10049 [(set_attr "type" "branch")
10050 (set_attr "length" "8")])
10052 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10053 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10054 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10055 (match_operand 2 "" "g")))
10056 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10057 (clobber (reg:SI LR_REGNO))]
10058 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10062 if (TARGET_SECURE_PLT && flag_pic == 2)
10063 return "bl %z1+32768(%&@tlsld)@plt";
10064 return "bl %z1(%&@tlsld)@plt";
10066 return "bl %z1(%&@tlsld)";
10068 [(set_attr "type" "branch")
10069 (set_attr "length" "4")])
10071 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10072 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10073 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10074 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10075 UNSPEC_TLSDTPREL))]
10077 "addi %0,%1,%2@dtprel")
10079 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10080 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10081 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10082 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10083 UNSPEC_TLSDTPRELHA))]
10085 "addis %0,%1,%2@dtprel@ha")
10087 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10088 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10089 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10090 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10091 UNSPEC_TLSDTPRELLO))]
10093 "addi %0,%1,%2@dtprel@l")
10095 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10096 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10097 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10098 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10099 UNSPEC_TLSGOTDTPREL))]
10101 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10102 "&& TARGET_CMODEL != CMODEL_SMALL"
10103 [(set (match_dup 3)
10105 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10107 (lo_sum:TLSmode (match_dup 3)
10108 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10111 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10113 [(set (attr "length")
10114 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10118 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10119 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10121 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10122 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10123 UNSPEC_TLSGOTDTPREL)))]
10124 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10125 "addis %0,%1,%2@got@dtprel@ha"
10126 [(set_attr "length" "4")])
10128 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10129 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10130 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10131 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10132 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10133 UNSPEC_TLSGOTDTPREL)))]
10134 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10135 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10136 [(set_attr "length" "4")])
10138 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10139 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10140 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10141 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10144 "addi %0,%1,%2@tprel")
10146 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10147 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10148 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10149 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10150 UNSPEC_TLSTPRELHA))]
10152 "addis %0,%1,%2@tprel@ha")
10154 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10155 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10156 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10157 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10158 UNSPEC_TLSTPRELLO))]
10160 "addi %0,%1,%2@tprel@l")
10162 ;; "b" output constraint here and on tls_tls input to support linker tls
10163 ;; optimization. The linker may edit the instructions emitted by a
10164 ;; tls_got_tprel/tls_tls pair to addis,addi.
10165 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10166 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10167 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10168 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10169 UNSPEC_TLSGOTTPREL))]
10171 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10172 "&& TARGET_CMODEL != CMODEL_SMALL"
10173 [(set (match_dup 3)
10175 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10177 (lo_sum:TLSmode (match_dup 3)
10178 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10181 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10183 [(set (attr "length")
10184 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10188 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10189 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10191 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10192 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10193 UNSPEC_TLSGOTTPREL)))]
10194 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10195 "addis %0,%1,%2@got@tprel@ha"
10196 [(set_attr "length" "4")])
10198 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10199 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10200 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10201 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10202 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10203 UNSPEC_TLSGOTTPREL)))]
10204 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10205 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10206 [(set_attr "length" "4")])
10208 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10209 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10210 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10211 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10213 "TARGET_ELF && HAVE_AS_TLS"
10214 "add %0,%1,%2@tls")
10216 (define_expand "tls_get_tpointer"
10217 [(set (match_operand:SI 0 "gpc_reg_operand" "")
10218 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10219 "TARGET_XCOFF && HAVE_AS_TLS"
10222 emit_insn (gen_tls_get_tpointer_internal ());
10223 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10227 (define_insn "tls_get_tpointer_internal"
10229 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10230 (clobber (reg:SI LR_REGNO))]
10231 "TARGET_XCOFF && HAVE_AS_TLS"
10232 "bla __get_tpointer")
10234 (define_expand "tls_get_addr<mode>"
10235 [(set (match_operand:P 0 "gpc_reg_operand" "")
10236 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10237 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10238 "TARGET_XCOFF && HAVE_AS_TLS"
10241 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10242 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10243 emit_insn (gen_tls_get_addr_internal<mode> ());
10244 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10248 (define_insn "tls_get_addr_internal<mode>"
10250 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10251 (clobber (reg:P 0))
10252 (clobber (reg:P 4))
10253 (clobber (reg:P 5))
10254 (clobber (reg:P 11))
10255 (clobber (reg:CC CR0_REGNO))
10256 (clobber (reg:P LR_REGNO))]
10257 "TARGET_XCOFF && HAVE_AS_TLS"
10258 "bla __tls_get_addr")
10260 ;; Next come insns related to the calling sequence.
10262 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10263 ;; We move the back-chain and decrement the stack pointer.
10265 (define_expand "allocate_stack"
10266 [(set (match_operand 0 "gpc_reg_operand" "")
10267 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10269 (minus (reg 1) (match_dup 1)))]
10272 { rtx chain = gen_reg_rtx (Pmode);
10273 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10275 rtx insn, par, set, mem;
10277 emit_move_insn (chain, stack_bot);
10279 /* Check stack bounds if necessary. */
10280 if (crtl->limit_stack)
10283 available = expand_binop (Pmode, sub_optab,
10284 stack_pointer_rtx, stack_limit_rtx,
10285 NULL_RTX, 1, OPTAB_WIDEN);
10286 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10289 if (GET_CODE (operands[1]) != CONST_INT
10290 || INTVAL (operands[1]) < -32767
10291 || INTVAL (operands[1]) > 32768)
10293 neg_op0 = gen_reg_rtx (Pmode);
10295 emit_insn (gen_negsi2 (neg_op0, operands[1]));
10297 emit_insn (gen_negdi2 (neg_op0, operands[1]));
10300 neg_op0 = GEN_INT (- INTVAL (operands[1]));
10302 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10303 : gen_movdi_di_update_stack))
10304 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10306 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10307 it now and set the alias set/attributes. The above gen_*_update
10308 calls will generate a PARALLEL with the MEM set being the first
10310 par = PATTERN (insn);
10311 gcc_assert (GET_CODE (par) == PARALLEL);
10312 set = XVECEXP (par, 0, 0);
10313 gcc_assert (GET_CODE (set) == SET);
10314 mem = SET_DEST (set);
10315 gcc_assert (MEM_P (mem));
10316 MEM_NOTRAP_P (mem) = 1;
10317 set_mem_alias_set (mem, get_frame_alias_set ());
10319 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10323 ;; These patterns say how to save and restore the stack pointer. We need not
10324 ;; save the stack pointer at function level since we are careful to
10325 ;; preserve the backchain. At block level, we have to restore the backchain
10326 ;; when we restore the stack pointer.
10328 ;; For nonlocal gotos, we must save both the stack pointer and its
10329 ;; backchain and restore both. Note that in the nonlocal case, the
10330 ;; save area is a memory location.
10332 (define_expand "save_stack_function"
10333 [(match_operand 0 "any_operand" "")
10334 (match_operand 1 "any_operand" "")]
10338 (define_expand "restore_stack_function"
10339 [(match_operand 0 "any_operand" "")
10340 (match_operand 1 "any_operand" "")]
10344 ;; Adjust stack pointer (op0) to a new value (op1).
10345 ;; First copy old stack backchain to new location, and ensure that the
10346 ;; scheduler won't reorder the sp assignment before the backchain write.
10347 (define_expand "restore_stack_block"
10348 [(set (match_dup 2) (match_dup 3))
10349 (set (match_dup 4) (match_dup 2))
10351 (set (match_operand 0 "register_operand" "")
10352 (match_operand 1 "register_operand" ""))]
10358 operands[1] = force_reg (Pmode, operands[1]);
10359 operands[2] = gen_reg_rtx (Pmode);
10360 operands[3] = gen_frame_mem (Pmode, operands[0]);
10361 operands[4] = gen_frame_mem (Pmode, operands[1]);
10362 p = rtvec_alloc (1);
10363 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10365 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10368 (define_expand "save_stack_nonlocal"
10369 [(set (match_dup 3) (match_dup 4))
10370 (set (match_operand 0 "memory_operand" "") (match_dup 3))
10371 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10375 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10377 /* Copy the backchain to the first word, sp to the second. */
10378 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10379 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10380 operands[3] = gen_reg_rtx (Pmode);
10381 operands[4] = gen_frame_mem (Pmode, operands[1]);
10384 (define_expand "restore_stack_nonlocal"
10385 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10386 (set (match_dup 3) (match_dup 4))
10387 (set (match_dup 5) (match_dup 2))
10389 (set (match_operand 0 "register_operand" "") (match_dup 3))]
10393 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10396 /* Restore the backchain from the first word, sp from the second. */
10397 operands[2] = gen_reg_rtx (Pmode);
10398 operands[3] = gen_reg_rtx (Pmode);
10399 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10400 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10401 operands[5] = gen_frame_mem (Pmode, operands[3]);
10402 p = rtvec_alloc (1);
10403 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10405 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10408 ;; TOC register handling.
10410 ;; Code to initialize the TOC register...
10412 (define_insn "load_toc_aix_si"
10413 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10414 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10415 (use (reg:SI 2))])]
10416 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10420 extern int need_toc_init;
10422 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10423 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10424 operands[2] = gen_rtx_REG (Pmode, 2);
10425 return \"lwz %0,%1(%2)\";
10427 [(set_attr "type" "load")
10428 (set_attr "update" "no")
10429 (set_attr "indexed" "no")])
10431 (define_insn "load_toc_aix_di"
10432 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10433 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10434 (use (reg:DI 2))])]
10435 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10439 extern int need_toc_init;
10441 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10442 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10444 strcat (buf, \"@toc\");
10445 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10446 operands[2] = gen_rtx_REG (Pmode, 2);
10447 return \"ld %0,%1(%2)\";
10449 [(set_attr "type" "load")
10450 (set_attr "update" "no")
10451 (set_attr "indexed" "no")])
10453 (define_insn "load_toc_v4_pic_si"
10454 [(set (reg:SI LR_REGNO)
10455 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10456 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10457 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10458 [(set_attr "type" "branch")
10459 (set_attr "length" "4")])
10461 (define_expand "load_toc_v4_PIC_1"
10462 [(parallel [(set (reg:SI LR_REGNO)
10463 (match_operand:SI 0 "immediate_operand" "s"))
10464 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10465 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10466 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10469 (define_insn "load_toc_v4_PIC_1_normal"
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))"
10475 "bcl 20,31,%0\\n%0:"
10476 [(set_attr "type" "branch")
10477 (set_attr "length" "4")
10478 (set_attr "cannot_copy" "yes")])
10480 (define_insn "load_toc_v4_PIC_1_476"
10481 [(set (reg:SI LR_REGNO)
10482 (match_operand:SI 0 "immediate_operand" "s"))
10483 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10484 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10485 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10489 static char templ[32];
10491 get_ppc476_thunk_name (name);
10492 sprintf (templ, \"bl %s\\n%%0:\", name);
10495 [(set_attr "type" "branch")
10496 (set_attr "length" "4")
10497 (set_attr "cannot_copy" "yes")])
10499 (define_expand "load_toc_v4_PIC_1b"
10500 [(parallel [(set (reg:SI LR_REGNO)
10501 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10502 (label_ref (match_operand 1 "" ""))]
10505 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10508 (define_insn "load_toc_v4_PIC_1b_normal"
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"
10515 "bcl 20,31,$+8\;.long %0-$"
10516 [(set_attr "type" "branch")
10517 (set_attr "length" "8")])
10519 (define_insn "load_toc_v4_PIC_1b_476"
10520 [(set (reg:SI LR_REGNO)
10521 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10522 (label_ref (match_operand 1 "" ""))]
10525 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10529 static char templ[32];
10531 get_ppc476_thunk_name (name);
10532 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10535 [(set_attr "type" "branch")
10536 (set_attr "length" "16")])
10538 (define_insn "load_toc_v4_PIC_2"
10539 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10540 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10541 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10542 (match_operand:SI 3 "immediate_operand" "s")))))]
10543 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10545 [(set_attr "type" "load")])
10547 (define_insn "load_toc_v4_PIC_3b"
10548 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10549 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10551 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10552 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10553 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10554 "addis %0,%1,%2-%3@ha")
10556 (define_insn "load_toc_v4_PIC_3c"
10557 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10558 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10559 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10560 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10561 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10562 "addi %0,%1,%2-%3@l")
10564 ;; If the TOC is shared over a translation unit, as happens with all
10565 ;; the kinds of PIC that we support, we need to restore the TOC
10566 ;; pointer only when jumping over units of translation.
10567 ;; On Darwin, we need to reload the picbase.
10569 (define_expand "builtin_setjmp_receiver"
10570 [(use (label_ref (match_operand 0 "" "")))]
10571 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10572 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10573 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10577 if (DEFAULT_ABI == ABI_DARWIN)
10579 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10580 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10584 crtl->uses_pic_offset_table = 1;
10585 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10586 CODE_LABEL_NUMBER (operands[0]));
10587 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10589 emit_insn (gen_load_macho_picbase (tmplabrtx));
10590 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10591 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10595 rs6000_emit_load_toc_table (FALSE);
10599 ;; Largetoc support
10600 (define_insn "*largetoc_high"
10601 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10603 (unspec [(match_operand:DI 1 "" "")
10604 (match_operand:DI 2 "gpc_reg_operand" "b")]
10606 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10607 "addis %0,%2,%1@toc@ha")
10609 (define_insn "*largetoc_high_aix<mode>"
10610 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10612 (unspec [(match_operand:P 1 "" "")
10613 (match_operand:P 2 "gpc_reg_operand" "b")]
10615 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10616 "addis %0,%1@u(%2)")
10618 (define_insn "*largetoc_high_plus"
10619 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10622 (unspec [(match_operand:DI 1 "" "")
10623 (match_operand:DI 2 "gpc_reg_operand" "b")]
10625 (match_operand:DI 3 "add_cint_operand" "n"))))]
10626 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10627 "addis %0,%2,%1+%3@toc@ha")
10629 (define_insn "*largetoc_high_plus_aix<mode>"
10630 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10633 (unspec [(match_operand:P 1 "" "")
10634 (match_operand:P 2 "gpc_reg_operand" "b")]
10636 (match_operand:P 3 "add_cint_operand" "n"))))]
10637 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10638 "addis %0,%1+%3@u(%2)")
10640 (define_insn "*largetoc_low"
10641 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10642 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10643 (match_operand:DI 2 "" "")))]
10644 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10647 (define_insn "*largetoc_low_aix<mode>"
10648 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10649 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10650 (match_operand:P 2 "" "")))]
10651 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10654 (define_insn_and_split "*tocref<mode>"
10655 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10656 (match_operand:P 1 "small_toc_ref" "R"))]
10659 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10660 [(set (match_dup 0) (high:P (match_dup 1)))
10661 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10663 ;; Elf specific ways of loading addresses for non-PIC code.
10664 ;; The output of this could be r0, but we make a very strong
10665 ;; preference for a base register because it will usually
10666 ;; be needed there.
10667 (define_insn "elf_high"
10668 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10669 (high:SI (match_operand 1 "" "")))]
10670 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10673 (define_insn "elf_low"
10674 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10675 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10676 (match_operand 2 "" "")))]
10677 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10680 ;; Call and call_value insns
10681 (define_expand "call"
10682 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10683 (match_operand 1 "" ""))
10684 (use (match_operand 2 "" ""))
10685 (clobber (reg:SI LR_REGNO))])]
10690 if (MACHOPIC_INDIRECT)
10691 operands[0] = machopic_indirect_call_target (operands[0]);
10694 gcc_assert (GET_CODE (operands[0]) == MEM);
10695 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10697 operands[0] = XEXP (operands[0], 0);
10699 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10701 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10705 if (GET_CODE (operands[0]) != SYMBOL_REF
10706 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10708 if (INTVAL (operands[2]) & CALL_LONG)
10709 operands[0] = rs6000_longcall_ref (operands[0]);
10711 switch (DEFAULT_ABI)
10715 operands[0] = force_reg (Pmode, operands[0]);
10719 gcc_unreachable ();
10724 (define_expand "call_value"
10725 [(parallel [(set (match_operand 0 "" "")
10726 (call (mem:SI (match_operand 1 "address_operand" ""))
10727 (match_operand 2 "" "")))
10728 (use (match_operand 3 "" ""))
10729 (clobber (reg:SI LR_REGNO))])]
10734 if (MACHOPIC_INDIRECT)
10735 operands[1] = machopic_indirect_call_target (operands[1]);
10738 gcc_assert (GET_CODE (operands[1]) == MEM);
10739 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10741 operands[1] = XEXP (operands[1], 0);
10743 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10745 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10749 if (GET_CODE (operands[1]) != SYMBOL_REF
10750 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10752 if (INTVAL (operands[3]) & CALL_LONG)
10753 operands[1] = rs6000_longcall_ref (operands[1]);
10755 switch (DEFAULT_ABI)
10759 operands[1] = force_reg (Pmode, operands[1]);
10763 gcc_unreachable ();
10768 ;; Call to function in current module. No TOC pointer reload needed.
10769 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10770 ;; either the function was not prototyped, or it was prototyped as a
10771 ;; variable argument function. It is > 0 if FP registers were passed
10772 ;; and < 0 if they were not.
10774 (define_insn "*call_local32"
10775 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10776 (match_operand 1 "" "g,g"))
10777 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10778 (clobber (reg:SI LR_REGNO))]
10779 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10782 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10783 output_asm_insn (\"crxor 6,6,6\", operands);
10785 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10786 output_asm_insn (\"creqv 6,6,6\", operands);
10788 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10790 [(set_attr "type" "branch")
10791 (set_attr "length" "4,8")])
10793 (define_insn "*call_local64"
10794 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10795 (match_operand 1 "" "g,g"))
10796 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10797 (clobber (reg:SI LR_REGNO))]
10798 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10801 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10802 output_asm_insn (\"crxor 6,6,6\", operands);
10804 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10805 output_asm_insn (\"creqv 6,6,6\", operands);
10807 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10809 [(set_attr "type" "branch")
10810 (set_attr "length" "4,8")])
10812 (define_insn "*call_value_local32"
10813 [(set (match_operand 0 "" "")
10814 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10815 (match_operand 2 "" "g,g")))
10816 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10817 (clobber (reg:SI LR_REGNO))]
10818 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10821 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10822 output_asm_insn (\"crxor 6,6,6\", operands);
10824 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10825 output_asm_insn (\"creqv 6,6,6\", operands);
10827 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10829 [(set_attr "type" "branch")
10830 (set_attr "length" "4,8")])
10833 (define_insn "*call_value_local64"
10834 [(set (match_operand 0 "" "")
10835 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10836 (match_operand 2 "" "g,g")))
10837 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10838 (clobber (reg:SI LR_REGNO))]
10839 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10842 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10843 output_asm_insn (\"crxor 6,6,6\", operands);
10845 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10846 output_asm_insn (\"creqv 6,6,6\", operands);
10848 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10850 [(set_attr "type" "branch")
10851 (set_attr "length" "4,8")])
10854 ;; A function pointer under System V is just a normal pointer
10855 ;; operands[0] is the function pointer
10856 ;; operands[1] is the stack size to clean up
10857 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10858 ;; which indicates how to set cr1
10860 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10861 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10862 (match_operand 1 "" "g,g,g,g"))
10863 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10864 (clobber (reg:SI LR_REGNO))]
10865 "DEFAULT_ABI == ABI_V4
10866 || DEFAULT_ABI == ABI_DARWIN"
10868 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10869 output_asm_insn ("crxor 6,6,6", operands);
10871 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10872 output_asm_insn ("creqv 6,6,6", operands);
10876 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10877 (set_attr "length" "4,4,8,8")])
10879 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10880 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10881 (match_operand 1 "" "g,g"))
10882 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10883 (clobber (reg:SI LR_REGNO))]
10884 "(DEFAULT_ABI == ABI_DARWIN
10885 || (DEFAULT_ABI == ABI_V4
10886 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10888 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10889 output_asm_insn ("crxor 6,6,6", operands);
10891 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10892 output_asm_insn ("creqv 6,6,6", operands);
10895 return output_call(insn, operands, 0, 2);
10897 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10899 gcc_assert (!TARGET_SECURE_PLT);
10900 return "bl %z0@plt";
10906 "DEFAULT_ABI == ABI_V4
10907 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10908 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10909 [(parallel [(call (mem:SI (match_dup 0))
10911 (use (match_dup 2))
10912 (use (match_dup 3))
10913 (clobber (reg:SI LR_REGNO))])]
10915 operands[3] = pic_offset_table_rtx;
10917 [(set_attr "type" "branch,branch")
10918 (set_attr "length" "4,8")])
10920 (define_insn "*call_nonlocal_sysv_secure<mode>"
10921 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10922 (match_operand 1 "" "g,g"))
10923 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10924 (use (match_operand:SI 3 "register_operand" "r,r"))
10925 (clobber (reg:SI LR_REGNO))]
10926 "(DEFAULT_ABI == ABI_V4
10927 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10928 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10930 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10931 output_asm_insn ("crxor 6,6,6", operands);
10933 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10934 output_asm_insn ("creqv 6,6,6", operands);
10937 /* The magic 32768 offset here and in the other sysv call insns
10938 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10939 See sysv4.h:toc_section. */
10940 return "bl %z0+32768@plt";
10942 return "bl %z0@plt";
10944 [(set_attr "type" "branch,branch")
10945 (set_attr "length" "4,8")])
10947 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10948 [(set (match_operand 0 "" "")
10949 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10950 (match_operand 2 "" "g,g,g,g")))
10951 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10952 (clobber (reg:SI LR_REGNO))]
10953 "DEFAULT_ABI == ABI_V4
10954 || DEFAULT_ABI == ABI_DARWIN"
10956 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10957 output_asm_insn ("crxor 6,6,6", operands);
10959 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10960 output_asm_insn ("creqv 6,6,6", operands);
10964 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10965 (set_attr "length" "4,4,8,8")])
10967 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10968 [(set (match_operand 0 "" "")
10969 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10970 (match_operand 2 "" "g,g")))
10971 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10972 (clobber (reg:SI LR_REGNO))]
10973 "(DEFAULT_ABI == ABI_DARWIN
10974 || (DEFAULT_ABI == ABI_V4
10975 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10977 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10978 output_asm_insn ("crxor 6,6,6", operands);
10980 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10981 output_asm_insn ("creqv 6,6,6", operands);
10984 return output_call(insn, operands, 1, 3);
10986 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10988 gcc_assert (!TARGET_SECURE_PLT);
10989 return "bl %z1@plt";
10995 "DEFAULT_ABI == ABI_V4
10996 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10997 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10998 [(parallel [(set (match_dup 0)
10999 (call (mem:SI (match_dup 1))
11001 (use (match_dup 3))
11002 (use (match_dup 4))
11003 (clobber (reg:SI LR_REGNO))])]
11005 operands[4] = pic_offset_table_rtx;
11007 [(set_attr "type" "branch,branch")
11008 (set_attr "length" "4,8")])
11010 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11011 [(set (match_operand 0 "" "")
11012 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11013 (match_operand 2 "" "g,g")))
11014 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11015 (use (match_operand:SI 4 "register_operand" "r,r"))
11016 (clobber (reg:SI LR_REGNO))]
11017 "(DEFAULT_ABI == ABI_V4
11018 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11019 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11021 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11022 output_asm_insn ("crxor 6,6,6", operands);
11024 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11025 output_asm_insn ("creqv 6,6,6", operands);
11028 return "bl %z1+32768@plt";
11030 return "bl %z1@plt";
11032 [(set_attr "type" "branch,branch")
11033 (set_attr "length" "4,8")])
11036 ;; Call to AIX abi function in the same module.
11038 (define_insn "*call_local_aix<mode>"
11039 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11040 (match_operand 1 "" "g"))
11041 (clobber (reg:P LR_REGNO))]
11042 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11044 [(set_attr "type" "branch")
11045 (set_attr "length" "4")])
11047 (define_insn "*call_value_local_aix<mode>"
11048 [(set (match_operand 0 "" "")
11049 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11050 (match_operand 2 "" "g")))
11051 (clobber (reg:P LR_REGNO))]
11052 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11054 [(set_attr "type" "branch")
11055 (set_attr "length" "4")])
11057 ;; Call to AIX abi function which may be in another module.
11058 ;; Restore the TOC pointer (r2) after the call.
11060 (define_insn "*call_nonlocal_aix<mode>"
11061 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11062 (match_operand 1 "" "g"))
11063 (clobber (reg:P LR_REGNO))]
11064 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11066 [(set_attr "type" "branch")
11067 (set_attr "length" "8")])
11069 (define_insn "*call_value_nonlocal_aix<mode>"
11070 [(set (match_operand 0 "" "")
11071 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11072 (match_operand 2 "" "g")))
11073 (clobber (reg:P LR_REGNO))]
11074 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11076 [(set_attr "type" "branch")
11077 (set_attr "length" "8")])
11079 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11080 ;; Operand0 is the addresss of the function to call
11081 ;; Operand2 is the location in the function descriptor to load r2 from
11082 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11084 (define_insn "*call_indirect_aix<mode>"
11085 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11086 (match_operand 1 "" "g,g"))
11087 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11088 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11089 (clobber (reg:P LR_REGNO))]
11090 "DEFAULT_ABI == ABI_AIX"
11091 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11092 [(set_attr "type" "jmpreg")
11093 (set_attr "length" "12")])
11095 (define_insn "*call_value_indirect_aix<mode>"
11096 [(set (match_operand 0 "" "")
11097 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11098 (match_operand 2 "" "g,g")))
11099 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11100 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11101 (clobber (reg:P LR_REGNO))]
11102 "DEFAULT_ABI == ABI_AIX"
11103 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11104 [(set_attr "type" "jmpreg")
11105 (set_attr "length" "12")])
11107 ;; Call to indirect functions with the ELFv2 ABI.
11108 ;; Operand0 is the addresss of the function to call
11109 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11111 (define_insn "*call_indirect_elfv2<mode>"
11112 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11113 (match_operand 1 "" "g,g"))
11114 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11115 (clobber (reg:P LR_REGNO))]
11116 "DEFAULT_ABI == ABI_ELFv2"
11117 "b%T0l\;<ptrload> 2,%2(1)"
11118 [(set_attr "type" "jmpreg")
11119 (set_attr "length" "8")])
11121 (define_insn "*call_value_indirect_elfv2<mode>"
11122 [(set (match_operand 0 "" "")
11123 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11124 (match_operand 2 "" "g,g")))
11125 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11126 (clobber (reg:P LR_REGNO))]
11127 "DEFAULT_ABI == ABI_ELFv2"
11128 "b%T1l\;<ptrload> 2,%3(1)"
11129 [(set_attr "type" "jmpreg")
11130 (set_attr "length" "8")])
11133 ;; Call subroutine returning any type.
11134 (define_expand "untyped_call"
11135 [(parallel [(call (match_operand 0 "" "")
11137 (match_operand 1 "" "")
11138 (match_operand 2 "" "")])]
11144 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11146 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11148 rtx set = XVECEXP (operands[2], 0, i);
11149 emit_move_insn (SET_DEST (set), SET_SRC (set));
11152 /* The optimizer does not know that the call sets the function value
11153 registers we stored in the result block. We avoid problems by
11154 claiming that all hard registers are used and clobbered at this
11156 emit_insn (gen_blockage ());
11161 ;; sibling call patterns
11162 (define_expand "sibcall"
11163 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11164 (match_operand 1 "" ""))
11165 (use (match_operand 2 "" ""))
11171 if (MACHOPIC_INDIRECT)
11172 operands[0] = machopic_indirect_call_target (operands[0]);
11175 gcc_assert (GET_CODE (operands[0]) == MEM);
11176 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11178 operands[0] = XEXP (operands[0], 0);
11180 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11182 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11187 (define_expand "sibcall_value"
11188 [(parallel [(set (match_operand 0 "register_operand" "")
11189 (call (mem:SI (match_operand 1 "address_operand" ""))
11190 (match_operand 2 "" "")))
11191 (use (match_operand 3 "" ""))
11197 if (MACHOPIC_INDIRECT)
11198 operands[1] = machopic_indirect_call_target (operands[1]);
11201 gcc_assert (GET_CODE (operands[1]) == MEM);
11202 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11204 operands[1] = XEXP (operands[1], 0);
11206 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11208 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11213 (define_insn "*sibcall_local32"
11214 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11215 (match_operand 1 "" "g,g"))
11216 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11218 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11221 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11222 output_asm_insn (\"crxor 6,6,6\", operands);
11224 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11225 output_asm_insn (\"creqv 6,6,6\", operands);
11227 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11229 [(set_attr "type" "branch")
11230 (set_attr "length" "4,8")])
11232 (define_insn "*sibcall_local64"
11233 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11234 (match_operand 1 "" "g,g"))
11235 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11237 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11240 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11241 output_asm_insn (\"crxor 6,6,6\", operands);
11243 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11244 output_asm_insn (\"creqv 6,6,6\", operands);
11246 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11248 [(set_attr "type" "branch")
11249 (set_attr "length" "4,8")])
11251 (define_insn "*sibcall_value_local32"
11252 [(set (match_operand 0 "" "")
11253 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11254 (match_operand 2 "" "g,g")))
11255 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11257 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11260 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11261 output_asm_insn (\"crxor 6,6,6\", operands);
11263 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11264 output_asm_insn (\"creqv 6,6,6\", operands);
11266 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11268 [(set_attr "type" "branch")
11269 (set_attr "length" "4,8")])
11271 (define_insn "*sibcall_value_local64"
11272 [(set (match_operand 0 "" "")
11273 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11274 (match_operand 2 "" "g,g")))
11275 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11277 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11280 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11281 output_asm_insn (\"crxor 6,6,6\", operands);
11283 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11284 output_asm_insn (\"creqv 6,6,6\", operands);
11286 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11288 [(set_attr "type" "branch")
11289 (set_attr "length" "4,8")])
11291 (define_insn "*sibcall_nonlocal_sysv<mode>"
11292 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11293 (match_operand 1 "" ""))
11294 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11296 "(DEFAULT_ABI == ABI_DARWIN
11297 || DEFAULT_ABI == ABI_V4)
11298 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11301 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11302 output_asm_insn (\"crxor 6,6,6\", operands);
11304 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11305 output_asm_insn (\"creqv 6,6,6\", operands);
11307 if (which_alternative >= 2)
11309 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11311 gcc_assert (!TARGET_SECURE_PLT);
11312 return \"b %z0@plt\";
11317 [(set_attr "type" "branch")
11318 (set_attr "length" "4,8,4,8")])
11320 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11321 [(set (match_operand 0 "" "")
11322 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11323 (match_operand 2 "" "")))
11324 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11326 "(DEFAULT_ABI == ABI_DARWIN
11327 || DEFAULT_ABI == ABI_V4)
11328 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11331 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11332 output_asm_insn (\"crxor 6,6,6\", operands);
11334 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11335 output_asm_insn (\"creqv 6,6,6\", operands);
11337 if (which_alternative >= 2)
11339 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11341 gcc_assert (!TARGET_SECURE_PLT);
11342 return \"b %z1@plt\";
11347 [(set_attr "type" "branch")
11348 (set_attr "length" "4,8,4,8")])
11350 ;; AIX ABI sibling call patterns.
11352 (define_insn "*sibcall_aix<mode>"
11353 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11354 (match_operand 1 "" "g,g"))
11356 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11360 [(set_attr "type" "branch")
11361 (set_attr "length" "4")])
11363 (define_insn "*sibcall_value_aix<mode>"
11364 [(set (match_operand 0 "" "")
11365 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11366 (match_operand 2 "" "g,g")))
11368 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11372 [(set_attr "type" "branch")
11373 (set_attr "length" "4")])
11375 (define_expand "sibcall_epilogue"
11376 [(use (const_int 0))]
11379 if (!TARGET_SCHED_PROLOG)
11380 emit_insn (gen_blockage ());
11381 rs6000_emit_epilogue (TRUE);
11385 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11386 ;; all of memory. This blocks insns from being moved across this point.
11388 (define_insn "blockage"
11389 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11393 (define_expand "probe_stack_address"
11394 [(use (match_operand 0 "address_operand"))]
11397 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11398 MEM_VOLATILE_P (operands[0]) = 1;
11401 emit_insn (gen_probe_stack_di (operands[0]));
11403 emit_insn (gen_probe_stack_si (operands[0]));
11407 (define_insn "probe_stack_<mode>"
11408 [(set (match_operand:P 0 "memory_operand" "=m")
11409 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11412 operands[1] = gen_rtx_REG (Pmode, 0);
11413 return "st<wd>%U0%X0 %1,%0";
11415 [(set_attr "type" "store")
11416 (set (attr "update")
11417 (if_then_else (match_operand 0 "update_address_mem")
11418 (const_string "yes")
11419 (const_string "no")))
11420 (set (attr "indexed")
11421 (if_then_else (match_operand 0 "indexed_address_mem")
11422 (const_string "yes")
11423 (const_string "no")))
11424 (set_attr "length" "4")])
11426 (define_insn "probe_stack_range<P:mode>"
11427 [(set (match_operand:P 0 "register_operand" "=r")
11428 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11429 (match_operand:P 2 "register_operand" "r")]
11430 UNSPECV_PROBE_STACK_RANGE))]
11432 "* return output_probe_stack_range (operands[0], operands[2]);"
11433 [(set_attr "type" "three")])
11435 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11436 ;; signed & unsigned, and one type of branch.
11438 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11439 ;; insns, and branches.
11441 (define_expand "cbranch<mode>4"
11442 [(use (match_operator 0 "rs6000_cbranch_operator"
11443 [(match_operand:GPR 1 "gpc_reg_operand" "")
11444 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11445 (use (match_operand 3 ""))]
11449 /* Take care of the possibility that operands[2] might be negative but
11450 this might be a logical operation. That insn doesn't exist. */
11451 if (GET_CODE (operands[2]) == CONST_INT
11452 && INTVAL (operands[2]) < 0)
11454 operands[2] = force_reg (<MODE>mode, operands[2]);
11455 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11456 GET_MODE (operands[0]),
11457 operands[1], operands[2]);
11460 rs6000_emit_cbranch (<MODE>mode, operands);
11464 (define_expand "cbranch<mode>4"
11465 [(use (match_operator 0 "rs6000_cbranch_operator"
11466 [(match_operand:FP 1 "gpc_reg_operand" "")
11467 (match_operand:FP 2 "gpc_reg_operand" "")]))
11468 (use (match_operand 3 ""))]
11472 rs6000_emit_cbranch (<MODE>mode, operands);
11476 (define_expand "cstore<mode>4_signed"
11477 [(use (match_operator 1 "signed_comparison_operator"
11478 [(match_operand:P 2 "gpc_reg_operand")
11479 (match_operand:P 3 "gpc_reg_operand")]))
11480 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11483 enum rtx_code cond_code = GET_CODE (operands[1]);
11485 rtx op0 = operands[0];
11486 rtx op1 = operands[2];
11487 rtx op2 = operands[3];
11489 if (cond_code == GE || cond_code == LT)
11491 cond_code = swap_condition (cond_code);
11492 std::swap (op1, op2);
11495 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11496 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11497 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11499 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11500 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11501 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11503 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11505 if (cond_code == LE)
11506 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11509 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11510 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11511 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11517 (define_expand "cstore<mode>4_unsigned"
11518 [(use (match_operator 1 "unsigned_comparison_operator"
11519 [(match_operand:P 2 "gpc_reg_operand")
11520 (match_operand:P 3 "reg_or_short_operand")]))
11521 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11524 enum rtx_code cond_code = GET_CODE (operands[1]);
11526 rtx op0 = operands[0];
11527 rtx op1 = operands[2];
11528 rtx op2 = operands[3];
11530 if (cond_code == GEU || cond_code == LTU)
11532 cond_code = swap_condition (cond_code);
11533 std::swap (op1, op2);
11536 if (!gpc_reg_operand (op1, <MODE>mode))
11537 op1 = force_reg (<MODE>mode, op1);
11538 if (!reg_or_short_operand (op2, <MODE>mode))
11539 op2 = force_reg (<MODE>mode, op2);
11541 rtx tmp = gen_reg_rtx (<MODE>mode);
11542 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11544 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11545 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11547 if (cond_code == LEU)
11548 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11550 emit_insn (gen_neg<mode>2 (op0, tmp2));
11555 (define_expand "cstore_si_as_di"
11556 [(use (match_operator 1 "unsigned_comparison_operator"
11557 [(match_operand:SI 2 "gpc_reg_operand")
11558 (match_operand:SI 3 "reg_or_short_operand")]))
11559 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11562 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11563 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11565 operands[2] = force_reg (SImode, operands[2]);
11566 operands[3] = force_reg (SImode, operands[3]);
11567 rtx op1 = gen_reg_rtx (DImode);
11568 rtx op2 = gen_reg_rtx (DImode);
11569 convert_move (op1, operands[2], uns_flag);
11570 convert_move (op2, operands[3], uns_flag);
11572 if (cond_code == GT || cond_code == LE)
11574 cond_code = swap_condition (cond_code);
11575 std::swap (op1, op2);
11578 rtx tmp = gen_reg_rtx (DImode);
11579 rtx tmp2 = gen_reg_rtx (DImode);
11580 emit_insn (gen_subdi3 (tmp, op1, op2));
11581 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11587 gcc_unreachable ();
11592 tmp3 = gen_reg_rtx (DImode);
11593 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11597 convert_move (operands[0], tmp3, 1);
11602 (define_expand "cstore<mode>4_signed_imm"
11603 [(use (match_operator 1 "signed_comparison_operator"
11604 [(match_operand:GPR 2 "gpc_reg_operand")
11605 (match_operand:GPR 3 "immediate_operand")]))
11606 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11609 bool invert = false;
11611 enum rtx_code cond_code = GET_CODE (operands[1]);
11613 rtx op0 = operands[0];
11614 rtx op1 = operands[2];
11615 HOST_WIDE_INT val = INTVAL (operands[3]);
11617 if (cond_code == GE || cond_code == GT)
11619 cond_code = reverse_condition (cond_code);
11623 if (cond_code == LE)
11626 rtx tmp = gen_reg_rtx (<MODE>mode);
11627 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11628 rtx x = gen_reg_rtx (<MODE>mode);
11630 emit_insn (gen_and<mode>3 (x, op1, tmp));
11632 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11636 rtx tmp = gen_reg_rtx (<MODE>mode);
11637 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11641 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11642 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11647 (define_expand "cstore<mode>4_unsigned_imm"
11648 [(use (match_operator 1 "unsigned_comparison_operator"
11649 [(match_operand:GPR 2 "gpc_reg_operand")
11650 (match_operand:GPR 3 "immediate_operand")]))
11651 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11654 bool invert = false;
11656 enum rtx_code cond_code = GET_CODE (operands[1]);
11658 rtx op0 = operands[0];
11659 rtx op1 = operands[2];
11660 HOST_WIDE_INT val = INTVAL (operands[3]);
11662 if (cond_code == GEU || cond_code == GTU)
11664 cond_code = reverse_condition (cond_code);
11668 if (cond_code == LEU)
11671 rtx tmp = gen_reg_rtx (<MODE>mode);
11672 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11673 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11674 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11675 rtx x = gen_reg_rtx (<MODE>mode);
11677 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11679 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11683 rtx tmp = gen_reg_rtx (<MODE>mode);
11684 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11688 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11689 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11694 (define_expand "cstore<mode>4"
11695 [(use (match_operator 1 "rs6000_cbranch_operator"
11696 [(match_operand:GPR 2 "gpc_reg_operand")
11697 (match_operand:GPR 3 "reg_or_short_operand")]))
11698 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11701 /* Use ISEL if the user asked for it. */
11703 rs6000_emit_sISEL (<MODE>mode, operands);
11705 /* Expanding EQ and NE directly to some machine instructions does not help
11706 but does hurt combine. So don't. */
11707 else if (GET_CODE (operands[1]) == EQ)
11708 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11709 else if (<MODE>mode == Pmode
11710 && GET_CODE (operands[1]) == NE)
11711 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11712 else if (GET_CODE (operands[1]) == NE)
11714 rtx tmp = gen_reg_rtx (<MODE>mode);
11715 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11716 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11719 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11720 etc. combinations magically work out just right. */
11721 else if (<MODE>mode == Pmode
11722 && unsigned_comparison_operator (operands[1], VOIDmode))
11723 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11724 operands[2], operands[3]));
11726 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11727 else if (<MODE>mode == SImode && Pmode == DImode)
11728 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11729 operands[2], operands[3]));
11731 /* For signed comparisons against a constant, we can do some simple
11733 else if (signed_comparison_operator (operands[1], VOIDmode)
11734 && CONST_INT_P (operands[3]))
11735 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11736 operands[2], operands[3]));
11738 /* And similarly for unsigned comparisons. */
11739 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11740 && CONST_INT_P (operands[3]))
11741 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11742 operands[2], operands[3]));
11744 /* We also do not want to use mfcr for signed comparisons. */
11745 else if (<MODE>mode == Pmode
11746 && signed_comparison_operator (operands[1], VOIDmode))
11747 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11748 operands[2], operands[3]));
11750 /* Everything else, use the mfcr brute force. */
11752 rs6000_emit_sCOND (<MODE>mode, operands);
11757 (define_expand "cstore<mode>4"
11758 [(use (match_operator 1 "rs6000_cbranch_operator"
11759 [(match_operand:FP 2 "gpc_reg_operand")
11760 (match_operand:FP 3 "gpc_reg_operand")]))
11761 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11764 rs6000_emit_sCOND (<MODE>mode, operands);
11769 (define_expand "stack_protect_set"
11770 [(match_operand 0 "memory_operand")
11771 (match_operand 1 "memory_operand")]
11774 if (rs6000_stack_protector_guard == SSP_TLS)
11776 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11777 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11778 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11779 operands[1] = gen_rtx_MEM (Pmode, addr);
11783 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11785 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11790 (define_insn "stack_protect_setsi"
11791 [(set (match_operand:SI 0 "memory_operand" "=m")
11792 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11793 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11795 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11796 [(set_attr "type" "three")
11797 (set_attr "length" "12")])
11799 (define_insn "stack_protect_setdi"
11800 [(set (match_operand:DI 0 "memory_operand" "=Y")
11801 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11802 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11804 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11805 [(set_attr "type" "three")
11806 (set_attr "length" "12")])
11808 (define_expand "stack_protect_test"
11809 [(match_operand 0 "memory_operand")
11810 (match_operand 1 "memory_operand")
11811 (match_operand 2 "")]
11814 rtx guard = operands[1];
11816 if (rs6000_stack_protector_guard == SSP_TLS)
11818 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11819 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11820 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11821 guard = gen_rtx_MEM (Pmode, addr);
11824 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11825 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11826 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11827 emit_jump_insn (jump);
11832 (define_insn "stack_protect_testsi"
11833 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11834 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11835 (match_operand:SI 2 "memory_operand" "m,m")]
11837 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11838 (clobber (match_scratch:SI 3 "=&r,&r"))]
11841 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11842 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11843 [(set_attr "length" "16,20")])
11845 (define_insn "stack_protect_testdi"
11846 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11847 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11848 (match_operand:DI 2 "memory_operand" "Y,Y")]
11850 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11851 (clobber (match_scratch:DI 3 "=&r,&r"))]
11854 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11855 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11856 [(set_attr "length" "16,20")])
11859 ;; Here are the actual compare insns.
11860 (define_insn "*cmp<mode>_signed"
11861 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11862 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11863 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11865 "cmp<wd>%I2 %0,%1,%2"
11866 [(set_attr "type" "cmp")])
11868 (define_insn "*cmp<mode>_unsigned"
11869 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11870 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11871 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11873 "cmpl<wd>%I2 %0,%1,%2"
11874 [(set_attr "type" "cmp")])
11876 ;; If we are comparing a register for equality with a large constant,
11877 ;; we can do this with an XOR followed by a compare. But this is profitable
11878 ;; only if the large constant is only used for the comparison (and in this
11879 ;; case we already have a register to reuse as scratch).
11881 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11882 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11885 [(set (match_operand:SI 0 "register_operand")
11886 (match_operand:SI 1 "logical_const_operand" ""))
11887 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11889 (match_operand:SI 2 "logical_const_operand" "")]))
11890 (set (match_operand:CC 4 "cc_reg_operand" "")
11891 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11894 (if_then_else (match_operator 6 "equality_operator"
11895 [(match_dup 4) (const_int 0)])
11896 (match_operand 7 "" "")
11897 (match_operand 8 "" "")))]
11898 "peep2_reg_dead_p (3, operands[0])
11899 && peep2_reg_dead_p (4, operands[4])
11900 && REGNO (operands[0]) != REGNO (operands[5])"
11901 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11902 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11903 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11906 /* Get the constant we are comparing against, and see what it looks like
11907 when sign-extended from 16 to 32 bits. Then see what constant we could
11908 XOR with SEXTC to get the sign-extended value. */
11909 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11911 operands[1], operands[2]);
11912 HOST_WIDE_INT c = INTVAL (cnst);
11913 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11914 HOST_WIDE_INT xorv = c ^ sextc;
11916 operands[9] = GEN_INT (xorv);
11917 operands[10] = GEN_INT (sextc);
11920 ;; The following two insns don't exist as single insns, but if we provide
11921 ;; them, we can swap an add and compare, which will enable us to overlap more
11922 ;; of the required delay between a compare and branch. We generate code for
11923 ;; them by splitting.
11926 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11927 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11928 (match_operand:SI 2 "short_cint_operand" "i")))
11929 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11930 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11933 [(set_attr "length" "8")])
11936 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11937 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11938 (match_operand:SI 2 "u_short_cint_operand" "i")))
11939 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11940 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11943 [(set_attr "length" "8")])
11946 [(set (match_operand:CC 3 "cc_reg_operand" "")
11947 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11948 (match_operand:SI 2 "short_cint_operand" "")))
11949 (set (match_operand:SI 0 "gpc_reg_operand" "")
11950 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11952 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11953 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11956 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11957 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11958 (match_operand:SI 2 "u_short_cint_operand" "")))
11959 (set (match_operand:SI 0 "gpc_reg_operand" "")
11960 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11962 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11963 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11965 ;; Only need to compare second words if first words equal
11966 (define_insn "*cmp<mode>_internal1"
11967 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11968 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11969 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11970 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11971 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11972 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11973 [(set_attr "type" "fpcompare")
11974 (set_attr "length" "12")])
11976 (define_insn_and_split "*cmp<mode>_internal2"
11977 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11978 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11979 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11980 (clobber (match_scratch:DF 3 "=d"))
11981 (clobber (match_scratch:DF 4 "=d"))
11982 (clobber (match_scratch:DF 5 "=d"))
11983 (clobber (match_scratch:DF 6 "=d"))
11984 (clobber (match_scratch:DF 7 "=d"))
11985 (clobber (match_scratch:DF 8 "=d"))
11986 (clobber (match_scratch:DF 9 "=d"))
11987 (clobber (match_scratch:DF 10 "=d"))
11988 (clobber (match_scratch:GPR 11 "=b"))]
11989 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11990 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11992 "&& reload_completed"
11993 [(set (match_dup 3) (match_dup 14))
11994 (set (match_dup 4) (match_dup 15))
11995 (set (match_dup 9) (abs:DF (match_dup 5)))
11996 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11997 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11998 (label_ref (match_dup 12))
12000 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12001 (set (pc) (label_ref (match_dup 13)))
12003 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12004 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12005 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12006 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12009 REAL_VALUE_TYPE rv;
12010 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12011 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12013 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12014 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12015 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12016 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12017 operands[12] = gen_label_rtx ();
12018 operands[13] = gen_label_rtx ();
12020 operands[14] = force_const_mem (DFmode,
12021 const_double_from_real_value (rv, DFmode));
12022 operands[15] = force_const_mem (DFmode,
12023 const_double_from_real_value (dconst0,
12028 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12029 operands[14] = gen_const_mem (DFmode, tocref);
12030 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12031 operands[15] = gen_const_mem (DFmode, tocref);
12032 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12033 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12037 ;; Now we have the scc insns. We can do some combinations because of the
12038 ;; way the machine works.
12040 ;; Note that this is probably faster if we can put an insn between the
12041 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12042 ;; cases the insns below which don't use an intermediate CR field will
12043 ;; be used instead.
12045 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12046 (match_operator:SI 1 "scc_comparison_operator"
12047 [(match_operand 2 "cc_reg_operand" "y")
12050 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12051 [(set (attr "type")
12052 (cond [(match_test "TARGET_MFCRF")
12053 (const_string "mfcrf")
12055 (const_string "mfcr")))
12056 (set_attr "length" "8")])
12058 ;; Same as above, but get the GT bit.
12059 (define_insn "move_from_CR_gt_bit"
12060 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12061 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
12062 "TARGET_HARD_FLOAT && !TARGET_FPRS"
12063 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
12064 [(set_attr "type" "mfcr")
12065 (set_attr "length" "8")])
12067 ;; Same as above, but get the OV/ORDERED bit.
12068 (define_insn "move_from_CR_ov_bit"
12069 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12070 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12073 "mfcr %0\;rlwinm %0,%0,%t1,1"
12074 [(set_attr "type" "mfcr")
12075 (set_attr "length" "8")])
12078 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12079 (match_operator:DI 1 "scc_comparison_operator"
12080 [(match_operand 2 "cc_reg_operand" "y")
12083 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12084 [(set (attr "type")
12085 (cond [(match_test "TARGET_MFCRF")
12086 (const_string "mfcrf")
12088 (const_string "mfcr")))
12089 (set_attr "length" "8")])
12092 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12093 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12094 [(match_operand 2 "cc_reg_operand" "y,y")
12097 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12098 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12101 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12103 [(set_attr "type" "shift")
12104 (set_attr "dot" "yes")
12105 (set_attr "length" "8,16")])
12108 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12109 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12110 [(match_operand 2 "cc_reg_operand" "")
12113 (set (match_operand:SI 3 "gpc_reg_operand" "")
12114 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12115 "TARGET_32BIT && reload_completed"
12116 [(set (match_dup 3)
12117 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12119 (compare:CC (match_dup 3)
12124 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12125 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12126 [(match_operand 2 "cc_reg_operand" "y")
12128 (match_operand:SI 3 "const_int_operand" "n")))]
12132 int is_bit = ccr_bit (operands[1], 1);
12133 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12136 if (is_bit >= put_bit)
12137 count = is_bit - put_bit;
12139 count = 32 - (put_bit - is_bit);
12141 operands[4] = GEN_INT (count);
12142 operands[5] = GEN_INT (put_bit);
12144 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12146 [(set (attr "type")
12147 (cond [(match_test "TARGET_MFCRF")
12148 (const_string "mfcrf")
12150 (const_string "mfcr")))
12151 (set_attr "length" "8")])
12154 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12156 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12157 [(match_operand 2 "cc_reg_operand" "y,y")
12159 (match_operand:SI 3 "const_int_operand" "n,n"))
12161 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12162 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12167 int is_bit = ccr_bit (operands[1], 1);
12168 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12171 /* Force split for non-cc0 compare. */
12172 if (which_alternative == 1)
12175 if (is_bit >= put_bit)
12176 count = is_bit - put_bit;
12178 count = 32 - (put_bit - is_bit);
12180 operands[5] = GEN_INT (count);
12181 operands[6] = GEN_INT (put_bit);
12183 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12185 [(set_attr "type" "shift")
12186 (set_attr "dot" "yes")
12187 (set_attr "length" "8,16")])
12190 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12192 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12193 [(match_operand 2 "cc_reg_operand" "")
12195 (match_operand:SI 3 "const_int_operand" ""))
12197 (set (match_operand:SI 4 "gpc_reg_operand" "")
12198 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12201 [(set (match_dup 4)
12202 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12205 (compare:CC (match_dup 4)
12210 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12213 (define_insn_and_split "eq<mode>3"
12214 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12215 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12216 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12217 (clobber (match_scratch:GPR 3 "=r"))
12218 (clobber (match_scratch:GPR 4 "=r"))]
12222 [(set (match_dup 4)
12223 (clz:GPR (match_dup 3)))
12225 (lshiftrt:GPR (match_dup 4)
12228 operands[3] = rs6000_emit_eqne (<MODE>mode,
12229 operands[1], operands[2], operands[3]);
12231 if (GET_CODE (operands[4]) == SCRATCH)
12232 operands[4] = gen_reg_rtx (<MODE>mode);
12234 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12236 [(set (attr "length")
12237 (if_then_else (match_test "operands[2] == const0_rtx")
12239 (const_string "12")))])
12241 (define_insn_and_split "ne<mode>3"
12242 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12243 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12244 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12245 (clobber (match_scratch:P 3 "=r"))
12246 (clobber (match_scratch:P 4 "=r"))
12247 (clobber (reg:P CA_REGNO))]
12251 [(parallel [(set (match_dup 4)
12252 (plus:P (match_dup 3)
12254 (set (reg:P CA_REGNO)
12255 (ne:P (match_dup 3)
12257 (parallel [(set (match_dup 0)
12258 (plus:P (plus:P (not:P (match_dup 4))
12261 (clobber (reg:P CA_REGNO))])]
12263 operands[3] = rs6000_emit_eqne (<MODE>mode,
12264 operands[1], operands[2], operands[3]);
12266 if (GET_CODE (operands[4]) == SCRATCH)
12267 operands[4] = gen_reg_rtx (<MODE>mode);
12269 [(set (attr "length")
12270 (if_then_else (match_test "operands[2] == const0_rtx")
12272 (const_string "12")))])
12274 (define_insn_and_split "*neg_eq_<mode>"
12275 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12276 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12277 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12278 (clobber (match_scratch:P 3 "=r"))
12279 (clobber (match_scratch:P 4 "=r"))
12280 (clobber (reg:P CA_REGNO))]
12284 [(parallel [(set (match_dup 4)
12285 (plus:P (match_dup 3)
12287 (set (reg:P CA_REGNO)
12288 (ne:P (match_dup 3)
12290 (parallel [(set (match_dup 0)
12291 (plus:P (reg:P CA_REGNO)
12293 (clobber (reg:P CA_REGNO))])]
12295 operands[3] = rs6000_emit_eqne (<MODE>mode,
12296 operands[1], operands[2], operands[3]);
12298 if (GET_CODE (operands[4]) == SCRATCH)
12299 operands[4] = gen_reg_rtx (<MODE>mode);
12301 [(set (attr "length")
12302 (if_then_else (match_test "operands[2] == const0_rtx")
12304 (const_string "12")))])
12306 (define_insn_and_split "*neg_ne_<mode>"
12307 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12308 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12309 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12310 (clobber (match_scratch:P 3 "=r"))
12311 (clobber (match_scratch:P 4 "=r"))
12312 (clobber (reg:P CA_REGNO))]
12316 [(parallel [(set (match_dup 4)
12317 (neg:P (match_dup 3)))
12318 (set (reg:P CA_REGNO)
12319 (eq:P (match_dup 3)
12321 (parallel [(set (match_dup 0)
12322 (plus:P (reg:P CA_REGNO)
12324 (clobber (reg:P CA_REGNO))])]
12326 operands[3] = rs6000_emit_eqne (<MODE>mode,
12327 operands[1], operands[2], operands[3]);
12329 if (GET_CODE (operands[4]) == SCRATCH)
12330 operands[4] = gen_reg_rtx (<MODE>mode);
12332 [(set (attr "length")
12333 (if_then_else (match_test "operands[2] == const0_rtx")
12335 (const_string "12")))])
12337 (define_insn_and_split "*plus_eq_<mode>"
12338 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12339 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12340 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12341 (match_operand:P 3 "gpc_reg_operand" "r")))
12342 (clobber (match_scratch:P 4 "=r"))
12343 (clobber (match_scratch:P 5 "=r"))
12344 (clobber (reg:P CA_REGNO))]
12348 [(parallel [(set (match_dup 5)
12349 (neg:P (match_dup 4)))
12350 (set (reg:P CA_REGNO)
12351 (eq:P (match_dup 4)
12353 (parallel [(set (match_dup 0)
12354 (plus:P (match_dup 3)
12356 (clobber (reg:P CA_REGNO))])]
12358 operands[4] = rs6000_emit_eqne (<MODE>mode,
12359 operands[1], operands[2], operands[4]);
12361 if (GET_CODE (operands[5]) == SCRATCH)
12362 operands[5] = gen_reg_rtx (<MODE>mode);
12364 [(set (attr "length")
12365 (if_then_else (match_test "operands[2] == const0_rtx")
12367 (const_string "12")))])
12369 (define_insn_and_split "*plus_ne_<mode>"
12370 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12371 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12372 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12373 (match_operand:P 3 "gpc_reg_operand" "r")))
12374 (clobber (match_scratch:P 4 "=r"))
12375 (clobber (match_scratch:P 5 "=r"))
12376 (clobber (reg:P CA_REGNO))]
12380 [(parallel [(set (match_dup 5)
12381 (plus:P (match_dup 4)
12383 (set (reg:P CA_REGNO)
12384 (ne:P (match_dup 4)
12386 (parallel [(set (match_dup 0)
12387 (plus:P (match_dup 3)
12389 (clobber (reg:P CA_REGNO))])]
12391 operands[4] = rs6000_emit_eqne (<MODE>mode,
12392 operands[1], operands[2], operands[4]);
12394 if (GET_CODE (operands[5]) == SCRATCH)
12395 operands[5] = gen_reg_rtx (<MODE>mode);
12397 [(set (attr "length")
12398 (if_then_else (match_test "operands[2] == const0_rtx")
12400 (const_string "12")))])
12402 (define_insn_and_split "*minus_eq_<mode>"
12403 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12404 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12405 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12406 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12407 (clobber (match_scratch:P 4 "=r"))
12408 (clobber (match_scratch:P 5 "=r"))
12409 (clobber (reg:P CA_REGNO))]
12413 [(parallel [(set (match_dup 5)
12414 (plus:P (match_dup 4)
12416 (set (reg:P CA_REGNO)
12417 (ne:P (match_dup 4)
12419 (parallel [(set (match_dup 0)
12420 (plus:P (plus:P (match_dup 3)
12423 (clobber (reg:P CA_REGNO))])]
12425 operands[4] = rs6000_emit_eqne (<MODE>mode,
12426 operands[1], operands[2], operands[4]);
12428 if (GET_CODE (operands[5]) == SCRATCH)
12429 operands[5] = gen_reg_rtx (<MODE>mode);
12431 [(set (attr "length")
12432 (if_then_else (match_test "operands[2] == const0_rtx")
12434 (const_string "12")))])
12436 (define_insn_and_split "*minus_ne_<mode>"
12437 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12438 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12439 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12440 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12441 (clobber (match_scratch:P 4 "=r"))
12442 (clobber (match_scratch:P 5 "=r"))
12443 (clobber (reg:P CA_REGNO))]
12447 [(parallel [(set (match_dup 5)
12448 (neg:P (match_dup 4)))
12449 (set (reg:P CA_REGNO)
12450 (eq:P (match_dup 4)
12452 (parallel [(set (match_dup 0)
12453 (plus:P (plus:P (match_dup 3)
12456 (clobber (reg:P CA_REGNO))])]
12458 operands[4] = rs6000_emit_eqne (<MODE>mode,
12459 operands[1], operands[2], operands[4]);
12461 if (GET_CODE (operands[5]) == SCRATCH)
12462 operands[5] = gen_reg_rtx (<MODE>mode);
12464 [(set (attr "length")
12465 (if_then_else (match_test "operands[2] == const0_rtx")
12467 (const_string "12")))])
12469 (define_insn_and_split "*eqsi3_ext<mode>"
12470 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12471 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12472 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12473 (clobber (match_scratch:SI 3 "=r"))
12474 (clobber (match_scratch:SI 4 "=r"))]
12478 [(set (match_dup 4)
12479 (clz:SI (match_dup 3)))
12482 (lshiftrt:SI (match_dup 4)
12485 operands[3] = rs6000_emit_eqne (SImode,
12486 operands[1], operands[2], operands[3]);
12488 if (GET_CODE (operands[4]) == SCRATCH)
12489 operands[4] = gen_reg_rtx (SImode);
12491 [(set (attr "length")
12492 (if_then_else (match_test "operands[2] == const0_rtx")
12494 (const_string "12")))])
12496 (define_insn_and_split "*nesi3_ext<mode>"
12497 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12498 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12499 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12500 (clobber (match_scratch:SI 3 "=r"))
12501 (clobber (match_scratch:SI 4 "=r"))
12502 (clobber (match_scratch:EXTSI 5 "=r"))]
12506 [(set (match_dup 4)
12507 (clz:SI (match_dup 3)))
12510 (lshiftrt:SI (match_dup 4)
12513 (xor:EXTSI (match_dup 5)
12516 operands[3] = rs6000_emit_eqne (SImode,
12517 operands[1], operands[2], operands[3]);
12519 if (GET_CODE (operands[4]) == SCRATCH)
12520 operands[4] = gen_reg_rtx (SImode);
12521 if (GET_CODE (operands[5]) == SCRATCH)
12522 operands[5] = gen_reg_rtx (<MODE>mode);
12524 [(set (attr "length")
12525 (if_then_else (match_test "operands[2] == const0_rtx")
12526 (const_string "12")
12527 (const_string "16")))])
12529 ;; Define both directions of branch and return. If we need a reload
12530 ;; register, we'd rather use CR0 since it is much easier to copy a
12531 ;; register CC value to there.
12535 (if_then_else (match_operator 1 "branch_comparison_operator"
12537 "cc_reg_operand" "y")
12539 (label_ref (match_operand 0 "" ""))
12544 return output_cbranch (operands[1], \"%l0\", 0, insn);
12546 [(set_attr "type" "branch")])
12550 (if_then_else (match_operator 0 "branch_comparison_operator"
12552 "cc_reg_operand" "y")
12559 return output_cbranch (operands[0], NULL, 0, insn);
12561 [(set_attr "type" "jmpreg")
12562 (set_attr "length" "4")])
12566 (if_then_else (match_operator 1 "branch_comparison_operator"
12568 "cc_reg_operand" "y")
12571 (label_ref (match_operand 0 "" ""))))]
12575 return output_cbranch (operands[1], \"%l0\", 1, insn);
12577 [(set_attr "type" "branch")])
12581 (if_then_else (match_operator 0 "branch_comparison_operator"
12583 "cc_reg_operand" "y")
12590 return output_cbranch (operands[0], NULL, 1, insn);
12592 [(set_attr "type" "jmpreg")
12593 (set_attr "length" "4")])
12595 ;; Logic on condition register values.
12597 ; This pattern matches things like
12598 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12599 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12601 ; which are generated by the branch logic.
12602 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12604 (define_insn "*cceq_ior_compare"
12605 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12606 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12607 [(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 ; Why is the constant -1 here, but 1 in the previous pattern?
12623 ; Because ~1 has all but the low bit set.
12625 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12626 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12627 [(not:SI (match_operator:SI 2
12628 "branch_positive_comparison_operator"
12630 "cc_reg_operand" "y,y")
12632 (match_operator:SI 4
12633 "branch_positive_comparison_operator"
12635 "cc_reg_operand" "0,y")
12639 "cr%q1 %E0,%j2,%j4"
12640 [(set_attr "type" "cr_logical,delayed_cr")])
12642 (define_insn "*cceq_rev_compare"
12643 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12644 (compare:CCEQ (match_operator:SI 1
12645 "branch_positive_comparison_operator"
12647 "cc_reg_operand" "0,y")
12652 [(set_attr "type" "cr_logical,delayed_cr")])
12654 ;; If we are comparing the result of two comparisons, this can be done
12655 ;; using creqv or crxor.
12657 (define_insn_and_split ""
12658 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12659 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12660 [(match_operand 2 "cc_reg_operand" "y")
12662 (match_operator 3 "branch_comparison_operator"
12663 [(match_operand 4 "cc_reg_operand" "y")
12668 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12672 int positive_1, positive_2;
12674 positive_1 = branch_positive_comparison_operator (operands[1],
12675 GET_MODE (operands[1]));
12676 positive_2 = branch_positive_comparison_operator (operands[3],
12677 GET_MODE (operands[3]));
12680 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12681 GET_CODE (operands[1])),
12683 operands[2], const0_rtx);
12684 else if (GET_MODE (operands[1]) != SImode)
12685 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12686 operands[2], const0_rtx);
12689 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12690 GET_CODE (operands[3])),
12692 operands[4], const0_rtx);
12693 else if (GET_MODE (operands[3]) != SImode)
12694 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12695 operands[4], const0_rtx);
12697 if (positive_1 == positive_2)
12699 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12700 operands[5] = constm1_rtx;
12704 operands[5] = const1_rtx;
12708 ;; Unconditional branch and return.
12710 (define_insn "jump"
12712 (label_ref (match_operand 0 "" "")))]
12715 [(set_attr "type" "branch")])
12717 (define_insn "<return_str>return"
12721 [(set_attr "type" "jmpreg")])
12723 (define_expand "indirect_jump"
12724 [(set (pc) (match_operand 0 "register_operand" ""))])
12726 (define_insn "*indirect_jump<mode>"
12727 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12732 [(set_attr "type" "jmpreg")])
12734 ;; Table jump for switch statements:
12735 (define_expand "tablejump"
12736 [(use (match_operand 0 "" ""))
12737 (use (label_ref (match_operand 1 "" "")))]
12742 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12744 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12748 (define_expand "tablejumpsi"
12749 [(set (match_dup 3)
12750 (plus:SI (match_operand:SI 0 "" "")
12752 (parallel [(set (pc) (match_dup 3))
12753 (use (label_ref (match_operand 1 "" "")))])]
12756 { operands[0] = force_reg (SImode, operands[0]);
12757 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12758 operands[3] = gen_reg_rtx (SImode);
12761 (define_expand "tablejumpdi"
12762 [(set (match_dup 4)
12763 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12765 (plus:DI (match_dup 4)
12767 (parallel [(set (pc) (match_dup 3))
12768 (use (label_ref (match_operand 1 "" "")))])]
12771 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12772 operands[3] = gen_reg_rtx (DImode);
12773 operands[4] = gen_reg_rtx (DImode);
12776 (define_insn "*tablejump<mode>_internal1"
12778 (match_operand:P 0 "register_operand" "c,*l"))
12779 (use (label_ref (match_operand 1 "" "")))]
12784 [(set_attr "type" "jmpreg")])
12787 [(unspec [(const_int 0)] UNSPEC_NOP)]
12791 (define_insn "group_ending_nop"
12792 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12796 if (rs6000_cpu_attr == CPU_POWER6)
12797 return \"ori 1,1,0\";
12798 return \"ori 2,2,0\";
12801 ;; Define the subtract-one-and-jump insns, starting with the template
12802 ;; so loop.c knows what to generate.
12804 (define_expand "doloop_end"
12805 [(use (match_operand 0 "" "")) ; loop pseudo
12806 (use (match_operand 1 "" ""))] ; label
12812 if (GET_MODE (operands[0]) != DImode)
12814 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12818 if (GET_MODE (operands[0]) != SImode)
12820 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12825 (define_expand "ctr<mode>"
12826 [(parallel [(set (pc)
12827 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12829 (label_ref (match_operand 1 "" ""))
12832 (plus:P (match_dup 0)
12834 (clobber (match_scratch:CC 2 ""))
12835 (clobber (match_scratch:P 3 ""))])]
12839 ;; We need to be able to do this for any operand, including MEM, or we
12840 ;; will cause reload to blow up since we don't allow output reloads on
12842 ;; For the length attribute to be calculated correctly, the
12843 ;; label MUST be operand 0.
12844 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12845 ;; the ctr<mode> insns.
12847 (define_insn "ctr<mode>_internal1"
12849 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12851 (label_ref (match_operand 0 "" ""))
12853 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12854 (plus:P (match_dup 1)
12856 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12857 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12861 if (which_alternative != 0)
12863 else if (get_attr_length (insn) == 4)
12864 return \"bdnz %l0\";
12866 return \"bdz $+8\;b %l0\";
12868 [(set_attr "type" "branch")
12869 (set_attr "length" "*,16,20,20")])
12871 (define_insn "ctr<mode>_internal2"
12873 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12876 (label_ref (match_operand 0 "" ""))))
12877 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12878 (plus:P (match_dup 1)
12880 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12881 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12885 if (which_alternative != 0)
12887 else if (get_attr_length (insn) == 4)
12888 return \"bdz %l0\";
12890 return \"bdnz $+8\;b %l0\";
12892 [(set_attr "type" "branch")
12893 (set_attr "length" "*,16,20,20")])
12895 ;; Similar but use EQ
12897 (define_insn "ctr<mode>_internal3"
12899 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12901 (label_ref (match_operand 0 "" ""))
12903 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12904 (plus:P (match_dup 1)
12906 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12907 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12911 if (which_alternative != 0)
12913 else if (get_attr_length (insn) == 4)
12914 return \"bdz %l0\";
12916 return \"bdnz $+8\;b %l0\";
12918 [(set_attr "type" "branch")
12919 (set_attr "length" "*,16,20,20")])
12921 (define_insn "ctr<mode>_internal4"
12923 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12926 (label_ref (match_operand 0 "" ""))))
12927 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12928 (plus:P (match_dup 1)
12930 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12931 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12935 if (which_alternative != 0)
12937 else if (get_attr_length (insn) == 4)
12938 return \"bdnz %l0\";
12940 return \"bdz $+8\;b %l0\";
12942 [(set_attr "type" "branch")
12943 (set_attr "length" "*,16,20,20")])
12945 ;; Now the splitters if we could not allocate the CTR register
12949 (if_then_else (match_operator 2 "comparison_operator"
12950 [(match_operand:P 1 "gpc_reg_operand" "")
12952 (match_operand 5 "" "")
12953 (match_operand 6 "" "")))
12954 (set (match_operand:P 0 "int_reg_operand" "")
12955 (plus:P (match_dup 1) (const_int -1)))
12956 (clobber (match_scratch:CC 3 ""))
12957 (clobber (match_scratch:P 4 ""))]
12959 [(set (match_dup 3)
12960 (compare:CC (match_dup 1)
12963 (plus:P (match_dup 1)
12965 (set (pc) (if_then_else (match_dup 7)
12969 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12970 operands[3], const0_rtx); }")
12974 (if_then_else (match_operator 2 "comparison_operator"
12975 [(match_operand:P 1 "gpc_reg_operand" "")
12977 (match_operand 5 "" "")
12978 (match_operand 6 "" "")))
12979 (set (match_operand:P 0 "nonimmediate_operand" "")
12980 (plus:P (match_dup 1) (const_int -1)))
12981 (clobber (match_scratch:CC 3 ""))
12982 (clobber (match_scratch:P 4 ""))]
12983 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12984 [(set (match_dup 3)
12985 (compare:CC (match_dup 1)
12988 (plus:P (match_dup 1)
12992 (set (pc) (if_then_else (match_dup 7)
12996 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12997 operands[3], const0_rtx); }")
12999 (define_insn "trap"
13000 [(trap_if (const_int 1) (const_int 0))]
13003 [(set_attr "type" "trap")])
13005 (define_expand "ctrap<mode>4"
13006 [(trap_if (match_operator 0 "ordered_comparison_operator"
13007 [(match_operand:GPR 1 "register_operand")
13008 (match_operand:GPR 2 "reg_or_short_operand")])
13009 (match_operand 3 "zero_constant" ""))]
13014 [(trap_if (match_operator 0 "ordered_comparison_operator"
13015 [(match_operand:GPR 1 "register_operand" "r")
13016 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13019 "t<wd>%V0%I2 %1,%2"
13020 [(set_attr "type" "trap")])
13022 ;; Insns related to generating the function prologue and epilogue.
13024 (define_expand "prologue"
13025 [(use (const_int 0))]
13028 rs6000_emit_prologue ();
13029 if (!TARGET_SCHED_PROLOG)
13030 emit_insn (gen_blockage ());
13034 (define_insn "*movesi_from_cr_one"
13035 [(match_parallel 0 "mfcr_operation"
13036 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13037 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13038 (match_operand 3 "immediate_operand" "n")]
13039 UNSPEC_MOVESI_FROM_CR))])]
13045 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13047 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13048 operands[4] = GEN_INT (mask);
13049 output_asm_insn (\"mfcr %1,%4\", operands);
13053 [(set_attr "type" "mfcrf")])
13055 (define_insn "movesi_from_cr"
13056 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13057 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13058 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13059 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13060 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13061 UNSPEC_MOVESI_FROM_CR))]
13064 [(set_attr "type" "mfcr")])
13066 (define_insn "*crsave"
13067 [(match_parallel 0 "crsave_operation"
13068 [(set (match_operand:SI 1 "memory_operand" "=m")
13069 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13072 [(set_attr "type" "store")])
13074 (define_insn "*stmw"
13075 [(match_parallel 0 "stmw_operation"
13076 [(set (match_operand:SI 1 "memory_operand" "=m")
13077 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13080 [(set_attr "type" "store")
13081 (set_attr "update" "yes")
13082 (set_attr "indexed" "yes")])
13084 ; The following comment applies to:
13088 ; return_and_restore_gpregs*
13089 ; return_and_restore_fpregs*
13090 ; return_and_restore_fpregs_aix*
13092 ; The out-of-line save / restore functions expects one input argument.
13093 ; Since those are not standard call_insn's, we must avoid using
13094 ; MATCH_OPERAND for that argument. That way the register rename
13095 ; optimization will not try to rename this register.
13096 ; Each pattern is repeated for each possible register number used in
13097 ; various ABIs (r11, r1, and for some functions r12)
13099 (define_insn "*save_gpregs_<mode>_r11"
13100 [(match_parallel 0 "any_parallel_operand"
13101 [(clobber (reg:P LR_REGNO))
13102 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13104 (set (match_operand:P 2 "memory_operand" "=m")
13105 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13108 [(set_attr "type" "branch")
13109 (set_attr "length" "4")])
13111 (define_insn "*save_gpregs_<mode>_r12"
13112 [(match_parallel 0 "any_parallel_operand"
13113 [(clobber (reg:P LR_REGNO))
13114 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13116 (set (match_operand:P 2 "memory_operand" "=m")
13117 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13120 [(set_attr "type" "branch")
13121 (set_attr "length" "4")])
13123 (define_insn "*save_gpregs_<mode>_r1"
13124 [(match_parallel 0 "any_parallel_operand"
13125 [(clobber (reg:P LR_REGNO))
13126 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13128 (set (match_operand:P 2 "memory_operand" "=m")
13129 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13132 [(set_attr "type" "branch")
13133 (set_attr "length" "4")])
13135 (define_insn "*save_fpregs_<mode>_r11"
13136 [(match_parallel 0 "any_parallel_operand"
13137 [(clobber (reg:P LR_REGNO))
13138 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13140 (set (match_operand:DF 2 "memory_operand" "=m")
13141 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13144 [(set_attr "type" "branch")
13145 (set_attr "length" "4")])
13147 (define_insn "*save_fpregs_<mode>_r12"
13148 [(match_parallel 0 "any_parallel_operand"
13149 [(clobber (reg:P LR_REGNO))
13150 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13152 (set (match_operand:DF 2 "memory_operand" "=m")
13153 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13156 [(set_attr "type" "branch")
13157 (set_attr "length" "4")])
13159 (define_insn "*save_fpregs_<mode>_r1"
13160 [(match_parallel 0 "any_parallel_operand"
13161 [(clobber (reg:P LR_REGNO))
13162 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13164 (set (match_operand:DF 2 "memory_operand" "=m")
13165 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13168 [(set_attr "type" "branch")
13169 (set_attr "length" "4")])
13171 ; This is to explain that changes to the stack pointer should
13172 ; not be moved over loads from or stores to stack memory.
13173 (define_insn "stack_tie"
13174 [(match_parallel 0 "tie_operand"
13175 [(set (mem:BLK (reg 1)) (const_int 0))])]
13178 [(set_attr "length" "0")])
13180 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13181 ; stay behind all restores from the stack, it cannot be reordered to before
13182 ; one. See PR77687. This insn is an add or mr, and a stack_tie on the
13183 ; operands of that.
13184 (define_insn "stack_restore_tie"
13185 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13186 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13187 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13188 (set (mem:BLK (match_dup 0)) (const_int 0))
13189 (set (mem:BLK (match_dup 1)) (const_int 0))]
13194 [(set_attr "type" "*,add")])
13196 (define_expand "epilogue"
13197 [(use (const_int 0))]
13200 if (!TARGET_SCHED_PROLOG)
13201 emit_insn (gen_blockage ());
13202 rs6000_emit_epilogue (FALSE);
13206 ; On some processors, doing the mtcrf one CC register at a time is
13207 ; faster (like on the 604e). On others, doing them all at once is
13208 ; faster; for instance, on the 601 and 750.
13210 (define_expand "movsi_to_cr_one"
13211 [(set (match_operand:CC 0 "cc_reg_operand" "")
13212 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13213 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13215 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13217 (define_insn "*movsi_to_cr"
13218 [(match_parallel 0 "mtcrf_operation"
13219 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13220 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13221 (match_operand 3 "immediate_operand" "n")]
13222 UNSPEC_MOVESI_TO_CR))])]
13228 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13229 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13230 operands[4] = GEN_INT (mask);
13231 return \"mtcrf %4,%2\";
13233 [(set_attr "type" "mtcr")])
13235 (define_insn "*mtcrfsi"
13236 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13237 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13238 (match_operand 2 "immediate_operand" "n")]
13239 UNSPEC_MOVESI_TO_CR))]
13240 "GET_CODE (operands[0]) == REG
13241 && CR_REGNO_P (REGNO (operands[0]))
13242 && GET_CODE (operands[2]) == CONST_INT
13243 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13245 [(set_attr "type" "mtcr")])
13247 ; The load-multiple instructions have similar properties.
13248 ; Note that "load_multiple" is a name known to the machine-independent
13249 ; code that actually corresponds to the PowerPC load-string.
13251 (define_insn "*lmw"
13252 [(match_parallel 0 "lmw_operation"
13253 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13254 (match_operand:SI 2 "memory_operand" "m"))])]
13257 [(set_attr "type" "load")
13258 (set_attr "update" "yes")
13259 (set_attr "indexed" "yes")
13260 (set_attr "cell_micro" "always")])
13262 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13263 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13265 ; The following comment applies to:
13269 ; return_and_restore_gpregs*
13270 ; return_and_restore_fpregs*
13271 ; return_and_restore_fpregs_aix*
13273 ; The out-of-line save / restore functions expects one input argument.
13274 ; Since those are not standard call_insn's, we must avoid using
13275 ; MATCH_OPERAND for that argument. That way the register rename
13276 ; optimization will not try to rename this register.
13277 ; Each pattern is repeated for each possible register number used in
13278 ; various ABIs (r11, r1, and for some functions r12)
13280 (define_insn "*restore_gpregs_<mode>_r11"
13281 [(match_parallel 0 "any_parallel_operand"
13282 [(clobber (reg:P LR_REGNO))
13283 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13285 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13286 (match_operand:P 3 "memory_operand" "m"))])]
13289 [(set_attr "type" "branch")
13290 (set_attr "length" "4")])
13292 (define_insn "*restore_gpregs_<mode>_r12"
13293 [(match_parallel 0 "any_parallel_operand"
13294 [(clobber (reg:P LR_REGNO))
13295 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13297 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13298 (match_operand:P 3 "memory_operand" "m"))])]
13301 [(set_attr "type" "branch")
13302 (set_attr "length" "4")])
13304 (define_insn "*restore_gpregs_<mode>_r1"
13305 [(match_parallel 0 "any_parallel_operand"
13306 [(clobber (reg:P LR_REGNO))
13307 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13309 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13310 (match_operand:P 3 "memory_operand" "m"))])]
13313 [(set_attr "type" "branch")
13314 (set_attr "length" "4")])
13316 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13317 [(match_parallel 0 "any_parallel_operand"
13319 (clobber (reg:P LR_REGNO))
13320 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13322 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13323 (match_operand:P 3 "memory_operand" "m"))])]
13326 [(set_attr "type" "branch")
13327 (set_attr "length" "4")])
13329 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13330 [(match_parallel 0 "any_parallel_operand"
13332 (clobber (reg:P LR_REGNO))
13333 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13335 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13336 (match_operand:P 3 "memory_operand" "m"))])]
13339 [(set_attr "type" "branch")
13340 (set_attr "length" "4")])
13342 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13343 [(match_parallel 0 "any_parallel_operand"
13345 (clobber (reg:P LR_REGNO))
13346 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13348 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13349 (match_operand:P 3 "memory_operand" "m"))])]
13352 [(set_attr "type" "branch")
13353 (set_attr "length" "4")])
13355 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13356 [(match_parallel 0 "any_parallel_operand"
13358 (clobber (reg:P LR_REGNO))
13359 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13361 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13362 (match_operand:DF 3 "memory_operand" "m"))])]
13365 [(set_attr "type" "branch")
13366 (set_attr "length" "4")])
13368 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13369 [(match_parallel 0 "any_parallel_operand"
13371 (clobber (reg:P LR_REGNO))
13372 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13374 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13375 (match_operand:DF 3 "memory_operand" "m"))])]
13378 [(set_attr "type" "branch")
13379 (set_attr "length" "4")])
13381 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13382 [(match_parallel 0 "any_parallel_operand"
13384 (clobber (reg:P LR_REGNO))
13385 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13387 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13388 (match_operand:DF 3 "memory_operand" "m"))])]
13391 [(set_attr "type" "branch")
13392 (set_attr "length" "4")])
13394 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13395 [(match_parallel 0 "any_parallel_operand"
13397 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13399 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13400 (match_operand:DF 3 "memory_operand" "m"))])]
13403 [(set_attr "type" "branch")
13404 (set_attr "length" "4")])
13406 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13407 [(match_parallel 0 "any_parallel_operand"
13409 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13411 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13412 (match_operand:DF 3 "memory_operand" "m"))])]
13415 [(set_attr "type" "branch")
13416 (set_attr "length" "4")])
13418 ; This is used in compiling the unwind routines.
13419 (define_expand "eh_return"
13420 [(use (match_operand 0 "general_operand" ""))]
13425 emit_insn (gen_eh_set_lr_si (operands[0]));
13427 emit_insn (gen_eh_set_lr_di (operands[0]));
13431 ; We can't expand this before we know where the link register is stored.
13432 (define_insn "eh_set_lr_<mode>"
13433 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13435 (clobber (match_scratch:P 1 "=&b"))]
13440 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13441 (clobber (match_scratch 1 ""))]
13446 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13450 (define_insn "prefetch"
13451 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13452 (match_operand:SI 1 "const_int_operand" "n")
13453 (match_operand:SI 2 "const_int_operand" "n"))]
13457 if (GET_CODE (operands[0]) == REG)
13458 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13459 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13461 [(set_attr "type" "load")])
13463 ;; Handle -fsplit-stack.
13465 (define_expand "split_stack_prologue"
13469 rs6000_expand_split_stack_prologue ();
13473 (define_expand "load_split_stack_limit"
13474 [(set (match_operand 0)
13475 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13478 emit_insn (gen_rtx_SET (operands[0],
13479 gen_rtx_UNSPEC (Pmode,
13480 gen_rtvec (1, const0_rtx),
13481 UNSPEC_STACK_CHECK)));
13485 (define_insn "load_split_stack_limit_di"
13486 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13487 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13489 "ld %0,-0x7040(13)"
13490 [(set_attr "type" "load")
13491 (set_attr "update" "no")
13492 (set_attr "indexed" "no")])
13494 (define_insn "load_split_stack_limit_si"
13495 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13496 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13498 "lwz %0,-0x7020(2)"
13499 [(set_attr "type" "load")
13500 (set_attr "update" "no")
13501 (set_attr "indexed" "no")])
13503 ;; A return instruction which the middle-end doesn't see.
13504 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13505 ;; after the call to __morestack.
13506 (define_insn "split_stack_return"
13507 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13510 [(set_attr "type" "jmpreg")])
13512 ;; If there are operand 0 bytes available on the stack, jump to
13514 (define_expand "split_stack_space_check"
13515 [(set (match_dup 2)
13516 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13518 (minus (reg STACK_POINTER_REGNUM)
13519 (match_operand 0)))
13520 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13521 (set (pc) (if_then_else
13522 (geu (match_dup 4) (const_int 0))
13523 (label_ref (match_operand 1))
13527 rs6000_split_stack_space_check (operands[0], operands[1]);
13531 (define_insn "bpermd_<mode>"
13532 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13533 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13534 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13537 [(set_attr "type" "popcnt")])
13540 ;; Builtin fma support. Handle
13541 ;; Note that the conditions for expansion are in the FMA_F iterator.
13543 (define_expand "fma<mode>4"
13544 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13546 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13547 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13548 (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13552 (define_insn "*fma<mode>4_fpr"
13553 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13555 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13556 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13557 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13558 "TARGET_<MODE>_FPR"
13560 fmadd<Ftrad> %0,%1,%2,%3
13561 xsmadda<Fvsx> %x0,%x1,%x2
13562 xsmaddm<Fvsx> %x0,%x1,%x3"
13563 [(set_attr "type" "fp")
13564 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13566 ; Altivec only has fma and nfms.
13567 (define_expand "fms<mode>4"
13568 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13570 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13571 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13572 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13573 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13576 (define_insn "*fms<mode>4_fpr"
13577 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13579 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13580 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13581 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13582 "TARGET_<MODE>_FPR"
13584 fmsub<Ftrad> %0,%1,%2,%3
13585 xsmsuba<Fvsx> %x0,%x1,%x2
13586 xsmsubm<Fvsx> %x0,%x1,%x3"
13587 [(set_attr "type" "fp")
13588 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13590 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13591 (define_expand "fnma<mode>4"
13592 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13595 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13596 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13597 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13598 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13601 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13602 (define_expand "fnms<mode>4"
13603 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13606 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13607 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13608 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13609 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13612 ; Not an official optab name, but used from builtins.
13613 (define_expand "nfma<mode>4"
13614 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13617 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13618 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13619 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13620 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13623 (define_insn "*nfma<mode>4_fpr"
13624 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13627 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13628 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13629 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13630 "TARGET_<MODE>_FPR"
13632 fnmadd<Ftrad> %0,%1,%2,%3
13633 xsnmadda<Fvsx> %x0,%x1,%x2
13634 xsnmaddm<Fvsx> %x0,%x1,%x3"
13635 [(set_attr "type" "fp")
13636 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13638 ; Not an official optab name, but used from builtins.
13639 (define_expand "nfms<mode>4"
13640 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13643 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13644 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13645 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13649 (define_insn "*nfmssf4_fpr"
13650 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13653 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13654 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13656 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13657 "TARGET_<MODE>_FPR"
13659 fnmsub<Ftrad> %0,%1,%2,%3
13660 xsnmsuba<Fvsx> %x0,%x1,%x2
13661 xsnmsubm<Fvsx> %x0,%x1,%x3"
13662 [(set_attr "type" "fp")
13663 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13666 (define_expand "rs6000_get_timebase"
13667 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13670 if (TARGET_POWERPC64)
13671 emit_insn (gen_rs6000_mftb_di (operands[0]));
13673 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13677 (define_insn "rs6000_get_timebase_ppc32"
13678 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13679 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13680 (clobber (match_scratch:SI 1 "=r"))
13681 (clobber (match_scratch:CC 2 "=y"))]
13682 "!TARGET_POWERPC64"
13684 if (WORDS_BIG_ENDIAN)
13687 return "mfspr %0,269\;"
13695 return "mftbu %0\;"
13704 return "mfspr %L0,269\;"
13712 return "mftbu %L0\;"
13719 [(set_attr "length" "20")])
13721 (define_insn "rs6000_mftb_<mode>"
13722 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13723 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13727 return "mfspr %0,268";
13733 (define_insn "rs6000_mffs"
13734 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13735 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13736 "TARGET_HARD_FLOAT && TARGET_FPRS"
13739 (define_insn "rs6000_mtfsf"
13740 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13741 (match_operand:DF 1 "gpc_reg_operand" "d")]
13743 "TARGET_HARD_FLOAT && TARGET_FPRS"
13747 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13748 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13749 ;; register that is being loaded. The fused ops must be physically adjacent.
13751 ;; There are two parts to addis fusion. The support for fused TOCs occur
13752 ;; before register allocation, and is meant to reduce the lifetime for the
13753 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13754 ;; to use the register that is being load. The peephole2 then gathers any
13755 ;; other fused possibilities that it can find after register allocation. If
13756 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13758 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13759 ;; before register allocation, so that we can avoid allocating a temporary base
13760 ;; register that won't be used, and that we try to load into base registers,
13761 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13762 ;; (addis followed by load) even on power8.
13765 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13766 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13767 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13768 [(parallel [(set (match_dup 0) (match_dup 2))
13769 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13770 (use (match_dup 3))
13771 (clobber (scratch:DI))])]
13773 operands[2] = fusion_wrap_memory_address (operands[1]);
13774 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13777 (define_insn "*toc_fusionload_<mode>"
13778 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13779 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13780 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13781 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13782 (clobber (match_scratch:DI 3 "=X,&b"))]
13783 "TARGET_TOC_FUSION_INT"
13785 if (base_reg_operand (operands[0], <MODE>mode))
13786 return emit_fusion_gpr_load (operands[0], operands[1]);
13788 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13790 [(set_attr "type" "load")
13791 (set_attr "length" "8")])
13793 (define_insn "*toc_fusionload_di"
13794 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13795 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13796 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13797 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13798 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13799 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13800 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13802 if (base_reg_operand (operands[0], DImode))
13803 return emit_fusion_gpr_load (operands[0], operands[1]);
13805 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13807 [(set_attr "type" "load")
13808 (set_attr "length" "8")])
13811 ;; Find cases where the addis that feeds into a load instruction is either used
13812 ;; once or is the same as the target register, and replace it with the fusion
13816 [(set (match_operand:P 0 "base_reg_operand" "")
13817 (match_operand:P 1 "fusion_gpr_addis" ""))
13818 (set (match_operand:INT1 2 "base_reg_operand" "")
13819 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13821 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13825 expand_fusion_gpr_load (operands);
13829 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13832 (define_insn "fusion_gpr_load_<mode>"
13833 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13834 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13835 UNSPEC_FUSION_GPR))]
13838 return emit_fusion_gpr_load (operands[0], operands[1]);
13840 [(set_attr "type" "load")
13841 (set_attr "length" "8")])
13844 ;; ISA 3.0 (power9) fusion support
13845 ;; Merge addis with floating load/store to FPRs (or GPRs).
13847 [(set (match_operand:P 0 "base_reg_operand" "")
13848 (match_operand:P 1 "fusion_gpr_addis" ""))
13849 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13850 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13851 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13852 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13855 expand_fusion_p9_load (operands);
13860 [(set (match_operand:P 0 "base_reg_operand" "")
13861 (match_operand:P 1 "fusion_gpr_addis" ""))
13862 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13863 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13864 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13865 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13866 && !rtx_equal_p (operands[0], operands[3])"
13869 expand_fusion_p9_store (operands);
13874 [(set (match_operand:SDI 0 "int_reg_operand" "")
13875 (match_operand:SDI 1 "upper16_cint_operand" ""))
13877 (ior:SDI (match_dup 0)
13878 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13880 [(set (match_dup 0)
13881 (unspec:SDI [(match_dup 1)
13882 (match_dup 2)] UNSPEC_FUSION_P9))])
13885 [(set (match_operand:SDI 0 "int_reg_operand" "")
13886 (match_operand:SDI 1 "upper16_cint_operand" ""))
13887 (set (match_operand:SDI 2 "int_reg_operand" "")
13888 (ior:SDI (match_dup 0)
13889 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13891 && !rtx_equal_p (operands[0], operands[2])
13892 && peep2_reg_dead_p (2, operands[0])"
13893 [(set (match_dup 2)
13894 (unspec:SDI [(match_dup 1)
13895 (match_dup 3)] UNSPEC_FUSION_P9))])
13897 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13898 ;; reload). Because we want to eventually have secondary_reload generate
13899 ;; these, they have to have a single alternative that gives the register
13900 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13901 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13902 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13904 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13906 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13909 /* This insn is a secondary reload insn, which cannot have alternatives.
13910 If we are not loading up register 0, use the power8 fusion instead. */
13911 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13912 return emit_fusion_gpr_load (operands[0], operands[1]);
13914 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13916 [(set_attr "type" "load")
13917 (set_attr "length" "8")])
13919 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13920 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13922 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13924 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13927 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13929 [(set_attr "type" "store")
13930 (set_attr "length" "8")])
13932 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13933 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13935 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13937 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13940 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13942 [(set_attr "type" "fpload")
13943 (set_attr "length" "8")])
13945 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13946 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13948 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13950 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13953 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13955 [(set_attr "type" "fpstore")
13956 (set_attr "length" "8")])
13958 (define_insn "*fusion_p9_<mode>_constant"
13959 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13960 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13961 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13962 UNSPEC_FUSION_P9))]
13965 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13966 return "ori %0,%0,%2";
13968 [(set_attr "type" "two")
13969 (set_attr "length" "8")])
13972 ;; Miscellaneous ISA 2.06 (power7) instructions
13973 (define_insn "addg6s"
13974 [(set (match_operand:SI 0 "register_operand" "=r")
13975 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13976 (match_operand:SI 2 "register_operand" "r")]
13980 [(set_attr "type" "integer")
13981 (set_attr "length" "4")])
13983 (define_insn "cdtbcd"
13984 [(set (match_operand:SI 0 "register_operand" "=r")
13985 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13989 [(set_attr "type" "integer")
13990 (set_attr "length" "4")])
13992 (define_insn "cbcdtd"
13993 [(set (match_operand:SI 0 "register_operand" "=r")
13994 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13998 [(set_attr "type" "integer")
13999 (set_attr "length" "4")])
14001 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14006 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14007 (UNSPEC_DIVEO "eo")
14008 (UNSPEC_DIVEU "eu")
14009 (UNSPEC_DIVEUO "euo")])
14011 (define_insn "div<div_extend>_<mode>"
14012 [(set (match_operand:GPR 0 "register_operand" "=r")
14013 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14014 (match_operand:GPR 2 "register_operand" "r")]
14015 UNSPEC_DIV_EXTEND))]
14017 "div<wd><div_extend> %0,%1,%2"
14018 [(set_attr "type" "div")
14019 (set_attr "size" "<bits>")])
14022 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14024 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14025 (define_mode_attr FP128_64 [(TF "DF")
14030 (define_expand "unpack<mode>"
14031 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14033 [(match_operand:FMOVE128 1 "register_operand" "")
14034 (match_operand:QI 2 "const_0_to_1_operand" "")]
14035 UNSPEC_UNPACK_128BIT))]
14036 "FLOAT128_2REG_P (<MODE>mode)"
14039 (define_insn_and_split "unpack<mode>_dm"
14040 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14042 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14043 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14044 UNSPEC_UNPACK_128BIT))]
14045 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14047 "&& reload_completed"
14048 [(set (match_dup 0) (match_dup 3))]
14050 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14052 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14054 emit_note (NOTE_INSN_DELETED);
14058 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14060 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14061 (set_attr "length" "4")])
14063 (define_insn_and_split "unpack<mode>_nodm"
14064 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14066 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14067 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14068 UNSPEC_UNPACK_128BIT))]
14069 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14071 "&& reload_completed"
14072 [(set (match_dup 0) (match_dup 3))]
14074 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14076 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14078 emit_note (NOTE_INSN_DELETED);
14082 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14084 [(set_attr "type" "fp,fpstore")
14085 (set_attr "length" "4")])
14087 (define_insn_and_split "pack<mode>"
14088 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14090 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14091 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14092 UNSPEC_PACK_128BIT))]
14093 "FLOAT128_2REG_P (<MODE>mode)"
14097 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14098 [(set (match_dup 3) (match_dup 1))
14099 (set (match_dup 4) (match_dup 2))]
14101 unsigned dest_hi = REGNO (operands[0]);
14102 unsigned dest_lo = dest_hi + 1;
14104 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14105 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14107 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14108 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14110 [(set_attr "type" "fpsimple,fp")
14111 (set_attr "length" "4,8")])
14113 (define_insn "unpack<mode>"
14114 [(set (match_operand:DI 0 "register_operand" "=d,d")
14115 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14116 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14117 UNSPEC_UNPACK_128BIT))]
14118 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14120 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14121 return ASM_COMMENT_START " xxpermdi to same register";
14123 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14124 return "xxpermdi %x0,%x1,%x1,%3";
14126 [(set_attr "type" "vecperm")])
14128 (define_insn "pack<mode>"
14129 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14130 (unspec:FMOVE128_VSX
14131 [(match_operand:DI 1 "register_operand" "d")
14132 (match_operand:DI 2 "register_operand" "d")]
14133 UNSPEC_PACK_128BIT))]
14135 "xxpermdi %x0,%x1,%x2,0"
14136 [(set_attr "type" "vecperm")])
14140 ;; ISA 2.08 IEEE 128-bit floating point support.
14142 (define_insn "add<mode>3"
14143 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14145 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14146 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14147 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14149 [(set_attr "type" "vecfloat")
14150 (set_attr "size" "128")])
14152 (define_insn "sub<mode>3"
14153 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14155 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14156 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14157 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14159 [(set_attr "type" "vecfloat")
14160 (set_attr "size" "128")])
14162 (define_insn "mul<mode>3"
14163 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14165 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14166 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14167 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14169 [(set_attr "type" "vecfloat")
14170 (set_attr "size" "128")])
14172 (define_insn "div<mode>3"
14173 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14175 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14176 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14177 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14179 [(set_attr "type" "vecdiv")
14180 (set_attr "size" "128")])
14182 (define_insn "sqrt<mode>2"
14183 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14185 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14186 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14188 [(set_attr "type" "vecdiv")
14189 (set_attr "size" "128")])
14191 (define_expand "copysign<mode>3"
14192 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14193 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14194 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14195 "FLOAT128_IEEE_P (<MODE>mode)"
14197 if (TARGET_FLOAT128_HW)
14198 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14202 rtx tmp = gen_reg_rtx (<MODE>mode);
14203 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14204 operands[2], tmp));
14209 (define_insn "copysign<mode>3_hard"
14210 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14212 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14213 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14215 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14216 "xscpsgnqp %0,%2,%1"
14217 [(set_attr "type" "vecmove")
14218 (set_attr "size" "128")])
14220 (define_insn "copysign<mode>3_soft"
14221 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14223 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14224 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14225 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14227 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14228 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14229 [(set_attr "type" "veccomplex")
14230 (set_attr "length" "8")])
14232 (define_insn "neg<mode>2_hw"
14233 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14235 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14236 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14238 [(set_attr "type" "vecmove")
14239 (set_attr "size" "128")])
14242 (define_insn "abs<mode>2_hw"
14243 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14245 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14246 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14248 [(set_attr "type" "vecmove")
14249 (set_attr "size" "128")])
14252 (define_insn "*nabs<mode>2_hw"
14253 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14256 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14257 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14259 [(set_attr "type" "vecmove")
14260 (set_attr "size" "128")])
14262 ;; Initially don't worry about doing fusion
14263 (define_insn "*fma<mode>4_hw"
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")
14268 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14269 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14270 "xsmaddqp %0,%1,%2"
14271 [(set_attr "type" "vecfloat")
14272 (set_attr "size" "128")])
14274 (define_insn "*fms<mode>4_hw"
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")
14280 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14281 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14282 "xsmsubqp %0,%1,%2"
14283 [(set_attr "type" "vecfloat")
14284 (set_attr "size" "128")])
14286 (define_insn "*nfma<mode>4_hw"
14287 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14290 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14291 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14292 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14293 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14294 "xsnmaddqp %0,%1,%2"
14295 [(set_attr "type" "vecfloat")
14296 (set_attr "size" "128")])
14298 (define_insn "*nfms<mode>4_hw"
14299 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14302 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14303 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14305 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14306 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14307 "xsnmsubqp %0,%1,%2"
14308 [(set_attr "type" "vecfloat")
14309 (set_attr "size" "128")])
14311 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14312 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14313 (float_extend:IEEE128
14314 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14315 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14317 [(set_attr "type" "vecfloat")
14318 (set_attr "size" "128")])
14320 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14321 ;; point is a simple copy.
14322 (define_insn_and_split "extendkftf2"
14323 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14324 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14325 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14329 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14332 emit_note (NOTE_INSN_DELETED);
14335 [(set_attr "type" "*,veclogical")
14336 (set_attr "length" "0,4")])
14338 (define_insn_and_split "trunctfkf2"
14339 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14340 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14341 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14345 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14348 emit_note (NOTE_INSN_DELETED);
14351 [(set_attr "type" "*,veclogical")
14352 (set_attr "length" "0,4")])
14354 (define_insn "trunc<mode>df2_hw"
14355 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14357 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14358 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14360 [(set_attr "type" "vecfloat")
14361 (set_attr "size" "128")])
14363 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14364 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14366 (define_insn_and_split "trunc<mode>sf2_hw"
14367 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14369 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14370 (clobber (match_scratch:DF 2 "=v"))]
14371 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14374 [(set (match_dup 2)
14375 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14377 (float_truncate:SF (match_dup 2)))]
14379 if (GET_CODE (operands[2]) == SCRATCH)
14380 operands[2] = gen_reg_rtx (DFmode);
14382 [(set_attr "type" "vecfloat")
14383 (set_attr "length" "8")])
14385 ;; Conversion between IEEE 128-bit and integer types
14386 (define_insn "fix_<mode>di2_hw"
14387 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14388 (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14389 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14391 [(set_attr "type" "vecfloat")
14392 (set_attr "size" "128")])
14394 (define_insn "fixuns_<mode>di2_hw"
14395 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14396 (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14397 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14399 [(set_attr "type" "vecfloat")
14400 (set_attr "size" "128")])
14402 (define_insn "fix_<mode>si2_hw"
14403 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14404 (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14405 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14407 [(set_attr "type" "vecfloat")
14408 (set_attr "size" "128")])
14410 (define_insn "fixuns_<mode>si2_hw"
14411 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14412 (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14413 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14415 [(set_attr "type" "vecfloat")
14416 (set_attr "size" "128")])
14418 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14419 ;; floating point value to 32-bit integer to GPR in order to save it.
14420 (define_insn_and_split "*fix<uns>_<mode>_mem"
14421 [(set (match_operand:SI 0 "memory_operand" "=Z")
14422 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14423 (clobber (match_scratch:SI 2 "=v"))]
14424 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14426 "&& reload_completed"
14427 [(set (match_dup 2)
14428 (any_fix:SI (match_dup 1)))
14432 (define_insn "float_<mode>di2_hw"
14433 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14434 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14435 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14437 [(set_attr "type" "vecfloat")
14438 (set_attr "size" "128")])
14440 (define_insn_and_split "float_<mode>si2_hw"
14441 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14442 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14443 (clobber (match_scratch:DI 2 "=v"))]
14444 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14447 [(set (match_dup 2)
14448 (sign_extend:DI (match_dup 1)))
14450 (float:IEEE128 (match_dup 2)))]
14452 if (GET_CODE (operands[2]) == SCRATCH)
14453 operands[2] = gen_reg_rtx (DImode);
14456 (define_insn "floatuns_<mode>di2_hw"
14457 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14458 (unsigned_float:IEEE128
14459 (match_operand:DI 1 "altivec_register_operand" "v")))]
14460 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14462 [(set_attr "type" "vecfloat")
14463 (set_attr "size" "128")])
14465 (define_insn_and_split "floatuns_<mode>si2_hw"
14466 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14467 (unsigned_float:IEEE128
14468 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14469 (clobber (match_scratch:DI 2 "=v"))]
14470 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14473 [(set (match_dup 2)
14474 (zero_extend:DI (match_dup 1)))
14476 (float:IEEE128 (match_dup 2)))]
14478 if (GET_CODE (operands[2]) == SCRATCH)
14479 operands[2] = gen_reg_rtx (DImode);
14482 ;; IEEE 128-bit instructions with round to odd semantics
14483 (define_insn "*trunc<mode>df2_odd"
14484 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14485 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14486 UNSPEC_ROUND_TO_ODD))]
14487 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14489 [(set_attr "type" "vecfloat")
14490 (set_attr "size" "128")])
14492 ;; IEEE 128-bit comparisons
14493 (define_insn "*cmp<mode>_hw"
14494 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14495 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14496 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14497 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14498 "xscmpuqp %0,%1,%2"
14499 [(set_attr "type" "veccmp")
14500 (set_attr "size" "128")])
14504 (include "sync.md")
14505 (include "vector.md")
14507 (include "altivec.md")
14510 (include "paired.md")
14511 (include "crypto.md")