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
150 UNSPEC_IEEE128_CONVERT
158 ;; UNSPEC_VOLATILE usage
161 (define_c_enum "unspecv"
163 UNSPECV_LL ; load-locked
164 UNSPECV_SC ; store-conditional
165 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
166 UNSPECV_EH_RR ; eh_reg_restore
167 UNSPECV_ISYNC ; isync instruction
168 UNSPECV_MFTB ; move from time base
169 UNSPECV_NLGR ; non-local goto receiver
170 UNSPECV_MFFS ; Move from FPSCR
171 UNSPECV_MTFSF ; Move to FPSCR Fields
172 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
176 ;; Define an insn type attribute. This is used in function unit delay
180 add,logical,shift,insert,
182 exts,cntlz,popcnt,isel,
183 load,store,fpload,fpstore,vecload,vecstore,
185 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
186 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
187 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
189 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
190 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
191 veclogical,veccmpfx,vecexts,vecmove,
193 (const_string "integer"))
195 ;; What data size does this instruction work on?
196 ;; This is used for insert, mul and others as necessary.
197 (define_attr "size" "8,16,32,64,128" (const_string "32"))
199 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
200 ;; This is used for add, logical, shift, exts, mul.
201 (define_attr "dot" "no,yes" (const_string "no"))
203 ;; Does this instruction sign-extend its result?
204 ;; This is used for load insns.
205 (define_attr "sign_extend" "no,yes" (const_string "no"))
207 ;; Does this instruction use indexed (that is, reg+reg) addressing?
208 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
209 ;; it is automatically set based on that. If a load or store instruction
210 ;; has fewer than two operands it needs to set this attribute manually
211 ;; or the compiler will crash.
212 (define_attr "indexed" "no,yes"
213 (if_then_else (ior (match_operand 0 "indexed_address_mem")
214 (match_operand 1 "indexed_address_mem"))
216 (const_string "no")))
218 ;; Does this instruction use update addressing?
219 ;; This is used for load and store insns. See the comments for "indexed".
220 (define_attr "update" "no,yes"
221 (if_then_else (ior (match_operand 0 "update_address_mem")
222 (match_operand 1 "update_address_mem"))
224 (const_string "no")))
226 ;; Is this instruction using operands[2] as shift amount, and can that be a
228 ;; This is used for shift insns.
229 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
231 ;; Is this instruction using a shift amount from a register?
232 ;; This is used for shift insns.
233 (define_attr "var_shift" "no,yes"
234 (if_then_else (and (eq_attr "type" "shift")
235 (eq_attr "maybe_var_shift" "yes"))
236 (if_then_else (match_operand 2 "gpc_reg_operand")
239 (const_string "no")))
241 ;; Is copying of this instruction disallowed?
242 (define_attr "cannot_copy" "no,yes" (const_string "no"))
244 ;; Define floating point instruction sub-types for use with Xfpu.md
245 (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"))
247 ;; Length (in bytes).
248 ; '(pc)' in the following doesn't include the instruction itself; it is
249 ; calculated as if the instruction had zero size.
250 (define_attr "length" ""
251 (if_then_else (eq_attr "type" "branch")
252 (if_then_else (and (ge (minus (match_dup 0) (pc))
254 (lt (minus (match_dup 0) (pc))
260 ;; Processor type -- this attribute must exactly match the processor_type
261 ;; enumeration in rs6000-opts.h.
263 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
264 ppc750,ppc7400,ppc7450,
265 ppc403,ppc405,ppc440,ppc476,
266 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
267 power4,power5,power6,power7,power8,power9,
268 rs64a,mpccore,cell,ppca2,titan"
269 (const (symbol_ref "rs6000_cpu_attr")))
272 ;; If this instruction is microcoded on the CELL processor
273 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
274 (define_attr "cell_micro" "not,conditional,always"
275 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
276 (eq_attr "dot" "yes"))
277 (and (eq_attr "type" "load")
278 (eq_attr "sign_extend" "yes"))
279 (and (eq_attr "type" "shift")
280 (eq_attr "var_shift" "yes")))
281 (const_string "always")
282 (const_string "not")))
284 (automata_option "ndfa")
297 (include "e300c2c3.md")
298 (include "e500mc.md")
299 (include "e500mc64.md")
302 (include "power4.md")
303 (include "power5.md")
304 (include "power6.md")
305 (include "power7.md")
306 (include "power8.md")
307 (include "power9.md")
313 (include "predicates.md")
314 (include "constraints.md")
316 (include "darwin.md")
321 ; This mode iterator allows :GPR to be used to indicate the allowable size
322 ; of whole values in GPRs.
323 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
325 ; Any supported integer mode.
326 (define_mode_iterator INT [QI HI SI DI TI PTI])
328 ; Any supported integer mode that fits in one register.
329 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
331 ; Integer modes supported in VSX registers with ISA 3.0 instructions
332 (define_mode_iterator INT_ISA3 [QI HI SI DI])
334 ; Everything we can extend QImode to.
335 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
337 ; Everything we can extend HImode to.
338 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
340 ; Everything we can extend SImode to.
341 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
343 ; QImode or HImode for small integer moves and small atomic ops
344 (define_mode_iterator QHI [QI HI])
346 ; QImode, HImode, SImode for fused ops only for GPR loads
347 (define_mode_iterator QHSI [QI HI SI])
349 ; HImode or SImode for sign extended fusion ops
350 (define_mode_iterator HSI [HI SI])
352 ; SImode or DImode, even if DImode doesn't fit in GPRs.
353 (define_mode_iterator SDI [SI DI])
355 ; Types that can be fused with an ADDIS instruction to load or store a GPR
356 ; register that has reg+offset addressing.
357 (define_mode_iterator GPR_FUSION [QI
360 (DI "TARGET_POWERPC64")
362 (DF "TARGET_POWERPC64")])
364 ; Types that can be fused with an ADDIS instruction to load or store a FPR
365 ; register that has reg+offset addressing.
366 (define_mode_iterator FPR_FUSION [DI SF DF])
368 ; The size of a pointer. Also, the size of the value that a record-condition
369 ; (one with a '.') will compare; and the size used for arithmetic carries.
370 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
372 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
373 ; PTImode is GPR only)
374 (define_mode_iterator TI2 [TI PTI])
376 ; Any hardware-supported floating-point mode
377 (define_mode_iterator FP [
378 (SF "TARGET_HARD_FLOAT
379 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
380 (DF "TARGET_HARD_FLOAT
381 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
382 (TF "TARGET_HARD_FLOAT
383 && (TARGET_FPRS || TARGET_E500_DOUBLE)
384 && TARGET_LONG_DOUBLE_128")
385 (IF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")
386 (KF "TARGET_FLOAT128_TYPE")
390 ; Any fma capable floating-point mode.
391 (define_mode_iterator FMA_F [
392 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
393 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
394 || VECTOR_UNIT_VSX_P (DFmode)")
395 (V2SF "TARGET_PAIRED_FLOAT")
396 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
397 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
398 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
399 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
402 ; Floating point move iterators to combine binary and decimal moves
403 (define_mode_iterator FMOVE32 [SF SD])
404 (define_mode_iterator FMOVE64 [DF DD])
405 (define_mode_iterator FMOVE64X [DI DF DD])
406 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
407 (IF "FLOAT128_IBM_P (IFmode)")
408 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
410 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
411 (IF "FLOAT128_2REG_P (IFmode)")
412 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
414 ; Iterators for 128 bit types for direct move
415 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
423 (KF "FLOAT128_VECTOR_P (KFmode)")
424 (TF "FLOAT128_VECTOR_P (TFmode)")])
426 ; Iterator for 128-bit VSX types for pack/unpack
427 (define_mode_iterator FMOVE128_VSX [V1TI KF])
429 ; Whether a floating point move is ok, don't allow SD without hardware FP
430 (define_mode_attr fmove_ok [(SF "")
432 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
435 ; Convert REAL_VALUE to the appropriate bits
436 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
437 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
438 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
439 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
441 ; Whether 0.0 has an all-zero bit pattern
442 (define_mode_attr zero_fp [(SF "j")
451 ; Definitions for load to 32-bit fpr register
452 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
453 (define_mode_attr f32_lr2 [(SF "wb") (SD "wn")])
454 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
455 (define_mode_attr f32_lm2 [(SF "wY") (SD "wn")])
456 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
457 (define_mode_attr f32_li2 [(SF "lxssp %0,%1") (SD "lfiwzx %0,%y1")])
458 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
460 ; Definitions for store from 32-bit fpr register
461 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
462 (define_mode_attr f32_sr2 [(SF "wb") (SD "wn")])
463 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
464 (define_mode_attr f32_sm2 [(SF "wY") (SD "wn")])
465 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
466 (define_mode_attr f32_si2 [(SF "stxssp %1,%0") (SD "stfiwx %1,%y0")])
467 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwx %x1,%y0")])
469 ; Definitions for 32-bit fpr direct move
470 ; At present, the decimal modes are not allowed in the traditional altivec
471 ; registers, so restrict the constraints to just the traditional FPRs.
472 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
474 ; Definitions for 32-bit VSX
475 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
477 ; Definitions for 32-bit use of altivec registers
478 (define_mode_attr f32_av [(SF "wu") (SD "wn")])
480 ; Definitions for 64-bit VSX
481 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
483 ; Definitions for 64-bit direct move
484 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
486 ; Definitions for 64-bit use of altivec registers
487 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
489 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
490 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
492 ; These modes do not fit in integer registers in 32-bit mode.
493 ; but on e500v2, the gpr are 64 bit registers
494 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
496 ; Iterator for reciprocal estimate instructions
497 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
499 ; Iterator for just SF/DF
500 (define_mode_iterator SFDF [SF DF])
502 ; Like SFDF, but a different name to match conditional move where the
503 ; comparison operands may be a different mode than the input operands.
504 (define_mode_iterator SFDF2 [SF DF])
506 ; Iterator for 128-bit floating point that uses the IBM double-double format
507 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
508 (TF "FLOAT128_IBM_P (TFmode)")])
510 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
511 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
512 (TF "FLOAT128_IEEE_P (TFmode)")])
514 ; Iterator for 128-bit floating point
515 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
516 (IF "TARGET_FLOAT128_TYPE")
517 (TF "TARGET_LONG_DOUBLE_128")])
519 ; Iterator for signbit on 64-bit machines with direct move
520 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
521 (TF "FLOAT128_VECTOR_P (TFmode)")])
523 ; Iterator for ISA 3.0 supported floating point types
524 (define_mode_iterator FP_ISA3 [SF DF])
526 ; SF/DF suffix for traditional floating instructions
527 (define_mode_attr Ftrad [(SF "s") (DF "")])
529 ; SF/DF suffix for VSX instructions
530 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
532 ; SF/DF constraint for arithmetic on traditional floating point registers
533 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
535 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
536 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
537 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
539 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
541 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
542 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
543 ; instructions added in ISA 2.07 (power8)
544 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
546 ; SF/DF constraint for arithmetic on altivec registers
547 (define_mode_attr Fa [(SF "wu") (DF "wv")])
549 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
550 (define_mode_attr Fs [(SF "s") (DF "d")])
553 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
554 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
556 ; Conditional returns.
557 (define_code_iterator any_return [return simple_return])
558 (define_code_attr return_pred [(return "direct_return ()")
559 (simple_return "1")])
560 (define_code_attr return_str [(return "") (simple_return "simple_")])
563 (define_code_iterator iorxor [ior xor])
564 (define_code_iterator and_ior_xor [and ior xor])
566 ; Signed/unsigned variants of ops.
567 (define_code_iterator any_extend [sign_extend zero_extend])
568 (define_code_iterator any_fix [fix unsigned_fix])
569 (define_code_iterator any_float [float unsigned_float])
571 (define_code_attr u [(sign_extend "")
574 (define_code_attr su [(sign_extend "s")
579 (unsigned_float "u")])
581 (define_code_attr az [(sign_extend "a")
586 (unsigned_float "z")])
588 (define_code_attr uns [(fix "")
591 (unsigned_float "uns")])
593 ; Various instructions that come in SI and DI forms.
594 ; A generic w/d attribute, for things like cmpw/cmpd.
595 (define_mode_attr wd [(QI "b")
606 ;; How many bits in this mode?
607 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
610 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
612 ;; ISEL/ISEL64 target selection
613 (define_mode_attr sel [(SI "") (DI "64")])
615 ;; Bitmask for shift instructions
616 (define_mode_attr hH [(SI "h") (DI "H")])
618 ;; A mode twice the size of the given mode
619 (define_mode_attr dmode [(SI "di") (DI "ti")])
620 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
622 ;; Suffix for reload patterns
623 (define_mode_attr ptrsize [(SI "32bit")
626 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
627 (DI "TARGET_64BIT")])
629 (define_mode_attr mptrsize [(SI "si")
632 (define_mode_attr ptrload [(SI "lwz")
635 (define_mode_attr ptrm [(SI "m")
638 (define_mode_attr rreg [(SF "f")
645 (define_mode_attr rreg2 [(SF "f")
648 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
649 (DF "TARGET_FCFID")])
651 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
652 (DF "TARGET_E500_DOUBLE")])
654 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
655 (DF "TARGET_DOUBLE_FLOAT")])
657 ;; Mode iterator for logical operations on 128-bit types
658 (define_mode_iterator BOOL_128 [TI
660 (V16QI "TARGET_ALTIVEC")
661 (V8HI "TARGET_ALTIVEC")
662 (V4SI "TARGET_ALTIVEC")
663 (V4SF "TARGET_ALTIVEC")
664 (V2DI "TARGET_ALTIVEC")
665 (V2DF "TARGET_ALTIVEC")
666 (V1TI "TARGET_ALTIVEC")])
668 ;; For the GPRs we use 3 constraints for register outputs, two that are the
669 ;; same as the output register, and a third where the output register is an
670 ;; early clobber, so we don't have to deal with register overlaps. For the
671 ;; vector types, we prefer to use the vector registers. For TI mode, allow
674 ;; Mode attribute for boolean operation register constraints for output
675 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
677 (V16QI "wa,v,&?r,?r,?r")
678 (V8HI "wa,v,&?r,?r,?r")
679 (V4SI "wa,v,&?r,?r,?r")
680 (V4SF "wa,v,&?r,?r,?r")
681 (V2DI "wa,v,&?r,?r,?r")
682 (V2DF "wa,v,&?r,?r,?r")
683 (V1TI "wa,v,&?r,?r,?r")])
685 ;; Mode attribute for boolean operation register constraints for operand1
686 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
694 (V1TI "wa,v,r,0,r")])
696 ;; Mode attribute for boolean operation register constraints for operand2
697 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
705 (V1TI "wa,v,r,r,0")])
707 ;; Mode attribute for boolean operation register constraints for operand1
708 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
709 ;; is used for operand1 or operand2
710 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
718 (V1TI "wa,v,r,0,0")])
720 ;; Reload iterator for creating the function to allocate a base register to
721 ;; supplement addressing modes.
722 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
723 SF SD SI DF DD DI TI PTI KF IF TF])
725 ;; Iterate over smin, smax
726 (define_code_iterator fp_minmax [smin smax])
728 (define_code_attr minmax [(smin "min")
731 (define_code_attr SMINMAX [(smin "SMIN")
735 ;; Start with fixed-point load and store insns. Here we put only the more
736 ;; complex forms. Basic data transfer is done later.
738 (define_insn "zero_extendqi<mode>2"
739 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
740 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
747 [(set_attr "type" "load,shift,fpload,vecperm")])
749 (define_insn_and_split "*zero_extendqi<mode>2_dot"
750 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
751 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
753 (clobber (match_scratch:EXTQI 0 "=r,r"))]
754 "rs6000_gen_cell_microcode"
758 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
760 (zero_extend:EXTQI (match_dup 1)))
762 (compare:CC (match_dup 0)
765 [(set_attr "type" "logical")
766 (set_attr "dot" "yes")
767 (set_attr "length" "4,8")])
769 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
770 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
771 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
773 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
774 (zero_extend:EXTQI (match_dup 1)))]
775 "rs6000_gen_cell_microcode"
779 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
781 (zero_extend:EXTQI (match_dup 1)))
783 (compare:CC (match_dup 0)
786 [(set_attr "type" "logical")
787 (set_attr "dot" "yes")
788 (set_attr "length" "4,8")])
791 (define_insn "zero_extendhi<mode>2"
792 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
793 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
797 rlwinm %0,%1,0,0xffff
800 [(set_attr "type" "load,shift,fpload,vecperm")])
802 (define_insn_and_split "*zero_extendhi<mode>2_dot"
803 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
804 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
806 (clobber (match_scratch:EXTHI 0 "=r,r"))]
807 "rs6000_gen_cell_microcode"
811 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
813 (zero_extend:EXTHI (match_dup 1)))
815 (compare:CC (match_dup 0)
818 [(set_attr "type" "logical")
819 (set_attr "dot" "yes")
820 (set_attr "length" "4,8")])
822 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
823 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
824 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
826 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
827 (zero_extend:EXTHI (match_dup 1)))]
828 "rs6000_gen_cell_microcode"
832 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
834 (zero_extend:EXTHI (match_dup 1)))
836 (compare:CC (match_dup 0)
839 [(set_attr "type" "logical")
840 (set_attr "dot" "yes")
841 (set_attr "length" "4,8")])
844 (define_insn "zero_extendsi<mode>2"
845 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
846 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
855 xxextractuw %x0,%x1,4"
856 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
858 (define_insn_and_split "*zero_extendsi<mode>2_dot"
859 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
860 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
862 (clobber (match_scratch:EXTSI 0 "=r,r"))]
863 "rs6000_gen_cell_microcode"
867 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
869 (zero_extend:DI (match_dup 1)))
871 (compare:CC (match_dup 0)
874 [(set_attr "type" "shift")
875 (set_attr "dot" "yes")
876 (set_attr "length" "4,8")])
878 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
879 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
880 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
882 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
883 (zero_extend:EXTSI (match_dup 1)))]
884 "rs6000_gen_cell_microcode"
888 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
890 (zero_extend:EXTSI (match_dup 1)))
892 (compare:CC (match_dup 0)
895 [(set_attr "type" "shift")
896 (set_attr "dot" "yes")
897 (set_attr "length" "4,8")])
900 (define_insn "extendqi<mode>2"
901 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
902 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
907 [(set_attr "type" "exts,vecperm")])
909 (define_insn_and_split "*extendqi<mode>2_dot"
910 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
911 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
913 (clobber (match_scratch:EXTQI 0 "=r,r"))]
914 "rs6000_gen_cell_microcode"
918 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
920 (sign_extend:EXTQI (match_dup 1)))
922 (compare:CC (match_dup 0)
925 [(set_attr "type" "exts")
926 (set_attr "dot" "yes")
927 (set_attr "length" "4,8")])
929 (define_insn_and_split "*extendqi<mode>2_dot2"
930 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
931 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
933 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
934 (sign_extend:EXTQI (match_dup 1)))]
935 "rs6000_gen_cell_microcode"
939 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
941 (sign_extend:EXTQI (match_dup 1)))
943 (compare:CC (match_dup 0)
946 [(set_attr "type" "exts")
947 (set_attr "dot" "yes")
948 (set_attr "length" "4,8")])
951 (define_expand "extendhi<mode>2"
952 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
953 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
957 (define_insn "*extendhi<mode>2"
958 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
959 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
960 "rs6000_gen_cell_microcode"
966 [(set_attr "type" "load,exts,fpload,vecperm")
967 (set_attr "sign_extend" "yes")
968 (set_attr "length" "4,4,8,4")])
971 [(set (match_operand:EXTHI 0 "altivec_register_operand")
973 (match_operand:HI 1 "indexed_or_indirect_operand")))]
974 "TARGET_P9_VECTOR && reload_completed"
978 (sign_extend:EXTHI (match_dup 2)))]
980 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
983 (define_insn "*extendhi<mode>2_noload"
984 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
985 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
986 "!rs6000_gen_cell_microcode"
988 [(set_attr "type" "exts")])
990 (define_insn_and_split "*extendhi<mode>2_dot"
991 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
992 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
994 (clobber (match_scratch:EXTHI 0 "=r,r"))]
995 "rs6000_gen_cell_microcode"
999 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1001 (sign_extend:EXTHI (match_dup 1)))
1003 (compare:CC (match_dup 0)
1006 [(set_attr "type" "exts")
1007 (set_attr "dot" "yes")
1008 (set_attr "length" "4,8")])
1010 (define_insn_and_split "*extendhi<mode>2_dot2"
1011 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1012 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1014 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1015 (sign_extend:EXTHI (match_dup 1)))]
1016 "rs6000_gen_cell_microcode"
1020 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1022 (sign_extend:EXTHI (match_dup 1)))
1024 (compare:CC (match_dup 0)
1027 [(set_attr "type" "exts")
1028 (set_attr "dot" "yes")
1029 (set_attr "length" "4,8")])
1032 (define_insn "extendsi<mode>2"
1033 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK")
1034 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK")))]
1043 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts")
1044 (set_attr "sign_extend" "yes")])
1046 (define_insn_and_split "*extendsi<mode>2_dot"
1047 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1048 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1050 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1051 "rs6000_gen_cell_microcode"
1055 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1057 (sign_extend:EXTSI (match_dup 1)))
1059 (compare:CC (match_dup 0)
1062 [(set_attr "type" "exts")
1063 (set_attr "dot" "yes")
1064 (set_attr "length" "4,8")])
1066 (define_insn_and_split "*extendsi<mode>2_dot2"
1067 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1068 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1070 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1071 (sign_extend:EXTSI (match_dup 1)))]
1072 "rs6000_gen_cell_microcode"
1076 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1078 (sign_extend:EXTSI (match_dup 1)))
1080 (compare:CC (match_dup 0)
1083 [(set_attr "type" "exts")
1084 (set_attr "dot" "yes")
1085 (set_attr "length" "4,8")])
1087 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1089 (define_insn "*macchwc"
1090 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1091 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1092 (match_operand:SI 2 "gpc_reg_operand" "r")
1095 (match_operand:HI 1 "gpc_reg_operand" "r")))
1096 (match_operand:SI 4 "gpc_reg_operand" "0"))
1098 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1099 (plus:SI (mult:SI (ashiftrt:SI
1107 [(set_attr "type" "halfmul")])
1109 (define_insn "*macchw"
1110 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1111 (plus:SI (mult:SI (ashiftrt:SI
1112 (match_operand:SI 2 "gpc_reg_operand" "r")
1115 (match_operand:HI 1 "gpc_reg_operand" "r")))
1116 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1119 [(set_attr "type" "halfmul")])
1121 (define_insn "*macchwuc"
1122 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1123 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1124 (match_operand:SI 2 "gpc_reg_operand" "r")
1127 (match_operand:HI 1 "gpc_reg_operand" "r")))
1128 (match_operand:SI 4 "gpc_reg_operand" "0"))
1130 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1131 (plus:SI (mult:SI (lshiftrt:SI
1139 [(set_attr "type" "halfmul")])
1141 (define_insn "*macchwu"
1142 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1143 (plus:SI (mult:SI (lshiftrt:SI
1144 (match_operand:SI 2 "gpc_reg_operand" "r")
1147 (match_operand:HI 1 "gpc_reg_operand" "r")))
1148 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1151 [(set_attr "type" "halfmul")])
1153 (define_insn "*machhwc"
1154 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1155 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1156 (match_operand:SI 1 "gpc_reg_operand" "%r")
1159 (match_operand:SI 2 "gpc_reg_operand" "r")
1161 (match_operand:SI 4 "gpc_reg_operand" "0"))
1163 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1164 (plus:SI (mult:SI (ashiftrt:SI
1173 [(set_attr "type" "halfmul")])
1175 (define_insn "*machhw"
1176 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1177 (plus:SI (mult:SI (ashiftrt:SI
1178 (match_operand:SI 1 "gpc_reg_operand" "%r")
1181 (match_operand:SI 2 "gpc_reg_operand" "r")
1183 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1186 [(set_attr "type" "halfmul")])
1188 (define_insn "*machhwuc"
1189 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1190 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1191 (match_operand:SI 1 "gpc_reg_operand" "%r")
1194 (match_operand:SI 2 "gpc_reg_operand" "r")
1196 (match_operand:SI 4 "gpc_reg_operand" "0"))
1198 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1199 (plus:SI (mult:SI (lshiftrt:SI
1208 [(set_attr "type" "halfmul")])
1210 (define_insn "*machhwu"
1211 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1212 (plus:SI (mult:SI (lshiftrt:SI
1213 (match_operand:SI 1 "gpc_reg_operand" "%r")
1216 (match_operand:SI 2 "gpc_reg_operand" "r")
1218 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1221 [(set_attr "type" "halfmul")])
1223 (define_insn "*maclhwc"
1224 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1225 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1226 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1228 (match_operand:HI 2 "gpc_reg_operand" "r")))
1229 (match_operand:SI 4 "gpc_reg_operand" "0"))
1231 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1232 (plus:SI (mult:SI (sign_extend:SI
1239 [(set_attr "type" "halfmul")])
1241 (define_insn "*maclhw"
1242 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1243 (plus:SI (mult:SI (sign_extend:SI
1244 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1246 (match_operand:HI 2 "gpc_reg_operand" "r")))
1247 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1250 [(set_attr "type" "halfmul")])
1252 (define_insn "*maclhwuc"
1253 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1254 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1255 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1257 (match_operand:HI 2 "gpc_reg_operand" "r")))
1258 (match_operand:SI 4 "gpc_reg_operand" "0"))
1260 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1261 (plus:SI (mult:SI (zero_extend:SI
1268 [(set_attr "type" "halfmul")])
1270 (define_insn "*maclhwu"
1271 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1272 (plus:SI (mult:SI (zero_extend:SI
1273 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1275 (match_operand:HI 2 "gpc_reg_operand" "r")))
1276 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1279 [(set_attr "type" "halfmul")])
1281 (define_insn "*nmacchwc"
1282 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1283 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1284 (mult:SI (ashiftrt:SI
1285 (match_operand:SI 2 "gpc_reg_operand" "r")
1288 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1290 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1291 (minus:SI (match_dup 4)
1292 (mult:SI (ashiftrt:SI
1299 [(set_attr "type" "halfmul")])
1301 (define_insn "*nmacchw"
1302 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1303 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1304 (mult:SI (ashiftrt:SI
1305 (match_operand:SI 2 "gpc_reg_operand" "r")
1308 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1311 [(set_attr "type" "halfmul")])
1313 (define_insn "*nmachhwc"
1314 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1315 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1316 (mult:SI (ashiftrt:SI
1317 (match_operand:SI 1 "gpc_reg_operand" "%r")
1320 (match_operand:SI 2 "gpc_reg_operand" "r")
1323 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1324 (minus:SI (match_dup 4)
1325 (mult:SI (ashiftrt:SI
1333 [(set_attr "type" "halfmul")])
1335 (define_insn "*nmachhw"
1336 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1337 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1338 (mult:SI (ashiftrt:SI
1339 (match_operand:SI 1 "gpc_reg_operand" "%r")
1342 (match_operand:SI 2 "gpc_reg_operand" "r")
1346 [(set_attr "type" "halfmul")])
1348 (define_insn "*nmaclhwc"
1349 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1350 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1351 (mult:SI (sign_extend:SI
1352 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1354 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1356 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1357 (minus:SI (match_dup 4)
1358 (mult:SI (sign_extend:SI
1364 [(set_attr "type" "halfmul")])
1366 (define_insn "*nmaclhw"
1367 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1368 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1369 (mult:SI (sign_extend:SI
1370 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1372 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1375 [(set_attr "type" "halfmul")])
1377 (define_insn "*mulchwc"
1378 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1379 (compare:CC (mult:SI (ashiftrt:SI
1380 (match_operand:SI 2 "gpc_reg_operand" "r")
1383 (match_operand:HI 1 "gpc_reg_operand" "r")))
1385 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1386 (mult:SI (ashiftrt:SI
1393 [(set_attr "type" "halfmul")])
1395 (define_insn "*mulchw"
1396 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1397 (mult:SI (ashiftrt:SI
1398 (match_operand:SI 2 "gpc_reg_operand" "r")
1401 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1404 [(set_attr "type" "halfmul")])
1406 (define_insn "*mulchwuc"
1407 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1408 (compare:CC (mult:SI (lshiftrt:SI
1409 (match_operand:SI 2 "gpc_reg_operand" "r")
1412 (match_operand:HI 1 "gpc_reg_operand" "r")))
1414 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1415 (mult:SI (lshiftrt:SI
1422 [(set_attr "type" "halfmul")])
1424 (define_insn "*mulchwu"
1425 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1426 (mult:SI (lshiftrt:SI
1427 (match_operand:SI 2 "gpc_reg_operand" "r")
1430 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1433 [(set_attr "type" "halfmul")])
1435 (define_insn "*mulhhwc"
1436 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1437 (compare:CC (mult:SI (ashiftrt:SI
1438 (match_operand:SI 1 "gpc_reg_operand" "%r")
1441 (match_operand:SI 2 "gpc_reg_operand" "r")
1444 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1445 (mult:SI (ashiftrt:SI
1453 [(set_attr "type" "halfmul")])
1455 (define_insn "*mulhhw"
1456 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1457 (mult:SI (ashiftrt:SI
1458 (match_operand:SI 1 "gpc_reg_operand" "%r")
1461 (match_operand:SI 2 "gpc_reg_operand" "r")
1465 [(set_attr "type" "halfmul")])
1467 (define_insn "*mulhhwuc"
1468 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1469 (compare:CC (mult:SI (lshiftrt:SI
1470 (match_operand:SI 1 "gpc_reg_operand" "%r")
1473 (match_operand:SI 2 "gpc_reg_operand" "r")
1476 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1477 (mult:SI (lshiftrt:SI
1485 [(set_attr "type" "halfmul")])
1487 (define_insn "*mulhhwu"
1488 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1489 (mult:SI (lshiftrt:SI
1490 (match_operand:SI 1 "gpc_reg_operand" "%r")
1493 (match_operand:SI 2 "gpc_reg_operand" "r")
1497 [(set_attr "type" "halfmul")])
1499 (define_insn "*mullhwc"
1500 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1501 (compare:CC (mult:SI (sign_extend:SI
1502 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1504 (match_operand:HI 2 "gpc_reg_operand" "r")))
1506 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1507 (mult:SI (sign_extend:SI
1513 [(set_attr "type" "halfmul")])
1515 (define_insn "*mullhw"
1516 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1517 (mult:SI (sign_extend:SI
1518 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1520 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1523 [(set_attr "type" "halfmul")])
1525 (define_insn "*mullhwuc"
1526 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1527 (compare:CC (mult:SI (zero_extend:SI
1528 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1530 (match_operand:HI 2 "gpc_reg_operand" "r")))
1532 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1533 (mult:SI (zero_extend:SI
1539 [(set_attr "type" "halfmul")])
1541 (define_insn "*mullhwu"
1542 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1543 (mult:SI (zero_extend:SI
1544 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1546 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1549 [(set_attr "type" "halfmul")])
1551 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1552 (define_insn "dlmzb"
1553 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1554 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1555 (match_operand:SI 2 "gpc_reg_operand" "r")]
1557 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1558 (unspec:SI [(match_dup 1)
1564 (define_expand "strlensi"
1565 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1566 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1567 (match_operand:QI 2 "const_int_operand" "")
1568 (match_operand 3 "const_int_operand" "")]
1569 UNSPEC_DLMZB_STRLEN))
1570 (clobber (match_scratch:CC 4 "=x"))]
1571 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1573 rtx result = operands[0];
1574 rtx src = operands[1];
1575 rtx search_char = operands[2];
1576 rtx align = operands[3];
1577 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1578 rtx loop_label, end_label, mem, cr0, cond;
1579 if (search_char != const0_rtx
1580 || GET_CODE (align) != CONST_INT
1581 || INTVAL (align) < 8)
1583 word1 = gen_reg_rtx (SImode);
1584 word2 = gen_reg_rtx (SImode);
1585 scratch_dlmzb = gen_reg_rtx (SImode);
1586 scratch_string = gen_reg_rtx (Pmode);
1587 loop_label = gen_label_rtx ();
1588 end_label = gen_label_rtx ();
1589 addr = force_reg (Pmode, XEXP (src, 0));
1590 emit_move_insn (scratch_string, addr);
1591 emit_label (loop_label);
1592 mem = change_address (src, SImode, scratch_string);
1593 emit_move_insn (word1, mem);
1594 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1595 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1596 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1597 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1598 emit_jump_insn (gen_rtx_SET (pc_rtx,
1599 gen_rtx_IF_THEN_ELSE (VOIDmode,
1605 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1606 emit_jump_insn (gen_rtx_SET (pc_rtx,
1607 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1609 emit_label (end_label);
1610 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1611 emit_insn (gen_subsi3 (result, scratch_string, addr));
1612 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1616 ;; Fixed-point arithmetic insns.
1618 (define_expand "add<mode>3"
1619 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1620 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1621 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1624 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1626 rtx lo0 = gen_lowpart (SImode, operands[0]);
1627 rtx lo1 = gen_lowpart (SImode, operands[1]);
1628 rtx lo2 = gen_lowpart (SImode, operands[2]);
1629 rtx hi0 = gen_highpart (SImode, operands[0]);
1630 rtx hi1 = gen_highpart (SImode, operands[1]);
1631 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1633 if (!reg_or_short_operand (lo2, SImode))
1634 lo2 = force_reg (SImode, lo2);
1635 if (!adde_operand (hi2, SImode))
1636 hi2 = force_reg (SImode, hi2);
1638 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1639 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1643 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1645 rtx tmp = ((!can_create_pseudo_p ()
1646 || rtx_equal_p (operands[0], operands[1]))
1647 ? operands[0] : gen_reg_rtx (<MODE>mode));
1649 HOST_WIDE_INT val = INTVAL (operands[2]);
1650 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1651 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1653 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1656 /* The ordering here is important for the prolog expander.
1657 When space is allocated from the stack, adding 'low' first may
1658 produce a temporary deallocation (which would be bad). */
1659 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1660 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1665 (define_insn "*add<mode>3"
1666 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1667 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1668 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1674 [(set_attr "type" "add")])
1676 (define_insn "addsi3_high"
1677 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1678 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1679 (high:SI (match_operand 2 "" ""))))]
1680 "TARGET_MACHO && !TARGET_64BIT"
1681 "addis %0,%1,ha16(%2)"
1682 [(set_attr "type" "add")])
1684 (define_insn_and_split "*add<mode>3_dot"
1685 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1686 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1687 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1689 (clobber (match_scratch:GPR 0 "=r,r"))]
1690 "<MODE>mode == Pmode"
1694 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1696 (plus:GPR (match_dup 1)
1699 (compare:CC (match_dup 0)
1702 [(set_attr "type" "add")
1703 (set_attr "dot" "yes")
1704 (set_attr "length" "4,8")])
1706 (define_insn_and_split "*add<mode>3_dot2"
1707 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1708 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1709 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1711 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1712 (plus:GPR (match_dup 1)
1714 "<MODE>mode == Pmode"
1718 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1720 (plus:GPR (match_dup 1)
1723 (compare:CC (match_dup 0)
1726 [(set_attr "type" "add")
1727 (set_attr "dot" "yes")
1728 (set_attr "length" "4,8")])
1730 (define_insn_and_split "*add<mode>3_imm_dot"
1731 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1732 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1733 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1735 (clobber (match_scratch:GPR 0 "=r,r"))
1736 (clobber (reg:GPR CA_REGNO))]
1737 "<MODE>mode == Pmode"
1741 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1743 (plus:GPR (match_dup 1)
1746 (compare:CC (match_dup 0)
1749 [(set_attr "type" "add")
1750 (set_attr "dot" "yes")
1751 (set_attr "length" "4,8")])
1753 (define_insn_and_split "*add<mode>3_imm_dot2"
1754 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1755 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1756 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1758 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1759 (plus:GPR (match_dup 1)
1761 (clobber (reg:GPR CA_REGNO))]
1762 "<MODE>mode == Pmode"
1766 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1768 (plus:GPR (match_dup 1)
1771 (compare:CC (match_dup 0)
1774 [(set_attr "type" "add")
1775 (set_attr "dot" "yes")
1776 (set_attr "length" "4,8")])
1778 ;; Split an add that we can't do in one insn into two insns, each of which
1779 ;; does one 16-bit part. This is used by combine. Note that the low-order
1780 ;; add should be last in case the result gets used in an address.
1783 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1784 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1785 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1787 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1788 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1790 HOST_WIDE_INT val = INTVAL (operands[2]);
1791 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1792 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1794 operands[4] = GEN_INT (low);
1795 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1796 operands[3] = GEN_INT (rest);
1797 else if (can_create_pseudo_p ())
1799 operands[3] = gen_reg_rtx (DImode);
1800 emit_move_insn (operands[3], operands[2]);
1801 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1809 (define_insn "add<mode>3_carry"
1810 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1811 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1812 (match_operand:P 2 "reg_or_short_operand" "rI")))
1813 (set (reg:P CA_REGNO)
1814 (ltu:P (plus:P (match_dup 1)
1819 [(set_attr "type" "add")])
1821 (define_insn "*add<mode>3_imm_carry_pos"
1822 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1823 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1824 (match_operand:P 2 "short_cint_operand" "n")))
1825 (set (reg:P CA_REGNO)
1826 (geu:P (match_dup 1)
1827 (match_operand:P 3 "const_int_operand" "n")))]
1828 "INTVAL (operands[2]) > 0
1829 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1831 [(set_attr "type" "add")])
1833 (define_insn "*add<mode>3_imm_carry_0"
1834 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1835 (match_operand:P 1 "gpc_reg_operand" "r"))
1836 (set (reg:P CA_REGNO)
1840 [(set_attr "type" "add")])
1842 (define_insn "*add<mode>3_imm_carry_m1"
1843 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1844 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1846 (set (reg:P CA_REGNO)
1851 [(set_attr "type" "add")])
1853 (define_insn "*add<mode>3_imm_carry_neg"
1854 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1855 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1856 (match_operand:P 2 "short_cint_operand" "n")))
1857 (set (reg:P CA_REGNO)
1858 (gtu:P (match_dup 1)
1859 (match_operand:P 3 "const_int_operand" "n")))]
1860 "INTVAL (operands[2]) < 0
1861 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1863 [(set_attr "type" "add")])
1866 (define_expand "add<mode>3_carry_in"
1868 (set (match_operand:GPR 0 "gpc_reg_operand")
1869 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1870 (match_operand:GPR 2 "adde_operand"))
1871 (reg:GPR CA_REGNO)))
1872 (clobber (reg:GPR CA_REGNO))])]
1875 if (operands[2] == const0_rtx)
1877 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1880 if (operands[2] == constm1_rtx)
1882 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1887 (define_insn "*add<mode>3_carry_in_internal"
1888 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1889 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1890 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1891 (reg:GPR CA_REGNO)))
1892 (clobber (reg:GPR CA_REGNO))]
1895 [(set_attr "type" "add")])
1897 (define_insn "add<mode>3_carry_in_0"
1898 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1899 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1900 (reg:GPR CA_REGNO)))
1901 (clobber (reg:GPR CA_REGNO))]
1904 [(set_attr "type" "add")])
1906 (define_insn "add<mode>3_carry_in_m1"
1907 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1908 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1911 (clobber (reg:GPR CA_REGNO))]
1914 [(set_attr "type" "add")])
1917 (define_expand "one_cmpl<mode>2"
1918 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1919 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1922 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1924 rs6000_split_logical (operands, NOT, false, false, false);
1929 (define_insn "*one_cmpl<mode>2"
1930 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1931 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1935 (define_insn_and_split "*one_cmpl<mode>2_dot"
1936 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1937 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1939 (clobber (match_scratch:GPR 0 "=r,r"))]
1940 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1944 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1946 (not:GPR (match_dup 1)))
1948 (compare:CC (match_dup 0)
1951 [(set_attr "type" "logical")
1952 (set_attr "dot" "yes")
1953 (set_attr "length" "4,8")])
1955 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1956 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1957 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1959 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1960 (not:GPR (match_dup 1)))]
1961 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1965 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1967 (not:GPR (match_dup 1)))
1969 (compare:CC (match_dup 0)
1972 [(set_attr "type" "logical")
1973 (set_attr "dot" "yes")
1974 (set_attr "length" "4,8")])
1977 (define_expand "sub<mode>3"
1978 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1979 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1980 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1983 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1985 rtx lo0 = gen_lowpart (SImode, operands[0]);
1986 rtx lo1 = gen_lowpart (SImode, operands[1]);
1987 rtx lo2 = gen_lowpart (SImode, operands[2]);
1988 rtx hi0 = gen_highpart (SImode, operands[0]);
1989 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1990 rtx hi2 = gen_highpart (SImode, operands[2]);
1992 if (!reg_or_short_operand (lo1, SImode))
1993 lo1 = force_reg (SImode, lo1);
1994 if (!adde_operand (hi1, SImode))
1995 hi1 = force_reg (SImode, hi1);
1997 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1998 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2002 if (short_cint_operand (operands[1], <MODE>mode))
2004 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2009 (define_insn "*subf<mode>3"
2010 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2011 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2012 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2015 [(set_attr "type" "add")])
2017 (define_insn_and_split "*subf<mode>3_dot"
2018 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2019 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2020 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2022 (clobber (match_scratch:GPR 0 "=r,r"))]
2023 "<MODE>mode == Pmode"
2027 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2029 (minus:GPR (match_dup 2)
2032 (compare:CC (match_dup 0)
2035 [(set_attr "type" "add")
2036 (set_attr "dot" "yes")
2037 (set_attr "length" "4,8")])
2039 (define_insn_and_split "*subf<mode>3_dot2"
2040 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2041 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2042 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2044 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2045 (minus:GPR (match_dup 2)
2047 "<MODE>mode == Pmode"
2051 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2053 (minus:GPR (match_dup 2)
2056 (compare:CC (match_dup 0)
2059 [(set_attr "type" "add")
2060 (set_attr "dot" "yes")
2061 (set_attr "length" "4,8")])
2063 (define_insn "subf<mode>3_imm"
2064 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2065 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2066 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2067 (clobber (reg:GPR CA_REGNO))]
2070 [(set_attr "type" "add")])
2073 (define_insn "subf<mode>3_carry"
2074 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2075 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2076 (match_operand:P 1 "gpc_reg_operand" "r")))
2077 (set (reg:P CA_REGNO)
2078 (leu:P (match_dup 1)
2082 [(set_attr "type" "add")])
2084 (define_insn "*subf<mode>3_imm_carry_0"
2085 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2086 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2087 (set (reg:P CA_REGNO)
2092 [(set_attr "type" "add")])
2094 (define_insn "*subf<mode>3_imm_carry_m1"
2095 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2096 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2097 (set (reg:P CA_REGNO)
2101 [(set_attr "type" "add")])
2104 (define_expand "subf<mode>3_carry_in"
2106 (set (match_operand:GPR 0 "gpc_reg_operand")
2107 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2109 (match_operand:GPR 2 "adde_operand")))
2110 (clobber (reg:GPR CA_REGNO))])]
2113 if (operands[2] == const0_rtx)
2115 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2118 if (operands[2] == constm1_rtx)
2120 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2125 (define_insn "*subf<mode>3_carry_in_internal"
2126 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2127 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2129 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2130 (clobber (reg:GPR CA_REGNO))]
2133 [(set_attr "type" "add")])
2135 (define_insn "subf<mode>3_carry_in_0"
2136 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2137 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2138 (reg:GPR CA_REGNO)))
2139 (clobber (reg:GPR CA_REGNO))]
2142 [(set_attr "type" "add")])
2144 (define_insn "subf<mode>3_carry_in_m1"
2145 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2146 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2147 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2149 (clobber (reg:GPR CA_REGNO))]
2152 [(set_attr "type" "add")])
2154 (define_insn "subf<mode>3_carry_in_xx"
2155 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2156 (plus:GPR (reg:GPR CA_REGNO)
2158 (clobber (reg:GPR CA_REGNO))]
2161 [(set_attr "type" "add")])
2164 (define_insn "neg<mode>2"
2165 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2166 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2169 [(set_attr "type" "add")])
2171 (define_insn_and_split "*neg<mode>2_dot"
2172 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2173 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2175 (clobber (match_scratch:GPR 0 "=r,r"))]
2176 "<MODE>mode == Pmode"
2180 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2182 (neg:GPR (match_dup 1)))
2184 (compare:CC (match_dup 0)
2187 [(set_attr "type" "add")
2188 (set_attr "dot" "yes")
2189 (set_attr "length" "4,8")])
2191 (define_insn_and_split "*neg<mode>2_dot2"
2192 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2193 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2195 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2196 (neg:GPR (match_dup 1)))]
2197 "<MODE>mode == Pmode"
2201 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2203 (neg:GPR (match_dup 1)))
2205 (compare:CC (match_dup 0)
2208 [(set_attr "type" "add")
2209 (set_attr "dot" "yes")
2210 (set_attr "length" "4,8")])
2213 (define_insn "clz<mode>2"
2214 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2215 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2218 [(set_attr "type" "cntlz")])
2220 (define_expand "ctz<mode>2"
2221 [(set (match_operand:GPR 0 "gpc_reg_operand")
2222 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2227 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2231 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2232 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2233 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2237 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2238 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2239 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2240 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2244 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2245 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2246 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2247 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2253 (define_insn "ctz<mode>2_hw"
2254 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2255 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2258 [(set_attr "type" "cntlz")])
2260 (define_expand "ffs<mode>2"
2261 [(set (match_operand:GPR 0 "gpc_reg_operand")
2262 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2265 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2266 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2267 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2268 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2269 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2270 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2271 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2276 (define_expand "popcount<mode>2"
2277 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2278 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2279 "TARGET_POPCNTB || TARGET_POPCNTD"
2281 rs6000_emit_popcount (operands[0], operands[1]);
2285 (define_insn "popcntb<mode>2"
2286 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2287 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2291 [(set_attr "type" "popcnt")])
2293 (define_insn "popcntd<mode>2"
2294 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2295 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2298 [(set_attr "type" "popcnt")])
2301 (define_expand "parity<mode>2"
2302 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2303 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2306 rs6000_emit_parity (operands[0], operands[1]);
2310 (define_insn "parity<mode>2_cmpb"
2311 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2312 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2313 "TARGET_CMPB && TARGET_POPCNTB"
2315 [(set_attr "type" "popcnt")])
2317 (define_insn "cmpb<mode>3"
2318 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2319 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2320 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2323 [(set_attr "type" "cmp")])
2325 ;; Since the hardware zeros the upper part of the register, save generating the
2326 ;; AND immediate if we are converting to unsigned
2327 (define_insn "*bswaphi2_extenddi"
2328 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2330 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2333 [(set_attr "length" "4")
2334 (set_attr "type" "load")])
2336 (define_insn "*bswaphi2_extendsi"
2337 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2339 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2342 [(set_attr "length" "4")
2343 (set_attr "type" "load")])
2345 (define_expand "bswaphi2"
2346 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2348 (match_operand:HI 1 "reg_or_mem_operand" "")))
2349 (clobber (match_scratch:SI 2 ""))])]
2352 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2353 operands[1] = force_reg (HImode, operands[1]);
2356 (define_insn "bswaphi2_internal"
2357 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2359 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2360 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2366 [(set_attr "length" "4,4,12")
2367 (set_attr "type" "load,store,*")])
2370 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2371 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2372 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2375 (and:SI (lshiftrt:SI (match_dup 4)
2379 (and:SI (ashift:SI (match_dup 4)
2381 (const_int 65280))) ;; 0xff00
2383 (ior:SI (match_dup 3)
2387 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2388 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2391 (define_insn "*bswapsi2_extenddi"
2392 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2394 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2397 [(set_attr "length" "4")
2398 (set_attr "type" "load")])
2400 (define_expand "bswapsi2"
2401 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2403 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2406 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2407 operands[1] = force_reg (SImode, operands[1]);
2410 (define_insn "*bswapsi2_internal"
2411 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2413 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2419 [(set_attr "length" "4,4,12")
2420 (set_attr "type" "load,store,*")])
2422 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2423 ;; zero_extract insns do not change for -mlittle.
2425 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2426 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2428 [(set (match_dup 0) ; DABC
2429 (rotate:SI (match_dup 1)
2431 (set (match_dup 0) ; DCBC
2432 (ior:SI (and:SI (ashift:SI (match_dup 1)
2434 (const_int 16711680))
2435 (and:SI (match_dup 0)
2436 (const_int -16711681))))
2437 (set (match_dup 0) ; DCBA
2438 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2441 (and:SI (match_dup 0)
2447 (define_expand "bswapdi2"
2448 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2450 (match_operand:DI 1 "reg_or_mem_operand" "")))
2451 (clobber (match_scratch:DI 2 ""))
2452 (clobber (match_scratch:DI 3 ""))])]
2455 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2456 operands[1] = force_reg (DImode, operands[1]);
2458 if (!TARGET_POWERPC64)
2460 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2461 that uses 64-bit registers needs the same scratch registers as 64-bit
2463 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2468 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2469 (define_insn "*bswapdi2_ldbrx"
2470 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2471 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2472 (clobber (match_scratch:DI 2 "=X,X,&r"))
2473 (clobber (match_scratch:DI 3 "=X,X,&r"))]
2474 "TARGET_POWERPC64 && TARGET_LDBRX
2475 && (REG_P (operands[0]) || REG_P (operands[1]))"
2480 [(set_attr "length" "4,4,36")
2481 (set_attr "type" "load,store,*")])
2483 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2484 (define_insn "*bswapdi2_64bit"
2485 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2486 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2487 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2488 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2489 "TARGET_POWERPC64 && !TARGET_LDBRX
2490 && (REG_P (operands[0]) || REG_P (operands[1]))
2491 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2492 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2494 [(set_attr "length" "16,12,36")])
2497 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2498 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2499 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2500 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2501 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2505 rtx dest = operands[0];
2506 rtx src = operands[1];
2507 rtx op2 = operands[2];
2508 rtx op3 = operands[3];
2509 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2510 BYTES_BIG_ENDIAN ? 4 : 0);
2511 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2512 BYTES_BIG_ENDIAN ? 4 : 0);
2518 addr1 = XEXP (src, 0);
2519 if (GET_CODE (addr1) == PLUS)
2521 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2522 if (TARGET_AVOID_XFORM)
2524 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2528 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2530 else if (TARGET_AVOID_XFORM)
2532 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2537 emit_move_insn (op2, GEN_INT (4));
2538 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2541 word1 = change_address (src, SImode, addr1);
2542 word2 = change_address (src, SImode, addr2);
2544 if (BYTES_BIG_ENDIAN)
2546 emit_insn (gen_bswapsi2 (op3_32, word2));
2547 emit_insn (gen_bswapsi2 (dest_32, word1));
2551 emit_insn (gen_bswapsi2 (op3_32, word1));
2552 emit_insn (gen_bswapsi2 (dest_32, word2));
2555 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2556 emit_insn (gen_iordi3 (dest, dest, op3));
2561 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2562 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2563 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2564 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2565 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2569 rtx dest = operands[0];
2570 rtx src = operands[1];
2571 rtx op2 = operands[2];
2572 rtx op3 = operands[3];
2573 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2574 BYTES_BIG_ENDIAN ? 4 : 0);
2575 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2576 BYTES_BIG_ENDIAN ? 4 : 0);
2582 addr1 = XEXP (dest, 0);
2583 if (GET_CODE (addr1) == PLUS)
2585 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2586 if (TARGET_AVOID_XFORM)
2588 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2592 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2594 else if (TARGET_AVOID_XFORM)
2596 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2601 emit_move_insn (op2, GEN_INT (4));
2602 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2605 word1 = change_address (dest, SImode, addr1);
2606 word2 = change_address (dest, SImode, addr2);
2608 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2610 if (BYTES_BIG_ENDIAN)
2612 emit_insn (gen_bswapsi2 (word1, src_si));
2613 emit_insn (gen_bswapsi2 (word2, op3_si));
2617 emit_insn (gen_bswapsi2 (word2, src_si));
2618 emit_insn (gen_bswapsi2 (word1, op3_si));
2624 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2625 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2626 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2627 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2628 "TARGET_POWERPC64 && reload_completed"
2632 rtx dest = operands[0];
2633 rtx src = operands[1];
2634 rtx op2 = operands[2];
2635 rtx op3 = operands[3];
2636 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2637 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2638 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2639 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2640 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2642 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2643 emit_insn (gen_bswapsi2 (dest_si, src_si));
2644 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2645 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2646 emit_insn (gen_iordi3 (dest, dest, op3));
2650 (define_insn "bswapdi2_32bit"
2651 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2652 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2653 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2654 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2656 [(set_attr "length" "16,12,36")])
2659 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2660 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2661 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2662 "!TARGET_POWERPC64 && reload_completed"
2666 rtx dest = operands[0];
2667 rtx src = operands[1];
2668 rtx op2 = operands[2];
2669 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2670 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2676 addr1 = XEXP (src, 0);
2677 if (GET_CODE (addr1) == PLUS)
2679 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2680 if (TARGET_AVOID_XFORM
2681 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2683 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2687 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2689 else if (TARGET_AVOID_XFORM
2690 || REGNO (addr1) == REGNO (dest2))
2692 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2697 emit_move_insn (op2, GEN_INT (4));
2698 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2701 word1 = change_address (src, SImode, addr1);
2702 word2 = change_address (src, SImode, addr2);
2704 emit_insn (gen_bswapsi2 (dest2, word1));
2705 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2706 thus allowing us to omit an early clobber on the output. */
2707 emit_insn (gen_bswapsi2 (dest1, word2));
2712 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2713 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2714 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2715 "!TARGET_POWERPC64 && reload_completed"
2719 rtx dest = operands[0];
2720 rtx src = operands[1];
2721 rtx op2 = operands[2];
2722 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2723 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2729 addr1 = XEXP (dest, 0);
2730 if (GET_CODE (addr1) == PLUS)
2732 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2733 if (TARGET_AVOID_XFORM)
2735 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2739 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2741 else if (TARGET_AVOID_XFORM)
2743 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2748 emit_move_insn (op2, GEN_INT (4));
2749 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2752 word1 = change_address (dest, SImode, addr1);
2753 word2 = change_address (dest, SImode, addr2);
2755 emit_insn (gen_bswapsi2 (word2, src1));
2756 emit_insn (gen_bswapsi2 (word1, src2));
2761 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2762 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2763 (clobber (match_operand:SI 2 "" ""))]
2764 "!TARGET_POWERPC64 && reload_completed"
2768 rtx dest = operands[0];
2769 rtx src = operands[1];
2770 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2771 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2772 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2773 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2775 emit_insn (gen_bswapsi2 (dest1, src2));
2776 emit_insn (gen_bswapsi2 (dest2, src1));
2781 (define_insn "mul<mode>3"
2782 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2783 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2784 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2789 [(set_attr "type" "mul")
2791 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2793 (match_operand:GPR 2 "short_cint_operand" "")
2794 (const_string "16")]
2795 (const_string "<bits>")))])
2797 (define_insn_and_split "*mul<mode>3_dot"
2798 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2799 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2800 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2802 (clobber (match_scratch:GPR 0 "=r,r"))]
2803 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2807 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2809 (mult:GPR (match_dup 1)
2812 (compare:CC (match_dup 0)
2815 [(set_attr "type" "mul")
2816 (set_attr "size" "<bits>")
2817 (set_attr "dot" "yes")
2818 (set_attr "length" "4,8")])
2820 (define_insn_and_split "*mul<mode>3_dot2"
2821 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2822 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2823 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2825 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2826 (mult:GPR (match_dup 1)
2828 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2832 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2834 (mult:GPR (match_dup 1)
2837 (compare:CC (match_dup 0)
2840 [(set_attr "type" "mul")
2841 (set_attr "size" "<bits>")
2842 (set_attr "dot" "yes")
2843 (set_attr "length" "4,8")])
2846 (define_expand "<su>mul<mode>3_highpart"
2847 [(set (match_operand:GPR 0 "gpc_reg_operand")
2849 (mult:<DMODE> (any_extend:<DMODE>
2850 (match_operand:GPR 1 "gpc_reg_operand"))
2852 (match_operand:GPR 2 "gpc_reg_operand")))
2856 if (<MODE>mode == SImode && TARGET_POWERPC64)
2858 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2863 if (!WORDS_BIG_ENDIAN)
2865 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2871 (define_insn "*<su>mul<mode>3_highpart"
2872 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2874 (mult:<DMODE> (any_extend:<DMODE>
2875 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2877 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2879 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2880 "mulh<wd><u> %0,%1,%2"
2881 [(set_attr "type" "mul")
2882 (set_attr "size" "<bits>")])
2884 (define_insn "<su>mulsi3_highpart_le"
2885 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2887 (mult:DI (any_extend:DI
2888 (match_operand:SI 1 "gpc_reg_operand" "r"))
2890 (match_operand:SI 2 "gpc_reg_operand" "r")))
2892 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2894 [(set_attr "type" "mul")])
2896 (define_insn "<su>muldi3_highpart_le"
2897 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2899 (mult:TI (any_extend:TI
2900 (match_operand:DI 1 "gpc_reg_operand" "r"))
2902 (match_operand:DI 2 "gpc_reg_operand" "r")))
2904 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2906 [(set_attr "type" "mul")
2907 (set_attr "size" "64")])
2909 (define_insn "<su>mulsi3_highpart_64"
2910 [(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")))
2920 [(set_attr "type" "mul")])
2922 (define_expand "<u>mul<mode><dmode>3"
2923 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2924 (mult:<DMODE> (any_extend:<DMODE>
2925 (match_operand:GPR 1 "gpc_reg_operand"))
2927 (match_operand:GPR 2 "gpc_reg_operand"))))]
2928 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2930 rtx l = gen_reg_rtx (<MODE>mode);
2931 rtx h = gen_reg_rtx (<MODE>mode);
2932 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2933 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2934 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2935 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2939 (define_insn "*maddld4"
2940 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2941 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2942 (match_operand:DI 2 "gpc_reg_operand" "r"))
2943 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2945 "maddld %0,%1,%2,%3"
2946 [(set_attr "type" "mul")])
2948 (define_insn "udiv<mode>3"
2949 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2950 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2951 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2954 [(set_attr "type" "div")
2955 (set_attr "size" "<bits>")])
2958 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2959 ;; modulus. If it isn't a power of two, force operands into register and do
2961 (define_expand "div<mode>3"
2962 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2963 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2964 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2967 if (CONST_INT_P (operands[2])
2968 && INTVAL (operands[2]) > 0
2969 && exact_log2 (INTVAL (operands[2])) >= 0)
2971 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2975 operands[2] = force_reg (<MODE>mode, operands[2]);
2978 (define_insn "*div<mode>3"
2979 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2980 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2981 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2984 [(set_attr "type" "div")
2985 (set_attr "size" "<bits>")])
2987 (define_insn "div<mode>3_sra"
2988 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2989 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2990 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2991 (clobber (reg:GPR CA_REGNO))]
2993 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2994 [(set_attr "type" "two")
2995 (set_attr "length" "8")])
2997 (define_insn_and_split "*div<mode>3_sra_dot"
2998 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2999 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3000 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3002 (clobber (match_scratch:GPR 0 "=r,r"))
3003 (clobber (reg:GPR CA_REGNO))]
3004 "<MODE>mode == Pmode"
3006 sra<wd>i %0,%1,%p2\;addze. %0,%0
3008 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3009 [(parallel [(set (match_dup 0)
3010 (div:GPR (match_dup 1)
3012 (clobber (reg:GPR CA_REGNO))])
3014 (compare:CC (match_dup 0)
3017 [(set_attr "type" "two")
3018 (set_attr "length" "8,12")
3019 (set_attr "cell_micro" "not")])
3021 (define_insn_and_split "*div<mode>3_sra_dot2"
3022 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3023 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3024 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3026 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3027 (div:GPR (match_dup 1)
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_expand "mod<mode>3"
3048 [(set (match_operand:GPR 0 "gpc_reg_operand")
3049 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3050 (match_operand:GPR 2 "reg_or_cint_operand")))]
3057 if (GET_CODE (operands[2]) != CONST_INT
3058 || INTVAL (operands[2]) <= 0
3059 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3064 operands[2] = force_reg (<MODE>mode, operands[2]);
3068 temp1 = gen_reg_rtx (<MODE>mode);
3069 temp2 = gen_reg_rtx (<MODE>mode);
3071 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3072 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3073 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3078 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3079 ;; mod, prefer putting the result of mod into a different register
3080 (define_insn "*mod<mode>3"
3081 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3082 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3083 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3086 [(set_attr "type" "div")
3087 (set_attr "size" "<bits>")])
3090 (define_insn "umod<mode>3"
3091 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3092 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3093 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3096 [(set_attr "type" "div")
3097 (set_attr "size" "<bits>")])
3099 ;; On machines with modulo support, do a combined div/mod the old fashioned
3100 ;; method, since the multiply/subtract is faster than doing the mod instruction
3104 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3105 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3106 (match_operand:GPR 2 "gpc_reg_operand" "")))
3107 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3108 (mod:GPR (match_dup 1)
3111 && ! reg_mentioned_p (operands[0], operands[1])
3112 && ! reg_mentioned_p (operands[0], operands[2])
3113 && ! reg_mentioned_p (operands[3], operands[1])
3114 && ! reg_mentioned_p (operands[3], operands[2])"
3116 (div:GPR (match_dup 1)
3119 (mult:GPR (match_dup 0)
3122 (minus:GPR (match_dup 1)
3126 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3127 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3128 (match_operand:GPR 2 "gpc_reg_operand" "")))
3129 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3130 (umod:GPR (match_dup 1)
3133 && ! reg_mentioned_p (operands[0], operands[1])
3134 && ! reg_mentioned_p (operands[0], operands[2])
3135 && ! reg_mentioned_p (operands[3], operands[1])
3136 && ! reg_mentioned_p (operands[3], operands[2])"
3138 (div:GPR (match_dup 1)
3141 (mult:GPR (match_dup 0)
3144 (minus:GPR (match_dup 1)
3148 ;; Logical instructions
3149 ;; The logical instructions are mostly combined by using match_operator,
3150 ;; but the plain AND insns are somewhat different because there is no
3151 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3152 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3154 (define_expand "and<mode>3"
3155 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3156 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3157 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3160 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3162 rs6000_split_logical (operands, AND, false, false, false);
3166 if (CONST_INT_P (operands[2]))
3168 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3170 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3174 if (logical_const_operand (operands[2], <MODE>mode)
3175 && rs6000_gen_cell_microcode)
3177 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3181 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3183 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3187 operands[2] = force_reg (<MODE>mode, operands[2]);
3192 (define_insn "and<mode>3_imm"
3193 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3194 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3195 (match_operand:GPR 2 "logical_const_operand" "n")))
3196 (clobber (match_scratch:CC 3 "=x"))]
3197 "rs6000_gen_cell_microcode
3198 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3199 "andi%e2. %0,%1,%u2"
3200 [(set_attr "type" "logical")
3201 (set_attr "dot" "yes")])
3203 (define_insn_and_split "*and<mode>3_imm_dot"
3204 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3205 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3206 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3208 (clobber (match_scratch:GPR 0 "=r,r"))
3209 (clobber (match_scratch:CC 4 "=X,x"))]
3210 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3211 && rs6000_gen_cell_microcode
3212 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3216 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3217 [(parallel [(set (match_dup 0)
3218 (and:GPR (match_dup 1)
3220 (clobber (match_dup 4))])
3222 (compare:CC (match_dup 0)
3225 [(set_attr "type" "logical")
3226 (set_attr "dot" "yes")
3227 (set_attr "length" "4,8")])
3229 (define_insn_and_split "*and<mode>3_imm_dot2"
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 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3235 (and:GPR (match_dup 1)
3237 (clobber (match_scratch:CC 4 "=X,x"))]
3238 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3239 && rs6000_gen_cell_microcode
3240 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3244 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3245 [(parallel [(set (match_dup 0)
3246 (and:GPR (match_dup 1)
3248 (clobber (match_dup 4))])
3250 (compare:CC (match_dup 0)
3253 [(set_attr "type" "logical")
3254 (set_attr "dot" "yes")
3255 (set_attr "length" "4,8")])
3257 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3258 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3259 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3260 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3262 (clobber (match_scratch:GPR 0 "=r,r"))]
3263 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3264 && rs6000_gen_cell_microcode
3265 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3269 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3271 (and:GPR (match_dup 1)
3274 (compare:CC (match_dup 0)
3277 [(set_attr "type" "logical")
3278 (set_attr "dot" "yes")
3279 (set_attr "length" "4,8")])
3281 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3282 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3283 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3284 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3286 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3287 (and:GPR (match_dup 1)
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<mode>3_imm_dot_shifted"
3308 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3311 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3312 (match_operand:SI 4 "const_int_operand" "n"))
3313 (match_operand:GPR 2 "const_int_operand" "n"))
3315 (clobber (match_scratch:GPR 0 "=r"))]
3316 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3317 << INTVAL (operands[4])),
3319 && (<MODE>mode == Pmode
3320 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3321 && rs6000_gen_cell_microcode"
3323 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3324 return "andi%e2. %0,%1,%u2";
3326 [(set_attr "type" "logical")
3327 (set_attr "dot" "yes")])
3330 (define_insn "and<mode>3_mask"
3331 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3332 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3333 (match_operand:GPR 2 "const_int_operand" "n")))]
3334 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3336 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3338 [(set_attr "type" "shift")])
3340 (define_insn_and_split "*and<mode>3_mask_dot"
3341 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3342 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3343 (match_operand:GPR 2 "const_int_operand" "n,n"))
3345 (clobber (match_scratch:GPR 0 "=r,r"))]
3346 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3347 && rs6000_gen_cell_microcode
3348 && !logical_const_operand (operands[2], <MODE>mode)
3349 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3351 if (which_alternative == 0)
3352 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3356 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3358 (and:GPR (match_dup 1)
3361 (compare:CC (match_dup 0)
3364 [(set_attr "type" "shift")
3365 (set_attr "dot" "yes")
3366 (set_attr "length" "4,8")])
3368 (define_insn_and_split "*and<mode>3_mask_dot2"
3369 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3370 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3371 (match_operand:GPR 2 "const_int_operand" "n,n"))
3373 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3374 (and:GPR (match_dup 1)
3376 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3377 && rs6000_gen_cell_microcode
3378 && !logical_const_operand (operands[2], <MODE>mode)
3379 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3381 if (which_alternative == 0)
3382 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3386 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3388 (and:GPR (match_dup 1)
3391 (compare:CC (match_dup 0)
3394 [(set_attr "type" "shift")
3395 (set_attr "dot" "yes")
3396 (set_attr "length" "4,8")])
3399 (define_insn_and_split "*and<mode>3_2insn"
3400 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3401 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3402 (match_operand:GPR 2 "const_int_operand" "n")))]
3403 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3404 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3405 || (logical_const_operand (operands[2], <MODE>mode)
3406 && rs6000_gen_cell_microcode))"
3411 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3414 [(set_attr "type" "shift")
3415 (set_attr "length" "8")])
3417 (define_insn_and_split "*and<mode>3_2insn_dot"
3418 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3419 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3420 (match_operand:GPR 2 "const_int_operand" "n,n"))
3422 (clobber (match_scratch:GPR 0 "=r,r"))]
3423 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3424 && rs6000_gen_cell_microcode
3425 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3426 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3427 || (logical_const_operand (operands[2], <MODE>mode)
3428 && rs6000_gen_cell_microcode))"
3430 "&& reload_completed"
3433 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3436 [(set_attr "type" "shift")
3437 (set_attr "dot" "yes")
3438 (set_attr "length" "8,12")])
3440 (define_insn_and_split "*and<mode>3_2insn_dot2"
3441 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3442 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3443 (match_operand:GPR 2 "const_int_operand" "n,n"))
3445 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3446 (and:GPR (match_dup 1)
3448 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3449 && rs6000_gen_cell_microcode
3450 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3451 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3452 || (logical_const_operand (operands[2], <MODE>mode)
3453 && rs6000_gen_cell_microcode))"
3455 "&& reload_completed"
3458 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3461 [(set_attr "type" "shift")
3462 (set_attr "dot" "yes")
3463 (set_attr "length" "8,12")])
3466 (define_expand "<code><mode>3"
3467 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3468 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3469 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3472 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3474 rs6000_split_logical (operands, <CODE>, false, false, false);
3478 if (non_logical_cint_operand (operands[2], <MODE>mode))
3480 rtx tmp = ((!can_create_pseudo_p ()
3481 || rtx_equal_p (operands[0], operands[1]))
3482 ? operands[0] : gen_reg_rtx (<MODE>mode));
3484 HOST_WIDE_INT value = INTVAL (operands[2]);
3485 HOST_WIDE_INT lo = value & 0xffff;
3486 HOST_WIDE_INT hi = value - lo;
3488 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3489 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3493 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3494 operands[2] = force_reg (<MODE>mode, operands[2]);
3498 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3499 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3500 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3503 (iorxor:GPR (match_dup 1)
3506 (iorxor:GPR (match_dup 3)
3509 operands[3] = ((!can_create_pseudo_p ()
3510 || rtx_equal_p (operands[0], operands[1]))
3511 ? operands[0] : gen_reg_rtx (<MODE>mode));
3513 HOST_WIDE_INT value = INTVAL (operands[2]);
3514 HOST_WIDE_INT lo = value & 0xffff;
3515 HOST_WIDE_INT hi = value - lo;
3517 operands[4] = GEN_INT (hi);
3518 operands[5] = GEN_INT (lo);
3521 (define_insn "*bool<mode>3_imm"
3522 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3523 (match_operator:GPR 3 "boolean_or_operator"
3524 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3525 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3528 [(set_attr "type" "logical")])
3530 (define_insn "*bool<mode>3"
3531 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3532 (match_operator:GPR 3 "boolean_operator"
3533 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3534 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3537 [(set_attr "type" "logical")])
3539 (define_insn_and_split "*bool<mode>3_dot"
3540 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3541 (compare:CC (match_operator:GPR 3 "boolean_operator"
3542 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3543 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3545 (clobber (match_scratch:GPR 0 "=r,r"))]
3546 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3550 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3554 (compare:CC (match_dup 0)
3557 [(set_attr "type" "logical")
3558 (set_attr "dot" "yes")
3559 (set_attr "length" "4,8")])
3561 (define_insn_and_split "*bool<mode>3_dot2"
3562 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3563 (compare:CC (match_operator:GPR 3 "boolean_operator"
3564 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3565 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3567 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3569 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3573 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3577 (compare:CC (match_dup 0)
3580 [(set_attr "type" "logical")
3581 (set_attr "dot" "yes")
3582 (set_attr "length" "4,8")])
3585 (define_insn "*boolc<mode>3"
3586 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3587 (match_operator:GPR 3 "boolean_operator"
3588 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3589 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3592 [(set_attr "type" "logical")])
3594 (define_insn_and_split "*boolc<mode>3_dot"
3595 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3596 (compare:CC (match_operator:GPR 3 "boolean_operator"
3597 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3598 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3600 (clobber (match_scratch:GPR 0 "=r,r"))]
3601 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3605 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3609 (compare:CC (match_dup 0)
3612 [(set_attr "type" "logical")
3613 (set_attr "dot" "yes")
3614 (set_attr "length" "4,8")])
3616 (define_insn_and_split "*boolc<mode>3_dot2"
3617 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3618 (compare:CC (match_operator:GPR 3 "boolean_operator"
3619 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3620 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3622 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3624 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3628 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3632 (compare:CC (match_dup 0)
3635 [(set_attr "type" "logical")
3636 (set_attr "dot" "yes")
3637 (set_attr "length" "4,8")])
3640 (define_insn "*boolcc<mode>3"
3641 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3642 (match_operator:GPR 3 "boolean_operator"
3643 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3644 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3647 [(set_attr "type" "logical")])
3649 (define_insn_and_split "*boolcc<mode>3_dot"
3650 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3651 (compare:CC (match_operator:GPR 3 "boolean_operator"
3652 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3653 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3655 (clobber (match_scratch:GPR 0 "=r,r"))]
3656 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3660 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3664 (compare:CC (match_dup 0)
3667 [(set_attr "type" "logical")
3668 (set_attr "dot" "yes")
3669 (set_attr "length" "4,8")])
3671 (define_insn_and_split "*boolcc<mode>3_dot2"
3672 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3673 (compare:CC (match_operator:GPR 3 "boolean_operator"
3674 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3675 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3677 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3679 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3683 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3687 (compare:CC (match_dup 0)
3690 [(set_attr "type" "logical")
3691 (set_attr "dot" "yes")
3692 (set_attr "length" "4,8")])
3695 ;; TODO: Should have dots of this as well.
3696 (define_insn "*eqv<mode>3"
3697 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3698 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3699 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3702 [(set_attr "type" "logical")])
3704 ;; Rotate-and-mask and insert.
3706 (define_insn "*rotl<mode>3_mask"
3707 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3708 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3709 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3710 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3711 (match_operand:GPR 3 "const_int_operand" "n")))]
3712 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3714 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3716 [(set_attr "type" "shift")
3717 (set_attr "maybe_var_shift" "yes")])
3719 (define_insn_and_split "*rotl<mode>3_mask_dot"
3720 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3722 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3723 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3724 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3725 (match_operand:GPR 3 "const_int_operand" "n,n"))
3727 (clobber (match_scratch:GPR 0 "=r,r"))]
3728 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3729 && rs6000_gen_cell_microcode
3730 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3732 if (which_alternative == 0)
3733 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3737 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3739 (and:GPR (match_dup 4)
3742 (compare:CC (match_dup 0)
3745 [(set_attr "type" "shift")
3746 (set_attr "maybe_var_shift" "yes")
3747 (set_attr "dot" "yes")
3748 (set_attr "length" "4,8")])
3750 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3751 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3753 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3754 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3755 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3756 (match_operand:GPR 3 "const_int_operand" "n,n"))
3758 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3759 (and:GPR (match_dup 4)
3761 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3762 && rs6000_gen_cell_microcode
3763 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3765 if (which_alternative == 0)
3766 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3770 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3772 (and:GPR (match_dup 4)
3775 (compare:CC (match_dup 0)
3778 [(set_attr "type" "shift")
3779 (set_attr "maybe_var_shift" "yes")
3780 (set_attr "dot" "yes")
3781 (set_attr "length" "4,8")])
3783 ; Special case for less-than-0. We can do it with just one machine
3784 ; instruction, but the generic optimizers do not realise it is cheap.
3785 (define_insn "*lt0_disi"
3786 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3787 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3790 "rlwinm %0,%1,1,31,31"
3791 [(set_attr "type" "shift")])
3795 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3796 ; both are an AND so are the same precedence).
3797 (define_insn "*rotl<mode>3_insert"
3798 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3799 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3800 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3801 (match_operand:SI 2 "const_int_operand" "n")])
3802 (match_operand:GPR 3 "const_int_operand" "n"))
3803 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3804 (match_operand:GPR 6 "const_int_operand" "n"))))]
3805 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3806 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3808 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3810 [(set_attr "type" "insert")])
3811 ; FIXME: this needs an attr "size", so that the scheduler can see the
3812 ; difference between rlwimi and rldimi. We also might want dot forms,
3813 ; but not for rlwimi on POWER4 and similar processors.
3815 (define_insn "*rotl<mode>3_insert_2"
3816 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3817 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3818 (match_operand:GPR 6 "const_int_operand" "n"))
3819 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3820 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3821 (match_operand:SI 2 "const_int_operand" "n")])
3822 (match_operand:GPR 3 "const_int_operand" "n"))))]
3823 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3824 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3826 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3828 [(set_attr "type" "insert")])
3830 ; There are also some forms without one of the ANDs.
3831 (define_insn "*rotl<mode>3_insert_3"
3832 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3833 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3834 (match_operand:GPR 4 "const_int_operand" "n"))
3835 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3836 (match_operand:SI 2 "const_int_operand" "n"))))]
3837 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3839 if (<MODE>mode == SImode)
3840 return "rlwimi %0,%1,%h2,0,31-%h2";
3842 return "rldimi %0,%1,%H2,0";
3844 [(set_attr "type" "insert")])
3846 (define_insn "*rotl<mode>3_insert_4"
3847 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3848 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3849 (match_operand:GPR 4 "const_int_operand" "n"))
3850 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3851 (match_operand:SI 2 "const_int_operand" "n"))))]
3852 "<MODE>mode == SImode &&
3853 GET_MODE_PRECISION (<MODE>mode)
3854 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3856 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3857 - INTVAL (operands[2]));
3858 if (<MODE>mode == SImode)
3859 return "rlwimi %0,%1,%h2,32-%h2,31";
3861 return "rldimi %0,%1,%H2,64-%H2";
3863 [(set_attr "type" "insert")])
3865 (define_insn "*rotlsi3_insert_5"
3866 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3867 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3868 (match_operand:SI 2 "const_int_operand" "n,n"))
3869 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3870 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3871 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3872 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3873 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3877 [(set_attr "type" "insert")])
3879 (define_insn "*rotldi3_insert_6"
3880 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3881 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3882 (match_operand:DI 2 "const_int_operand" "n"))
3883 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3884 (match_operand:DI 4 "const_int_operand" "n"))))]
3885 "exact_log2 (-UINTVAL (operands[2])) > 0
3886 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3888 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3889 return "rldimi %0,%3,0,%5";
3891 [(set_attr "type" "insert")
3892 (set_attr "size" "64")])
3894 (define_insn "*rotldi3_insert_7"
3895 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3896 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3897 (match_operand:DI 4 "const_int_operand" "n"))
3898 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3899 (match_operand:DI 2 "const_int_operand" "n"))))]
3900 "exact_log2 (-UINTVAL (operands[2])) > 0
3901 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3903 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3904 return "rldimi %0,%3,0,%5";
3906 [(set_attr "type" "insert")
3907 (set_attr "size" "64")])
3910 ; This handles the important case of multiple-precision shifts. There is
3911 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3913 [(set (match_operand:GPR 0 "gpc_reg_operand")
3914 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3915 (match_operand:SI 3 "const_int_operand"))
3916 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3917 (match_operand:SI 4 "const_int_operand"))))]
3918 "can_create_pseudo_p ()
3919 && INTVAL (operands[3]) + INTVAL (operands[4])
3920 >= GET_MODE_PRECISION (<MODE>mode)"
3922 (lshiftrt:GPR (match_dup 2)
3925 (ior:GPR (and:GPR (match_dup 5)
3927 (ashift:GPR (match_dup 1)
3930 unsigned HOST_WIDE_INT mask = 1;
3931 mask = (mask << INTVAL (operands[3])) - 1;
3932 operands[5] = gen_reg_rtx (<MODE>mode);
3933 operands[6] = GEN_INT (mask);
3937 [(set (match_operand:GPR 0 "gpc_reg_operand")
3938 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3939 (match_operand:SI 4 "const_int_operand"))
3940 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3941 (match_operand:SI 3 "const_int_operand"))))]
3942 "can_create_pseudo_p ()
3943 && INTVAL (operands[3]) + INTVAL (operands[4])
3944 >= GET_MODE_PRECISION (<MODE>mode)"
3946 (lshiftrt:GPR (match_dup 2)
3949 (ior:GPR (and:GPR (match_dup 5)
3951 (ashift:GPR (match_dup 1)
3954 unsigned HOST_WIDE_INT mask = 1;
3955 mask = (mask << INTVAL (operands[3])) - 1;
3956 operands[5] = gen_reg_rtx (<MODE>mode);
3957 operands[6] = GEN_INT (mask);
3961 ; Another important case is setting some bits to 1; we can do that with
3962 ; an insert instruction, in many cases.
3963 (define_insn_and_split "*ior<mode>_mask"
3964 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3965 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3966 (match_operand:GPR 2 "const_int_operand" "n")))
3967 (clobber (match_scratch:GPR 3 "=r"))]
3968 "!logical_const_operand (operands[2], <MODE>mode)
3969 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3975 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3978 (and:GPR (match_dup 1)
3982 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3983 if (GET_CODE (operands[3]) == SCRATCH)
3984 operands[3] = gen_reg_rtx (<MODE>mode);
3985 operands[4] = GEN_INT (ne);
3986 operands[5] = GEN_INT (~UINTVAL (operands[2]));
3988 [(set_attr "type" "two")
3989 (set_attr "length" "8")])
3992 ;; Now the simple shifts.
3994 (define_insn "rotl<mode>3"
3995 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3996 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3997 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3999 "rotl<wd>%I2 %0,%1,%<hH>2"
4000 [(set_attr "type" "shift")
4001 (set_attr "maybe_var_shift" "yes")])
4003 (define_insn "*rotlsi3_64"
4004 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4006 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4007 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4009 "rotlw%I2 %0,%1,%h2"
4010 [(set_attr "type" "shift")
4011 (set_attr "maybe_var_shift" "yes")])
4013 (define_insn_and_split "*rotl<mode>3_dot"
4014 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4015 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4016 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4018 (clobber (match_scratch:GPR 0 "=r,r"))]
4019 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4021 rotl<wd>%I2. %0,%1,%<hH>2
4023 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4025 (rotate:GPR (match_dup 1)
4028 (compare:CC (match_dup 0)
4031 [(set_attr "type" "shift")
4032 (set_attr "maybe_var_shift" "yes")
4033 (set_attr "dot" "yes")
4034 (set_attr "length" "4,8")])
4036 (define_insn_and_split "*rotl<mode>3_dot2"
4037 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4038 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4039 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4041 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4042 (rotate:GPR (match_dup 1)
4044 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4046 rotl<wd>%I2. %0,%1,%<hH>2
4048 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4050 (rotate:GPR (match_dup 1)
4053 (compare:CC (match_dup 0)
4056 [(set_attr "type" "shift")
4057 (set_attr "maybe_var_shift" "yes")
4058 (set_attr "dot" "yes")
4059 (set_attr "length" "4,8")])
4062 (define_insn "ashl<mode>3"
4063 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4064 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4065 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4067 "sl<wd>%I2 %0,%1,%<hH>2"
4068 [(set_attr "type" "shift")
4069 (set_attr "maybe_var_shift" "yes")])
4071 (define_insn "*ashlsi3_64"
4072 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4074 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4075 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4078 [(set_attr "type" "shift")
4079 (set_attr "maybe_var_shift" "yes")])
4081 (define_insn_and_split "*ashl<mode>3_dot"
4082 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4083 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4084 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4086 (clobber (match_scratch:GPR 0 "=r,r"))]
4087 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4089 sl<wd>%I2. %0,%1,%<hH>2
4091 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4093 (ashift:GPR (match_dup 1)
4096 (compare:CC (match_dup 0)
4099 [(set_attr "type" "shift")
4100 (set_attr "maybe_var_shift" "yes")
4101 (set_attr "dot" "yes")
4102 (set_attr "length" "4,8")])
4104 (define_insn_and_split "*ashl<mode>3_dot2"
4105 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4106 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4107 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4109 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4110 (ashift:GPR (match_dup 1)
4112 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4114 sl<wd>%I2. %0,%1,%<hH>2
4116 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4118 (ashift:GPR (match_dup 1)
4121 (compare:CC (match_dup 0)
4124 [(set_attr "type" "shift")
4125 (set_attr "maybe_var_shift" "yes")
4126 (set_attr "dot" "yes")
4127 (set_attr "length" "4,8")])
4129 ;; Pretend we have a memory form of extswsli until register allocation is done
4130 ;; so that we use LWZ to load the value from memory, instead of LWA.
4131 (define_insn_and_split "ashdi3_extswsli"
4132 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4134 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4135 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4140 "&& reload_completed && MEM_P (operands[1])"
4144 (ashift:DI (sign_extend:DI (match_dup 3))
4147 operands[3] = gen_lowpart (SImode, operands[0]);
4149 [(set_attr "type" "shift")
4150 (set_attr "maybe_var_shift" "no")])
4153 (define_insn_and_split "ashdi3_extswsli_dot"
4154 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4157 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4158 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4160 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4167 "&& reload_completed
4168 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4169 || memory_operand (operands[1], SImode))"
4172 rtx dest = operands[0];
4173 rtx src = operands[1];
4174 rtx shift = operands[2];
4175 rtx cr = operands[3];
4182 src2 = gen_lowpart (SImode, dest);
4183 emit_move_insn (src2, src);
4186 if (REGNO (cr) == CR0_REGNO)
4188 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4192 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4193 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4196 [(set_attr "type" "shift")
4197 (set_attr "maybe_var_shift" "no")
4198 (set_attr "dot" "yes")
4199 (set_attr "length" "4,8,8,12")])
4201 (define_insn_and_split "ashdi3_extswsli_dot2"
4202 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4205 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4206 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4208 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4209 (ashift:DI (sign_extend:DI (match_dup 1))
4217 "&& reload_completed
4218 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4219 || memory_operand (operands[1], SImode))"
4222 rtx dest = operands[0];
4223 rtx src = operands[1];
4224 rtx shift = operands[2];
4225 rtx cr = operands[3];
4232 src2 = gen_lowpart (SImode, dest);
4233 emit_move_insn (src2, src);
4236 if (REGNO (cr) == CR0_REGNO)
4238 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4242 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4243 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4246 [(set_attr "type" "shift")
4247 (set_attr "maybe_var_shift" "no")
4248 (set_attr "dot" "yes")
4249 (set_attr "length" "4,8,8,12")])
4251 (define_insn "lshr<mode>3"
4252 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4253 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4254 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4256 "sr<wd>%I2 %0,%1,%<hH>2"
4257 [(set_attr "type" "shift")
4258 (set_attr "maybe_var_shift" "yes")])
4260 (define_insn "*lshrsi3_64"
4261 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4263 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4264 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4267 [(set_attr "type" "shift")
4268 (set_attr "maybe_var_shift" "yes")])
4270 (define_insn_and_split "*lshr<mode>3_dot"
4271 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4272 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4273 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4275 (clobber (match_scratch:GPR 0 "=r,r"))]
4276 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4278 sr<wd>%I2. %0,%1,%<hH>2
4280 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4282 (lshiftrt:GPR (match_dup 1)
4285 (compare:CC (match_dup 0)
4288 [(set_attr "type" "shift")
4289 (set_attr "maybe_var_shift" "yes")
4290 (set_attr "dot" "yes")
4291 (set_attr "length" "4,8")])
4293 (define_insn_and_split "*lshr<mode>3_dot2"
4294 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4295 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4296 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4298 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4299 (lshiftrt:GPR (match_dup 1)
4301 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4303 sr<wd>%I2. %0,%1,%<hH>2
4305 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4307 (lshiftrt:GPR (match_dup 1)
4310 (compare:CC (match_dup 0)
4313 [(set_attr "type" "shift")
4314 (set_attr "maybe_var_shift" "yes")
4315 (set_attr "dot" "yes")
4316 (set_attr "length" "4,8")])
4319 (define_insn "ashr<mode>3"
4320 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4321 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4322 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4323 (clobber (reg:GPR CA_REGNO))]
4325 "sra<wd>%I2 %0,%1,%<hH>2"
4326 [(set_attr "type" "shift")
4327 (set_attr "maybe_var_shift" "yes")])
4329 (define_insn "*ashrsi3_64"
4330 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4332 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4333 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4334 (clobber (reg:SI CA_REGNO))]
4337 [(set_attr "type" "shift")
4338 (set_attr "maybe_var_shift" "yes")])
4340 (define_insn_and_split "*ashr<mode>3_dot"
4341 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4342 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4343 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4345 (clobber (match_scratch:GPR 0 "=r,r"))
4346 (clobber (reg:GPR CA_REGNO))]
4347 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4349 sra<wd>%I2. %0,%1,%<hH>2
4351 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4352 [(parallel [(set (match_dup 0)
4353 (ashiftrt:GPR (match_dup 1)
4355 (clobber (reg:GPR CA_REGNO))])
4357 (compare:CC (match_dup 0)
4360 [(set_attr "type" "shift")
4361 (set_attr "maybe_var_shift" "yes")
4362 (set_attr "dot" "yes")
4363 (set_attr "length" "4,8")])
4365 (define_insn_and_split "*ashr<mode>3_dot2"
4366 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4367 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4368 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4370 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4371 (ashiftrt:GPR (match_dup 1)
4373 (clobber (reg:GPR CA_REGNO))]
4374 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4376 sra<wd>%I2. %0,%1,%<hH>2
4378 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4379 [(parallel [(set (match_dup 0)
4380 (ashiftrt:GPR (match_dup 1)
4382 (clobber (reg:GPR CA_REGNO))])
4384 (compare:CC (match_dup 0)
4387 [(set_attr "type" "shift")
4388 (set_attr "maybe_var_shift" "yes")
4389 (set_attr "dot" "yes")
4390 (set_attr "length" "4,8")])
4392 ;; Builtins to replace a division to generate FRE reciprocal estimate
4393 ;; instructions and the necessary fixup instructions
4394 (define_expand "recip<mode>3"
4395 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4396 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4397 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4398 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4400 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4404 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4405 ;; hardware division. This is only done before register allocation and with
4406 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4407 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4408 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4410 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4411 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4412 (match_operand 2 "gpc_reg_operand" "")))]
4413 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4414 && can_create_pseudo_p () && flag_finite_math_only
4415 && !flag_trapping_math && flag_reciprocal_math"
4418 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4422 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4423 ;; appropriate fixup.
4424 (define_expand "rsqrt<mode>2"
4425 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4426 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4427 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4429 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4433 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4434 ;; modes here, and also add in conditional vsx/power8-vector support to access
4435 ;; values in the traditional Altivec registers if the appropriate
4436 ;; -mupper-regs-{df,sf} option is enabled.
4438 (define_expand "abs<mode>2"
4439 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4440 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4441 "TARGET_<MODE>_INSN"
4444 (define_insn "*abs<mode>2_fpr"
4445 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4446 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4451 [(set_attr "type" "fpsimple")
4452 (set_attr "fp_type" "fp_addsub_<Fs>")])
4454 (define_insn "*nabs<mode>2_fpr"
4455 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4458 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4463 [(set_attr "type" "fpsimple")
4464 (set_attr "fp_type" "fp_addsub_<Fs>")])
4466 (define_expand "neg<mode>2"
4467 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4468 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4469 "TARGET_<MODE>_INSN"
4472 (define_insn "*neg<mode>2_fpr"
4473 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4474 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4479 [(set_attr "type" "fpsimple")
4480 (set_attr "fp_type" "fp_addsub_<Fs>")])
4482 (define_expand "add<mode>3"
4483 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4484 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4485 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4486 "TARGET_<MODE>_INSN"
4489 (define_insn "*add<mode>3_fpr"
4490 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4491 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4492 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4495 fadd<Ftrad> %0,%1,%2
4496 xsadd<Fvsx> %x0,%x1,%x2"
4497 [(set_attr "type" "fp")
4498 (set_attr "fp_type" "fp_addsub_<Fs>")])
4500 (define_expand "sub<mode>3"
4501 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4502 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4503 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4504 "TARGET_<MODE>_INSN"
4507 (define_insn "*sub<mode>3_fpr"
4508 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4509 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4510 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4513 fsub<Ftrad> %0,%1,%2
4514 xssub<Fvsx> %x0,%x1,%x2"
4515 [(set_attr "type" "fp")
4516 (set_attr "fp_type" "fp_addsub_<Fs>")])
4518 (define_expand "mul<mode>3"
4519 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4520 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4521 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4522 "TARGET_<MODE>_INSN"
4525 (define_insn "*mul<mode>3_fpr"
4526 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4527 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4528 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4531 fmul<Ftrad> %0,%1,%2
4532 xsmul<Fvsx> %x0,%x1,%x2"
4533 [(set_attr "type" "dmul")
4534 (set_attr "fp_type" "fp_mul_<Fs>")])
4536 (define_expand "div<mode>3"
4537 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4538 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4539 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4540 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4542 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4543 && can_create_pseudo_p () && flag_finite_math_only
4544 && !flag_trapping_math && flag_reciprocal_math)
4546 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4551 (define_insn "*div<mode>3_fpr"
4552 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4553 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4554 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4555 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4557 fdiv<Ftrad> %0,%1,%2
4558 xsdiv<Fvsx> %x0,%x1,%x2"
4559 [(set_attr "type" "<Fs>div")
4560 (set_attr "fp_type" "fp_div_<Fs>")])
4562 (define_insn "*sqrt<mode>2_internal"
4563 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4564 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4565 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4566 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4569 xssqrt<Fvsx> %x0,%x1"
4570 [(set_attr "type" "<Fs>sqrt")
4571 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4573 (define_expand "sqrt<mode>2"
4574 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4575 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4576 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4577 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4579 if (<MODE>mode == SFmode
4580 && TARGET_RECIP_PRECISION
4581 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4582 && !optimize_function_for_size_p (cfun)
4583 && flag_finite_math_only && !flag_trapping_math
4584 && flag_unsafe_math_optimizations)
4586 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4591 ;; Floating point reciprocal approximation
4592 (define_insn "fre<Fs>"
4593 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4594 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4600 [(set_attr "type" "fp")])
4602 (define_insn "*rsqrt<mode>2"
4603 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4604 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4606 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4608 frsqrte<Ftrad> %0,%1
4609 xsrsqrte<Fvsx> %x0,%x1"
4610 [(set_attr "type" "fp")])
4612 ;; Floating point comparisons
4613 (define_insn "*cmp<mode>_fpr"
4614 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4615 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4616 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4620 xscmpudp %0,%x1,%x2"
4621 [(set_attr "type" "fpcompare")])
4623 ;; Floating point conversions
4624 (define_expand "extendsfdf2"
4625 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4626 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4627 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4630 (define_insn_and_split "*extendsfdf2_fpr"
4631 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4632 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4633 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4639 xscpsgndp %x0,%x1,%x1
4642 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4645 emit_note (NOTE_INSN_DELETED);
4648 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4650 (define_expand "truncdfsf2"
4651 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4652 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4653 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4656 (define_insn "*truncdfsf2_fpr"
4657 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4658 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4659 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4663 [(set_attr "type" "fp")])
4665 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4666 ;; builtins.c and optabs.c that are not correct for IBM long double
4667 ;; when little-endian.
4668 (define_expand "signbit<mode>2"
4670 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4672 (subreg:DI (match_dup 2) 0))
4675 (set (match_operand:SI 0 "gpc_reg_operand" "")
4678 && (TARGET_FPRS || TARGET_E500_DOUBLE)
4679 && (!FLOAT128_IEEE_P (<MODE>mode)
4680 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4682 if (FLOAT128_IEEE_P (<MODE>mode))
4684 if (<MODE>mode == KFmode)
4685 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4686 else if (<MODE>mode == TFmode)
4687 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4692 operands[2] = gen_reg_rtx (DFmode);
4693 operands[3] = gen_reg_rtx (DImode);
4694 if (TARGET_POWERPC64)
4696 operands[4] = gen_reg_rtx (DImode);
4697 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4698 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4699 WORDS_BIG_ENDIAN ? 4 : 0);
4703 operands[4] = gen_reg_rtx (SImode);
4704 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4705 WORDS_BIG_ENDIAN ? 0 : 4);
4706 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4710 (define_expand "copysign<mode>3"
4712 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4714 (neg:SFDF (abs:SFDF (match_dup 1))))
4715 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4716 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4720 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4721 && ((TARGET_PPC_GFXOPT
4722 && !HONOR_NANS (<MODE>mode)
4723 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4725 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4727 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4729 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4734 operands[3] = gen_reg_rtx (<MODE>mode);
4735 operands[4] = gen_reg_rtx (<MODE>mode);
4736 operands[5] = CONST0_RTX (<MODE>mode);
4739 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4741 (define_insn_and_split "signbit<mode>2_dm"
4742 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4744 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4746 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4748 "&& reload_completed"
4751 rs6000_split_signbit (operands[0], operands[1]);
4754 [(set_attr "length" "8,8,4")
4755 (set_attr "type" "mftgpr,load,integer")])
4757 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4758 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4761 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4763 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4765 "&& reload_completed"
4768 rs6000_split_signbit (operands[0], operands[1]);
4771 [(set_attr "length" "8,8,4")
4772 (set_attr "type" "mftgpr,load,integer")])
4774 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4775 ;; point types, which makes normal SUBREG's problematical. Instead use a
4776 ;; special pattern to avoid using a normal movdi.
4777 (define_insn "signbit<mode>2_dm2"
4778 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4779 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4782 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4784 [(set_attr "type" "mftgpr")])
4787 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4788 ;; compiler from optimizing -0.0
4789 (define_insn "copysign<mode>3_fcpsgn"
4790 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4791 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4792 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4794 "TARGET_<MODE>_FPR && TARGET_CMPB"
4797 xscpsgndp %x0,%x2,%x1"
4798 [(set_attr "type" "fpsimple")])
4800 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4801 ;; fsel instruction and some auxiliary computations. Then we just have a
4802 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4804 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4805 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4806 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4807 ;; define_splits to make them if made by combine. On VSX machines we have the
4808 ;; min/max instructions.
4810 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4811 ;; to allow either DF/SF to use only traditional registers.
4813 (define_expand "s<minmax><mode>3"
4814 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4815 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4816 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4817 "TARGET_MINMAX_<MODE>"
4819 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4823 (define_insn "*s<minmax><mode>3_vsx"
4824 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4825 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4826 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4827 "TARGET_VSX && TARGET_<MODE>_FPR"
4829 return (TARGET_P9_MINMAX
4830 ? "xs<minmax>cdp %x0,%x1,%x2"
4831 : "xs<minmax>dp %x0,%x1,%x2");
4833 [(set_attr "type" "fp")])
4835 ;; The conditional move instructions allow us to perform max and min operations
4836 ;; even when we don't have the appropriate max/min instruction using the FSEL
4839 (define_insn_and_split "*s<minmax><mode>3_fpr"
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_VSX && TARGET_MINMAX_<MODE>"
4848 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4852 (define_expand "mov<mode>cc"
4853 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4854 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4855 (match_operand:GPR 2 "gpc_reg_operand" "")
4856 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4860 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4866 ;; We use the BASE_REGS for the isel input operands because, if rA is
4867 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4868 ;; because we may switch the operands and rB may end up being rA.
4870 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4871 ;; leave out the mode in operand 4 and use one pattern, but reload can
4872 ;; change the mode underneath our feet and then gets confused trying
4873 ;; to reload the value.
4874 (define_insn "isel_signed_<mode>"
4875 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4877 (match_operator 1 "scc_comparison_operator"
4878 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4880 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4881 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4884 { return output_isel (operands); }"
4885 [(set_attr "type" "isel")
4886 (set_attr "length" "4")])
4888 (define_insn "isel_unsigned_<mode>"
4889 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4891 (match_operator 1 "scc_comparison_operator"
4892 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4894 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4895 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4898 { return output_isel (operands); }"
4899 [(set_attr "type" "isel")
4900 (set_attr "length" "4")])
4902 ;; These patterns can be useful for combine; they let combine know that
4903 ;; isel can handle reversed comparisons so long as the operands are
4906 (define_insn "*isel_reversed_signed_<mode>"
4907 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4909 (match_operator 1 "scc_rev_comparison_operator"
4910 [(match_operand:CC 4 "cc_reg_operand" "y")
4912 (match_operand:GPR 2 "gpc_reg_operand" "b")
4913 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4916 { return output_isel (operands); }"
4917 [(set_attr "type" "isel")
4918 (set_attr "length" "4")])
4920 (define_insn "*isel_reversed_unsigned_<mode>"
4921 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4923 (match_operator 1 "scc_rev_comparison_operator"
4924 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4926 (match_operand:GPR 2 "gpc_reg_operand" "b")
4927 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4930 { return output_isel (operands); }"
4931 [(set_attr "type" "isel")
4932 (set_attr "length" "4")])
4934 ;; Floating point conditional move
4935 (define_expand "mov<mode>cc"
4936 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4937 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4938 (match_operand:SFDF 2 "gpc_reg_operand" "")
4939 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4940 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4943 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4949 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
4950 [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>")
4952 (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>")
4953 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
4954 (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>")
4955 (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))]
4956 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
4958 [(set_attr "type" "fp")])
4960 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
4961 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4963 (match_operator:CCFP 1 "fpmask_comparison_operator"
4964 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4965 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4966 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4967 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
4968 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
4973 (if_then_else:V2DI (match_dup 1)
4977 (if_then_else:SFDF (ne (match_dup 6)
4982 if (GET_CODE (operands[6]) == SCRATCH)
4983 operands[6] = gen_reg_rtx (V2DImode);
4985 operands[7] = CONSTM1_RTX (V2DImode);
4986 operands[8] = CONST0_RTX (V2DImode);
4988 [(set_attr "length" "8")
4989 (set_attr "type" "vecperm")])
4991 ;; Handle inverting the fpmask comparisons.
4992 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
4993 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
4995 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
4996 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
4997 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
4998 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
4999 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5000 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5005 (if_then_else:V2DI (match_dup 9)
5009 (if_then_else:SFDF (ne (match_dup 6)
5014 rtx op1 = operands[1];
5015 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5017 if (GET_CODE (operands[6]) == SCRATCH)
5018 operands[6] = gen_reg_rtx (V2DImode);
5020 operands[7] = CONSTM1_RTX (V2DImode);
5021 operands[8] = CONST0_RTX (V2DImode);
5023 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5025 [(set_attr "length" "8")
5026 (set_attr "type" "vecperm")])
5028 (define_insn "*fpmask<mode>"
5029 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5031 (match_operator:CCFP 1 "fpmask_comparison_operator"
5032 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5033 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5034 (match_operand:V2DI 4 "all_ones_constant" "")
5035 (match_operand:V2DI 5 "zero_constant" "")))]
5037 "xscmp%V1dp %x0,%x2,%x3"
5038 [(set_attr "type" "fpcompare")])
5040 (define_insn "*xxsel<mode>"
5041 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5042 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5043 (match_operand:V2DI 2 "zero_constant" ""))
5044 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5045 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5047 "xxsel %x0,%x4,%x3,%x1"
5048 [(set_attr "type" "vecmove")])
5051 ;; Conversions to and from floating-point.
5053 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5054 ; don't want to support putting SImode in FPR registers.
5055 (define_insn "lfiwax"
5056 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5057 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5059 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5065 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5067 ; This split must be run before register allocation because it allocates the
5068 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5069 ; it earlier to allow for the combiner to merge insns together where it might
5070 ; not be needed and also in case the insns are deleted as dead code.
5072 (define_insn_and_split "floatsi<mode>2_lfiwax"
5073 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5074 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5075 (clobber (match_scratch:DI 2 "=wi"))]
5076 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5077 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5083 rtx dest = operands[0];
5084 rtx src = operands[1];
5087 if (!MEM_P (src) && TARGET_POWERPC64
5088 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5089 tmp = convert_to_mode (DImode, src, false);
5093 if (GET_CODE (tmp) == SCRATCH)
5094 tmp = gen_reg_rtx (DImode);
5097 src = rs6000_address_for_fpconvert (src);
5098 emit_insn (gen_lfiwax (tmp, src));
5102 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5103 emit_move_insn (stack, src);
5104 emit_insn (gen_lfiwax (tmp, stack));
5107 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5110 [(set_attr "length" "12")
5111 (set_attr "type" "fpload")])
5113 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5114 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5117 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5118 (clobber (match_scratch:DI 2 "=wi"))]
5119 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5126 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5127 if (GET_CODE (operands[2]) == SCRATCH)
5128 operands[2] = gen_reg_rtx (DImode);
5129 if (TARGET_VSX_SMALL_INTEGER)
5130 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5132 emit_insn (gen_lfiwax (operands[2], operands[1]));
5133 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5136 [(set_attr "length" "8")
5137 (set_attr "type" "fpload")])
5139 (define_insn "lfiwzx"
5140 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5141 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5143 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5148 xxextractuw %x0,%x1,4"
5149 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5151 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5152 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5153 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5154 (clobber (match_scratch:DI 2 "=wi"))]
5155 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5162 rtx dest = operands[0];
5163 rtx src = operands[1];
5166 if (!MEM_P (src) && TARGET_POWERPC64
5167 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5168 tmp = convert_to_mode (DImode, src, true);
5172 if (GET_CODE (tmp) == SCRATCH)
5173 tmp = gen_reg_rtx (DImode);
5176 src = rs6000_address_for_fpconvert (src);
5177 emit_insn (gen_lfiwzx (tmp, src));
5181 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5182 emit_move_insn (stack, src);
5183 emit_insn (gen_lfiwzx (tmp, stack));
5186 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5189 [(set_attr "length" "12")
5190 (set_attr "type" "fpload")])
5192 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5193 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5194 (unsigned_float:SFDF
5196 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5197 (clobber (match_scratch:DI 2 "=wi"))]
5198 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5205 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5206 if (GET_CODE (operands[2]) == SCRATCH)
5207 operands[2] = gen_reg_rtx (DImode);
5208 if (TARGET_VSX_SMALL_INTEGER)
5209 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5211 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5212 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5215 [(set_attr "length" "8")
5216 (set_attr "type" "fpload")])
5218 ; For each of these conversions, there is a define_expand, a define_insn
5219 ; with a '#' template, and a define_split (with C code). The idea is
5220 ; to allow constant folding with the template of the define_insn,
5221 ; then to have the insns split later (between sched1 and final).
5223 (define_expand "floatsidf2"
5224 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5225 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5228 (clobber (match_dup 4))
5229 (clobber (match_dup 5))
5230 (clobber (match_dup 6))])]
5232 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5235 if (TARGET_E500_DOUBLE)
5237 if (!REG_P (operands[1]))
5238 operands[1] = force_reg (SImode, operands[1]);
5239 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5242 else if (TARGET_LFIWAX && TARGET_FCFID)
5244 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5247 else if (TARGET_FCFID)
5249 rtx dreg = operands[1];
5251 dreg = force_reg (SImode, dreg);
5252 dreg = convert_to_mode (DImode, dreg, false);
5253 emit_insn (gen_floatdidf2 (operands[0], dreg));
5257 if (!REG_P (operands[1]))
5258 operands[1] = force_reg (SImode, operands[1]);
5259 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5260 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5261 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5262 operands[5] = gen_reg_rtx (DFmode);
5263 operands[6] = gen_reg_rtx (SImode);
5266 (define_insn_and_split "*floatsidf2_internal"
5267 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5268 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5269 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5270 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5271 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5272 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5273 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5274 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5280 rtx lowword, highword;
5281 gcc_assert (MEM_P (operands[4]));
5282 highword = adjust_address (operands[4], SImode, 0);
5283 lowword = adjust_address (operands[4], SImode, 4);
5284 if (! WORDS_BIG_ENDIAN)
5285 std::swap (lowword, highword);
5287 emit_insn (gen_xorsi3 (operands[6], operands[1],
5288 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5289 emit_move_insn (lowword, operands[6]);
5290 emit_move_insn (highword, operands[2]);
5291 emit_move_insn (operands[5], operands[4]);
5292 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5295 [(set_attr "length" "24")
5296 (set_attr "type" "fp")])
5298 ;; If we don't have a direct conversion to single precision, don't enable this
5299 ;; conversion for 32-bit without fast math, because we don't have the insn to
5300 ;; generate the fixup swizzle to avoid double rounding problems.
5301 (define_expand "floatunssisf2"
5302 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5303 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5304 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5307 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5308 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5309 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5314 if (!REG_P (operands[1]))
5315 operands[1] = force_reg (SImode, operands[1]);
5317 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5319 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5324 rtx dreg = operands[1];
5326 dreg = force_reg (SImode, dreg);
5327 dreg = convert_to_mode (DImode, dreg, true);
5328 emit_insn (gen_floatdisf2 (operands[0], dreg));
5333 (define_expand "floatunssidf2"
5334 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5335 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5338 (clobber (match_dup 4))
5339 (clobber (match_dup 5))])]
5341 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5344 if (TARGET_E500_DOUBLE)
5346 if (!REG_P (operands[1]))
5347 operands[1] = force_reg (SImode, operands[1]);
5348 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5351 else if (TARGET_LFIWZX && TARGET_FCFID)
5353 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5356 else if (TARGET_FCFID)
5358 rtx dreg = operands[1];
5360 dreg = force_reg (SImode, dreg);
5361 dreg = convert_to_mode (DImode, dreg, true);
5362 emit_insn (gen_floatdidf2 (operands[0], dreg));
5366 if (!REG_P (operands[1]))
5367 operands[1] = force_reg (SImode, operands[1]);
5368 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5369 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5370 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5371 operands[5] = gen_reg_rtx (DFmode);
5374 (define_insn_and_split "*floatunssidf2_internal"
5375 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5376 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5377 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5378 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5379 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5380 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5381 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5382 && !(TARGET_FCFID && TARGET_POWERPC64)"
5388 rtx lowword, highword;
5389 gcc_assert (MEM_P (operands[4]));
5390 highword = adjust_address (operands[4], SImode, 0);
5391 lowword = adjust_address (operands[4], SImode, 4);
5392 if (! WORDS_BIG_ENDIAN)
5393 std::swap (lowword, highword);
5395 emit_move_insn (lowword, operands[1]);
5396 emit_move_insn (highword, operands[2]);
5397 emit_move_insn (operands[5], operands[4]);
5398 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5401 [(set_attr "length" "20")
5402 (set_attr "type" "fp")])
5404 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5405 ;; vector registers. These insns favor doing the sign/zero extension in
5406 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5407 ;; extension and then a direct move.
5409 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5410 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5412 (match_operand:QHI 1 "input_operand")))
5413 (clobber (match_scratch:DI 2))
5414 (clobber (match_scratch:DI 3))
5415 (clobber (match_scratch:<QHI:MODE> 4))])]
5416 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5417 && TARGET_VSX_SMALL_INTEGER"
5419 if (MEM_P (operands[1]))
5420 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5423 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5424 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5426 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5427 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5428 (clobber (match_scratch:DI 3 "=X,r,X"))
5429 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5430 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5431 && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5433 "&& reload_completed"
5436 rtx result = operands[0];
5437 rtx input = operands[1];
5438 rtx di = operands[2];
5442 rtx tmp = operands[3];
5443 if (altivec_register_operand (input, <QHI:MODE>mode))
5444 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5445 else if (GET_CODE (tmp) == SCRATCH)
5446 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5449 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5450 emit_move_insn (di, tmp);
5455 rtx tmp = operands[4];
5456 emit_move_insn (tmp, input);
5457 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5460 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5464 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5465 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5466 (unsigned_float:FP_ISA3
5467 (match_operand:QHI 1 "input_operand" "")))
5468 (clobber (match_scratch:DI 2 ""))
5469 (clobber (match_scratch:DI 3 ""))])]
5470 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5471 && TARGET_VSX_SMALL_INTEGER"
5473 if (MEM_P (operands[1]))
5474 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5477 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5478 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5479 (unsigned_float:FP_ISA3
5480 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5481 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5482 (clobber (match_scratch:DI 3 "=X,r,X"))]
5483 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5484 && TARGET_VSX_SMALL_INTEGER"
5486 "&& reload_completed"
5489 rtx result = operands[0];
5490 rtx input = operands[1];
5491 rtx di = operands[2];
5493 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5494 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5497 rtx tmp = operands[3];
5498 if (GET_CODE (tmp) == SCRATCH)
5499 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5502 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5503 emit_move_insn (di, tmp);
5507 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5511 (define_expand "fix_trunc<mode>si2"
5512 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5513 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5514 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5517 if (!<E500_CONVERT>)
5519 rtx src = force_reg (<MODE>mode, operands[1]);
5522 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5525 rtx tmp = gen_reg_rtx (DImode);
5526 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5527 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5534 ; Like the convert to float patterns, this insn must be split before
5535 ; register allocation so that it can allocate the memory slot if it
5537 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5538 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5539 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5540 (clobber (match_scratch:DI 2 "=d"))]
5541 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5542 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5543 && TARGET_STFIWX && can_create_pseudo_p ()"
5548 rtx dest = operands[0];
5549 rtx src = operands[1];
5550 rtx tmp = operands[2];
5552 if (GET_CODE (tmp) == SCRATCH)
5553 tmp = gen_reg_rtx (DImode);
5555 emit_insn (gen_fctiwz_<mode> (tmp, src));
5558 dest = rs6000_address_for_fpconvert (dest);
5559 emit_insn (gen_stfiwx (dest, tmp));
5562 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5564 dest = gen_lowpart (DImode, dest);
5565 emit_move_insn (dest, tmp);
5570 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5571 emit_insn (gen_stfiwx (stack, tmp));
5572 emit_move_insn (dest, stack);
5576 [(set_attr "length" "12")
5577 (set_attr "type" "fp")])
5579 (define_insn_and_split "fix_trunc<mode>si2_internal"
5580 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5581 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5582 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5583 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5584 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5591 gcc_assert (MEM_P (operands[3]));
5592 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5594 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5595 emit_move_insn (operands[3], operands[2]);
5596 emit_move_insn (operands[0], lowword);
5599 [(set_attr "length" "16")
5600 (set_attr "type" "fp")])
5602 (define_expand "fix_trunc<mode>di2"
5603 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5604 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5605 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5609 (define_insn "*fix_trunc<mode>di2_fctidz"
5610 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5611 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5612 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5617 [(set_attr "type" "fp")])
5619 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5620 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5621 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5622 (clobber (match_scratch:DI 2))])]
5623 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5624 && TARGET_VSX_SMALL_INTEGER"
5626 if (MEM_P (operands[0]))
5627 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5630 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5631 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5633 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5634 (clobber (match_scratch:DI 2 "=X,wi"))]
5635 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5636 && TARGET_VSX_SMALL_INTEGER"
5638 "&& reload_completed"
5641 rtx dest = operands[0];
5642 rtx src = operands[1];
5644 if (vsx_register_operand (dest, <QHI:MODE>mode))
5646 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5647 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5651 rtx tmp = operands[2];
5652 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5654 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5655 emit_move_insn (dest, tmp2);
5660 (define_expand "fixuns_trunc<mode>si2"
5661 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5662 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5664 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5668 if (!<E500_CONVERT>)
5670 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5675 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5676 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5677 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5678 (clobber (match_scratch:DI 2 "=d"))]
5679 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5680 && TARGET_STFIWX && can_create_pseudo_p ()"
5685 rtx dest = operands[0];
5686 rtx src = operands[1];
5687 rtx tmp = operands[2];
5689 if (GET_CODE (tmp) == SCRATCH)
5690 tmp = gen_reg_rtx (DImode);
5692 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5695 dest = rs6000_address_for_fpconvert (dest);
5696 emit_insn (gen_stfiwx (dest, tmp));
5699 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5701 dest = gen_lowpart (DImode, dest);
5702 emit_move_insn (dest, tmp);
5707 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5708 emit_insn (gen_stfiwx (stack, tmp));
5709 emit_move_insn (dest, stack);
5713 [(set_attr "length" "12")
5714 (set_attr "type" "fp")])
5716 (define_expand "fixuns_trunc<mode>di2"
5717 [(set (match_operand:DI 0 "register_operand" "")
5718 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5719 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5722 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5723 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5724 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5725 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5730 [(set_attr "type" "fp")])
5732 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5733 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5734 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5735 (clobber (match_scratch:DI 2))])]
5736 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5737 && TARGET_VSX_SMALL_INTEGER"
5739 if (MEM_P (operands[0]))
5740 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5743 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5744 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5746 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5747 (clobber (match_scratch:DI 2 "=X,wi"))]
5748 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5749 && TARGET_VSX_SMALL_INTEGER"
5751 "&& reload_completed"
5754 rtx dest = operands[0];
5755 rtx src = operands[1];
5757 if (vsx_register_operand (dest, <QHI:MODE>mode))
5759 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5760 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5764 rtx tmp = operands[2];
5765 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5767 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5768 emit_move_insn (dest, tmp2);
5772 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5773 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5774 ; because the first makes it clear that operand 0 is not live
5775 ; before the instruction.
5776 (define_insn "fctiwz_<mode>"
5777 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5778 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5780 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5784 [(set_attr "type" "fp")])
5786 (define_insn "fctiwuz_<mode>"
5787 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5788 (unspec:DI [(unsigned_fix:SI
5789 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5791 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5795 [(set_attr "type" "fp")])
5797 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5798 ;; since the friz instruction does not truncate the value if the floating
5799 ;; point value is < LONG_MIN or > LONG_MAX.
5800 (define_insn "*friz"
5801 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5802 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5803 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5804 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5808 [(set_attr "type" "fp")])
5810 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5811 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5812 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5813 ;; extend it, store it back on the stack from the GPR, load it back into the
5814 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5815 ;; disable using store and load to sign/zero extend the value.
5816 (define_insn_and_split "*round32<mode>2_fprs"
5817 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5819 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5820 (clobber (match_scratch:DI 2 "=d"))
5821 (clobber (match_scratch:DI 3 "=d"))]
5822 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5823 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5824 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5829 rtx dest = operands[0];
5830 rtx src = operands[1];
5831 rtx tmp1 = operands[2];
5832 rtx tmp2 = operands[3];
5833 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5835 if (GET_CODE (tmp1) == SCRATCH)
5836 tmp1 = gen_reg_rtx (DImode);
5837 if (GET_CODE (tmp2) == SCRATCH)
5838 tmp2 = gen_reg_rtx (DImode);
5840 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5841 emit_insn (gen_stfiwx (stack, tmp1));
5842 emit_insn (gen_lfiwax (tmp2, stack));
5843 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5846 [(set_attr "type" "fpload")
5847 (set_attr "length" "16")])
5849 (define_insn_and_split "*roundu32<mode>2_fprs"
5850 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5851 (unsigned_float:SFDF
5852 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5853 (clobber (match_scratch:DI 2 "=d"))
5854 (clobber (match_scratch:DI 3 "=d"))]
5855 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5856 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5857 && can_create_pseudo_p ()"
5862 rtx dest = operands[0];
5863 rtx src = operands[1];
5864 rtx tmp1 = operands[2];
5865 rtx tmp2 = operands[3];
5866 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5868 if (GET_CODE (tmp1) == SCRATCH)
5869 tmp1 = gen_reg_rtx (DImode);
5870 if (GET_CODE (tmp2) == SCRATCH)
5871 tmp2 = gen_reg_rtx (DImode);
5873 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5874 emit_insn (gen_stfiwx (stack, tmp1));
5875 emit_insn (gen_lfiwzx (tmp2, stack));
5876 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5879 [(set_attr "type" "fpload")
5880 (set_attr "length" "16")])
5882 ;; No VSX equivalent to fctid
5883 (define_insn "lrint<mode>di2"
5884 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5885 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5887 "TARGET_<MODE>_FPR && TARGET_FPRND"
5889 [(set_attr "type" "fp")])
5891 (define_insn "btrunc<mode>2"
5892 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5893 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5895 "TARGET_<MODE>_FPR && TARGET_FPRND"
5899 [(set_attr "type" "fp")
5900 (set_attr "fp_type" "fp_addsub_<Fs>")])
5902 (define_insn "ceil<mode>2"
5903 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5904 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5906 "TARGET_<MODE>_FPR && TARGET_FPRND"
5910 [(set_attr "type" "fp")
5911 (set_attr "fp_type" "fp_addsub_<Fs>")])
5913 (define_insn "floor<mode>2"
5914 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5915 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5917 "TARGET_<MODE>_FPR && TARGET_FPRND"
5921 [(set_attr "type" "fp")
5922 (set_attr "fp_type" "fp_addsub_<Fs>")])
5924 ;; No VSX equivalent to frin
5925 (define_insn "round<mode>2"
5926 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5927 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5929 "TARGET_<MODE>_FPR && TARGET_FPRND"
5931 [(set_attr "type" "fp")
5932 (set_attr "fp_type" "fp_addsub_<Fs>")])
5934 (define_insn "*xsrdpi<mode>2"
5935 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5936 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5938 "TARGET_<MODE>_FPR && TARGET_VSX"
5940 [(set_attr "type" "fp")
5941 (set_attr "fp_type" "fp_addsub_<Fs>")])
5943 (define_expand "lround<mode>di2"
5945 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5947 (set (match_operand:DI 0 "gpc_reg_operand" "")
5948 (unspec:DI [(match_dup 2)]
5950 "TARGET_<MODE>_FPR && TARGET_VSX"
5952 operands[2] = gen_reg_rtx (<MODE>mode);
5955 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5956 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5957 ; is only generated for Power8 or later.
5958 (define_insn "stfiwx"
5959 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5960 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5966 [(set_attr "type" "fpstore")])
5968 ;; If we don't have a direct conversion to single precision, don't enable this
5969 ;; conversion for 32-bit without fast math, because we don't have the insn to
5970 ;; generate the fixup swizzle to avoid double rounding problems.
5971 (define_expand "floatsisf2"
5972 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5973 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5974 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5977 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5978 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5979 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5984 if (!REG_P (operands[1]))
5985 operands[1] = force_reg (SImode, operands[1]);
5987 else if (TARGET_FCFIDS && TARGET_LFIWAX)
5989 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5992 else if (TARGET_FCFID && TARGET_LFIWAX)
5994 rtx dfreg = gen_reg_rtx (DFmode);
5995 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5996 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6001 rtx dreg = operands[1];
6003 dreg = force_reg (SImode, dreg);
6004 dreg = convert_to_mode (DImode, dreg, false);
6005 emit_insn (gen_floatdisf2 (operands[0], dreg));
6010 (define_expand "floatdidf2"
6011 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6012 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6013 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6016 (define_insn "*floatdidf2_fpr"
6017 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6018 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6019 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6023 [(set_attr "type" "fp")])
6025 ; Allow the combiner to merge source memory operands to the conversion so that
6026 ; the optimizer/register allocator doesn't try to load the value too early in a
6027 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6028 ; hit. We will split after reload to avoid the trip through the GPRs
6030 (define_insn_and_split "*floatdidf2_mem"
6031 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6032 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6033 (clobber (match_scratch:DI 2 "=d,wi"))]
6034 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6036 "&& reload_completed"
6037 [(set (match_dup 2) (match_dup 1))
6038 (set (match_dup 0) (float:DF (match_dup 2)))]
6040 [(set_attr "length" "8")
6041 (set_attr "type" "fpload")])
6043 (define_expand "floatunsdidf2"
6044 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6046 (match_operand:DI 1 "gpc_reg_operand" "")))]
6047 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6050 (define_insn "*floatunsdidf2_fcfidu"
6051 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6052 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6053 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6057 [(set_attr "type" "fp")
6058 (set_attr "length" "4")])
6060 (define_insn_and_split "*floatunsdidf2_mem"
6061 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6062 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6063 (clobber (match_scratch:DI 2 "=d,wi"))]
6064 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6066 "&& reload_completed"
6067 [(set (match_dup 2) (match_dup 1))
6068 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6070 [(set_attr "length" "8")
6071 (set_attr "type" "fpload")])
6073 (define_expand "floatdisf2"
6074 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6075 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6076 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6077 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6082 rtx val = operands[1];
6083 if (!flag_unsafe_math_optimizations)
6085 rtx label = gen_label_rtx ();
6086 val = gen_reg_rtx (DImode);
6087 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6090 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6095 (define_insn "floatdisf2_fcfids"
6096 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6097 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6098 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6099 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6103 [(set_attr "type" "fp")])
6105 (define_insn_and_split "*floatdisf2_mem"
6106 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6107 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6108 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6109 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6110 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6112 "&& reload_completed"
6116 emit_move_insn (operands[2], operands[1]);
6117 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6120 [(set_attr "length" "8")])
6122 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6123 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6124 ;; from double rounding.
6125 ;; Instead of creating a new cpu type for two FP operations, just use fp
6126 (define_insn_and_split "floatdisf2_internal1"
6127 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6128 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6129 (clobber (match_scratch:DF 2 "=d"))]
6130 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6133 "&& reload_completed"
6135 (float:DF (match_dup 1)))
6137 (float_truncate:SF (match_dup 2)))]
6139 [(set_attr "length" "8")
6140 (set_attr "type" "fp")])
6142 ;; Twiddles bits to avoid double rounding.
6143 ;; Bits that might be truncated when converting to DFmode are replaced
6144 ;; by a bit that won't be lost at that stage, but is below the SFmode
6145 ;; rounding position.
6146 (define_expand "floatdisf2_internal2"
6147 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6149 (clobber (reg:DI CA_REGNO))])
6150 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6152 (set (match_dup 3) (plus:DI (match_dup 3)
6154 (set (match_dup 0) (plus:DI (match_dup 0)
6156 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6158 (set (match_dup 0) (ior:DI (match_dup 0)
6160 (set (match_dup 0) (and:DI (match_dup 0)
6162 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6163 (label_ref (match_operand:DI 2 "" ""))
6165 (set (match_dup 0) (match_dup 1))]
6166 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6170 operands[3] = gen_reg_rtx (DImode);
6171 operands[4] = gen_reg_rtx (CCUNSmode);
6174 (define_expand "floatunsdisf2"
6175 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6176 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6177 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6178 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6181 (define_insn "floatunsdisf2_fcfidus"
6182 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6183 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6184 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6185 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6189 [(set_attr "type" "fp")])
6191 (define_insn_and_split "*floatunsdisf2_mem"
6192 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6193 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6194 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6195 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6196 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6198 "&& reload_completed"
6202 emit_move_insn (operands[2], operands[1]);
6203 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6206 [(set_attr "length" "8")
6207 (set_attr "type" "fpload")])
6209 ;; Define the TImode operations that can be done in a small number
6210 ;; of instructions. The & constraints are to prevent the register
6211 ;; allocator from allocating registers that overlap with the inputs
6212 ;; (for example, having an input in 7,8 and an output in 6,7). We
6213 ;; also allow for the output being the same as one of the inputs.
6215 (define_expand "addti3"
6216 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6217 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6218 (match_operand:TI 2 "reg_or_short_operand" "")))]
6221 rtx lo0 = gen_lowpart (DImode, operands[0]);
6222 rtx lo1 = gen_lowpart (DImode, operands[1]);
6223 rtx lo2 = gen_lowpart (DImode, operands[2]);
6224 rtx hi0 = gen_highpart (DImode, operands[0]);
6225 rtx hi1 = gen_highpart (DImode, operands[1]);
6226 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6228 if (!reg_or_short_operand (lo2, DImode))
6229 lo2 = force_reg (DImode, lo2);
6230 if (!adde_operand (hi2, DImode))
6231 hi2 = force_reg (DImode, hi2);
6233 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6234 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6238 (define_expand "subti3"
6239 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6240 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6241 (match_operand:TI 2 "gpc_reg_operand" "")))]
6244 rtx lo0 = gen_lowpart (DImode, operands[0]);
6245 rtx lo1 = gen_lowpart (DImode, operands[1]);
6246 rtx lo2 = gen_lowpart (DImode, operands[2]);
6247 rtx hi0 = gen_highpart (DImode, operands[0]);
6248 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6249 rtx hi2 = gen_highpart (DImode, operands[2]);
6251 if (!reg_or_short_operand (lo1, DImode))
6252 lo1 = force_reg (DImode, lo1);
6253 if (!adde_operand (hi1, DImode))
6254 hi1 = force_reg (DImode, hi1);
6256 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6257 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6261 ;; 128-bit logical operations expanders
6263 (define_expand "and<mode>3"
6264 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6265 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6266 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6270 (define_expand "ior<mode>3"
6271 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6272 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6273 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6277 (define_expand "xor<mode>3"
6278 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6279 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6280 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6284 (define_expand "one_cmpl<mode>2"
6285 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6286 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6290 (define_expand "nor<mode>3"
6291 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6293 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6294 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6298 (define_expand "andc<mode>3"
6299 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6301 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6302 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6306 ;; Power8 vector logical instructions.
6307 (define_expand "eqv<mode>3"
6308 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6310 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6311 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6312 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6315 ;; Rewrite nand into canonical form
6316 (define_expand "nand<mode>3"
6317 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6319 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6320 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6321 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6324 ;; The canonical form is to have the negated element first, so we need to
6325 ;; reverse arguments.
6326 (define_expand "orc<mode>3"
6327 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6329 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6330 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6331 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6334 ;; 128-bit logical operations insns and split operations
6335 (define_insn_and_split "*and<mode>3_internal"
6336 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6338 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6339 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6342 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6343 return "xxland %x0,%x1,%x2";
6345 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6346 return "vand %0,%1,%2";
6350 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6353 rs6000_split_logical (operands, AND, false, false, false);
6358 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6359 (const_string "veclogical")
6360 (const_string "integer")))
6361 (set (attr "length")
6363 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6366 (match_test "TARGET_POWERPC64")
6368 (const_string "16"))))])
6371 (define_insn_and_split "*bool<mode>3_internal"
6372 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6373 (match_operator:BOOL_128 3 "boolean_or_operator"
6374 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6375 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6378 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6379 return "xxl%q3 %x0,%x1,%x2";
6381 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6382 return "v%q3 %0,%1,%2";
6386 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6389 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6394 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6395 (const_string "veclogical")
6396 (const_string "integer")))
6397 (set (attr "length")
6399 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6402 (match_test "TARGET_POWERPC64")
6404 (const_string "16"))))])
6407 (define_insn_and_split "*boolc<mode>3_internal1"
6408 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6409 (match_operator:BOOL_128 3 "boolean_operator"
6411 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6412 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6413 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6415 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6416 return "xxl%q3 %x0,%x1,%x2";
6418 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6419 return "v%q3 %0,%1,%2";
6423 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6424 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6427 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6432 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6433 (const_string "veclogical")
6434 (const_string "integer")))
6435 (set (attr "length")
6437 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6440 (match_test "TARGET_POWERPC64")
6442 (const_string "16"))))])
6444 (define_insn_and_split "*boolc<mode>3_internal2"
6445 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6446 (match_operator:TI2 3 "boolean_operator"
6448 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6449 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6450 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6452 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6455 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6458 [(set_attr "type" "integer")
6459 (set (attr "length")
6461 (match_test "TARGET_POWERPC64")
6463 (const_string "16")))])
6466 (define_insn_and_split "*boolcc<mode>3_internal1"
6467 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6468 (match_operator:BOOL_128 3 "boolean_operator"
6470 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6472 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6473 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6475 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6476 return "xxl%q3 %x0,%x1,%x2";
6478 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6479 return "v%q3 %0,%1,%2";
6483 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6484 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6487 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6492 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6493 (const_string "veclogical")
6494 (const_string "integer")))
6495 (set (attr "length")
6497 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6500 (match_test "TARGET_POWERPC64")
6502 (const_string "16"))))])
6504 (define_insn_and_split "*boolcc<mode>3_internal2"
6505 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6506 (match_operator:TI2 3 "boolean_operator"
6508 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6510 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6511 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6513 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6516 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6519 [(set_attr "type" "integer")
6520 (set (attr "length")
6522 (match_test "TARGET_POWERPC64")
6524 (const_string "16")))])
6528 (define_insn_and_split "*eqv<mode>3_internal1"
6529 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6532 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6533 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6536 if (vsx_register_operand (operands[0], <MODE>mode))
6537 return "xxleqv %x0,%x1,%x2";
6541 "TARGET_P8_VECTOR && reload_completed
6542 && int_reg_operand (operands[0], <MODE>mode)"
6545 rs6000_split_logical (operands, XOR, true, false, false);
6550 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6551 (const_string "veclogical")
6552 (const_string "integer")))
6553 (set (attr "length")
6555 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6558 (match_test "TARGET_POWERPC64")
6560 (const_string "16"))))])
6562 (define_insn_and_split "*eqv<mode>3_internal2"
6563 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6566 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6567 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6570 "reload_completed && !TARGET_P8_VECTOR"
6573 rs6000_split_logical (operands, XOR, true, false, false);
6576 [(set_attr "type" "integer")
6577 (set (attr "length")
6579 (match_test "TARGET_POWERPC64")
6581 (const_string "16")))])
6583 ;; 128-bit one's complement
6584 (define_insn_and_split "*one_cmpl<mode>3_internal"
6585 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6587 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6590 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6591 return "xxlnor %x0,%x1,%x1";
6593 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6594 return "vnor %0,%1,%1";
6598 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6601 rs6000_split_logical (operands, NOT, false, false, false);
6606 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6607 (const_string "veclogical")
6608 (const_string "integer")))
6609 (set (attr "length")
6611 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6614 (match_test "TARGET_POWERPC64")
6616 (const_string "16"))))])
6619 ;; Now define ways of moving data around.
6621 ;; Set up a register with a value from the GOT table
6623 (define_expand "movsi_got"
6624 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6625 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6626 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6627 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6630 if (GET_CODE (operands[1]) == CONST)
6632 rtx offset = const0_rtx;
6633 HOST_WIDE_INT value;
6635 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6636 value = INTVAL (offset);
6639 rtx tmp = (!can_create_pseudo_p ()
6641 : gen_reg_rtx (Pmode));
6642 emit_insn (gen_movsi_got (tmp, operands[1]));
6643 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6648 operands[2] = rs6000_got_register (operands[1]);
6651 (define_insn "*movsi_got_internal"
6652 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6653 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6654 (match_operand:SI 2 "gpc_reg_operand" "b")]
6656 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6657 "lwz %0,%a1@got(%2)"
6658 [(set_attr "type" "load")])
6660 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6661 ;; didn't get allocated to a hard register.
6663 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6664 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6665 (match_operand:SI 2 "memory_operand" "")]
6667 "DEFAULT_ABI == ABI_V4
6669 && (reload_in_progress || reload_completed)"
6670 [(set (match_dup 0) (match_dup 2))
6671 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6675 ;; For SI, we special-case integers that can't be loaded in one insn. We
6676 ;; do the load 16-bits at a time. We could do this by loading from memory,
6677 ;; and this is even supposed to be faster, but it is simpler not to get
6678 ;; integers in the TOC.
6679 (define_insn "movsi_low"
6680 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6681 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6682 (match_operand 2 "" ""))))]
6683 "TARGET_MACHO && ! TARGET_64BIT"
6684 "lwz %0,lo16(%2)(%1)"
6685 [(set_attr "type" "load")
6686 (set_attr "length" "4")])
6688 ;; MR LA LWZ LFIWZX LXSIWZX
6689 ;; STW STFIWX STXSIWX LI LIS
6690 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6691 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6692 ;; MF%1 MT%0 MT%0 NOP
6693 (define_insn "*movsi_internal1"
6694 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6695 "=r, r, r, ?*wI, ?*wH,
6697 r, ?*wIwH, ?*wJwK, ?*wK, ?*wJwK,
6698 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6701 (match_operand:SI 1 "input_operand"
6708 "!TARGET_SINGLE_FPU &&
6709 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6736 "*, *, load, fpload, fpload,
6737 store, fpstore, fpstore, *, *,
6738 *, veclogical, vecsimple, vecsimple, vecsimple,
6739 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6749 (define_insn "*movsi_internal1_single"
6750 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6751 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6752 "TARGET_SINGLE_FPU &&
6753 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6768 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6769 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6771 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6772 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6774 ;; Because SF values are actually stored as DF values within the vector
6775 ;; registers, we need to convert the value to the vector SF format when
6776 ;; we need to use the bits in a union or similar cases. We only need
6777 ;; to do this transformation when the value is a vector register. Loads,
6778 ;; stores, and transfers within GPRs are assumed to be safe.
6780 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6781 ;; no alternatives, because the call is created as part of secondary_reload,
6782 ;; and operand #2's register class is used to allocate the temporary register.
6783 ;; This function is called before reload, and it creates the temporary as
6786 ;; MR LWZ LFIWZX LXSIWZX STW
6787 ;; STFS STXSSP STXSSPX VSX->GPR MTVSRWZ
6790 (define_insn_and_split "movsi_from_sf"
6791 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6792 "=r, r, ?*wI, ?*wH, m,
6796 (unspec:SI [(match_operand:SF 1 "input_operand"
6802 (clobber (match_scratch:V4SF 2
6807 "TARGET_NO_SF_SUBREG
6808 && (register_operand (operands[0], SImode)
6809 || register_operand (operands[1], SFmode))"
6822 "&& reload_completed
6823 && register_operand (operands[0], SImode)
6824 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6827 rtx op0 = operands[0];
6828 rtx op1 = operands[1];
6829 rtx op2 = operands[2];
6830 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6832 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6834 if (int_reg_operand (op0, SImode))
6836 emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6837 emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6841 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6842 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6843 emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6849 "*, load, fpload, fpload, store,
6850 fpstore, fpstore, fpstore, mftgpr, mffgpr,
6858 ;; movsi_from_sf with zero extension
6860 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6863 (define_insn_and_split "*movdi_from_sf_zero_ext"
6864 [(set (match_operand:DI 0 "gpc_reg_operand"
6865 "=r, r, ?*wI, ?*wH, r,
6869 (unspec:SI [(match_operand:SF 1 "input_operand"
6872 UNSPEC_SI_FROM_SF)))
6874 (clobber (match_scratch:V4SF 2
6878 "TARGET_DIRECT_MOVE_64BIT
6879 && (register_operand (operands[0], DImode)
6880 || register_operand (operands[1], SImode))"
6889 "&& reload_completed
6890 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6893 rtx op0 = operands[0];
6894 rtx op1 = operands[1];
6895 rtx op2 = operands[2];
6897 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6899 if (int_reg_operand (op0, DImode))
6901 emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6902 emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6906 rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6907 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6908 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6909 emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
6915 "*, load, fpload, fpload, mftgpr,
6916 mffgpr, veclogical")
6922 ;; Split a load of a large constant into the appropriate two-insn
6926 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6927 (match_operand:SI 1 "const_int_operand" ""))]
6928 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6929 && (INTVAL (operands[1]) & 0xffff) != 0"
6933 (ior:SI (match_dup 0)
6937 if (rs6000_emit_set_const (operands[0], operands[1]))
6943 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6945 [(set (match_operand:DI 0 "altivec_register_operand")
6946 (match_operand:DI 1 "xxspltib_constant_split"))]
6947 "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
6950 rtx op0 = operands[0];
6951 rtx op1 = operands[1];
6952 int r = REGNO (op0);
6953 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6955 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6956 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6960 (define_insn "*mov<mode>_internal2"
6961 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6962 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6964 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6970 [(set_attr "type" "cmp,logical,cmp")
6971 (set_attr "dot" "yes")
6972 (set_attr "length" "4,4,8")])
6975 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6976 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6978 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6980 [(set (match_dup 0) (match_dup 1))
6982 (compare:CC (match_dup 0)
6986 (define_expand "mov<mode>"
6987 [(set (match_operand:INT 0 "general_operand" "")
6988 (match_operand:INT 1 "any_operand" ""))]
6990 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6992 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
6993 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
6994 ;; MTVSRWZ MF%1 MT%1 NOP
6995 (define_insn "*mov<mode>_internal"
6996 [(set (match_operand:QHI 0 "nonimmediate_operand"
6997 "=r, r, ?*wJwK, m, Z, r,
6998 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
6999 ?*wJwK, r, *c*l, *h")
7001 (match_operand:QHI 1 "input_operand"
7002 "r, m, Z, r, wJwK, i,
7003 wJwK, O, wM, wB, wS, ?*wJwK,
7006 "gpc_reg_operand (operands[0], <MODE>mode)
7007 || gpc_reg_operand (operands[1], <MODE>mode)"
7026 "*, load, fpload, store, fpstore, *,
7027 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7028 mffgpr, mfjmpr, mtjmpr, *")
7036 ;; Here is how to move condition codes around. When we store CC data in
7037 ;; an integer register or memory, we store just the high-order 4 bits.
7038 ;; This lets us not shift in the most common case of CR0.
7039 (define_expand "movcc"
7040 [(set (match_operand:CC 0 "nonimmediate_operand" "")
7041 (match_operand:CC 1 "nonimmediate_operand" ""))]
7045 (define_insn "*movcc_internal1"
7046 [(set (match_operand:CC 0 "nonimmediate_operand"
7047 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7048 (match_operand:CC 1 "general_operand"
7049 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7050 "register_operand (operands[0], CCmode)
7051 || register_operand (operands[1], CCmode)"
7055 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7058 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7066 (cond [(eq_attr "alternative" "0,3")
7067 (const_string "cr_logical")
7068 (eq_attr "alternative" "1,2")
7069 (const_string "mtcr")
7070 (eq_attr "alternative" "6,7")
7071 (const_string "integer")
7072 (eq_attr "alternative" "8")
7073 (const_string "mfjmpr")
7074 (eq_attr "alternative" "9")
7075 (const_string "mtjmpr")
7076 (eq_attr "alternative" "10")
7077 (const_string "load")
7078 (eq_attr "alternative" "11")
7079 (const_string "store")
7080 (match_test "TARGET_MFCRF")
7081 (const_string "mfcrf")
7083 (const_string "mfcr")))
7084 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7086 ;; For floating-point, we normally deal with the floating-point registers
7087 ;; unless -msoft-float is used. The sole exception is that parameter passing
7088 ;; can produce floating-point values in fixed-point registers. Unless the
7089 ;; value is a simple constant or already in memory, we deal with this by
7090 ;; allocating memory and copying the value explicitly via that memory location.
7092 ;; Move 32-bit binary/decimal floating point
7093 (define_expand "mov<mode>"
7094 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7095 (match_operand:FMOVE32 1 "any_operand" ""))]
7097 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7100 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7101 (match_operand:FMOVE32 1 "const_double_operand" ""))]
7103 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7104 || (GET_CODE (operands[0]) == SUBREG
7105 && GET_CODE (SUBREG_REG (operands[0])) == REG
7106 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7107 [(set (match_dup 2) (match_dup 3))]
7112 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7114 if (! TARGET_POWERPC64)
7115 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7117 operands[2] = gen_lowpart (SImode, operands[0]);
7119 operands[3] = gen_int_mode (l, SImode);
7122 (define_insn "mov<mode>_hardfloat"
7123 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7124 "=!r, <f32_lr>, <f32_lr2>, <f32_av>, m, <f32_sm>,
7125 <f32_sm2>, Z, <f32_vsx>, !r, ?<f32_dm>, ?r,
7126 f, <f32_vsx>, !r, *c*l, !r, *h")
7127 (match_operand:FMOVE32 1 "input_operand"
7128 "m, <f32_lm>, <f32_lm2>, Z, r, <f32_sr>,
7129 <f32_sr2>, <f32_av>, <zero_fp>, <zero_fp>, r, <f32_dm>,
7130 f, <f32_vsx>, r, r, *h, 0"))]
7131 "(register_operand (operands[0], <MODE>mode)
7132 || register_operand (operands[1], <MODE>mode))
7133 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7134 && (TARGET_ALLOW_SF_SUBREG
7135 || valid_sf_si_move (operands[0], operands[1], <MODE>mode))"
7150 xscpsgndp %x0,%x1,%x1
7155 [(set_attr "type" "load,fpload,fpload,fpload,store,fpstore,fpstore,fpstore,veclogical,integer,mffgpr,mftgpr,fpsimple,fpsimple,*,mtjmpr,mfjmpr,*")])
7157 (define_insn "*mov<mode>_softfloat"
7158 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7159 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7160 "(gpc_reg_operand (operands[0], <MODE>mode)
7161 || gpc_reg_operand (operands[1], <MODE>mode))
7162 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7174 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7175 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7177 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7178 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7180 ;; Because SF values are actually stored as DF values within the vector
7181 ;; registers, we need to convert the value to the vector SF format when
7182 ;; we need to use the bits in a union or similar cases. We only need
7183 ;; to do this transformation when the value is a vector register. Loads,
7184 ;; stores, and transfers within GPRs are assumed to be safe.
7186 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7187 ;; no alternatives, because the call is created as part of secondary_reload,
7188 ;; and operand #2's register class is used to allocate the temporary register.
7189 ;; This function is called before reload, and it creates the temporary as
7192 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7193 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7194 (define_insn_and_split "movsf_from_si"
7195 [(set (match_operand:SF 0 "rs6000_nonimmediate_operand"
7196 "=!r, f, wb, wu, m, Z,
7199 (unspec:SF [(match_operand:SI 1 "input_operand"
7204 (clobber (match_scratch:DI 2
7208 "TARGET_NO_SF_SUBREG
7209 && (register_operand (operands[0], SFmode)
7210 || register_operand (operands[1], SImode))"
7223 "&& reload_completed
7224 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7225 && int_reg_operand_not_pseudo (operands[1], SImode)"
7228 rtx op0 = operands[0];
7229 rtx op1 = operands[1];
7230 rtx op2 = operands[2];
7231 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7233 /* Move SF value to upper 32-bits for xscvspdpn. */
7234 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7235 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7236 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7243 "load, fpload, fpload, fpload, store, fpstore,
7244 fpstore, vecfloat, mffgpr, *")])
7247 ;; Move 64-bit binary/decimal floating point
7248 (define_expand "mov<mode>"
7249 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7250 (match_operand:FMOVE64 1 "any_operand" ""))]
7252 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7255 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7256 (match_operand:FMOVE64 1 "const_int_operand" ""))]
7257 "! TARGET_POWERPC64 && reload_completed
7258 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7259 || (GET_CODE (operands[0]) == SUBREG
7260 && GET_CODE (SUBREG_REG (operands[0])) == REG
7261 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7262 [(set (match_dup 2) (match_dup 4))
7263 (set (match_dup 3) (match_dup 1))]
7266 int endian = (WORDS_BIG_ENDIAN == 0);
7267 HOST_WIDE_INT value = INTVAL (operands[1]);
7269 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7270 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7271 operands[4] = GEN_INT (value >> 32);
7272 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7276 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7277 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7278 "! TARGET_POWERPC64 && reload_completed
7279 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7280 || (GET_CODE (operands[0]) == SUBREG
7281 && GET_CODE (SUBREG_REG (operands[0])) == REG
7282 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7283 [(set (match_dup 2) (match_dup 4))
7284 (set (match_dup 3) (match_dup 5))]
7287 int endian = (WORDS_BIG_ENDIAN == 0);
7290 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7292 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7293 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7294 operands[4] = gen_int_mode (l[endian], SImode);
7295 operands[5] = gen_int_mode (l[1 - endian], SImode);
7299 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7300 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7301 "TARGET_POWERPC64 && reload_completed
7302 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7303 || (GET_CODE (operands[0]) == SUBREG
7304 && GET_CODE (SUBREG_REG (operands[0])) == REG
7305 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7306 [(set (match_dup 2) (match_dup 3))]
7309 int endian = (WORDS_BIG_ENDIAN == 0);
7313 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7315 operands[2] = gen_lowpart (DImode, operands[0]);
7316 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7317 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7318 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7320 operands[3] = gen_int_mode (val, DImode);
7323 ;; Don't have reload use general registers to load a constant. It is
7324 ;; less efficient than loading the constant into an FP register, since
7325 ;; it will probably be used there.
7327 ;; The move constraints are ordered to prefer floating point registers before
7328 ;; general purpose registers to avoid doing a store and a load to get the value
7329 ;; into a floating point register when it is needed for a floating point
7330 ;; operation. Prefer traditional floating point registers over VSX registers,
7331 ;; since the D-form version of the memory instructions does not need a GPR for
7332 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7335 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7336 ;; except for 0.0 which can be created on VSX with an xor instruction.
7338 (define_insn "*mov<mode>_hardfloat32"
7339 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7340 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7341 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7342 && (gpc_reg_operand (operands[0], <MODE>mode)
7343 || gpc_reg_operand (operands[1], <MODE>mode))"
7358 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7359 (set_attr "size" "64")
7360 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7362 (define_insn "*mov<mode>_softfloat32"
7363 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7364 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7366 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
7367 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7368 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7369 && (gpc_reg_operand (operands[0], <MODE>mode)
7370 || gpc_reg_operand (operands[1], <MODE>mode))"
7372 [(set_attr "type" "store,load,two,*,*,*")
7373 (set_attr "length" "8,8,8,8,12,16")])
7375 ; ld/std require word-aligned displacements -> 'Y' constraint.
7376 ; List Y->r and r->Y before r->r for reload.
7377 (define_insn "*mov<mode>_hardfloat64"
7378 [(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>")
7379 (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"))]
7380 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7381 && (gpc_reg_operand (operands[0], <MODE>mode)
7382 || gpc_reg_operand (operands[1], <MODE>mode))"
7404 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7405 (set_attr "size" "64")
7406 (set_attr "length" "4")])
7408 (define_insn "*mov<mode>_softfloat64"
7409 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7410 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7411 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7412 && (gpc_reg_operand (operands[0], <MODE>mode)
7413 || gpc_reg_operand (operands[1], <MODE>mode))"
7424 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7425 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7427 (define_expand "mov<mode>"
7428 [(set (match_operand:FMOVE128 0 "general_operand" "")
7429 (match_operand:FMOVE128 1 "any_operand" ""))]
7431 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7433 ;; It's important to list Y->r and r->Y before r->r because otherwise
7434 ;; reload, given m->r, will try to pick r->r and reload it, which
7435 ;; doesn't make progress.
7437 ;; We can't split little endian direct moves of TDmode, because the words are
7438 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7439 ;; problematical. Don't allow direct move for this case.
7441 (define_insn_and_split "*mov<mode>_64bit_dm"
7442 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7443 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7444 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7445 && FLOAT128_2REG_P (<MODE>mode)
7446 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7447 && (gpc_reg_operand (operands[0], <MODE>mode)
7448 || gpc_reg_operand (operands[1], <MODE>mode))"
7450 "&& reload_completed"
7452 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7453 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7455 (define_insn_and_split "*movtd_64bit_nodm"
7456 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7457 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7458 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7459 && (gpc_reg_operand (operands[0], TDmode)
7460 || gpc_reg_operand (operands[1], TDmode))"
7462 "&& reload_completed"
7464 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7465 [(set_attr "length" "8,8,8,12,12,8")])
7467 (define_insn_and_split "*mov<mode>_32bit"
7468 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7469 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7470 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7471 && (FLOAT128_2REG_P (<MODE>mode)
7472 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7473 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7474 && (gpc_reg_operand (operands[0], <MODE>mode)
7475 || gpc_reg_operand (operands[1], <MODE>mode))"
7477 "&& reload_completed"
7479 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7480 [(set_attr "length" "8,8,8,8,20,20,16")])
7482 (define_insn_and_split "*mov<mode>_softfloat"
7483 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7484 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7485 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7486 && (gpc_reg_operand (operands[0], <MODE>mode)
7487 || gpc_reg_operand (operands[1], <MODE>mode))"
7489 "&& reload_completed"
7491 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7492 [(set_attr "length" "20,20,16")])
7494 (define_expand "extenddf<mode>2"
7495 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7496 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7497 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7498 && TARGET_LONG_DOUBLE_128"
7500 if (FLOAT128_IEEE_P (<MODE>mode))
7501 rs6000_expand_float128_convert (operands[0], operands[1], false);
7502 else if (TARGET_E500_DOUBLE)
7504 gcc_assert (<MODE>mode == TFmode);
7505 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7507 else if (TARGET_VSX)
7509 if (<MODE>mode == TFmode)
7510 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7511 else if (<MODE>mode == IFmode)
7512 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7518 rtx zero = gen_reg_rtx (DFmode);
7519 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7521 if (<MODE>mode == TFmode)
7522 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7523 else if (<MODE>mode == IFmode)
7524 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7531 ;; Allow memory operands for the source to be created by the combiner.
7532 (define_insn_and_split "extenddf<mode>2_fprs"
7533 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7534 (float_extend:IBM128
7535 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7536 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7537 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7538 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7540 "&& reload_completed"
7541 [(set (match_dup 3) (match_dup 1))
7542 (set (match_dup 4) (match_dup 2))]
7544 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7545 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7547 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7548 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7551 (define_insn_and_split "extenddf<mode>2_vsx"
7552 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7553 (float_extend:IBM128
7554 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7555 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7557 "&& reload_completed"
7558 [(set (match_dup 2) (match_dup 1))
7559 (set (match_dup 3) (match_dup 4))]
7561 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7562 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7564 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7565 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7566 operands[4] = CONST0_RTX (DFmode);
7569 (define_expand "extendsf<mode>2"
7570 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7571 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7573 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7574 && TARGET_LONG_DOUBLE_128"
7576 if (FLOAT128_IEEE_P (<MODE>mode))
7577 rs6000_expand_float128_convert (operands[0], operands[1], false);
7580 rtx tmp = gen_reg_rtx (DFmode);
7581 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7582 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7587 (define_expand "trunc<mode>df2"
7588 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7589 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7591 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7592 && TARGET_LONG_DOUBLE_128"
7594 if (FLOAT128_IEEE_P (<MODE>mode))
7596 rs6000_expand_float128_convert (operands[0], operands[1], false);
7601 (define_insn_and_split "trunc<mode>df2_internal1"
7602 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7604 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7605 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7606 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7610 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7613 emit_note (NOTE_INSN_DELETED);
7616 [(set_attr "type" "fpsimple")])
7618 (define_insn "trunc<mode>df2_internal2"
7619 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7620 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7621 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7622 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7624 [(set_attr "type" "fp")
7625 (set_attr "fp_type" "fp_addsub_d")])
7627 (define_expand "trunc<mode>sf2"
7628 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7629 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7631 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7632 && TARGET_LONG_DOUBLE_128"
7634 if (FLOAT128_IEEE_P (<MODE>mode))
7635 rs6000_expand_float128_convert (operands[0], operands[1], false);
7636 else if (TARGET_E500_DOUBLE)
7638 gcc_assert (<MODE>mode == TFmode);
7639 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7641 else if (<MODE>mode == TFmode)
7642 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7643 else if (<MODE>mode == IFmode)
7644 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7650 (define_insn_and_split "trunc<mode>sf2_fprs"
7651 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7652 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7653 (clobber (match_scratch:DF 2 "=d"))]
7654 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7655 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7657 "&& reload_completed"
7659 (float_truncate:DF (match_dup 1)))
7661 (float_truncate:SF (match_dup 2)))]
7664 (define_expand "floatsi<mode>2"
7665 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7666 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7668 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7669 && TARGET_LONG_DOUBLE_128"
7671 if (FLOAT128_IEEE_P (<MODE>mode))
7672 rs6000_expand_float128_convert (operands[0], operands[1], false);
7675 rtx tmp = gen_reg_rtx (DFmode);
7676 expand_float (tmp, operands[1], false);
7677 if (<MODE>mode == TFmode)
7678 emit_insn (gen_extenddftf2 (operands[0], tmp));
7679 else if (<MODE>mode == IFmode)
7680 emit_insn (gen_extenddfif2 (operands[0], tmp));
7687 ; fadd, but rounding towards zero.
7688 ; This is probably not the optimal code sequence.
7689 (define_insn "fix_trunc_helper<mode>"
7690 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7691 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7692 UNSPEC_FIX_TRUNC_TF))
7693 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7694 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7695 && FLOAT128_IBM_P (<MODE>mode)"
7696 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7697 [(set_attr "type" "fp")
7698 (set_attr "length" "20")])
7700 (define_expand "fix_trunc<mode>si2"
7701 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7702 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7704 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7706 if (FLOAT128_IEEE_P (<MODE>mode))
7707 rs6000_expand_float128_convert (operands[0], operands[1], false);
7708 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7709 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7710 else if (<MODE>mode == TFmode)
7711 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7712 else if (<MODE>mode == IFmode)
7713 emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7719 (define_expand "fix_trunc<mode>si2_fprs"
7720 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7721 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7722 (clobber (match_dup 2))
7723 (clobber (match_dup 3))
7724 (clobber (match_dup 4))
7725 (clobber (match_dup 5))])]
7726 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7728 operands[2] = gen_reg_rtx (DFmode);
7729 operands[3] = gen_reg_rtx (DFmode);
7730 operands[4] = gen_reg_rtx (DImode);
7731 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7734 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7735 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7736 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7737 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7738 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7739 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7740 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7741 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7747 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7750 gcc_assert (MEM_P (operands[5]));
7751 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7753 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7754 emit_move_insn (operands[5], operands[4]);
7755 emit_move_insn (operands[0], lowword);
7759 (define_expand "fix_trunc<mode>di2"
7760 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7761 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7762 "TARGET_FLOAT128_TYPE"
7764 rs6000_expand_float128_convert (operands[0], operands[1], false);
7768 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7769 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7770 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7771 "TARGET_FLOAT128_TYPE"
7773 rs6000_expand_float128_convert (operands[0], operands[1], true);
7777 (define_expand "floatdi<mode>2"
7778 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7779 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7780 "TARGET_FLOAT128_TYPE"
7782 rs6000_expand_float128_convert (operands[0], operands[1], false);
7786 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7787 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7788 (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7789 "TARGET_FLOAT128_TYPE"
7791 rs6000_expand_float128_convert (operands[0], operands[1], true);
7795 (define_expand "neg<mode>2"
7796 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7797 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7798 "FLOAT128_IEEE_P (<MODE>mode)
7799 || (FLOAT128_IBM_P (<MODE>mode)
7800 && TARGET_HARD_FLOAT
7801 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7804 if (FLOAT128_IEEE_P (<MODE>mode))
7806 if (TARGET_FLOAT128_HW)
7808 if (<MODE>mode == TFmode)
7809 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7810 else if (<MODE>mode == KFmode)
7811 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7815 else if (TARGET_FLOAT128_TYPE)
7817 if (<MODE>mode == TFmode)
7818 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7819 else if (<MODE>mode == KFmode)
7820 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7826 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7827 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7829 operands[1], <MODE>mode);
7831 if (target && !rtx_equal_p (target, operands[0]))
7832 emit_move_insn (operands[0], target);
7838 (define_insn "neg<mode>2_internal"
7839 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7840 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7841 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7844 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7845 return \"fneg %L0,%L1\;fneg %0,%1\";
7847 return \"fneg %0,%1\;fneg %L0,%L1\";
7849 [(set_attr "type" "fpsimple")
7850 (set_attr "length" "8")])
7852 (define_expand "abs<mode>2"
7853 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7854 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7855 "FLOAT128_IEEE_P (<MODE>mode)
7856 || (FLOAT128_IBM_P (<MODE>mode)
7857 && TARGET_HARD_FLOAT
7858 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7863 if (FLOAT128_IEEE_P (<MODE>mode))
7865 if (TARGET_FLOAT128_HW)
7867 if (<MODE>mode == TFmode)
7868 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7869 else if (<MODE>mode == KFmode)
7870 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7875 else if (TARGET_FLOAT128_TYPE)
7877 if (<MODE>mode == TFmode)
7878 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7879 else if (<MODE>mode == KFmode)
7880 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7889 label = gen_label_rtx ();
7890 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7892 if (flag_finite_math_only && !flag_trapping_math)
7893 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7895 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7897 else if (<MODE>mode == TFmode)
7898 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7899 else if (<MODE>mode == TFmode)
7900 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7907 (define_expand "abs<mode>2_internal"
7908 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7909 (match_operand:IBM128 1 "gpc_reg_operand" ""))
7910 (set (match_dup 3) (match_dup 5))
7911 (set (match_dup 5) (abs:DF (match_dup 5)))
7912 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7913 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7914 (label_ref (match_operand 2 "" ""))
7916 (set (match_dup 6) (neg:DF (match_dup 6)))]
7917 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7918 && TARGET_LONG_DOUBLE_128"
7921 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7922 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7923 operands[3] = gen_reg_rtx (DFmode);
7924 operands[4] = gen_reg_rtx (CCFPmode);
7925 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7926 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7930 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7933 (define_expand "ieee_128bit_negative_zero"
7934 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7935 "TARGET_FLOAT128_TYPE"
7937 rtvec v = rtvec_alloc (16);
7940 for (i = 0; i < 16; i++)
7941 RTVEC_ELT (v, i) = const0_rtx;
7943 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7944 RTVEC_ELT (v, high) = GEN_INT (0x80);
7946 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7950 ;; IEEE 128-bit negate
7952 ;; We have 2 insns here for negate and absolute value. The first uses
7953 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7954 ;; insns, and second insn after the first split pass loads up the bit to
7955 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
7956 ;; neg/abs to create the constant just once.
7958 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7959 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7960 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7961 (clobber (match_scratch:V16QI 2 "=v"))]
7962 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7965 [(parallel [(set (match_dup 0)
7966 (neg:IEEE128 (match_dup 1)))
7967 (use (match_dup 2))])]
7969 if (GET_CODE (operands[2]) == SCRATCH)
7970 operands[2] = gen_reg_rtx (V16QImode);
7972 operands[3] = gen_reg_rtx (V16QImode);
7973 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7975 [(set_attr "length" "8")
7976 (set_attr "type" "vecsimple")])
7978 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7979 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7980 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7981 (use (match_operand:V16QI 2 "register_operand" "v"))]
7982 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
7983 "xxlxor %x0,%x1,%x2"
7984 [(set_attr "type" "veclogical")])
7986 ;; IEEE 128-bit absolute value
7987 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7988 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7989 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7990 (clobber (match_scratch:V16QI 2 "=v"))]
7991 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7994 [(parallel [(set (match_dup 0)
7995 (abs:IEEE128 (match_dup 1)))
7996 (use (match_dup 2))])]
7998 if (GET_CODE (operands[2]) == SCRATCH)
7999 operands[2] = gen_reg_rtx (V16QImode);
8001 operands[3] = gen_reg_rtx (V16QImode);
8002 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8004 [(set_attr "length" "8")
8005 (set_attr "type" "vecsimple")])
8007 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8008 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8009 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8010 (use (match_operand:V16QI 2 "register_operand" "v"))]
8011 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8012 "xxlandc %x0,%x1,%x2"
8013 [(set_attr "type" "veclogical")])
8015 ;; IEEE 128-bit negative absolute value
8016 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8017 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8020 (match_operand:IEEE128 1 "register_operand" "wa"))))
8021 (clobber (match_scratch:V16QI 2 "=v"))]
8022 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8023 && FLOAT128_IEEE_P (<MODE>mode)"
8026 [(parallel [(set (match_dup 0)
8027 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8028 (use (match_dup 2))])]
8030 if (GET_CODE (operands[2]) == SCRATCH)
8031 operands[2] = gen_reg_rtx (V16QImode);
8033 operands[3] = gen_reg_rtx (V16QImode);
8034 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8036 [(set_attr "length" "8")
8037 (set_attr "type" "vecsimple")])
8039 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8040 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8043 (match_operand:IEEE128 1 "register_operand" "wa"))))
8044 (use (match_operand:V16QI 2 "register_operand" "v"))]
8045 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8047 [(set_attr "type" "veclogical")])
8049 ;; Float128 conversion functions. These expand to library function calls.
8050 ;; We use expand to convert from IBM double double to IEEE 128-bit
8051 ;; and trunc for the opposite.
8052 (define_expand "extendiftf2"
8053 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8054 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8055 "TARGET_FLOAT128_TYPE"
8057 rs6000_expand_float128_convert (operands[0], operands[1], false);
8061 (define_expand "extendifkf2"
8062 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8063 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8064 "TARGET_FLOAT128_TYPE"
8066 rs6000_expand_float128_convert (operands[0], operands[1], false);
8070 (define_expand "extendtfkf2"
8071 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8072 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8073 "TARGET_FLOAT128_TYPE"
8075 rs6000_expand_float128_convert (operands[0], operands[1], false);
8079 (define_expand "trunciftf2"
8080 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8081 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8082 "TARGET_FLOAT128_TYPE"
8084 rs6000_expand_float128_convert (operands[0], operands[1], false);
8088 (define_expand "truncifkf2"
8089 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8090 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8091 "TARGET_FLOAT128_TYPE"
8093 rs6000_expand_float128_convert (operands[0], operands[1], false);
8097 (define_expand "trunckftf2"
8098 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8099 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8100 "TARGET_FLOAT128_TYPE"
8102 rs6000_expand_float128_convert (operands[0], operands[1], false);
8106 (define_expand "trunctfif2"
8107 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8108 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8109 "TARGET_FLOAT128_TYPE"
8111 rs6000_expand_float128_convert (operands[0], operands[1], false);
8116 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8117 ;; must have 3 arguments, and scratch register constraint must be a single
8120 ;; Reload patterns to support gpr load/store with misaligned mem.
8121 ;; and multiple gpr load/store at offset >= 0xfffc
8122 (define_expand "reload_<mode>_store"
8123 [(parallel [(match_operand 0 "memory_operand" "=m")
8124 (match_operand 1 "gpc_reg_operand" "r")
8125 (match_operand:GPR 2 "register_operand" "=&b")])]
8128 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8132 (define_expand "reload_<mode>_load"
8133 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8134 (match_operand 1 "memory_operand" "m")
8135 (match_operand:GPR 2 "register_operand" "=b")])]
8138 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8143 ;; Reload patterns for various types using the vector registers. We may need
8144 ;; an additional base register to convert the reg+offset addressing to reg+reg
8145 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8146 ;; index register for gpr registers.
8147 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8148 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8149 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8150 (match_operand:P 2 "register_operand" "=b")])]
8153 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8157 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8158 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8159 (match_operand:RELOAD 1 "memory_operand" "m")
8160 (match_operand:P 2 "register_operand" "=b")])]
8163 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8168 ;; Reload sometimes tries to move the address to a GPR, and can generate
8169 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8170 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8172 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8173 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8174 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8175 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8177 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
8179 "&& reload_completed"
8181 (plus:P (match_dup 1)
8184 (and:P (match_dup 0)
8187 ;; Power8 merge instructions to allow direct move to/from floating point
8188 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8189 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8190 ;; value, since it is allocated in reload and not all of the flow information
8191 ;; is setup for it. We have two patterns to do the two moves between gprs and
8192 ;; fprs. There isn't a dependancy between the two, but we could potentially
8193 ;; schedule other instructions between the two instructions.
8195 (define_insn "p8_fmrgow_<mode>"
8196 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8198 (match_operand:DF 1 "register_operand" "d")
8199 (match_operand:DF 2 "register_operand" "d")]
8200 UNSPEC_P8V_FMRGOW))]
8201 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8203 [(set_attr "type" "fpsimple")])
8205 (define_insn "p8_mtvsrwz"
8206 [(set (match_operand:DF 0 "register_operand" "=d")
8207 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8208 UNSPEC_P8V_MTVSRWZ))]
8209 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8211 [(set_attr "type" "mftgpr")])
8213 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8214 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8215 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8216 UNSPEC_P8V_RELOAD_FROM_GPR))
8217 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8218 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8220 "&& reload_completed"
8223 rtx dest = operands[0];
8224 rtx src = operands[1];
8225 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8226 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8227 rtx gpr_hi_reg = gen_highpart (SImode, src);
8228 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8230 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8231 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8232 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8235 [(set_attr "length" "12")
8236 (set_attr "type" "three")])
8238 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8239 (define_insn "p8_mtvsrd_df"
8240 [(set (match_operand:DF 0 "register_operand" "=wa")
8241 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8242 UNSPEC_P8V_MTVSRD))]
8243 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8245 [(set_attr "type" "mftgpr")])
8247 (define_insn "p8_xxpermdi_<mode>"
8248 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8249 (unspec:FMOVE128_GPR [
8250 (match_operand:DF 1 "register_operand" "wa")
8251 (match_operand:DF 2 "register_operand" "wa")]
8252 UNSPEC_P8V_XXPERMDI))]
8253 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8254 "xxpermdi %x0,%x1,%x2,0"
8255 [(set_attr "type" "vecperm")])
8257 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8258 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8259 (unspec:FMOVE128_GPR
8260 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8261 UNSPEC_P8V_RELOAD_FROM_GPR))
8262 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8263 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8265 "&& reload_completed"
8268 rtx dest = operands[0];
8269 rtx src = operands[1];
8270 /* You might think that we could use op0 as one temp and a DF clobber
8271 as op2, but you'd be wrong. Secondary reload move patterns don't
8272 check for overlap of the clobber and the destination. */
8273 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8274 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8275 rtx gpr_hi_reg = gen_highpart (DImode, src);
8276 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8278 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8279 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8280 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8283 [(set_attr "length" "12")
8284 (set_attr "type" "three")])
8287 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8288 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8290 && (int_reg_operand (operands[0], <MODE>mode)
8291 || int_reg_operand (operands[1], <MODE>mode))
8292 && (!TARGET_DIRECT_MOVE_128
8293 || (!vsx_register_operand (operands[0], <MODE>mode)
8294 && !vsx_register_operand (operands[1], <MODE>mode)))"
8296 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8298 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8299 ;; type is stored internally as double precision in the VSX registers, we have
8300 ;; to convert it from the vector format.
8301 (define_insn "p8_mtvsrd_sf"
8302 [(set (match_operand:SF 0 "register_operand" "=wa")
8303 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8304 UNSPEC_P8V_MTVSRD))]
8305 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8307 [(set_attr "type" "mftgpr")])
8309 (define_insn_and_split "reload_vsx_from_gprsf"
8310 [(set (match_operand:SF 0 "register_operand" "=wa")
8311 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8312 UNSPEC_P8V_RELOAD_FROM_GPR))
8313 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8314 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8316 "&& reload_completed"
8319 rtx op0 = operands[0];
8320 rtx op1 = operands[1];
8321 rtx op2 = operands[2];
8322 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8324 /* Move SF value to upper 32-bits for xscvspdpn. */
8325 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8326 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8327 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8330 [(set_attr "length" "8")
8331 (set_attr "type" "two")])
8333 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8334 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8335 ;; and then doing a move of that.
8336 (define_insn "p8_mfvsrd_3_<mode>"
8337 [(set (match_operand:DF 0 "register_operand" "=r")
8338 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8339 UNSPEC_P8V_RELOAD_FROM_VSX))]
8340 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8342 [(set_attr "type" "mftgpr")])
8344 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8345 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8346 (unspec:FMOVE128_GPR
8347 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8348 UNSPEC_P8V_RELOAD_FROM_VSX))
8349 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8350 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8352 "&& reload_completed"
8355 rtx dest = operands[0];
8356 rtx src = operands[1];
8357 rtx tmp = operands[2];
8358 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8359 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8361 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8362 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
8363 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8366 [(set_attr "length" "12")
8367 (set_attr "type" "three")])
8369 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8370 ;; type is stored internally as double precision, we have to convert it to the
8373 (define_insn_and_split "reload_gpr_from_vsxsf"
8374 [(set (match_operand:SF 0 "register_operand" "=r")
8375 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8376 UNSPEC_P8V_RELOAD_FROM_VSX))
8377 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8378 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8380 "&& reload_completed"
8383 rtx op0 = operands[0];
8384 rtx op1 = operands[1];
8385 rtx op2 = operands[2];
8386 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8388 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8389 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8390 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8393 [(set_attr "length" "12")
8394 (set_attr "type" "three")])
8396 (define_insn "p8_mfvsrd_4_disf"
8397 [(set (match_operand:DI 0 "register_operand" "=r")
8398 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8399 UNSPEC_P8V_RELOAD_FROM_VSX))]
8400 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8402 [(set_attr "type" "mftgpr")])
8405 ;; Next come the multi-word integer load and store and the load and store
8408 ;; List r->r after r->Y, otherwise reload will try to reload a
8409 ;; non-offsettable address by using r->r which won't make progress.
8410 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8411 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8413 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8414 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8415 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8418 (define_insn "*movdi_internal32"
8419 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8420 "=Y, r, r, ^m, ^d, ^d,
8421 r, ^wY, $Z, ^wb, $wv, ^wi,
8422 *wo, *wo, *wv, *wi, *wi, *wv,
8425 (match_operand:DI 1 "input_operand"
8427 IJKnGHF, wb, wv, wY, Z, wi,
8428 Oj, wM, OjwM, Oj, wM, wS,
8432 && (gpc_reg_operand (operands[0], DImode)
8433 || gpc_reg_operand (operands[1], DImode))"
8455 "store, load, *, fpstore, fpload, fpsimple,
8456 *, fpstore, fpstore, fpload, fpload, veclogical,
8457 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8459 (set_attr "size" "64")])
8462 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8463 (match_operand:DI 1 "const_int_operand" ""))]
8464 "! TARGET_POWERPC64 && reload_completed
8465 && gpr_or_gpr_p (operands[0], operands[1])
8466 && !direct_move_p (operands[0], operands[1])"
8467 [(set (match_dup 2) (match_dup 4))
8468 (set (match_dup 3) (match_dup 1))]
8471 HOST_WIDE_INT value = INTVAL (operands[1]);
8472 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8474 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8476 operands[4] = GEN_INT (value >> 32);
8477 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8481 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8482 (match_operand:DIFD 1 "input_operand" ""))]
8483 "reload_completed && !TARGET_POWERPC64
8484 && gpr_or_gpr_p (operands[0], operands[1])
8485 && !direct_move_p (operands[0], operands[1])"
8487 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8489 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8490 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8491 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8492 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8493 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8494 (define_insn "*movdi_internal64"
8495 [(set (match_operand:DI 0 "nonimmediate_operand"
8497 ^m, ^d, ^d, ^wY, $Z, $wb,
8498 $wv, ^wi, *wo, *wo, *wv, *wi,
8499 *wi, *wv, *wv, r, *h, *h,
8500 ?*r, ?*wg, ?*r, ?*wj")
8502 (match_operand:DI 1 "input_operand"
8504 d, m, d, wb, wv, wY,
8505 Z, wi, Oj, wM, OjwM, Oj,
8506 wM, wS, wB, *h, r, 0,
8510 && (gpc_reg_operand (operands[0], DImode)
8511 || gpc_reg_operand (operands[1], DImode))"
8542 "store, load, *, *, *, *,
8543 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8544 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8545 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8546 mftgpr, mffgpr, mftgpr, mffgpr")
8548 (set_attr "size" "64")
8556 ; Some DImode loads are best done as a load of -1 followed by a mask
8559 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8560 (match_operand:DI 1 "const_int_operand"))]
8562 && num_insns_constant (operands[1], DImode) > 1
8563 && rs6000_is_valid_and_mask (operands[1], DImode)"
8567 (and:DI (match_dup 0)
8571 ;; Split a load of a large constant into the appropriate five-instruction
8572 ;; sequence. Handle anything in a constant number of insns.
8573 ;; When non-easy constants can go in the TOC, this should use
8574 ;; easy_fp_constant predicate.
8576 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8577 (match_operand:DI 1 "const_int_operand" ""))]
8578 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8579 [(set (match_dup 0) (match_dup 2))
8580 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8583 if (rs6000_emit_set_const (operands[0], operands[1]))
8590 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8591 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8592 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8593 [(set (match_dup 0) (match_dup 2))
8594 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8597 if (rs6000_emit_set_const (operands[0], operands[1]))
8604 [(set (match_operand:DI 0 "altivec_register_operand" "")
8605 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8606 "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8609 rtx op0 = operands[0];
8610 rtx op1 = operands[1];
8611 int r = REGNO (op0);
8612 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8614 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8615 if (op1 != const0_rtx && op1 != constm1_rtx)
8617 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8618 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8623 ;; Split integer constants that can be loaded with XXSPLTIB and a
8624 ;; sign extend operation.
8626 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8627 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8628 "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8631 rtx op0 = operands[0];
8632 rtx op1 = operands[1];
8633 int r = REGNO (op0);
8634 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8636 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8637 if (<MODE>mode == DImode)
8638 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8639 else if (<MODE>mode == SImode)
8640 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8641 else if (<MODE>mode == HImode)
8643 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8644 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8650 ;; TImode/PTImode is similar, except that we usually want to compute the
8651 ;; address into a register and use lsi/stsi (the exception is during reload).
8653 (define_insn "*mov<mode>_string"
8654 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8655 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8657 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8658 && (gpc_reg_operand (operands[0], <MODE>mode)
8659 || gpc_reg_operand (operands[1], <MODE>mode))"
8662 switch (which_alternative)
8668 return \"stswi %1,%P0,16\";
8673 /* If the address is not used in the output, we can use lsi. Otherwise,
8674 fall through to generating four loads. */
8676 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8677 return \"lswi %0,%P1,16\";
8685 [(set_attr "type" "store,store,load,load,*,*")
8686 (set_attr "update" "yes")
8687 (set_attr "indexed" "yes")
8688 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8689 (const_string "always")
8690 (const_string "conditional")))])
8692 (define_insn "*mov<mode>_ppc64"
8693 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8694 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8695 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8696 && (gpc_reg_operand (operands[0], <MODE>mode)
8697 || gpc_reg_operand (operands[1], <MODE>mode)))"
8699 return rs6000_output_move_128bit (operands);
8701 [(set_attr "type" "store,store,load,load,*,*")
8702 (set_attr "length" "8")])
8705 [(set (match_operand:TI2 0 "int_reg_operand" "")
8706 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8708 && (VECTOR_MEM_NONE_P (<MODE>mode)
8709 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8710 [(set (match_dup 2) (match_dup 4))
8711 (set (match_dup 3) (match_dup 5))]
8714 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8716 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8718 if (CONST_WIDE_INT_P (operands[1]))
8720 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8721 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8723 else if (CONST_INT_P (operands[1]))
8725 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8726 operands[5] = operands[1];
8733 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8734 (match_operand:TI2 1 "input_operand" ""))]
8736 && gpr_or_gpr_p (operands[0], operands[1])
8737 && !direct_move_p (operands[0], operands[1])
8738 && !quad_load_store_p (operands[0], operands[1])"
8740 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8742 (define_expand "load_multiple"
8743 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8744 (match_operand:SI 1 "" ""))
8745 (use (match_operand:SI 2 "" ""))])]
8746 "TARGET_STRING && !TARGET_POWERPC64"
8754 /* Support only loading a constant number of fixed-point registers from
8755 memory and only bother with this if more than two; the machine
8756 doesn't support more than eight. */
8757 if (GET_CODE (operands[2]) != CONST_INT
8758 || INTVAL (operands[2]) <= 2
8759 || INTVAL (operands[2]) > 8
8760 || GET_CODE (operands[1]) != MEM
8761 || GET_CODE (operands[0]) != REG
8762 || REGNO (operands[0]) >= 32)
8765 count = INTVAL (operands[2]);
8766 regno = REGNO (operands[0]);
8768 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8769 op1 = replace_equiv_address (operands[1],
8770 force_reg (SImode, XEXP (operands[1], 0)));
8772 for (i = 0; i < count; i++)
8773 XVECEXP (operands[3], 0, i)
8774 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8775 adjust_address_nv (op1, SImode, i * 4));
8778 (define_insn "*ldmsi8"
8779 [(match_parallel 0 "load_multiple_operation"
8780 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8781 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8782 (set (match_operand:SI 3 "gpc_reg_operand" "")
8783 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8784 (set (match_operand:SI 4 "gpc_reg_operand" "")
8785 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8786 (set (match_operand:SI 5 "gpc_reg_operand" "")
8787 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8788 (set (match_operand:SI 6 "gpc_reg_operand" "")
8789 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8790 (set (match_operand:SI 7 "gpc_reg_operand" "")
8791 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8792 (set (match_operand:SI 8 "gpc_reg_operand" "")
8793 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8794 (set (match_operand:SI 9 "gpc_reg_operand" "")
8795 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8796 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8798 { return rs6000_output_load_multiple (operands); }"
8799 [(set_attr "type" "load")
8800 (set_attr "update" "yes")
8801 (set_attr "indexed" "yes")
8802 (set_attr "length" "32")])
8804 (define_insn "*ldmsi7"
8805 [(match_parallel 0 "load_multiple_operation"
8806 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8807 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8808 (set (match_operand:SI 3 "gpc_reg_operand" "")
8809 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8810 (set (match_operand:SI 4 "gpc_reg_operand" "")
8811 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8812 (set (match_operand:SI 5 "gpc_reg_operand" "")
8813 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8814 (set (match_operand:SI 6 "gpc_reg_operand" "")
8815 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8816 (set (match_operand:SI 7 "gpc_reg_operand" "")
8817 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8818 (set (match_operand:SI 8 "gpc_reg_operand" "")
8819 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8820 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8822 { return rs6000_output_load_multiple (operands); }"
8823 [(set_attr "type" "load")
8824 (set_attr "update" "yes")
8825 (set_attr "indexed" "yes")
8826 (set_attr "length" "32")])
8828 (define_insn "*ldmsi6"
8829 [(match_parallel 0 "load_multiple_operation"
8830 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8831 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8832 (set (match_operand:SI 3 "gpc_reg_operand" "")
8833 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8834 (set (match_operand:SI 4 "gpc_reg_operand" "")
8835 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8836 (set (match_operand:SI 5 "gpc_reg_operand" "")
8837 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8838 (set (match_operand:SI 6 "gpc_reg_operand" "")
8839 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8840 (set (match_operand:SI 7 "gpc_reg_operand" "")
8841 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8842 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8844 { return rs6000_output_load_multiple (operands); }"
8845 [(set_attr "type" "load")
8846 (set_attr "update" "yes")
8847 (set_attr "indexed" "yes")
8848 (set_attr "length" "32")])
8850 (define_insn "*ldmsi5"
8851 [(match_parallel 0 "load_multiple_operation"
8852 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8853 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8854 (set (match_operand:SI 3 "gpc_reg_operand" "")
8855 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8856 (set (match_operand:SI 4 "gpc_reg_operand" "")
8857 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8858 (set (match_operand:SI 5 "gpc_reg_operand" "")
8859 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8860 (set (match_operand:SI 6 "gpc_reg_operand" "")
8861 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8862 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8864 { return rs6000_output_load_multiple (operands); }"
8865 [(set_attr "type" "load")
8866 (set_attr "update" "yes")
8867 (set_attr "indexed" "yes")
8868 (set_attr "length" "32")])
8870 (define_insn "*ldmsi4"
8871 [(match_parallel 0 "load_multiple_operation"
8872 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8873 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8874 (set (match_operand:SI 3 "gpc_reg_operand" "")
8875 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8876 (set (match_operand:SI 4 "gpc_reg_operand" "")
8877 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8878 (set (match_operand:SI 5 "gpc_reg_operand" "")
8879 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8880 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
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 "*ldmsi3"
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 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8898 { return rs6000_output_load_multiple (operands); }"
8899 [(set_attr "type" "load")
8900 (set_attr "update" "yes")
8901 (set_attr "indexed" "yes")
8902 (set_attr "length" "32")])
8904 (define_expand "store_multiple"
8905 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8906 (match_operand:SI 1 "" ""))
8907 (clobber (scratch:SI))
8908 (use (match_operand:SI 2 "" ""))])]
8909 "TARGET_STRING && !TARGET_POWERPC64"
8918 /* Support only storing a constant number of fixed-point registers to
8919 memory and only bother with this if more than two; the machine
8920 doesn't support more than eight. */
8921 if (GET_CODE (operands[2]) != CONST_INT
8922 || INTVAL (operands[2]) <= 2
8923 || INTVAL (operands[2]) > 8
8924 || GET_CODE (operands[0]) != MEM
8925 || GET_CODE (operands[1]) != REG
8926 || REGNO (operands[1]) >= 32)
8929 count = INTVAL (operands[2]);
8930 regno = REGNO (operands[1]);
8932 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8933 to = force_reg (SImode, XEXP (operands[0], 0));
8934 op0 = replace_equiv_address (operands[0], to);
8936 XVECEXP (operands[3], 0, 0)
8937 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8938 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8939 gen_rtx_SCRATCH (SImode));
8941 for (i = 1; i < count; i++)
8942 XVECEXP (operands[3], 0, i + 1)
8943 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8944 gen_rtx_REG (SImode, regno + i));
8947 (define_insn "*stmsi8"
8948 [(match_parallel 0 "store_multiple_operation"
8949 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8950 (match_operand:SI 2 "gpc_reg_operand" "r"))
8951 (clobber (match_scratch:SI 3 "=X"))
8952 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8953 (match_operand:SI 4 "gpc_reg_operand" "r"))
8954 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8955 (match_operand:SI 5 "gpc_reg_operand" "r"))
8956 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8957 (match_operand:SI 6 "gpc_reg_operand" "r"))
8958 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8959 (match_operand:SI 7 "gpc_reg_operand" "r"))
8960 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8961 (match_operand:SI 8 "gpc_reg_operand" "r"))
8962 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8963 (match_operand:SI 9 "gpc_reg_operand" "r"))
8964 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8965 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8966 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8968 [(set_attr "type" "store")
8969 (set_attr "update" "yes")
8970 (set_attr "indexed" "yes")
8971 (set_attr "cell_micro" "always")])
8973 (define_insn "*stmsi7"
8974 [(match_parallel 0 "store_multiple_operation"
8975 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8976 (match_operand:SI 2 "gpc_reg_operand" "r"))
8977 (clobber (match_scratch:SI 3 "=X"))
8978 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8979 (match_operand:SI 4 "gpc_reg_operand" "r"))
8980 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8981 (match_operand:SI 5 "gpc_reg_operand" "r"))
8982 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8983 (match_operand:SI 6 "gpc_reg_operand" "r"))
8984 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8985 (match_operand:SI 7 "gpc_reg_operand" "r"))
8986 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8987 (match_operand:SI 8 "gpc_reg_operand" "r"))
8988 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8989 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8990 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8992 [(set_attr "type" "store")
8993 (set_attr "update" "yes")
8994 (set_attr "indexed" "yes")
8995 (set_attr "cell_micro" "always")])
8997 (define_insn "*stmsi6"
8998 [(match_parallel 0 "store_multiple_operation"
8999 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9000 (match_operand:SI 2 "gpc_reg_operand" "r"))
9001 (clobber (match_scratch:SI 3 "=X"))
9002 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9003 (match_operand:SI 4 "gpc_reg_operand" "r"))
9004 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9005 (match_operand:SI 5 "gpc_reg_operand" "r"))
9006 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9007 (match_operand:SI 6 "gpc_reg_operand" "r"))
9008 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9009 (match_operand:SI 7 "gpc_reg_operand" "r"))
9010 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9011 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9012 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9014 [(set_attr "type" "store")
9015 (set_attr "update" "yes")
9016 (set_attr "indexed" "yes")
9017 (set_attr "cell_micro" "always")])
9019 (define_insn "*stmsi5"
9020 [(match_parallel 0 "store_multiple_operation"
9021 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9022 (match_operand:SI 2 "gpc_reg_operand" "r"))
9023 (clobber (match_scratch:SI 3 "=X"))
9024 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9025 (match_operand:SI 4 "gpc_reg_operand" "r"))
9026 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9027 (match_operand:SI 5 "gpc_reg_operand" "r"))
9028 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9029 (match_operand:SI 6 "gpc_reg_operand" "r"))
9030 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9031 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9032 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9034 [(set_attr "type" "store")
9035 (set_attr "update" "yes")
9036 (set_attr "indexed" "yes")
9037 (set_attr "cell_micro" "always")])
9039 (define_insn "*stmsi4"
9040 [(match_parallel 0 "store_multiple_operation"
9041 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9042 (match_operand:SI 2 "gpc_reg_operand" "r"))
9043 (clobber (match_scratch:SI 3 "=X"))
9044 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9045 (match_operand:SI 4 "gpc_reg_operand" "r"))
9046 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9047 (match_operand:SI 5 "gpc_reg_operand" "r"))
9048 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9049 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9050 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9052 [(set_attr "type" "store")
9053 (set_attr "update" "yes")
9054 (set_attr "indexed" "yes")
9055 (set_attr "cell_micro" "always")])
9057 (define_insn "*stmsi3"
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 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9068 [(set_attr "type" "store")
9069 (set_attr "update" "yes")
9070 (set_attr "indexed" "yes")
9071 (set_attr "cell_micro" "always")])
9073 (define_expand "setmemsi"
9074 [(parallel [(set (match_operand:BLK 0 "" "")
9075 (match_operand 2 "const_int_operand" ""))
9076 (use (match_operand:SI 1 "" ""))
9077 (use (match_operand:SI 3 "" ""))])]
9081 /* If value to set is not zero, use the library routine. */
9082 if (operands[2] != const0_rtx)
9085 if (expand_block_clear (operands))
9091 ;; String compare N insn.
9092 ;; Argument 0 is the target (result)
9093 ;; Argument 1 is the destination
9094 ;; Argument 2 is the source
9095 ;; Argument 3 is the length
9096 ;; Argument 4 is the alignment
9098 (define_expand "cmpstrnsi"
9099 [(parallel [(set (match_operand:SI 0)
9100 (compare:SI (match_operand:BLK 1)
9101 (match_operand:BLK 2)))
9102 (use (match_operand:SI 3))
9103 (use (match_operand:SI 4))])]
9104 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9106 if (expand_strn_compare (operands))
9112 ;; Block compare insn.
9113 ;; Argument 0 is the target (result)
9114 ;; Argument 1 is the destination
9115 ;; Argument 2 is the source
9116 ;; Argument 3 is the length
9117 ;; Argument 4 is the alignment
9119 (define_expand "cmpmemsi"
9120 [(parallel [(set (match_operand:SI 0)
9121 (compare:SI (match_operand:BLK 1)
9122 (match_operand:BLK 2)))
9123 (use (match_operand:SI 3))
9124 (use (match_operand:SI 4))])]
9127 if (expand_block_compare (operands))
9133 ;; String/block move insn.
9134 ;; Argument 0 is the destination
9135 ;; Argument 1 is the source
9136 ;; Argument 2 is the length
9137 ;; Argument 3 is the alignment
9139 (define_expand "movmemsi"
9140 [(parallel [(set (match_operand:BLK 0 "" "")
9141 (match_operand:BLK 1 "" ""))
9142 (use (match_operand:SI 2 "" ""))
9143 (use (match_operand:SI 3 "" ""))])]
9147 if (expand_block_move (operands))
9153 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
9154 ;; register allocator doesn't have a clue about allocating 8 word registers.
9155 ;; rD/rS = r5 is preferred, efficient form.
9156 (define_expand "movmemsi_8reg"
9157 [(parallel [(set (match_operand 0 "" "")
9158 (match_operand 1 "" ""))
9159 (use (match_operand 2 "" ""))
9160 (use (match_operand 3 "" ""))
9161 (clobber (reg:SI 5))
9162 (clobber (reg:SI 6))
9163 (clobber (reg:SI 7))
9164 (clobber (reg:SI 8))
9165 (clobber (reg:SI 9))
9166 (clobber (reg:SI 10))
9167 (clobber (reg:SI 11))
9168 (clobber (reg:SI 12))
9169 (clobber (match_scratch:SI 4 ""))])]
9174 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9175 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9176 (use (match_operand:SI 2 "immediate_operand" "i"))
9177 (use (match_operand:SI 3 "immediate_operand" "i"))
9178 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9179 (clobber (reg:SI 6))
9180 (clobber (reg:SI 7))
9181 (clobber (reg:SI 8))
9182 (clobber (reg:SI 9))
9183 (clobber (reg:SI 10))
9184 (clobber (reg:SI 11))
9185 (clobber (reg:SI 12))
9186 (clobber (match_scratch:SI 5 "=X"))]
9188 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9189 || INTVAL (operands[2]) == 0)
9190 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9191 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9192 && REGNO (operands[4]) == 5"
9193 "lswi %4,%1,%2\;stswi %4,%0,%2"
9194 [(set_attr "type" "store")
9195 (set_attr "update" "yes")
9196 (set_attr "indexed" "yes")
9197 (set_attr "cell_micro" "always")
9198 (set_attr "length" "8")])
9200 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
9201 ;; register allocator doesn't have a clue about allocating 6 word registers.
9202 ;; rD/rS = r5 is preferred, efficient form.
9203 (define_expand "movmemsi_6reg"
9204 [(parallel [(set (match_operand 0 "" "")
9205 (match_operand 1 "" ""))
9206 (use (match_operand 2 "" ""))
9207 (use (match_operand 3 "" ""))
9208 (clobber (reg:SI 5))
9209 (clobber (reg:SI 6))
9210 (clobber (reg:SI 7))
9211 (clobber (reg:SI 8))
9212 (clobber (reg:SI 9))
9213 (clobber (reg:SI 10))
9214 (clobber (match_scratch:SI 4 ""))])]
9219 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9220 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9221 (use (match_operand:SI 2 "immediate_operand" "i"))
9222 (use (match_operand:SI 3 "immediate_operand" "i"))
9223 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9224 (clobber (reg:SI 6))
9225 (clobber (reg:SI 7))
9226 (clobber (reg:SI 8))
9227 (clobber (reg:SI 9))
9228 (clobber (reg:SI 10))
9229 (clobber (match_scratch:SI 5 "=X"))]
9231 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9232 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9233 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9234 && REGNO (operands[4]) == 5"
9235 "lswi %4,%1,%2\;stswi %4,%0,%2"
9236 [(set_attr "type" "store")
9237 (set_attr "update" "yes")
9238 (set_attr "indexed" "yes")
9239 (set_attr "cell_micro" "always")
9240 (set_attr "length" "8")])
9242 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9243 ;; problems with TImode.
9244 ;; rD/rS = r5 is preferred, efficient form.
9245 (define_expand "movmemsi_4reg"
9246 [(parallel [(set (match_operand 0 "" "")
9247 (match_operand 1 "" ""))
9248 (use (match_operand 2 "" ""))
9249 (use (match_operand 3 "" ""))
9250 (clobber (reg:SI 5))
9251 (clobber (reg:SI 6))
9252 (clobber (reg:SI 7))
9253 (clobber (reg:SI 8))
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 (match_scratch:SI 5 "=X"))]
9269 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9270 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9271 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9272 && REGNO (operands[4]) == 5"
9273 "lswi %4,%1,%2\;stswi %4,%0,%2"
9274 [(set_attr "type" "store")
9275 (set_attr "update" "yes")
9276 (set_attr "indexed" "yes")
9277 (set_attr "cell_micro" "always")
9278 (set_attr "length" "8")])
9280 ;; Move up to 8 bytes at a time.
9281 (define_expand "movmemsi_2reg"
9282 [(parallel [(set (match_operand 0 "" "")
9283 (match_operand 1 "" ""))
9284 (use (match_operand 2 "" ""))
9285 (use (match_operand 3 "" ""))
9286 (clobber (match_scratch:DI 4 ""))
9287 (clobber (match_scratch:SI 5 ""))])]
9288 "TARGET_STRING && ! TARGET_POWERPC64"
9292 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9293 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9294 (use (match_operand:SI 2 "immediate_operand" "i"))
9295 (use (match_operand:SI 3 "immediate_operand" "i"))
9296 (clobber (match_scratch:DI 4 "=&r"))
9297 (clobber (match_scratch:SI 5 "=X"))]
9298 "TARGET_STRING && ! TARGET_POWERPC64
9299 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9300 "lswi %4,%1,%2\;stswi %4,%0,%2"
9301 [(set_attr "type" "store")
9302 (set_attr "update" "yes")
9303 (set_attr "indexed" "yes")
9304 (set_attr "cell_micro" "always")
9305 (set_attr "length" "8")])
9307 ;; Move up to 4 bytes at a time.
9308 (define_expand "movmemsi_1reg"
9309 [(parallel [(set (match_operand 0 "" "")
9310 (match_operand 1 "" ""))
9311 (use (match_operand 2 "" ""))
9312 (use (match_operand 3 "" ""))
9313 (clobber (match_scratch:SI 4 ""))
9314 (clobber (match_scratch:SI 5 ""))])]
9319 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9320 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9321 (use (match_operand:SI 2 "immediate_operand" "i"))
9322 (use (match_operand:SI 3 "immediate_operand" "i"))
9323 (clobber (match_scratch:SI 4 "=&r"))
9324 (clobber (match_scratch:SI 5 "=X"))]
9325 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9326 "lswi %4,%1,%2\;stswi %4,%0,%2"
9327 [(set_attr "type" "store")
9328 (set_attr "update" "yes")
9329 (set_attr "indexed" "yes")
9330 (set_attr "cell_micro" "always")
9331 (set_attr "length" "8")])
9333 ;; Define insns that do load or store with update. Some of these we can
9334 ;; get by using pre-decrement or pre-increment, but the hardware can also
9335 ;; do cases where the increment is not the size of the object.
9337 ;; In all these cases, we use operands 0 and 1 for the register being
9338 ;; incremented because those are the operands that local-alloc will
9339 ;; tie and these are the pair most likely to be tieable (and the ones
9340 ;; that will benefit the most).
9342 (define_insn "*movdi_update1"
9343 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9344 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9345 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9346 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9347 (plus:DI (match_dup 1) (match_dup 2)))]
9348 "TARGET_POWERPC64 && TARGET_UPDATE
9349 && (!avoiding_indexed_address_p (DImode)
9350 || !gpc_reg_operand (operands[2], DImode))"
9354 [(set_attr "type" "load")
9355 (set_attr "update" "yes")
9356 (set_attr "indexed" "yes,no")])
9358 (define_insn "movdi_<mode>_update"
9359 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9360 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9361 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9362 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9363 (plus:P (match_dup 1) (match_dup 2)))]
9364 "TARGET_POWERPC64 && TARGET_UPDATE
9365 && (!avoiding_indexed_address_p (Pmode)
9366 || !gpc_reg_operand (operands[2], Pmode)
9367 || (REG_P (operands[0])
9368 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9372 [(set_attr "type" "store")
9373 (set_attr "update" "yes")
9374 (set_attr "indexed" "yes,no")])
9376 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9377 ;; needed for stack allocation, even if the user passes -mno-update.
9378 (define_insn "movdi_<mode>_update_stack"
9379 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9380 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9381 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9382 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9383 (plus:P (match_dup 1) (match_dup 2)))]
9388 [(set_attr "type" "store")
9389 (set_attr "update" "yes")
9390 (set_attr "indexed" "yes,no")])
9392 (define_insn "*movsi_update1"
9393 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9394 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9395 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9396 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9397 (plus:SI (match_dup 1) (match_dup 2)))]
9399 && (!avoiding_indexed_address_p (SImode)
9400 || !gpc_reg_operand (operands[2], SImode))"
9404 [(set_attr "type" "load")
9405 (set_attr "update" "yes")
9406 (set_attr "indexed" "yes,no")])
9408 (define_insn "*movsi_update2"
9409 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9411 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9412 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9413 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9414 (plus:DI (match_dup 1) (match_dup 2)))]
9415 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9416 && !avoiding_indexed_address_p (DImode)"
9418 [(set_attr "type" "load")
9419 (set_attr "sign_extend" "yes")
9420 (set_attr "update" "yes")
9421 (set_attr "indexed" "yes")])
9423 (define_insn "movsi_update"
9424 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9425 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9426 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9427 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9428 (plus:SI (match_dup 1) (match_dup 2)))]
9430 && (!avoiding_indexed_address_p (SImode)
9431 || !gpc_reg_operand (operands[2], SImode)
9432 || (REG_P (operands[0])
9433 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9437 [(set_attr "type" "store")
9438 (set_attr "update" "yes")
9439 (set_attr "indexed" "yes,no")])
9441 ;; This is an unconditional pattern; needed for stack allocation, even
9442 ;; if the user passes -mno-update.
9443 (define_insn "movsi_update_stack"
9444 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9445 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9446 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9447 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9448 (plus:SI (match_dup 1) (match_dup 2)))]
9453 [(set_attr "type" "store")
9454 (set_attr "update" "yes")
9455 (set_attr "indexed" "yes,no")])
9457 (define_insn "*movhi_update1"
9458 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9459 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9460 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9461 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9462 (plus:SI (match_dup 1) (match_dup 2)))]
9464 && (!avoiding_indexed_address_p (SImode)
9465 || !gpc_reg_operand (operands[2], SImode))"
9469 [(set_attr "type" "load")
9470 (set_attr "update" "yes")
9471 (set_attr "indexed" "yes,no")])
9473 (define_insn "*movhi_update2"
9474 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9476 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9477 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9478 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9479 (plus:SI (match_dup 1) (match_dup 2)))]
9481 && (!avoiding_indexed_address_p (SImode)
9482 || !gpc_reg_operand (operands[2], SImode))"
9486 [(set_attr "type" "load")
9487 (set_attr "update" "yes")
9488 (set_attr "indexed" "yes,no")])
9490 (define_insn "*movhi_update3"
9491 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9493 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9494 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9495 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9496 (plus:SI (match_dup 1) (match_dup 2)))]
9497 "TARGET_UPDATE && rs6000_gen_cell_microcode
9498 && (!avoiding_indexed_address_p (SImode)
9499 || !gpc_reg_operand (operands[2], SImode))"
9503 [(set_attr "type" "load")
9504 (set_attr "sign_extend" "yes")
9505 (set_attr "update" "yes")
9506 (set_attr "indexed" "yes,no")])
9508 (define_insn "*movhi_update4"
9509 [(set (mem:HI (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:HI 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))"
9520 [(set_attr "type" "store")
9521 (set_attr "update" "yes")
9522 (set_attr "indexed" "yes,no")])
9524 (define_insn "*movqi_update1"
9525 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9526 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9527 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9528 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9529 (plus:SI (match_dup 1) (match_dup 2)))]
9531 && (!avoiding_indexed_address_p (SImode)
9532 || !gpc_reg_operand (operands[2], SImode))"
9536 [(set_attr "type" "load")
9537 (set_attr "update" "yes")
9538 (set_attr "indexed" "yes,no")])
9540 (define_insn "*movqi_update2"
9541 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9543 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9544 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9545 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9546 (plus:SI (match_dup 1) (match_dup 2)))]
9548 && (!avoiding_indexed_address_p (SImode)
9549 || !gpc_reg_operand (operands[2], SImode))"
9553 [(set_attr "type" "load")
9554 (set_attr "update" "yes")
9555 (set_attr "indexed" "yes,no")])
9557 (define_insn "*movqi_update3"
9558 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9559 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9560 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9561 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9562 (plus:SI (match_dup 1) (match_dup 2)))]
9564 && (!avoiding_indexed_address_p (SImode)
9565 || !gpc_reg_operand (operands[2], SImode))"
9569 [(set_attr "type" "store")
9570 (set_attr "update" "yes")
9571 (set_attr "indexed" "yes,no")])
9573 (define_insn "*movsf_update1"
9574 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9575 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9576 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9577 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9578 (plus:SI (match_dup 1) (match_dup 2)))]
9579 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9580 && (!avoiding_indexed_address_p (SImode)
9581 || !gpc_reg_operand (operands[2], SImode))"
9585 [(set_attr "type" "fpload")
9586 (set_attr "update" "yes")
9587 (set_attr "indexed" "yes,no")])
9589 (define_insn "*movsf_update2"
9590 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9591 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9592 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9593 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9594 (plus:SI (match_dup 1) (match_dup 2)))]
9595 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9596 && (!avoiding_indexed_address_p (SImode)
9597 || !gpc_reg_operand (operands[2], SImode))"
9601 [(set_attr "type" "fpstore")
9602 (set_attr "update" "yes")
9603 (set_attr "indexed" "yes,no")])
9605 (define_insn "*movsf_update3"
9606 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9607 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9608 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9609 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9610 (plus:SI (match_dup 1) (match_dup 2)))]
9611 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9612 && (!avoiding_indexed_address_p (SImode)
9613 || !gpc_reg_operand (operands[2], SImode))"
9617 [(set_attr "type" "load")
9618 (set_attr "update" "yes")
9619 (set_attr "indexed" "yes,no")])
9621 (define_insn "*movsf_update4"
9622 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9623 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9624 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9625 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9626 (plus:SI (match_dup 1) (match_dup 2)))]
9627 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9628 && (!avoiding_indexed_address_p (SImode)
9629 || !gpc_reg_operand (operands[2], SImode))"
9633 [(set_attr "type" "store")
9634 (set_attr "update" "yes")
9635 (set_attr "indexed" "yes,no")])
9637 (define_insn "*movdf_update1"
9638 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9639 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9640 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9641 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9642 (plus:SI (match_dup 1) (match_dup 2)))]
9643 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9644 && (!avoiding_indexed_address_p (SImode)
9645 || !gpc_reg_operand (operands[2], SImode))"
9649 [(set_attr "type" "fpload")
9650 (set_attr "update" "yes")
9651 (set_attr "indexed" "yes,no")
9652 (set_attr "size" "64")])
9654 (define_insn "*movdf_update2"
9655 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9656 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9657 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9658 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9659 (plus:SI (match_dup 1) (match_dup 2)))]
9660 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9661 && (!avoiding_indexed_address_p (SImode)
9662 || !gpc_reg_operand (operands[2], SImode))"
9666 [(set_attr "type" "fpstore")
9667 (set_attr "update" "yes")
9668 (set_attr "indexed" "yes,no")])
9671 ;; After inserting conditional returns we can sometimes have
9672 ;; unnecessary register moves. Unfortunately we cannot have a
9673 ;; modeless peephole here, because some single SImode sets have early
9674 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9675 ;; sequences, using get_attr_length here will smash the operands
9676 ;; array. Neither is there an early_cobbler_p predicate.
9677 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9678 ;; Also this optimization interferes with scalars going into
9679 ;; altivec registers (the code does reloading through the FPRs).
9681 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9682 (match_operand:DF 1 "any_operand" ""))
9683 (set (match_operand:DF 2 "gpc_reg_operand" "")
9685 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9686 && !TARGET_UPPER_REGS_DF
9687 && peep2_reg_dead_p (2, operands[0])"
9688 [(set (match_dup 2) (match_dup 1))])
9691 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9692 (match_operand:SF 1 "any_operand" ""))
9693 (set (match_operand:SF 2 "gpc_reg_operand" "")
9695 "!TARGET_UPPER_REGS_SF
9696 && peep2_reg_dead_p (2, operands[0])"
9697 [(set (match_dup 2) (match_dup 1))])
9702 ;; Mode attributes for different ABIs.
9703 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9704 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9705 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9706 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9708 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9709 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9710 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9711 (match_operand 4 "" "g")))
9712 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9713 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9715 (clobber (reg:SI LR_REGNO))]
9716 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9718 if (TARGET_CMODEL != CMODEL_SMALL)
9719 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9722 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9724 "&& TARGET_TLS_MARKERS"
9726 (unspec:TLSmode [(match_dup 1)
9729 (parallel [(set (match_dup 0)
9730 (call (mem:TLSmode (match_dup 3))
9732 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9733 (clobber (reg:SI LR_REGNO))])]
9735 [(set_attr "type" "two")
9736 (set (attr "length")
9737 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9741 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9742 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9743 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9744 (match_operand 4 "" "g")))
9745 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9746 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9748 (clobber (reg:SI LR_REGNO))]
9749 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9753 if (TARGET_SECURE_PLT && flag_pic == 2)
9754 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9756 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9759 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9761 "&& TARGET_TLS_MARKERS"
9763 (unspec:TLSmode [(match_dup 1)
9766 (parallel [(set (match_dup 0)
9767 (call (mem:TLSmode (match_dup 3))
9769 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9770 (clobber (reg:SI LR_REGNO))])]
9772 [(set_attr "type" "two")
9773 (set_attr "length" "8")])
9775 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9776 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9777 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9778 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9780 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9781 "addi %0,%1,%2@got@tlsgd"
9782 "&& TARGET_CMODEL != CMODEL_SMALL"
9785 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9787 (lo_sum:TLSmode (match_dup 3)
9788 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9791 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9793 [(set (attr "length")
9794 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9798 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9799 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9801 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9802 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9804 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9805 "addis %0,%1,%2@got@tlsgd@ha"
9806 [(set_attr "length" "4")])
9808 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9809 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9810 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9811 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9812 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9814 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9815 "addi %0,%1,%2@got@tlsgd@l"
9816 [(set_attr "length" "4")])
9818 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9819 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9820 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9821 (match_operand 2 "" "g")))
9822 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9824 (clobber (reg:SI LR_REGNO))]
9825 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9826 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9827 "bl %z1(%3@tlsgd)\;nop"
9828 [(set_attr "type" "branch")
9829 (set_attr "length" "8")])
9831 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9832 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9833 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9834 (match_operand 2 "" "g")))
9835 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9837 (clobber (reg:SI LR_REGNO))]
9838 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9842 if (TARGET_SECURE_PLT && flag_pic == 2)
9843 return "bl %z1+32768(%3@tlsgd)@plt";
9844 return "bl %z1(%3@tlsgd)@plt";
9846 return "bl %z1(%3@tlsgd)";
9848 [(set_attr "type" "branch")
9849 (set_attr "length" "4")])
9851 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9852 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9853 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9854 (match_operand 3 "" "g")))
9855 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9857 (clobber (reg:SI LR_REGNO))]
9858 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9860 if (TARGET_CMODEL != CMODEL_SMALL)
9861 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9864 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9866 "&& TARGET_TLS_MARKERS"
9868 (unspec:TLSmode [(match_dup 1)]
9870 (parallel [(set (match_dup 0)
9871 (call (mem:TLSmode (match_dup 2))
9873 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9874 (clobber (reg:SI LR_REGNO))])]
9876 [(set_attr "type" "two")
9877 (set (attr "length")
9878 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9882 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9883 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9884 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9885 (match_operand 3 "" "g")))
9886 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9888 (clobber (reg:SI LR_REGNO))]
9889 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9893 if (TARGET_SECURE_PLT && flag_pic == 2)
9894 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9896 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9899 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9901 "&& TARGET_TLS_MARKERS"
9903 (unspec:TLSmode [(match_dup 1)]
9905 (parallel [(set (match_dup 0)
9906 (call (mem:TLSmode (match_dup 2))
9908 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9909 (clobber (reg:SI LR_REGNO))])]
9911 [(set_attr "length" "8")])
9913 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9914 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9915 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9917 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9918 "addi %0,%1,%&@got@tlsld"
9919 "&& TARGET_CMODEL != CMODEL_SMALL"
9922 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9924 (lo_sum:TLSmode (match_dup 2)
9925 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9928 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9930 [(set (attr "length")
9931 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9935 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9936 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9938 (unspec:TLSmode [(const_int 0)
9939 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9941 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9942 "addis %0,%1,%&@got@tlsld@ha"
9943 [(set_attr "length" "4")])
9945 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9946 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9947 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9948 (unspec:TLSmode [(const_int 0)
9949 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9951 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9952 "addi %0,%1,%&@got@tlsld@l"
9953 [(set_attr "length" "4")])
9955 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9956 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9957 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9958 (match_operand 2 "" "g")))
9959 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9960 (clobber (reg:SI LR_REGNO))]
9961 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9962 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9963 "bl %z1(%&@tlsld)\;nop"
9964 [(set_attr "type" "branch")
9965 (set_attr "length" "8")])
9967 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9968 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9969 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9970 (match_operand 2 "" "g")))
9971 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9972 (clobber (reg:SI LR_REGNO))]
9973 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9977 if (TARGET_SECURE_PLT && flag_pic == 2)
9978 return "bl %z1+32768(%&@tlsld)@plt";
9979 return "bl %z1(%&@tlsld)@plt";
9981 return "bl %z1(%&@tlsld)";
9983 [(set_attr "type" "branch")
9984 (set_attr "length" "4")])
9986 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9987 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9988 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9989 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9992 "addi %0,%1,%2@dtprel")
9994 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9995 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9996 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9997 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9998 UNSPEC_TLSDTPRELHA))]
10000 "addis %0,%1,%2@dtprel@ha")
10002 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10003 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10004 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10005 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10006 UNSPEC_TLSDTPRELLO))]
10008 "addi %0,%1,%2@dtprel@l")
10010 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10011 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10012 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10013 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10014 UNSPEC_TLSGOTDTPREL))]
10016 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10017 "&& TARGET_CMODEL != CMODEL_SMALL"
10018 [(set (match_dup 3)
10020 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10022 (lo_sum:TLSmode (match_dup 3)
10023 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10026 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10028 [(set (attr "length")
10029 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10033 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10034 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10036 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10037 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10038 UNSPEC_TLSGOTDTPREL)))]
10039 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10040 "addis %0,%1,%2@got@dtprel@ha"
10041 [(set_attr "length" "4")])
10043 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10044 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10045 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10046 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10047 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10048 UNSPEC_TLSGOTDTPREL)))]
10049 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10050 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10051 [(set_attr "length" "4")])
10053 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10054 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10055 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10056 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10059 "addi %0,%1,%2@tprel")
10061 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10062 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10063 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10064 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10065 UNSPEC_TLSTPRELHA))]
10067 "addis %0,%1,%2@tprel@ha")
10069 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10070 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10071 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10072 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10073 UNSPEC_TLSTPRELLO))]
10075 "addi %0,%1,%2@tprel@l")
10077 ;; "b" output constraint here and on tls_tls input to support linker tls
10078 ;; optimization. The linker may edit the instructions emitted by a
10079 ;; tls_got_tprel/tls_tls pair to addis,addi.
10080 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10081 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10082 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10083 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10084 UNSPEC_TLSGOTTPREL))]
10086 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10087 "&& TARGET_CMODEL != CMODEL_SMALL"
10088 [(set (match_dup 3)
10090 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10092 (lo_sum:TLSmode (match_dup 3)
10093 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10096 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10098 [(set (attr "length")
10099 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10103 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10104 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10106 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10107 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10108 UNSPEC_TLSGOTTPREL)))]
10109 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10110 "addis %0,%1,%2@got@tprel@ha"
10111 [(set_attr "length" "4")])
10113 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10114 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10115 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10116 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10117 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10118 UNSPEC_TLSGOTTPREL)))]
10119 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10120 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10121 [(set_attr "length" "4")])
10123 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10124 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10125 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10126 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10128 "TARGET_ELF && HAVE_AS_TLS"
10129 "add %0,%1,%2@tls")
10131 (define_expand "tls_get_tpointer"
10132 [(set (match_operand:SI 0 "gpc_reg_operand" "")
10133 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10134 "TARGET_XCOFF && HAVE_AS_TLS"
10137 emit_insn (gen_tls_get_tpointer_internal ());
10138 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10142 (define_insn "tls_get_tpointer_internal"
10144 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10145 (clobber (reg:SI LR_REGNO))]
10146 "TARGET_XCOFF && HAVE_AS_TLS"
10147 "bla __get_tpointer")
10149 (define_expand "tls_get_addr<mode>"
10150 [(set (match_operand:P 0 "gpc_reg_operand" "")
10151 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10152 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10153 "TARGET_XCOFF && HAVE_AS_TLS"
10156 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10157 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10158 emit_insn (gen_tls_get_addr_internal<mode> ());
10159 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10163 (define_insn "tls_get_addr_internal<mode>"
10165 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10166 (clobber (reg:P 0))
10167 (clobber (reg:P 4))
10168 (clobber (reg:P 5))
10169 (clobber (reg:P 11))
10170 (clobber (reg:CC CR0_REGNO))
10171 (clobber (reg:P LR_REGNO))]
10172 "TARGET_XCOFF && HAVE_AS_TLS"
10173 "bla __tls_get_addr")
10175 ;; Next come insns related to the calling sequence.
10177 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10178 ;; We move the back-chain and decrement the stack pointer.
10180 (define_expand "allocate_stack"
10181 [(set (match_operand 0 "gpc_reg_operand" "")
10182 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10184 (minus (reg 1) (match_dup 1)))]
10187 { rtx chain = gen_reg_rtx (Pmode);
10188 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10190 rtx insn, par, set, mem;
10192 emit_move_insn (chain, stack_bot);
10194 /* Check stack bounds if necessary. */
10195 if (crtl->limit_stack)
10198 available = expand_binop (Pmode, sub_optab,
10199 stack_pointer_rtx, stack_limit_rtx,
10200 NULL_RTX, 1, OPTAB_WIDEN);
10201 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10204 if (GET_CODE (operands[1]) != CONST_INT
10205 || INTVAL (operands[1]) < -32767
10206 || INTVAL (operands[1]) > 32768)
10208 neg_op0 = gen_reg_rtx (Pmode);
10210 emit_insn (gen_negsi2 (neg_op0, operands[1]));
10212 emit_insn (gen_negdi2 (neg_op0, operands[1]));
10215 neg_op0 = GEN_INT (- INTVAL (operands[1]));
10217 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10218 : gen_movdi_di_update_stack))
10219 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10221 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10222 it now and set the alias set/attributes. The above gen_*_update
10223 calls will generate a PARALLEL with the MEM set being the first
10225 par = PATTERN (insn);
10226 gcc_assert (GET_CODE (par) == PARALLEL);
10227 set = XVECEXP (par, 0, 0);
10228 gcc_assert (GET_CODE (set) == SET);
10229 mem = SET_DEST (set);
10230 gcc_assert (MEM_P (mem));
10231 MEM_NOTRAP_P (mem) = 1;
10232 set_mem_alias_set (mem, get_frame_alias_set ());
10234 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10238 ;; These patterns say how to save and restore the stack pointer. We need not
10239 ;; save the stack pointer at function level since we are careful to
10240 ;; preserve the backchain. At block level, we have to restore the backchain
10241 ;; when we restore the stack pointer.
10243 ;; For nonlocal gotos, we must save both the stack pointer and its
10244 ;; backchain and restore both. Note that in the nonlocal case, the
10245 ;; save area is a memory location.
10247 (define_expand "save_stack_function"
10248 [(match_operand 0 "any_operand" "")
10249 (match_operand 1 "any_operand" "")]
10253 (define_expand "restore_stack_function"
10254 [(match_operand 0 "any_operand" "")
10255 (match_operand 1 "any_operand" "")]
10259 ;; Adjust stack pointer (op0) to a new value (op1).
10260 ;; First copy old stack backchain to new location, and ensure that the
10261 ;; scheduler won't reorder the sp assignment before the backchain write.
10262 (define_expand "restore_stack_block"
10263 [(set (match_dup 2) (match_dup 3))
10264 (set (match_dup 4) (match_dup 2))
10266 (set (match_operand 0 "register_operand" "")
10267 (match_operand 1 "register_operand" ""))]
10273 operands[1] = force_reg (Pmode, operands[1]);
10274 operands[2] = gen_reg_rtx (Pmode);
10275 operands[3] = gen_frame_mem (Pmode, operands[0]);
10276 operands[4] = gen_frame_mem (Pmode, operands[1]);
10277 p = rtvec_alloc (1);
10278 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10280 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10283 (define_expand "save_stack_nonlocal"
10284 [(set (match_dup 3) (match_dup 4))
10285 (set (match_operand 0 "memory_operand" "") (match_dup 3))
10286 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10290 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10292 /* Copy the backchain to the first word, sp to the second. */
10293 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10294 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10295 operands[3] = gen_reg_rtx (Pmode);
10296 operands[4] = gen_frame_mem (Pmode, operands[1]);
10299 (define_expand "restore_stack_nonlocal"
10300 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10301 (set (match_dup 3) (match_dup 4))
10302 (set (match_dup 5) (match_dup 2))
10304 (set (match_operand 0 "register_operand" "") (match_dup 3))]
10308 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10311 /* Restore the backchain from the first word, sp from the second. */
10312 operands[2] = gen_reg_rtx (Pmode);
10313 operands[3] = gen_reg_rtx (Pmode);
10314 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10315 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10316 operands[5] = gen_frame_mem (Pmode, operands[3]);
10317 p = rtvec_alloc (1);
10318 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10320 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10323 ;; TOC register handling.
10325 ;; Code to initialize the TOC register...
10327 (define_insn "load_toc_aix_si"
10328 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10329 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10330 (use (reg:SI 2))])]
10331 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10335 extern int need_toc_init;
10337 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10338 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10339 operands[2] = gen_rtx_REG (Pmode, 2);
10340 return \"lwz %0,%1(%2)\";
10342 [(set_attr "type" "load")
10343 (set_attr "update" "no")
10344 (set_attr "indexed" "no")])
10346 (define_insn "load_toc_aix_di"
10347 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10348 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10349 (use (reg:DI 2))])]
10350 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10354 extern int need_toc_init;
10356 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10357 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10359 strcat (buf, \"@toc\");
10360 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10361 operands[2] = gen_rtx_REG (Pmode, 2);
10362 return \"ld %0,%1(%2)\";
10364 [(set_attr "type" "load")
10365 (set_attr "update" "no")
10366 (set_attr "indexed" "no")])
10368 (define_insn "load_toc_v4_pic_si"
10369 [(set (reg:SI LR_REGNO)
10370 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10371 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10372 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10373 [(set_attr "type" "branch")
10374 (set_attr "length" "4")])
10376 (define_expand "load_toc_v4_PIC_1"
10377 [(parallel [(set (reg:SI LR_REGNO)
10378 (match_operand:SI 0 "immediate_operand" "s"))
10379 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10380 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10381 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10384 (define_insn "load_toc_v4_PIC_1_normal"
10385 [(set (reg:SI LR_REGNO)
10386 (match_operand:SI 0 "immediate_operand" "s"))
10387 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10388 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10389 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10390 "bcl 20,31,%0\\n%0:"
10391 [(set_attr "type" "branch")
10392 (set_attr "length" "4")
10393 (set_attr "cannot_copy" "yes")])
10395 (define_insn "load_toc_v4_PIC_1_476"
10396 [(set (reg:SI LR_REGNO)
10397 (match_operand:SI 0 "immediate_operand" "s"))
10398 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10399 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10400 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10404 static char templ[32];
10406 get_ppc476_thunk_name (name);
10407 sprintf (templ, \"bl %s\\n%%0:\", name);
10410 [(set_attr "type" "branch")
10411 (set_attr "length" "4")
10412 (set_attr "cannot_copy" "yes")])
10414 (define_expand "load_toc_v4_PIC_1b"
10415 [(parallel [(set (reg:SI LR_REGNO)
10416 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10417 (label_ref (match_operand 1 "" ""))]
10420 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10423 (define_insn "load_toc_v4_PIC_1b_normal"
10424 [(set (reg:SI LR_REGNO)
10425 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10426 (label_ref (match_operand 1 "" ""))]
10429 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10430 "bcl 20,31,$+8\;.long %0-$"
10431 [(set_attr "type" "branch")
10432 (set_attr "length" "8")])
10434 (define_insn "load_toc_v4_PIC_1b_476"
10435 [(set (reg:SI LR_REGNO)
10436 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10437 (label_ref (match_operand 1 "" ""))]
10440 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10444 static char templ[32];
10446 get_ppc476_thunk_name (name);
10447 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10450 [(set_attr "type" "branch")
10451 (set_attr "length" "16")])
10453 (define_insn "load_toc_v4_PIC_2"
10454 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10455 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10456 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10457 (match_operand:SI 3 "immediate_operand" "s")))))]
10458 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10460 [(set_attr "type" "load")])
10462 (define_insn "load_toc_v4_PIC_3b"
10463 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10464 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10466 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10467 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10468 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10469 "addis %0,%1,%2-%3@ha")
10471 (define_insn "load_toc_v4_PIC_3c"
10472 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10473 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10474 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10475 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10476 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10477 "addi %0,%1,%2-%3@l")
10479 ;; If the TOC is shared over a translation unit, as happens with all
10480 ;; the kinds of PIC that we support, we need to restore the TOC
10481 ;; pointer only when jumping over units of translation.
10482 ;; On Darwin, we need to reload the picbase.
10484 (define_expand "builtin_setjmp_receiver"
10485 [(use (label_ref (match_operand 0 "" "")))]
10486 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10487 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10488 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10492 if (DEFAULT_ABI == ABI_DARWIN)
10494 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10495 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10499 crtl->uses_pic_offset_table = 1;
10500 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10501 CODE_LABEL_NUMBER (operands[0]));
10502 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10504 emit_insn (gen_load_macho_picbase (tmplabrtx));
10505 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10506 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10510 rs6000_emit_load_toc_table (FALSE);
10514 ;; Largetoc support
10515 (define_insn "*largetoc_high"
10516 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10518 (unspec [(match_operand:DI 1 "" "")
10519 (match_operand:DI 2 "gpc_reg_operand" "b")]
10521 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10522 "addis %0,%2,%1@toc@ha")
10524 (define_insn "*largetoc_high_aix<mode>"
10525 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10527 (unspec [(match_operand:P 1 "" "")
10528 (match_operand:P 2 "gpc_reg_operand" "b")]
10530 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10531 "addis %0,%1@u(%2)")
10533 (define_insn "*largetoc_high_plus"
10534 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10537 (unspec [(match_operand:DI 1 "" "")
10538 (match_operand:DI 2 "gpc_reg_operand" "b")]
10540 (match_operand:DI 3 "add_cint_operand" "n"))))]
10541 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10542 "addis %0,%2,%1+%3@toc@ha")
10544 (define_insn "*largetoc_high_plus_aix<mode>"
10545 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10548 (unspec [(match_operand:P 1 "" "")
10549 (match_operand:P 2 "gpc_reg_operand" "b")]
10551 (match_operand:P 3 "add_cint_operand" "n"))))]
10552 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10553 "addis %0,%1+%3@u(%2)")
10555 (define_insn "*largetoc_low"
10556 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10557 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10558 (match_operand:DI 2 "" "")))]
10559 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10562 (define_insn "*largetoc_low_aix<mode>"
10563 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10564 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10565 (match_operand:P 2 "" "")))]
10566 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10569 (define_insn_and_split "*tocref<mode>"
10570 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10571 (match_operand:P 1 "small_toc_ref" "R"))]
10574 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10575 [(set (match_dup 0) (high:P (match_dup 1)))
10576 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10578 ;; Elf specific ways of loading addresses for non-PIC code.
10579 ;; The output of this could be r0, but we make a very strong
10580 ;; preference for a base register because it will usually
10581 ;; be needed there.
10582 (define_insn "elf_high"
10583 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10584 (high:SI (match_operand 1 "" "")))]
10585 "TARGET_ELF && ! TARGET_64BIT"
10588 (define_insn "elf_low"
10589 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10590 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10591 (match_operand 2 "" "")))]
10592 "TARGET_ELF && ! TARGET_64BIT"
10595 ;; Call and call_value insns
10596 (define_expand "call"
10597 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10598 (match_operand 1 "" ""))
10599 (use (match_operand 2 "" ""))
10600 (clobber (reg:SI LR_REGNO))])]
10605 if (MACHOPIC_INDIRECT)
10606 operands[0] = machopic_indirect_call_target (operands[0]);
10609 gcc_assert (GET_CODE (operands[0]) == MEM);
10610 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10612 operands[0] = XEXP (operands[0], 0);
10614 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10616 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10620 if (GET_CODE (operands[0]) != SYMBOL_REF
10621 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10623 if (INTVAL (operands[2]) & CALL_LONG)
10624 operands[0] = rs6000_longcall_ref (operands[0]);
10626 switch (DEFAULT_ABI)
10630 operands[0] = force_reg (Pmode, operands[0]);
10634 gcc_unreachable ();
10639 (define_expand "call_value"
10640 [(parallel [(set (match_operand 0 "" "")
10641 (call (mem:SI (match_operand 1 "address_operand" ""))
10642 (match_operand 2 "" "")))
10643 (use (match_operand 3 "" ""))
10644 (clobber (reg:SI LR_REGNO))])]
10649 if (MACHOPIC_INDIRECT)
10650 operands[1] = machopic_indirect_call_target (operands[1]);
10653 gcc_assert (GET_CODE (operands[1]) == MEM);
10654 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10656 operands[1] = XEXP (operands[1], 0);
10658 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10660 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10664 if (GET_CODE (operands[1]) != SYMBOL_REF
10665 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10667 if (INTVAL (operands[3]) & CALL_LONG)
10668 operands[1] = rs6000_longcall_ref (operands[1]);
10670 switch (DEFAULT_ABI)
10674 operands[1] = force_reg (Pmode, operands[1]);
10678 gcc_unreachable ();
10683 ;; Call to function in current module. No TOC pointer reload needed.
10684 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10685 ;; either the function was not prototyped, or it was prototyped as a
10686 ;; variable argument function. It is > 0 if FP registers were passed
10687 ;; and < 0 if they were not.
10689 (define_insn "*call_local32"
10690 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10691 (match_operand 1 "" "g,g"))
10692 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10693 (clobber (reg:SI LR_REGNO))]
10694 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10697 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10698 output_asm_insn (\"crxor 6,6,6\", operands);
10700 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10701 output_asm_insn (\"creqv 6,6,6\", operands);
10703 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10705 [(set_attr "type" "branch")
10706 (set_attr "length" "4,8")])
10708 (define_insn "*call_local64"
10709 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10710 (match_operand 1 "" "g,g"))
10711 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10712 (clobber (reg:SI LR_REGNO))]
10713 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10716 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10717 output_asm_insn (\"crxor 6,6,6\", operands);
10719 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10720 output_asm_insn (\"creqv 6,6,6\", operands);
10722 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10724 [(set_attr "type" "branch")
10725 (set_attr "length" "4,8")])
10727 (define_insn "*call_value_local32"
10728 [(set (match_operand 0 "" "")
10729 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10730 (match_operand 2 "" "g,g")))
10731 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10732 (clobber (reg:SI LR_REGNO))]
10733 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10736 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10737 output_asm_insn (\"crxor 6,6,6\", operands);
10739 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10740 output_asm_insn (\"creqv 6,6,6\", operands);
10742 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10744 [(set_attr "type" "branch")
10745 (set_attr "length" "4,8")])
10748 (define_insn "*call_value_local64"
10749 [(set (match_operand 0 "" "")
10750 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10751 (match_operand 2 "" "g,g")))
10752 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10753 (clobber (reg:SI LR_REGNO))]
10754 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10757 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10758 output_asm_insn (\"crxor 6,6,6\", operands);
10760 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10761 output_asm_insn (\"creqv 6,6,6\", operands);
10763 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10765 [(set_attr "type" "branch")
10766 (set_attr "length" "4,8")])
10769 ;; A function pointer under System V is just a normal pointer
10770 ;; operands[0] is the function pointer
10771 ;; operands[1] is the stack size to clean up
10772 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10773 ;; which indicates how to set cr1
10775 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10776 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10777 (match_operand 1 "" "g,g,g,g"))
10778 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10779 (clobber (reg:SI LR_REGNO))]
10780 "DEFAULT_ABI == ABI_V4
10781 || DEFAULT_ABI == ABI_DARWIN"
10783 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10784 output_asm_insn ("crxor 6,6,6", operands);
10786 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10787 output_asm_insn ("creqv 6,6,6", operands);
10791 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10792 (set_attr "length" "4,4,8,8")])
10794 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10795 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10796 (match_operand 1 "" "g,g"))
10797 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10798 (clobber (reg:SI LR_REGNO))]
10799 "(DEFAULT_ABI == ABI_DARWIN
10800 || (DEFAULT_ABI == ABI_V4
10801 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10803 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10804 output_asm_insn ("crxor 6,6,6", operands);
10806 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10807 output_asm_insn ("creqv 6,6,6", operands);
10810 return output_call(insn, operands, 0, 2);
10812 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10814 gcc_assert (!TARGET_SECURE_PLT);
10815 return "bl %z0@plt";
10821 "DEFAULT_ABI == ABI_V4
10822 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10823 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10824 [(parallel [(call (mem:SI (match_dup 0))
10826 (use (match_dup 2))
10827 (use (match_dup 3))
10828 (clobber (reg:SI LR_REGNO))])]
10830 operands[3] = pic_offset_table_rtx;
10832 [(set_attr "type" "branch,branch")
10833 (set_attr "length" "4,8")])
10835 (define_insn "*call_nonlocal_sysv_secure<mode>"
10836 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10837 (match_operand 1 "" "g,g"))
10838 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10839 (use (match_operand:SI 3 "register_operand" "r,r"))
10840 (clobber (reg:SI LR_REGNO))]
10841 "(DEFAULT_ABI == ABI_V4
10842 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10843 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10845 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10846 output_asm_insn ("crxor 6,6,6", operands);
10848 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10849 output_asm_insn ("creqv 6,6,6", operands);
10852 /* The magic 32768 offset here and in the other sysv call insns
10853 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10854 See sysv4.h:toc_section. */
10855 return "bl %z0+32768@plt";
10857 return "bl %z0@plt";
10859 [(set_attr "type" "branch,branch")
10860 (set_attr "length" "4,8")])
10862 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10863 [(set (match_operand 0 "" "")
10864 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10865 (match_operand 2 "" "g,g,g,g")))
10866 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10867 (clobber (reg:SI LR_REGNO))]
10868 "DEFAULT_ABI == ABI_V4
10869 || DEFAULT_ABI == ABI_DARWIN"
10871 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10872 output_asm_insn ("crxor 6,6,6", operands);
10874 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10875 output_asm_insn ("creqv 6,6,6", operands);
10879 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10880 (set_attr "length" "4,4,8,8")])
10882 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10883 [(set (match_operand 0 "" "")
10884 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10885 (match_operand 2 "" "g,g")))
10886 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10887 (clobber (reg:SI LR_REGNO))]
10888 "(DEFAULT_ABI == ABI_DARWIN
10889 || (DEFAULT_ABI == ABI_V4
10890 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10892 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10893 output_asm_insn ("crxor 6,6,6", operands);
10895 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10896 output_asm_insn ("creqv 6,6,6", operands);
10899 return output_call(insn, operands, 1, 3);
10901 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10903 gcc_assert (!TARGET_SECURE_PLT);
10904 return "bl %z1@plt";
10910 "DEFAULT_ABI == ABI_V4
10911 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10912 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10913 [(parallel [(set (match_dup 0)
10914 (call (mem:SI (match_dup 1))
10916 (use (match_dup 3))
10917 (use (match_dup 4))
10918 (clobber (reg:SI LR_REGNO))])]
10920 operands[4] = pic_offset_table_rtx;
10922 [(set_attr "type" "branch,branch")
10923 (set_attr "length" "4,8")])
10925 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10926 [(set (match_operand 0 "" "")
10927 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10928 (match_operand 2 "" "g,g")))
10929 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10930 (use (match_operand:SI 4 "register_operand" "r,r"))
10931 (clobber (reg:SI LR_REGNO))]
10932 "(DEFAULT_ABI == ABI_V4
10933 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10934 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10936 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10937 output_asm_insn ("crxor 6,6,6", operands);
10939 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10940 output_asm_insn ("creqv 6,6,6", operands);
10943 return "bl %z1+32768@plt";
10945 return "bl %z1@plt";
10947 [(set_attr "type" "branch,branch")
10948 (set_attr "length" "4,8")])
10951 ;; Call to AIX abi function in the same module.
10953 (define_insn "*call_local_aix<mode>"
10954 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10955 (match_operand 1 "" "g"))
10956 (clobber (reg:P LR_REGNO))]
10957 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10959 [(set_attr "type" "branch")
10960 (set_attr "length" "4")])
10962 (define_insn "*call_value_local_aix<mode>"
10963 [(set (match_operand 0 "" "")
10964 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10965 (match_operand 2 "" "g")))
10966 (clobber (reg:P LR_REGNO))]
10967 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10969 [(set_attr "type" "branch")
10970 (set_attr "length" "4")])
10972 ;; Call to AIX abi function which may be in another module.
10973 ;; Restore the TOC pointer (r2) after the call.
10975 (define_insn "*call_nonlocal_aix<mode>"
10976 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10977 (match_operand 1 "" "g"))
10978 (clobber (reg:P LR_REGNO))]
10979 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10981 [(set_attr "type" "branch")
10982 (set_attr "length" "8")])
10984 (define_insn "*call_value_nonlocal_aix<mode>"
10985 [(set (match_operand 0 "" "")
10986 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10987 (match_operand 2 "" "g")))
10988 (clobber (reg:P LR_REGNO))]
10989 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10991 [(set_attr "type" "branch")
10992 (set_attr "length" "8")])
10994 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10995 ;; Operand0 is the addresss of the function to call
10996 ;; Operand2 is the location in the function descriptor to load r2 from
10997 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10999 (define_insn "*call_indirect_aix<mode>"
11000 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11001 (match_operand 1 "" "g,g"))
11002 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11003 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11004 (clobber (reg:P LR_REGNO))]
11005 "DEFAULT_ABI == ABI_AIX"
11006 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11007 [(set_attr "type" "jmpreg")
11008 (set_attr "length" "12")])
11010 (define_insn "*call_value_indirect_aix<mode>"
11011 [(set (match_operand 0 "" "")
11012 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11013 (match_operand 2 "" "g,g")))
11014 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11015 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11016 (clobber (reg:P LR_REGNO))]
11017 "DEFAULT_ABI == ABI_AIX"
11018 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11019 [(set_attr "type" "jmpreg")
11020 (set_attr "length" "12")])
11022 ;; Call to indirect functions with the ELFv2 ABI.
11023 ;; Operand0 is the addresss of the function to call
11024 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11026 (define_insn "*call_indirect_elfv2<mode>"
11027 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11028 (match_operand 1 "" "g,g"))
11029 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11030 (clobber (reg:P LR_REGNO))]
11031 "DEFAULT_ABI == ABI_ELFv2"
11032 "b%T0l\;<ptrload> 2,%2(1)"
11033 [(set_attr "type" "jmpreg")
11034 (set_attr "length" "8")])
11036 (define_insn "*call_value_indirect_elfv2<mode>"
11037 [(set (match_operand 0 "" "")
11038 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11039 (match_operand 2 "" "g,g")))
11040 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11041 (clobber (reg:P LR_REGNO))]
11042 "DEFAULT_ABI == ABI_ELFv2"
11043 "b%T1l\;<ptrload> 2,%3(1)"
11044 [(set_attr "type" "jmpreg")
11045 (set_attr "length" "8")])
11048 ;; Call subroutine returning any type.
11049 (define_expand "untyped_call"
11050 [(parallel [(call (match_operand 0 "" "")
11052 (match_operand 1 "" "")
11053 (match_operand 2 "" "")])]
11059 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11061 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11063 rtx set = XVECEXP (operands[2], 0, i);
11064 emit_move_insn (SET_DEST (set), SET_SRC (set));
11067 /* The optimizer does not know that the call sets the function value
11068 registers we stored in the result block. We avoid problems by
11069 claiming that all hard registers are used and clobbered at this
11071 emit_insn (gen_blockage ());
11076 ;; sibling call patterns
11077 (define_expand "sibcall"
11078 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11079 (match_operand 1 "" ""))
11080 (use (match_operand 2 "" ""))
11086 if (MACHOPIC_INDIRECT)
11087 operands[0] = machopic_indirect_call_target (operands[0]);
11090 gcc_assert (GET_CODE (operands[0]) == MEM);
11091 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11093 operands[0] = XEXP (operands[0], 0);
11095 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11097 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11102 (define_expand "sibcall_value"
11103 [(parallel [(set (match_operand 0 "register_operand" "")
11104 (call (mem:SI (match_operand 1 "address_operand" ""))
11105 (match_operand 2 "" "")))
11106 (use (match_operand 3 "" ""))
11112 if (MACHOPIC_INDIRECT)
11113 operands[1] = machopic_indirect_call_target (operands[1]);
11116 gcc_assert (GET_CODE (operands[1]) == MEM);
11117 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11119 operands[1] = XEXP (operands[1], 0);
11121 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11123 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11128 (define_insn "*sibcall_local32"
11129 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11130 (match_operand 1 "" "g,g"))
11131 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11133 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11136 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11137 output_asm_insn (\"crxor 6,6,6\", operands);
11139 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11140 output_asm_insn (\"creqv 6,6,6\", operands);
11142 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11144 [(set_attr "type" "branch")
11145 (set_attr "length" "4,8")])
11147 (define_insn "*sibcall_local64"
11148 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11149 (match_operand 1 "" "g,g"))
11150 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11152 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11155 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11156 output_asm_insn (\"crxor 6,6,6\", operands);
11158 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11159 output_asm_insn (\"creqv 6,6,6\", operands);
11161 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11163 [(set_attr "type" "branch")
11164 (set_attr "length" "4,8")])
11166 (define_insn "*sibcall_value_local32"
11167 [(set (match_operand 0 "" "")
11168 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11169 (match_operand 2 "" "g,g")))
11170 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11172 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11175 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11176 output_asm_insn (\"crxor 6,6,6\", operands);
11178 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11179 output_asm_insn (\"creqv 6,6,6\", operands);
11181 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11183 [(set_attr "type" "branch")
11184 (set_attr "length" "4,8")])
11186 (define_insn "*sibcall_value_local64"
11187 [(set (match_operand 0 "" "")
11188 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11189 (match_operand 2 "" "g,g")))
11190 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11192 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11195 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11196 output_asm_insn (\"crxor 6,6,6\", operands);
11198 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11199 output_asm_insn (\"creqv 6,6,6\", operands);
11201 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11203 [(set_attr "type" "branch")
11204 (set_attr "length" "4,8")])
11206 (define_insn "*sibcall_nonlocal_sysv<mode>"
11207 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11208 (match_operand 1 "" ""))
11209 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11211 "(DEFAULT_ABI == ABI_DARWIN
11212 || DEFAULT_ABI == ABI_V4)
11213 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11216 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11217 output_asm_insn (\"crxor 6,6,6\", operands);
11219 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11220 output_asm_insn (\"creqv 6,6,6\", operands);
11222 if (which_alternative >= 2)
11224 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11226 gcc_assert (!TARGET_SECURE_PLT);
11227 return \"b %z0@plt\";
11232 [(set_attr "type" "branch")
11233 (set_attr "length" "4,8,4,8")])
11235 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11236 [(set (match_operand 0 "" "")
11237 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11238 (match_operand 2 "" "")))
11239 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11241 "(DEFAULT_ABI == ABI_DARWIN
11242 || DEFAULT_ABI == ABI_V4)
11243 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11246 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11247 output_asm_insn (\"crxor 6,6,6\", operands);
11249 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11250 output_asm_insn (\"creqv 6,6,6\", operands);
11252 if (which_alternative >= 2)
11254 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11256 gcc_assert (!TARGET_SECURE_PLT);
11257 return \"b %z1@plt\";
11262 [(set_attr "type" "branch")
11263 (set_attr "length" "4,8,4,8")])
11265 ;; AIX ABI sibling call patterns.
11267 (define_insn "*sibcall_aix<mode>"
11268 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11269 (match_operand 1 "" "g,g"))
11271 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11275 [(set_attr "type" "branch")
11276 (set_attr "length" "4")])
11278 (define_insn "*sibcall_value_aix<mode>"
11279 [(set (match_operand 0 "" "")
11280 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11281 (match_operand 2 "" "g,g")))
11283 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11287 [(set_attr "type" "branch")
11288 (set_attr "length" "4")])
11290 (define_expand "sibcall_epilogue"
11291 [(use (const_int 0))]
11294 if (!TARGET_SCHED_PROLOG)
11295 emit_insn (gen_blockage ());
11296 rs6000_emit_epilogue (TRUE);
11300 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11301 ;; all of memory. This blocks insns from being moved across this point.
11303 (define_insn "blockage"
11304 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11308 (define_expand "probe_stack_address"
11309 [(use (match_operand 0 "address_operand"))]
11312 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11313 MEM_VOLATILE_P (operands[0]) = 1;
11316 emit_insn (gen_probe_stack_di (operands[0]));
11318 emit_insn (gen_probe_stack_si (operands[0]));
11322 (define_insn "probe_stack_<mode>"
11323 [(set (match_operand:P 0 "memory_operand" "=m")
11324 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11327 operands[1] = gen_rtx_REG (Pmode, 0);
11328 return "st<wd>%U0%X0 %1,%0";
11330 [(set_attr "type" "store")
11331 (set (attr "update")
11332 (if_then_else (match_operand 0 "update_address_mem")
11333 (const_string "yes")
11334 (const_string "no")))
11335 (set (attr "indexed")
11336 (if_then_else (match_operand 0 "indexed_address_mem")
11337 (const_string "yes")
11338 (const_string "no")))
11339 (set_attr "length" "4")])
11341 (define_insn "probe_stack_range<P:mode>"
11342 [(set (match_operand:P 0 "register_operand" "=r")
11343 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11344 (match_operand:P 2 "register_operand" "r")]
11345 UNSPECV_PROBE_STACK_RANGE))]
11347 "* return output_probe_stack_range (operands[0], operands[2]);"
11348 [(set_attr "type" "three")])
11350 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11351 ;; signed & unsigned, and one type of branch.
11353 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11354 ;; insns, and branches.
11356 (define_expand "cbranch<mode>4"
11357 [(use (match_operator 0 "rs6000_cbranch_operator"
11358 [(match_operand:GPR 1 "gpc_reg_operand" "")
11359 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11360 (use (match_operand 3 ""))]
11364 /* Take care of the possibility that operands[2] might be negative but
11365 this might be a logical operation. That insn doesn't exist. */
11366 if (GET_CODE (operands[2]) == CONST_INT
11367 && INTVAL (operands[2]) < 0)
11369 operands[2] = force_reg (<MODE>mode, operands[2]);
11370 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11371 GET_MODE (operands[0]),
11372 operands[1], operands[2]);
11375 rs6000_emit_cbranch (<MODE>mode, operands);
11379 (define_expand "cbranch<mode>4"
11380 [(use (match_operator 0 "rs6000_cbranch_operator"
11381 [(match_operand:FP 1 "gpc_reg_operand" "")
11382 (match_operand:FP 2 "gpc_reg_operand" "")]))
11383 (use (match_operand 3 ""))]
11387 rs6000_emit_cbranch (<MODE>mode, operands);
11391 (define_expand "cstore<mode>4_signed"
11392 [(use (match_operator 1 "signed_comparison_operator"
11393 [(match_operand:P 2 "gpc_reg_operand")
11394 (match_operand:P 3 "gpc_reg_operand")]))
11395 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11398 enum rtx_code cond_code = GET_CODE (operands[1]);
11400 rtx op0 = operands[0];
11401 rtx op1 = operands[2];
11402 rtx op2 = operands[3];
11404 if (cond_code == GE || cond_code == LT)
11406 cond_code = swap_condition (cond_code);
11407 std::swap (op1, op2);
11410 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11411 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11412 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11414 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11415 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11416 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11418 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11420 if (cond_code == LE)
11421 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11424 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11425 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11426 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11432 (define_expand "cstore<mode>4_unsigned"
11433 [(use (match_operator 1 "unsigned_comparison_operator"
11434 [(match_operand:P 2 "gpc_reg_operand")
11435 (match_operand:P 3 "reg_or_short_operand")]))
11436 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11439 enum rtx_code cond_code = GET_CODE (operands[1]);
11441 rtx op0 = operands[0];
11442 rtx op1 = operands[2];
11443 rtx op2 = operands[3];
11445 if (cond_code == GEU || cond_code == LTU)
11447 cond_code = swap_condition (cond_code);
11448 std::swap (op1, op2);
11451 if (!gpc_reg_operand (op1, <MODE>mode))
11452 op1 = force_reg (<MODE>mode, op1);
11453 if (!reg_or_short_operand (op2, <MODE>mode))
11454 op2 = force_reg (<MODE>mode, op2);
11456 rtx tmp = gen_reg_rtx (<MODE>mode);
11457 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11459 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11460 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11462 if (cond_code == LEU)
11463 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11465 emit_insn (gen_neg<mode>2 (op0, tmp2));
11470 (define_expand "cstore_si_as_di"
11471 [(use (match_operator 1 "unsigned_comparison_operator"
11472 [(match_operand:SI 2 "gpc_reg_operand")
11473 (match_operand:SI 3 "reg_or_short_operand")]))
11474 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11477 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11478 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11480 operands[2] = force_reg (SImode, operands[2]);
11481 operands[3] = force_reg (SImode, operands[3]);
11482 rtx op1 = gen_reg_rtx (DImode);
11483 rtx op2 = gen_reg_rtx (DImode);
11484 convert_move (op1, operands[2], uns_flag);
11485 convert_move (op2, operands[3], uns_flag);
11487 if (cond_code == GT || cond_code == LE)
11489 cond_code = swap_condition (cond_code);
11490 std::swap (op1, op2);
11493 rtx tmp = gen_reg_rtx (DImode);
11494 rtx tmp2 = gen_reg_rtx (DImode);
11495 emit_insn (gen_subdi3 (tmp, op1, op2));
11496 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11502 gcc_unreachable ();
11507 tmp3 = gen_reg_rtx (DImode);
11508 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11512 convert_move (operands[0], tmp3, 1);
11517 (define_expand "cstore<mode>4_signed_imm"
11518 [(use (match_operator 1 "signed_comparison_operator"
11519 [(match_operand:GPR 2 "gpc_reg_operand")
11520 (match_operand:GPR 3 "immediate_operand")]))
11521 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11524 bool invert = false;
11526 enum rtx_code cond_code = GET_CODE (operands[1]);
11528 rtx op0 = operands[0];
11529 rtx op1 = operands[2];
11530 HOST_WIDE_INT val = INTVAL (operands[3]);
11532 if (cond_code == GE || cond_code == GT)
11534 cond_code = reverse_condition (cond_code);
11538 if (cond_code == LE)
11541 rtx tmp = gen_reg_rtx (<MODE>mode);
11542 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11543 rtx x = gen_reg_rtx (<MODE>mode);
11545 emit_insn (gen_and<mode>3 (x, op1, tmp));
11547 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11551 rtx tmp = gen_reg_rtx (<MODE>mode);
11552 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11556 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11557 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11562 (define_expand "cstore<mode>4_unsigned_imm"
11563 [(use (match_operator 1 "unsigned_comparison_operator"
11564 [(match_operand:GPR 2 "gpc_reg_operand")
11565 (match_operand:GPR 3 "immediate_operand")]))
11566 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11569 bool invert = false;
11571 enum rtx_code cond_code = GET_CODE (operands[1]);
11573 rtx op0 = operands[0];
11574 rtx op1 = operands[2];
11575 HOST_WIDE_INT val = INTVAL (operands[3]);
11577 if (cond_code == GEU || cond_code == GTU)
11579 cond_code = reverse_condition (cond_code);
11583 if (cond_code == LEU)
11586 rtx tmp = gen_reg_rtx (<MODE>mode);
11587 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11588 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11589 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11590 rtx x = gen_reg_rtx (<MODE>mode);
11592 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11594 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11598 rtx tmp = gen_reg_rtx (<MODE>mode);
11599 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11603 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11604 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11609 (define_expand "cstore<mode>4"
11610 [(use (match_operator 1 "rs6000_cbranch_operator"
11611 [(match_operand:GPR 2 "gpc_reg_operand")
11612 (match_operand:GPR 3 "reg_or_short_operand")]))
11613 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11616 /* Use ISEL if the user asked for it. */
11618 rs6000_emit_sISEL (<MODE>mode, operands);
11620 /* Expanding EQ and NE directly to some machine instructions does not help
11621 but does hurt combine. So don't. */
11622 else if (GET_CODE (operands[1]) == EQ)
11623 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11624 else if (<MODE>mode == Pmode
11625 && GET_CODE (operands[1]) == NE)
11626 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11627 else if (GET_CODE (operands[1]) == NE)
11629 rtx tmp = gen_reg_rtx (<MODE>mode);
11630 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11631 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11634 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11635 etc. combinations magically work out just right. */
11636 else if (<MODE>mode == Pmode
11637 && unsigned_comparison_operator (operands[1], VOIDmode))
11638 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11639 operands[2], operands[3]));
11641 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11642 else if (<MODE>mode == SImode && Pmode == DImode)
11643 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11644 operands[2], operands[3]));
11646 /* For signed comparisons against a constant, we can do some simple
11648 else if (signed_comparison_operator (operands[1], VOIDmode)
11649 && CONST_INT_P (operands[3]))
11650 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11651 operands[2], operands[3]));
11653 /* And similarly for unsigned comparisons. */
11654 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11655 && CONST_INT_P (operands[3]))
11656 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11657 operands[2], operands[3]));
11659 /* We also do not want to use mfcr for signed comparisons. */
11660 else if (<MODE>mode == Pmode
11661 && signed_comparison_operator (operands[1], VOIDmode))
11662 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11663 operands[2], operands[3]));
11665 /* Everything else, use the mfcr brute force. */
11667 rs6000_emit_sCOND (<MODE>mode, operands);
11672 (define_expand "cstore<mode>4"
11673 [(use (match_operator 1 "rs6000_cbranch_operator"
11674 [(match_operand:FP 2 "gpc_reg_operand")
11675 (match_operand:FP 3 "gpc_reg_operand")]))
11676 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11679 rs6000_emit_sCOND (<MODE>mode, operands);
11684 (define_expand "stack_protect_set"
11685 [(match_operand 0 "memory_operand" "")
11686 (match_operand 1 "memory_operand" "")]
11689 #ifdef TARGET_THREAD_SSP_OFFSET
11690 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11691 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11692 operands[1] = gen_rtx_MEM (Pmode, addr);
11695 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11697 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11701 (define_insn "stack_protect_setsi"
11702 [(set (match_operand:SI 0 "memory_operand" "=m")
11703 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11704 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11706 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11707 [(set_attr "type" "three")
11708 (set_attr "length" "12")])
11710 (define_insn "stack_protect_setdi"
11711 [(set (match_operand:DI 0 "memory_operand" "=Y")
11712 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11713 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11715 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11716 [(set_attr "type" "three")
11717 (set_attr "length" "12")])
11719 (define_expand "stack_protect_test"
11720 [(match_operand 0 "memory_operand" "")
11721 (match_operand 1 "memory_operand" "")
11722 (match_operand 2 "" "")]
11725 rtx test, op0, op1;
11726 #ifdef TARGET_THREAD_SSP_OFFSET
11727 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11728 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11729 operands[1] = gen_rtx_MEM (Pmode, addr);
11732 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
11733 test = gen_rtx_EQ (VOIDmode, op0, op1);
11734 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
11738 (define_insn "stack_protect_testsi"
11739 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11740 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11741 (match_operand:SI 2 "memory_operand" "m,m")]
11743 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11744 (clobber (match_scratch:SI 3 "=&r,&r"))]
11747 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11748 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11749 [(set_attr "length" "16,20")])
11751 (define_insn "stack_protect_testdi"
11752 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11753 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11754 (match_operand:DI 2 "memory_operand" "Y,Y")]
11756 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11757 (clobber (match_scratch:DI 3 "=&r,&r"))]
11760 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11761 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11762 [(set_attr "length" "16,20")])
11765 ;; Here are the actual compare insns.
11766 (define_insn "*cmp<mode>_signed"
11767 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11768 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11769 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11771 "cmp<wd>%I2 %0,%1,%2"
11772 [(set_attr "type" "cmp")])
11774 (define_insn "*cmp<mode>_unsigned"
11775 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11776 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11777 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11779 "cmpl<wd>%I2 %0,%1,%2"
11780 [(set_attr "type" "cmp")])
11782 ;; If we are comparing a register for equality with a large constant,
11783 ;; we can do this with an XOR followed by a compare. But this is profitable
11784 ;; only if the large constant is only used for the comparison (and in this
11785 ;; case we already have a register to reuse as scratch).
11787 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11788 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11791 [(set (match_operand:SI 0 "register_operand")
11792 (match_operand:SI 1 "logical_const_operand" ""))
11793 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11795 (match_operand:SI 2 "logical_const_operand" "")]))
11796 (set (match_operand:CC 4 "cc_reg_operand" "")
11797 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11800 (if_then_else (match_operator 6 "equality_operator"
11801 [(match_dup 4) (const_int 0)])
11802 (match_operand 7 "" "")
11803 (match_operand 8 "" "")))]
11804 "peep2_reg_dead_p (3, operands[0])
11805 && peep2_reg_dead_p (4, operands[4])
11806 && REGNO (operands[0]) != REGNO (operands[5])"
11807 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11808 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11809 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11812 /* Get the constant we are comparing against, and see what it looks like
11813 when sign-extended from 16 to 32 bits. Then see what constant we could
11814 XOR with SEXTC to get the sign-extended value. */
11815 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11817 operands[1], operands[2]);
11818 HOST_WIDE_INT c = INTVAL (cnst);
11819 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11820 HOST_WIDE_INT xorv = c ^ sextc;
11822 operands[9] = GEN_INT (xorv);
11823 operands[10] = GEN_INT (sextc);
11826 ;; The following two insns don't exist as single insns, but if we provide
11827 ;; them, we can swap an add and compare, which will enable us to overlap more
11828 ;; of the required delay between a compare and branch. We generate code for
11829 ;; them by splitting.
11832 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11833 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11834 (match_operand:SI 2 "short_cint_operand" "i")))
11835 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11836 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11839 [(set_attr "length" "8")])
11842 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11843 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11844 (match_operand:SI 2 "u_short_cint_operand" "i")))
11845 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11846 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11849 [(set_attr "length" "8")])
11852 [(set (match_operand:CC 3 "cc_reg_operand" "")
11853 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11854 (match_operand:SI 2 "short_cint_operand" "")))
11855 (set (match_operand:SI 0 "gpc_reg_operand" "")
11856 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11858 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11859 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11862 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11863 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11864 (match_operand:SI 2 "u_short_cint_operand" "")))
11865 (set (match_operand:SI 0 "gpc_reg_operand" "")
11866 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11868 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11869 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11871 ;; Only need to compare second words if first words equal
11872 (define_insn "*cmp<mode>_internal1"
11873 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11874 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11875 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11876 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11877 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11878 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11879 [(set_attr "type" "fpcompare")
11880 (set_attr "length" "12")])
11882 (define_insn_and_split "*cmp<mode>_internal2"
11883 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11884 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11885 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11886 (clobber (match_scratch:DF 3 "=d"))
11887 (clobber (match_scratch:DF 4 "=d"))
11888 (clobber (match_scratch:DF 5 "=d"))
11889 (clobber (match_scratch:DF 6 "=d"))
11890 (clobber (match_scratch:DF 7 "=d"))
11891 (clobber (match_scratch:DF 8 "=d"))
11892 (clobber (match_scratch:DF 9 "=d"))
11893 (clobber (match_scratch:DF 10 "=d"))
11894 (clobber (match_scratch:GPR 11 "=b"))]
11895 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11896 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11898 "&& reload_completed"
11899 [(set (match_dup 3) (match_dup 14))
11900 (set (match_dup 4) (match_dup 15))
11901 (set (match_dup 9) (abs:DF (match_dup 5)))
11902 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11903 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11904 (label_ref (match_dup 12))
11906 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11907 (set (pc) (label_ref (match_dup 13)))
11909 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11910 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11911 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11912 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11915 REAL_VALUE_TYPE rv;
11916 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11917 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11919 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11920 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11921 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11922 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11923 operands[12] = gen_label_rtx ();
11924 operands[13] = gen_label_rtx ();
11926 operands[14] = force_const_mem (DFmode,
11927 const_double_from_real_value (rv, DFmode));
11928 operands[15] = force_const_mem (DFmode,
11929 const_double_from_real_value (dconst0,
11934 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11935 operands[14] = gen_const_mem (DFmode, tocref);
11936 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11937 operands[15] = gen_const_mem (DFmode, tocref);
11938 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11939 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11943 ;; Now we have the scc insns. We can do some combinations because of the
11944 ;; way the machine works.
11946 ;; Note that this is probably faster if we can put an insn between the
11947 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11948 ;; cases the insns below which don't use an intermediate CR field will
11949 ;; be used instead.
11951 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11952 (match_operator:SI 1 "scc_comparison_operator"
11953 [(match_operand 2 "cc_reg_operand" "y")
11956 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11957 [(set (attr "type")
11958 (cond [(match_test "TARGET_MFCRF")
11959 (const_string "mfcrf")
11961 (const_string "mfcr")))
11962 (set_attr "length" "8")])
11964 ;; Same as above, but get the GT bit.
11965 (define_insn "move_from_CR_gt_bit"
11966 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11967 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11968 "TARGET_HARD_FLOAT && !TARGET_FPRS"
11969 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11970 [(set_attr "type" "mfcr")
11971 (set_attr "length" "8")])
11973 ;; Same as above, but get the OV/ORDERED bit.
11974 (define_insn "move_from_CR_ov_bit"
11975 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11976 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11979 "mfcr %0\;rlwinm %0,%0,%t1,1"
11980 [(set_attr "type" "mfcr")
11981 (set_attr "length" "8")])
11984 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11985 (match_operator:DI 1 "scc_comparison_operator"
11986 [(match_operand 2 "cc_reg_operand" "y")
11989 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11990 [(set (attr "type")
11991 (cond [(match_test "TARGET_MFCRF")
11992 (const_string "mfcrf")
11994 (const_string "mfcr")))
11995 (set_attr "length" "8")])
11998 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11999 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12000 [(match_operand 2 "cc_reg_operand" "y,y")
12003 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12004 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12007 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12009 [(set_attr "type" "shift")
12010 (set_attr "dot" "yes")
12011 (set_attr "length" "8,16")])
12014 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12015 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12016 [(match_operand 2 "cc_reg_operand" "")
12019 (set (match_operand:SI 3 "gpc_reg_operand" "")
12020 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12021 "TARGET_32BIT && reload_completed"
12022 [(set (match_dup 3)
12023 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12025 (compare:CC (match_dup 3)
12030 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12031 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12032 [(match_operand 2 "cc_reg_operand" "y")
12034 (match_operand:SI 3 "const_int_operand" "n")))]
12038 int is_bit = ccr_bit (operands[1], 1);
12039 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12042 if (is_bit >= put_bit)
12043 count = is_bit - put_bit;
12045 count = 32 - (put_bit - is_bit);
12047 operands[4] = GEN_INT (count);
12048 operands[5] = GEN_INT (put_bit);
12050 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12052 [(set (attr "type")
12053 (cond [(match_test "TARGET_MFCRF")
12054 (const_string "mfcrf")
12056 (const_string "mfcr")))
12057 (set_attr "length" "8")])
12060 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12062 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12063 [(match_operand 2 "cc_reg_operand" "y,y")
12065 (match_operand:SI 3 "const_int_operand" "n,n"))
12067 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12068 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12073 int is_bit = ccr_bit (operands[1], 1);
12074 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12077 /* Force split for non-cc0 compare. */
12078 if (which_alternative == 1)
12081 if (is_bit >= put_bit)
12082 count = is_bit - put_bit;
12084 count = 32 - (put_bit - is_bit);
12086 operands[5] = GEN_INT (count);
12087 operands[6] = GEN_INT (put_bit);
12089 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12091 [(set_attr "type" "shift")
12092 (set_attr "dot" "yes")
12093 (set_attr "length" "8,16")])
12096 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12098 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12099 [(match_operand 2 "cc_reg_operand" "")
12101 (match_operand:SI 3 "const_int_operand" ""))
12103 (set (match_operand:SI 4 "gpc_reg_operand" "")
12104 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12107 [(set (match_dup 4)
12108 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12111 (compare:CC (match_dup 4)
12116 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12119 (define_insn_and_split "eq<mode>3"
12120 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12121 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12122 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12123 (clobber (match_scratch:GPR 3 "=r"))
12124 (clobber (match_scratch:GPR 4 "=r"))]
12128 [(set (match_dup 4)
12129 (clz:GPR (match_dup 3)))
12131 (lshiftrt:GPR (match_dup 4)
12134 operands[3] = rs6000_emit_eqne (<MODE>mode,
12135 operands[1], operands[2], operands[3]);
12137 if (GET_CODE (operands[4]) == SCRATCH)
12138 operands[4] = gen_reg_rtx (<MODE>mode);
12140 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12142 [(set (attr "length")
12143 (if_then_else (match_test "operands[2] == const0_rtx")
12145 (const_string "12")))])
12147 (define_insn_and_split "ne<mode>3"
12148 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12149 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12150 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12151 (clobber (match_scratch:P 3 "=r"))
12152 (clobber (match_scratch:P 4 "=r"))
12153 (clobber (reg:P CA_REGNO))]
12157 [(parallel [(set (match_dup 4)
12158 (plus:P (match_dup 3)
12160 (set (reg:P CA_REGNO)
12161 (ne:P (match_dup 3)
12163 (parallel [(set (match_dup 0)
12164 (plus:P (plus:P (not:P (match_dup 4))
12167 (clobber (reg:P CA_REGNO))])]
12169 operands[3] = rs6000_emit_eqne (<MODE>mode,
12170 operands[1], operands[2], operands[3]);
12172 if (GET_CODE (operands[4]) == SCRATCH)
12173 operands[4] = gen_reg_rtx (<MODE>mode);
12175 [(set (attr "length")
12176 (if_then_else (match_test "operands[2] == const0_rtx")
12178 (const_string "12")))])
12180 (define_insn_and_split "*neg_eq_<mode>"
12181 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12182 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12183 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12184 (clobber (match_scratch:P 3 "=r"))
12185 (clobber (match_scratch:P 4 "=r"))
12186 (clobber (reg:P CA_REGNO))]
12190 [(parallel [(set (match_dup 4)
12191 (plus:P (match_dup 3)
12193 (set (reg:P CA_REGNO)
12194 (ne:P (match_dup 3)
12196 (parallel [(set (match_dup 0)
12197 (plus:P (reg:P CA_REGNO)
12199 (clobber (reg:P CA_REGNO))])]
12201 operands[3] = rs6000_emit_eqne (<MODE>mode,
12202 operands[1], operands[2], operands[3]);
12204 if (GET_CODE (operands[4]) == SCRATCH)
12205 operands[4] = gen_reg_rtx (<MODE>mode);
12207 [(set (attr "length")
12208 (if_then_else (match_test "operands[2] == const0_rtx")
12210 (const_string "12")))])
12212 (define_insn_and_split "*neg_ne_<mode>"
12213 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12214 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12215 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12216 (clobber (match_scratch:P 3 "=r"))
12217 (clobber (match_scratch:P 4 "=r"))
12218 (clobber (reg:P CA_REGNO))]
12222 [(parallel [(set (match_dup 4)
12223 (neg:P (match_dup 3)))
12224 (set (reg:P CA_REGNO)
12225 (eq:P (match_dup 3)
12227 (parallel [(set (match_dup 0)
12228 (plus:P (reg:P CA_REGNO)
12230 (clobber (reg:P CA_REGNO))])]
12232 operands[3] = rs6000_emit_eqne (<MODE>mode,
12233 operands[1], operands[2], operands[3]);
12235 if (GET_CODE (operands[4]) == SCRATCH)
12236 operands[4] = gen_reg_rtx (<MODE>mode);
12238 [(set (attr "length")
12239 (if_then_else (match_test "operands[2] == const0_rtx")
12241 (const_string "12")))])
12243 (define_insn_and_split "*plus_eq_<mode>"
12244 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12245 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12246 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12247 (match_operand:P 3 "gpc_reg_operand" "r")))
12248 (clobber (match_scratch:P 4 "=r"))
12249 (clobber (match_scratch:P 5 "=r"))
12250 (clobber (reg:P CA_REGNO))]
12254 [(parallel [(set (match_dup 5)
12255 (neg:P (match_dup 4)))
12256 (set (reg:P CA_REGNO)
12257 (eq:P (match_dup 4)
12259 (parallel [(set (match_dup 0)
12260 (plus:P (match_dup 3)
12262 (clobber (reg:P CA_REGNO))])]
12264 operands[4] = rs6000_emit_eqne (<MODE>mode,
12265 operands[1], operands[2], operands[4]);
12267 if (GET_CODE (operands[5]) == SCRATCH)
12268 operands[5] = gen_reg_rtx (<MODE>mode);
12270 [(set (attr "length")
12271 (if_then_else (match_test "operands[2] == const0_rtx")
12273 (const_string "12")))])
12275 (define_insn_and_split "*plus_ne_<mode>"
12276 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12277 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12278 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12279 (match_operand:P 3 "gpc_reg_operand" "r")))
12280 (clobber (match_scratch:P 4 "=r"))
12281 (clobber (match_scratch:P 5 "=r"))
12282 (clobber (reg:P CA_REGNO))]
12286 [(parallel [(set (match_dup 5)
12287 (plus:P (match_dup 4)
12289 (set (reg:P CA_REGNO)
12290 (ne:P (match_dup 4)
12292 (parallel [(set (match_dup 0)
12293 (plus:P (match_dup 3)
12295 (clobber (reg:P CA_REGNO))])]
12297 operands[4] = rs6000_emit_eqne (<MODE>mode,
12298 operands[1], operands[2], operands[4]);
12300 if (GET_CODE (operands[5]) == SCRATCH)
12301 operands[5] = gen_reg_rtx (<MODE>mode);
12303 [(set (attr "length")
12304 (if_then_else (match_test "operands[2] == const0_rtx")
12306 (const_string "12")))])
12308 (define_insn_and_split "*minus_eq_<mode>"
12309 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12310 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12311 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12312 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12313 (clobber (match_scratch:P 4 "=r"))
12314 (clobber (match_scratch:P 5 "=r"))
12315 (clobber (reg:P CA_REGNO))]
12319 [(parallel [(set (match_dup 5)
12320 (plus:P (match_dup 4)
12322 (set (reg:P CA_REGNO)
12323 (ne:P (match_dup 4)
12325 (parallel [(set (match_dup 0)
12326 (plus:P (plus:P (match_dup 3)
12329 (clobber (reg:P CA_REGNO))])]
12331 operands[4] = rs6000_emit_eqne (<MODE>mode,
12332 operands[1], operands[2], operands[4]);
12334 if (GET_CODE (operands[5]) == SCRATCH)
12335 operands[5] = gen_reg_rtx (<MODE>mode);
12337 [(set (attr "length")
12338 (if_then_else (match_test "operands[2] == const0_rtx")
12340 (const_string "12")))])
12342 (define_insn_and_split "*minus_ne_<mode>"
12343 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12344 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12345 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12346 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12347 (clobber (match_scratch:P 4 "=r"))
12348 (clobber (match_scratch:P 5 "=r"))
12349 (clobber (reg:P CA_REGNO))]
12353 [(parallel [(set (match_dup 5)
12354 (neg:P (match_dup 4)))
12355 (set (reg:P CA_REGNO)
12356 (eq:P (match_dup 4)
12358 (parallel [(set (match_dup 0)
12359 (plus:P (plus:P (match_dup 3)
12362 (clobber (reg:P CA_REGNO))])]
12364 operands[4] = rs6000_emit_eqne (<MODE>mode,
12365 operands[1], operands[2], operands[4]);
12367 if (GET_CODE (operands[5]) == SCRATCH)
12368 operands[5] = gen_reg_rtx (<MODE>mode);
12370 [(set (attr "length")
12371 (if_then_else (match_test "operands[2] == const0_rtx")
12373 (const_string "12")))])
12375 (define_insn_and_split "*eqsi3_ext<mode>"
12376 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12377 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12378 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12379 (clobber (match_scratch:SI 3 "=r"))
12380 (clobber (match_scratch:SI 4 "=r"))]
12384 [(set (match_dup 4)
12385 (clz:SI (match_dup 3)))
12388 (lshiftrt:SI (match_dup 4)
12391 operands[3] = rs6000_emit_eqne (SImode,
12392 operands[1], operands[2], operands[3]);
12394 if (GET_CODE (operands[4]) == SCRATCH)
12395 operands[4] = gen_reg_rtx (SImode);
12397 [(set (attr "length")
12398 (if_then_else (match_test "operands[2] == const0_rtx")
12400 (const_string "12")))])
12402 (define_insn_and_split "*nesi3_ext<mode>"
12403 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12404 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12405 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12406 (clobber (match_scratch:SI 3 "=r"))
12407 (clobber (match_scratch:SI 4 "=r"))
12408 (clobber (match_scratch:EXTSI 5 "=r"))]
12412 [(set (match_dup 4)
12413 (clz:SI (match_dup 3)))
12416 (lshiftrt:SI (match_dup 4)
12419 (xor:EXTSI (match_dup 5)
12422 operands[3] = rs6000_emit_eqne (SImode,
12423 operands[1], operands[2], operands[3]);
12425 if (GET_CODE (operands[4]) == SCRATCH)
12426 operands[4] = gen_reg_rtx (SImode);
12427 if (GET_CODE (operands[5]) == SCRATCH)
12428 operands[5] = gen_reg_rtx (<MODE>mode);
12430 [(set (attr "length")
12431 (if_then_else (match_test "operands[2] == const0_rtx")
12432 (const_string "12")
12433 (const_string "16")))])
12435 ;; Define both directions of branch and return. If we need a reload
12436 ;; register, we'd rather use CR0 since it is much easier to copy a
12437 ;; register CC value to there.
12441 (if_then_else (match_operator 1 "branch_comparison_operator"
12443 "cc_reg_operand" "y")
12445 (label_ref (match_operand 0 "" ""))
12450 return output_cbranch (operands[1], \"%l0\", 0, insn);
12452 [(set_attr "type" "branch")])
12456 (if_then_else (match_operator 0 "branch_comparison_operator"
12458 "cc_reg_operand" "y")
12465 return output_cbranch (operands[0], NULL, 0, insn);
12467 [(set_attr "type" "jmpreg")
12468 (set_attr "length" "4")])
12472 (if_then_else (match_operator 1 "branch_comparison_operator"
12474 "cc_reg_operand" "y")
12477 (label_ref (match_operand 0 "" ""))))]
12481 return output_cbranch (operands[1], \"%l0\", 1, insn);
12483 [(set_attr "type" "branch")])
12487 (if_then_else (match_operator 0 "branch_comparison_operator"
12489 "cc_reg_operand" "y")
12496 return output_cbranch (operands[0], NULL, 1, insn);
12498 [(set_attr "type" "jmpreg")
12499 (set_attr "length" "4")])
12501 ;; Logic on condition register values.
12503 ; This pattern matches things like
12504 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12505 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12507 ; which are generated by the branch logic.
12508 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12510 (define_insn "*cceq_ior_compare"
12511 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12512 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12513 [(match_operator:SI 2
12514 "branch_positive_comparison_operator"
12516 "cc_reg_operand" "y,y")
12518 (match_operator:SI 4
12519 "branch_positive_comparison_operator"
12521 "cc_reg_operand" "0,y")
12525 "cr%q1 %E0,%j2,%j4"
12526 [(set_attr "type" "cr_logical,delayed_cr")])
12528 ; Why is the constant -1 here, but 1 in the previous pattern?
12529 ; Because ~1 has all but the low bit set.
12531 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12532 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12533 [(not:SI (match_operator:SI 2
12534 "branch_positive_comparison_operator"
12536 "cc_reg_operand" "y,y")
12538 (match_operator:SI 4
12539 "branch_positive_comparison_operator"
12541 "cc_reg_operand" "0,y")
12545 "cr%q1 %E0,%j2,%j4"
12546 [(set_attr "type" "cr_logical,delayed_cr")])
12548 (define_insn "*cceq_rev_compare"
12549 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12550 (compare:CCEQ (match_operator:SI 1
12551 "branch_positive_comparison_operator"
12553 "cc_reg_operand" "0,y")
12558 [(set_attr "type" "cr_logical,delayed_cr")])
12560 ;; If we are comparing the result of two comparisons, this can be done
12561 ;; using creqv or crxor.
12563 (define_insn_and_split ""
12564 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12565 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12566 [(match_operand 2 "cc_reg_operand" "y")
12568 (match_operator 3 "branch_comparison_operator"
12569 [(match_operand 4 "cc_reg_operand" "y")
12574 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12578 int positive_1, positive_2;
12580 positive_1 = branch_positive_comparison_operator (operands[1],
12581 GET_MODE (operands[1]));
12582 positive_2 = branch_positive_comparison_operator (operands[3],
12583 GET_MODE (operands[3]));
12586 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12587 GET_CODE (operands[1])),
12589 operands[2], const0_rtx);
12590 else if (GET_MODE (operands[1]) != SImode)
12591 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12592 operands[2], const0_rtx);
12595 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12596 GET_CODE (operands[3])),
12598 operands[4], const0_rtx);
12599 else if (GET_MODE (operands[3]) != SImode)
12600 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12601 operands[4], const0_rtx);
12603 if (positive_1 == positive_2)
12605 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12606 operands[5] = constm1_rtx;
12610 operands[5] = const1_rtx;
12614 ;; Unconditional branch and return.
12616 (define_insn "jump"
12618 (label_ref (match_operand 0 "" "")))]
12621 [(set_attr "type" "branch")])
12623 (define_insn "<return_str>return"
12627 [(set_attr "type" "jmpreg")])
12629 (define_expand "indirect_jump"
12630 [(set (pc) (match_operand 0 "register_operand" ""))])
12632 (define_insn "*indirect_jump<mode>"
12633 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12638 [(set_attr "type" "jmpreg")])
12640 ;; Table jump for switch statements:
12641 (define_expand "tablejump"
12642 [(use (match_operand 0 "" ""))
12643 (use (label_ref (match_operand 1 "" "")))]
12648 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12650 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12654 (define_expand "tablejumpsi"
12655 [(set (match_dup 3)
12656 (plus:SI (match_operand:SI 0 "" "")
12658 (parallel [(set (pc) (match_dup 3))
12659 (use (label_ref (match_operand 1 "" "")))])]
12662 { operands[0] = force_reg (SImode, operands[0]);
12663 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12664 operands[3] = gen_reg_rtx (SImode);
12667 (define_expand "tablejumpdi"
12668 [(set (match_dup 4)
12669 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12671 (plus:DI (match_dup 4)
12673 (parallel [(set (pc) (match_dup 3))
12674 (use (label_ref (match_operand 1 "" "")))])]
12677 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12678 operands[3] = gen_reg_rtx (DImode);
12679 operands[4] = gen_reg_rtx (DImode);
12682 (define_insn "*tablejump<mode>_internal1"
12684 (match_operand:P 0 "register_operand" "c,*l"))
12685 (use (label_ref (match_operand 1 "" "")))]
12690 [(set_attr "type" "jmpreg")])
12693 [(unspec [(const_int 0)] UNSPEC_NOP)]
12697 (define_insn "group_ending_nop"
12698 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12702 if (rs6000_cpu_attr == CPU_POWER6)
12703 return \"ori 1,1,0\";
12704 return \"ori 2,2,0\";
12707 ;; Define the subtract-one-and-jump insns, starting with the template
12708 ;; so loop.c knows what to generate.
12710 (define_expand "doloop_end"
12711 [(use (match_operand 0 "" "")) ; loop pseudo
12712 (use (match_operand 1 "" ""))] ; label
12718 if (GET_MODE (operands[0]) != DImode)
12720 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12724 if (GET_MODE (operands[0]) != SImode)
12726 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12731 (define_expand "ctr<mode>"
12732 [(parallel [(set (pc)
12733 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12735 (label_ref (match_operand 1 "" ""))
12738 (plus:P (match_dup 0)
12740 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12741 (clobber (match_scratch:CC 2 ""))
12742 (clobber (match_scratch:P 3 ""))])]
12746 ;; We need to be able to do this for any operand, including MEM, or we
12747 ;; will cause reload to blow up since we don't allow output reloads on
12749 ;; For the length attribute to be calculated correctly, the
12750 ;; label MUST be operand 0.
12751 ;; The UNSPEC is present to prevent combine creating this pattern.
12753 (define_insn "*ctr<mode>_internal1"
12755 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12757 (label_ref (match_operand 0 "" ""))
12759 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12760 (plus:P (match_dup 1)
12762 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12763 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12764 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12768 if (which_alternative != 0)
12770 else if (get_attr_length (insn) == 4)
12771 return \"bdnz %l0\";
12773 return \"bdz $+8\;b %l0\";
12775 [(set_attr "type" "branch")
12776 (set_attr "length" "*,16,20,20")])
12778 (define_insn "*ctr<mode>_internal2"
12780 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12783 (label_ref (match_operand 0 "" ""))))
12784 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12785 (plus:P (match_dup 1)
12787 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12788 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12789 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12793 if (which_alternative != 0)
12795 else if (get_attr_length (insn) == 4)
12796 return \"bdz %l0\";
12798 return \"bdnz $+8\;b %l0\";
12800 [(set_attr "type" "branch")
12801 (set_attr "length" "*,16,20,20")])
12803 ;; Similar but use EQ
12805 (define_insn "*ctr<mode>_internal5"
12807 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12809 (label_ref (match_operand 0 "" ""))
12811 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12812 (plus:P (match_dup 1)
12814 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12815 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12816 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12820 if (which_alternative != 0)
12822 else if (get_attr_length (insn) == 4)
12823 return \"bdz %l0\";
12825 return \"bdnz $+8\;b %l0\";
12827 [(set_attr "type" "branch")
12828 (set_attr "length" "*,16,20,20")])
12830 (define_insn "*ctr<mode>_internal6"
12832 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12835 (label_ref (match_operand 0 "" ""))))
12836 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12837 (plus:P (match_dup 1)
12839 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12840 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12841 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12845 if (which_alternative != 0)
12847 else if (get_attr_length (insn) == 4)
12848 return \"bdnz %l0\";
12850 return \"bdz $+8\;b %l0\";
12852 [(set_attr "type" "branch")
12853 (set_attr "length" "*,16,20,20")])
12855 ;; Now the splitters if we could not allocate the CTR register
12859 (if_then_else (match_operator 2 "comparison_operator"
12860 [(match_operand:P 1 "gpc_reg_operand" "")
12862 (match_operand 5 "" "")
12863 (match_operand 6 "" "")))
12864 (set (match_operand:P 0 "int_reg_operand" "")
12865 (plus:P (match_dup 1) (const_int -1)))
12866 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12867 (clobber (match_scratch:CC 3 ""))
12868 (clobber (match_scratch:P 4 ""))]
12870 [(set (match_dup 3)
12871 (compare:CC (match_dup 1)
12874 (plus:P (match_dup 1)
12876 (set (pc) (if_then_else (match_dup 7)
12880 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12881 operands[3], const0_rtx); }")
12885 (if_then_else (match_operator 2 "comparison_operator"
12886 [(match_operand:P 1 "gpc_reg_operand" "")
12888 (match_operand 5 "" "")
12889 (match_operand 6 "" "")))
12890 (set (match_operand:P 0 "nonimmediate_operand" "")
12891 (plus:P (match_dup 1) (const_int -1)))
12892 (unspec [(const_int 0)] UNSPEC_DOLOOP)
12893 (clobber (match_scratch:CC 3 ""))
12894 (clobber (match_scratch:P 4 ""))]
12895 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12896 [(set (match_dup 3)
12897 (compare:CC (match_dup 1)
12900 (plus:P (match_dup 1)
12904 (set (pc) (if_then_else (match_dup 7)
12908 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12909 operands[3], const0_rtx); }")
12911 (define_insn "trap"
12912 [(trap_if (const_int 1) (const_int 0))]
12915 [(set_attr "type" "trap")])
12917 (define_expand "ctrap<mode>4"
12918 [(trap_if (match_operator 0 "ordered_comparison_operator"
12919 [(match_operand:GPR 1 "register_operand")
12920 (match_operand:GPR 2 "reg_or_short_operand")])
12921 (match_operand 3 "zero_constant" ""))]
12926 [(trap_if (match_operator 0 "ordered_comparison_operator"
12927 [(match_operand:GPR 1 "register_operand" "r")
12928 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12931 "t<wd>%V0%I2 %1,%2"
12932 [(set_attr "type" "trap")])
12934 ;; Insns related to generating the function prologue and epilogue.
12936 (define_expand "prologue"
12937 [(use (const_int 0))]
12940 rs6000_emit_prologue ();
12941 if (!TARGET_SCHED_PROLOG)
12942 emit_insn (gen_blockage ());
12946 (define_insn "*movesi_from_cr_one"
12947 [(match_parallel 0 "mfcr_operation"
12948 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12949 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12950 (match_operand 3 "immediate_operand" "n")]
12951 UNSPEC_MOVESI_FROM_CR))])]
12957 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12959 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12960 operands[4] = GEN_INT (mask);
12961 output_asm_insn (\"mfcr %1,%4\", operands);
12965 [(set_attr "type" "mfcrf")])
12967 (define_insn "movesi_from_cr"
12968 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12969 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12970 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12971 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12972 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12973 UNSPEC_MOVESI_FROM_CR))]
12976 [(set_attr "type" "mfcr")])
12978 (define_insn "*crsave"
12979 [(match_parallel 0 "crsave_operation"
12980 [(set (match_operand:SI 1 "memory_operand" "=m")
12981 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12984 [(set_attr "type" "store")])
12986 (define_insn "*stmw"
12987 [(match_parallel 0 "stmw_operation"
12988 [(set (match_operand:SI 1 "memory_operand" "=m")
12989 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12992 [(set_attr "type" "store")
12993 (set_attr "update" "yes")
12994 (set_attr "indexed" "yes")])
12996 ; The following comment applies to:
13000 ; return_and_restore_gpregs*
13001 ; return_and_restore_fpregs*
13002 ; return_and_restore_fpregs_aix*
13004 ; The out-of-line save / restore functions expects one input argument.
13005 ; Since those are not standard call_insn's, we must avoid using
13006 ; MATCH_OPERAND for that argument. That way the register rename
13007 ; optimization will not try to rename this register.
13008 ; Each pattern is repeated for each possible register number used in
13009 ; various ABIs (r11, r1, and for some functions r12)
13011 (define_insn "*save_gpregs_<mode>_r11"
13012 [(match_parallel 0 "any_parallel_operand"
13013 [(clobber (reg:P LR_REGNO))
13014 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13016 (set (match_operand:P 2 "memory_operand" "=m")
13017 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13020 [(set_attr "type" "branch")
13021 (set_attr "length" "4")])
13023 (define_insn "*save_gpregs_<mode>_r12"
13024 [(match_parallel 0 "any_parallel_operand"
13025 [(clobber (reg:P LR_REGNO))
13026 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13028 (set (match_operand:P 2 "memory_operand" "=m")
13029 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13032 [(set_attr "type" "branch")
13033 (set_attr "length" "4")])
13035 (define_insn "*save_gpregs_<mode>_r1"
13036 [(match_parallel 0 "any_parallel_operand"
13037 [(clobber (reg:P LR_REGNO))
13038 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13040 (set (match_operand:P 2 "memory_operand" "=m")
13041 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13044 [(set_attr "type" "branch")
13045 (set_attr "length" "4")])
13047 (define_insn "*save_fpregs_<mode>_r11"
13048 [(match_parallel 0 "any_parallel_operand"
13049 [(clobber (reg:P LR_REGNO))
13050 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13052 (set (match_operand:DF 2 "memory_operand" "=m")
13053 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13056 [(set_attr "type" "branch")
13057 (set_attr "length" "4")])
13059 (define_insn "*save_fpregs_<mode>_r12"
13060 [(match_parallel 0 "any_parallel_operand"
13061 [(clobber (reg:P LR_REGNO))
13062 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13064 (set (match_operand:DF 2 "memory_operand" "=m")
13065 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13068 [(set_attr "type" "branch")
13069 (set_attr "length" "4")])
13071 (define_insn "*save_fpregs_<mode>_r1"
13072 [(match_parallel 0 "any_parallel_operand"
13073 [(clobber (reg:P LR_REGNO))
13074 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13076 (set (match_operand:DF 2 "memory_operand" "=m")
13077 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13080 [(set_attr "type" "branch")
13081 (set_attr "length" "4")])
13083 ; This is to explain that changes to the stack pointer should
13084 ; not be moved over loads from or stores to stack memory.
13085 (define_insn "stack_tie"
13086 [(match_parallel 0 "tie_operand"
13087 [(set (mem:BLK (reg 1)) (const_int 0))])]
13090 [(set_attr "length" "0")])
13092 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13093 ; stay behind all restores from the stack, it cannot be reordered to before
13094 ; one. See PR77687. This insn is an add or mr, and a stack_tie on the
13095 ; operands of that.
13096 (define_insn "stack_restore_tie"
13097 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13098 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13099 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13100 (set (mem:BLK (match_dup 0)) (const_int 0))
13101 (set (mem:BLK (match_dup 1)) (const_int 0))]
13106 [(set_attr "type" "*,add")])
13108 (define_expand "epilogue"
13109 [(use (const_int 0))]
13112 if (!TARGET_SCHED_PROLOG)
13113 emit_insn (gen_blockage ());
13114 rs6000_emit_epilogue (FALSE);
13118 ; On some processors, doing the mtcrf one CC register at a time is
13119 ; faster (like on the 604e). On others, doing them all at once is
13120 ; faster; for instance, on the 601 and 750.
13122 (define_expand "movsi_to_cr_one"
13123 [(set (match_operand:CC 0 "cc_reg_operand" "")
13124 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13125 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13127 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13129 (define_insn "*movsi_to_cr"
13130 [(match_parallel 0 "mtcrf_operation"
13131 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13132 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13133 (match_operand 3 "immediate_operand" "n")]
13134 UNSPEC_MOVESI_TO_CR))])]
13140 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13141 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13142 operands[4] = GEN_INT (mask);
13143 return \"mtcrf %4,%2\";
13145 [(set_attr "type" "mtcr")])
13147 (define_insn "*mtcrfsi"
13148 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13149 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13150 (match_operand 2 "immediate_operand" "n")]
13151 UNSPEC_MOVESI_TO_CR))]
13152 "GET_CODE (operands[0]) == REG
13153 && CR_REGNO_P (REGNO (operands[0]))
13154 && GET_CODE (operands[2]) == CONST_INT
13155 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13157 [(set_attr "type" "mtcr")])
13159 ; The load-multiple instructions have similar properties.
13160 ; Note that "load_multiple" is a name known to the machine-independent
13161 ; code that actually corresponds to the PowerPC load-string.
13163 (define_insn "*lmw"
13164 [(match_parallel 0 "lmw_operation"
13165 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13166 (match_operand:SI 2 "memory_operand" "m"))])]
13169 [(set_attr "type" "load")
13170 (set_attr "update" "yes")
13171 (set_attr "indexed" "yes")
13172 (set_attr "cell_micro" "always")])
13174 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13175 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13177 ; The following comment applies to:
13181 ; return_and_restore_gpregs*
13182 ; return_and_restore_fpregs*
13183 ; return_and_restore_fpregs_aix*
13185 ; The out-of-line save / restore functions expects one input argument.
13186 ; Since those are not standard call_insn's, we must avoid using
13187 ; MATCH_OPERAND for that argument. That way the register rename
13188 ; optimization will not try to rename this register.
13189 ; Each pattern is repeated for each possible register number used in
13190 ; various ABIs (r11, r1, and for some functions r12)
13192 (define_insn "*restore_gpregs_<mode>_r11"
13193 [(match_parallel 0 "any_parallel_operand"
13194 [(clobber (reg:P LR_REGNO))
13195 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13197 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13198 (match_operand:P 3 "memory_operand" "m"))])]
13201 [(set_attr "type" "branch")
13202 (set_attr "length" "4")])
13204 (define_insn "*restore_gpregs_<mode>_r12"
13205 [(match_parallel 0 "any_parallel_operand"
13206 [(clobber (reg:P LR_REGNO))
13207 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13209 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13210 (match_operand:P 3 "memory_operand" "m"))])]
13213 [(set_attr "type" "branch")
13214 (set_attr "length" "4")])
13216 (define_insn "*restore_gpregs_<mode>_r1"
13217 [(match_parallel 0 "any_parallel_operand"
13218 [(clobber (reg:P LR_REGNO))
13219 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13221 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13222 (match_operand:P 3 "memory_operand" "m"))])]
13225 [(set_attr "type" "branch")
13226 (set_attr "length" "4")])
13228 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13229 [(match_parallel 0 "any_parallel_operand"
13231 (clobber (reg:P LR_REGNO))
13232 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13234 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13235 (match_operand:P 3 "memory_operand" "m"))])]
13238 [(set_attr "type" "branch")
13239 (set_attr "length" "4")])
13241 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13242 [(match_parallel 0 "any_parallel_operand"
13244 (clobber (reg:P LR_REGNO))
13245 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13247 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13248 (match_operand:P 3 "memory_operand" "m"))])]
13251 [(set_attr "type" "branch")
13252 (set_attr "length" "4")])
13254 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13255 [(match_parallel 0 "any_parallel_operand"
13257 (clobber (reg:P LR_REGNO))
13258 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13260 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13261 (match_operand:P 3 "memory_operand" "m"))])]
13264 [(set_attr "type" "branch")
13265 (set_attr "length" "4")])
13267 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13268 [(match_parallel 0 "any_parallel_operand"
13270 (clobber (reg:P LR_REGNO))
13271 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13273 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13274 (match_operand:DF 3 "memory_operand" "m"))])]
13277 [(set_attr "type" "branch")
13278 (set_attr "length" "4")])
13280 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13281 [(match_parallel 0 "any_parallel_operand"
13283 (clobber (reg:P LR_REGNO))
13284 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13286 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13287 (match_operand:DF 3 "memory_operand" "m"))])]
13290 [(set_attr "type" "branch")
13291 (set_attr "length" "4")])
13293 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13294 [(match_parallel 0 "any_parallel_operand"
13296 (clobber (reg:P LR_REGNO))
13297 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13299 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13300 (match_operand:DF 3 "memory_operand" "m"))])]
13303 [(set_attr "type" "branch")
13304 (set_attr "length" "4")])
13306 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13307 [(match_parallel 0 "any_parallel_operand"
13309 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13311 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13312 (match_operand:DF 3 "memory_operand" "m"))])]
13315 [(set_attr "type" "branch")
13316 (set_attr "length" "4")])
13318 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13319 [(match_parallel 0 "any_parallel_operand"
13321 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13323 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13324 (match_operand:DF 3 "memory_operand" "m"))])]
13327 [(set_attr "type" "branch")
13328 (set_attr "length" "4")])
13330 ; This is used in compiling the unwind routines.
13331 (define_expand "eh_return"
13332 [(use (match_operand 0 "general_operand" ""))]
13337 emit_insn (gen_eh_set_lr_si (operands[0]));
13339 emit_insn (gen_eh_set_lr_di (operands[0]));
13343 ; We can't expand this before we know where the link register is stored.
13344 (define_insn "eh_set_lr_<mode>"
13345 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13347 (clobber (match_scratch:P 1 "=&b"))]
13352 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13353 (clobber (match_scratch 1 ""))]
13358 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13362 (define_insn "prefetch"
13363 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13364 (match_operand:SI 1 "const_int_operand" "n")
13365 (match_operand:SI 2 "const_int_operand" "n"))]
13369 if (GET_CODE (operands[0]) == REG)
13370 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13371 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13373 [(set_attr "type" "load")])
13375 ;; Handle -fsplit-stack.
13377 (define_expand "split_stack_prologue"
13381 rs6000_expand_split_stack_prologue ();
13385 (define_expand "load_split_stack_limit"
13386 [(set (match_operand 0)
13387 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13390 emit_insn (gen_rtx_SET (operands[0],
13391 gen_rtx_UNSPEC (Pmode,
13392 gen_rtvec (1, const0_rtx),
13393 UNSPEC_STACK_CHECK)));
13397 (define_insn "load_split_stack_limit_di"
13398 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13399 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13401 "ld %0,-0x7040(13)"
13402 [(set_attr "type" "load")
13403 (set_attr "update" "no")
13404 (set_attr "indexed" "no")])
13406 (define_insn "load_split_stack_limit_si"
13407 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13408 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13410 "lwz %0,-0x7020(2)"
13411 [(set_attr "type" "load")
13412 (set_attr "update" "no")
13413 (set_attr "indexed" "no")])
13415 ;; A return instruction which the middle-end doesn't see.
13416 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13417 ;; after the call to __morestack.
13418 (define_insn "split_stack_return"
13419 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13422 [(set_attr "type" "jmpreg")])
13424 ;; If there are operand 0 bytes available on the stack, jump to
13426 (define_expand "split_stack_space_check"
13427 [(set (match_dup 2)
13428 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13430 (minus (reg STACK_POINTER_REGNUM)
13431 (match_operand 0)))
13432 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13433 (set (pc) (if_then_else
13434 (geu (match_dup 4) (const_int 0))
13435 (label_ref (match_operand 1))
13439 rs6000_split_stack_space_check (operands[0], operands[1]);
13443 (define_insn "bpermd_<mode>"
13444 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13445 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13446 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13449 [(set_attr "type" "popcnt")])
13452 ;; Builtin fma support. Handle
13453 ;; Note that the conditions for expansion are in the FMA_F iterator.
13455 (define_expand "fma<mode>4"
13456 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13458 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13459 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13460 (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13464 (define_insn "*fma<mode>4_fpr"
13465 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13467 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13468 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13469 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13470 "TARGET_<MODE>_FPR"
13472 fmadd<Ftrad> %0,%1,%2,%3
13473 xsmadda<Fvsx> %x0,%x1,%x2
13474 xsmaddm<Fvsx> %x0,%x1,%x3"
13475 [(set_attr "type" "fp")
13476 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13478 ; Altivec only has fma and nfms.
13479 (define_expand "fms<mode>4"
13480 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13482 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13483 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13484 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13485 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13488 (define_insn "*fms<mode>4_fpr"
13489 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13491 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13492 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13493 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13494 "TARGET_<MODE>_FPR"
13496 fmsub<Ftrad> %0,%1,%2,%3
13497 xsmsuba<Fvsx> %x0,%x1,%x2
13498 xsmsubm<Fvsx> %x0,%x1,%x3"
13499 [(set_attr "type" "fp")
13500 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13502 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13503 (define_expand "fnma<mode>4"
13504 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13507 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13508 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13509 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13510 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13513 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13514 (define_expand "fnms<mode>4"
13515 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13518 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13519 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13520 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13521 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13524 ; Not an official optab name, but used from builtins.
13525 (define_expand "nfma<mode>4"
13526 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13529 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13530 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13531 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13532 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13535 (define_insn "*nfma<mode>4_fpr"
13536 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13539 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13540 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13541 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13542 "TARGET_<MODE>_FPR"
13544 fnmadd<Ftrad> %0,%1,%2,%3
13545 xsnmadda<Fvsx> %x0,%x1,%x2
13546 xsnmaddm<Fvsx> %x0,%x1,%x3"
13547 [(set_attr "type" "fp")
13548 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13550 ; Not an official optab name, but used from builtins.
13551 (define_expand "nfms<mode>4"
13552 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13555 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13556 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13557 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13561 (define_insn "*nfmssf4_fpr"
13562 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13565 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13566 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13568 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13569 "TARGET_<MODE>_FPR"
13571 fnmsub<Ftrad> %0,%1,%2,%3
13572 xsnmsuba<Fvsx> %x0,%x1,%x2
13573 xsnmsubm<Fvsx> %x0,%x1,%x3"
13574 [(set_attr "type" "fp")
13575 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13578 (define_expand "rs6000_get_timebase"
13579 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13582 if (TARGET_POWERPC64)
13583 emit_insn (gen_rs6000_mftb_di (operands[0]));
13585 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13589 (define_insn "rs6000_get_timebase_ppc32"
13590 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13591 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13592 (clobber (match_scratch:SI 1 "=r"))
13593 (clobber (match_scratch:CC 2 "=y"))]
13594 "!TARGET_POWERPC64"
13596 if (WORDS_BIG_ENDIAN)
13599 return "mfspr %0,269\;"
13607 return "mftbu %0\;"
13616 return "mfspr %L0,269\;"
13624 return "mftbu %L0\;"
13631 [(set_attr "length" "20")])
13633 (define_insn "rs6000_mftb_<mode>"
13634 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13635 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13639 return "mfspr %0,268";
13645 (define_insn "rs6000_mffs"
13646 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13647 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13648 "TARGET_HARD_FLOAT && TARGET_FPRS"
13651 (define_insn "rs6000_mtfsf"
13652 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13653 (match_operand:DF 1 "gpc_reg_operand" "d")]
13655 "TARGET_HARD_FLOAT && TARGET_FPRS"
13659 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13660 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13661 ;; register that is being loaded. The fused ops must be physically adjacent.
13663 ;; There are two parts to addis fusion. The support for fused TOCs occur
13664 ;; before register allocation, and is meant to reduce the lifetime for the
13665 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13666 ;; to use the register that is being load. The peephole2 then gathers any
13667 ;; other fused possibilities that it can find after register allocation. If
13668 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13670 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13671 ;; before register allocation, so that we can avoid allocating a temporary base
13672 ;; register that won't be used, and that we try to load into base registers,
13673 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13674 ;; (addis followed by load) even on power8.
13677 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13678 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13679 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13680 [(parallel [(set (match_dup 0) (match_dup 2))
13681 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13682 (use (match_dup 3))
13683 (clobber (scratch:DI))])]
13685 operands[2] = fusion_wrap_memory_address (operands[1]);
13686 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13689 (define_insn "*toc_fusionload_<mode>"
13690 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13691 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13692 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13693 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13694 (clobber (match_scratch:DI 3 "=X,&b"))]
13695 "TARGET_TOC_FUSION_INT"
13697 if (base_reg_operand (operands[0], <MODE>mode))
13698 return emit_fusion_gpr_load (operands[0], operands[1]);
13700 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13702 [(set_attr "type" "load")
13703 (set_attr "length" "8")])
13705 (define_insn "*toc_fusionload_di"
13706 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13707 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13708 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13709 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13710 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13711 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13712 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13714 if (base_reg_operand (operands[0], DImode))
13715 return emit_fusion_gpr_load (operands[0], operands[1]);
13717 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13719 [(set_attr "type" "load")
13720 (set_attr "length" "8")])
13723 ;; Find cases where the addis that feeds into a load instruction is either used
13724 ;; once or is the same as the target register, and replace it with the fusion
13728 [(set (match_operand:P 0 "base_reg_operand" "")
13729 (match_operand:P 1 "fusion_gpr_addis" ""))
13730 (set (match_operand:INT1 2 "base_reg_operand" "")
13731 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13733 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13737 expand_fusion_gpr_load (operands);
13741 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13744 (define_insn "fusion_gpr_load_<mode>"
13745 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13746 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13747 UNSPEC_FUSION_GPR))]
13750 return emit_fusion_gpr_load (operands[0], operands[1]);
13752 [(set_attr "type" "load")
13753 (set_attr "length" "8")])
13756 ;; ISA 3.0 (power9) fusion support
13757 ;; Merge addis with floating load/store to FPRs (or GPRs).
13759 [(set (match_operand:P 0 "base_reg_operand" "")
13760 (match_operand:P 1 "fusion_gpr_addis" ""))
13761 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13762 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13763 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13764 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13767 expand_fusion_p9_load (operands);
13772 [(set (match_operand:P 0 "base_reg_operand" "")
13773 (match_operand:P 1 "fusion_gpr_addis" ""))
13774 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13775 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13776 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13777 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13778 && !rtx_equal_p (operands[0], operands[3])"
13781 expand_fusion_p9_store (operands);
13786 [(set (match_operand:SDI 0 "int_reg_operand" "")
13787 (match_operand:SDI 1 "upper16_cint_operand" ""))
13789 (ior:SDI (match_dup 0)
13790 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13792 [(set (match_dup 0)
13793 (unspec:SDI [(match_dup 1)
13794 (match_dup 2)] UNSPEC_FUSION_P9))])
13797 [(set (match_operand:SDI 0 "int_reg_operand" "")
13798 (match_operand:SDI 1 "upper16_cint_operand" ""))
13799 (set (match_operand:SDI 2 "int_reg_operand" "")
13800 (ior:SDI (match_dup 0)
13801 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13803 && !rtx_equal_p (operands[0], operands[2])
13804 && peep2_reg_dead_p (2, operands[0])"
13805 [(set (match_dup 2)
13806 (unspec:SDI [(match_dup 1)
13807 (match_dup 3)] UNSPEC_FUSION_P9))])
13809 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13810 ;; reload). Because we want to eventually have secondary_reload generate
13811 ;; these, they have to have a single alternative that gives the register
13812 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13813 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13814 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13816 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13818 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13821 /* This insn is a secondary reload insn, which cannot have alternatives.
13822 If we are not loading up register 0, use the power8 fusion instead. */
13823 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13824 return emit_fusion_gpr_load (operands[0], operands[1]);
13826 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13828 [(set_attr "type" "load")
13829 (set_attr "length" "8")])
13831 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13832 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13834 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13836 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13839 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13841 [(set_attr "type" "store")
13842 (set_attr "length" "8")])
13844 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13845 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13847 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13849 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13852 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13854 [(set_attr "type" "fpload")
13855 (set_attr "length" "8")])
13857 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13858 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13860 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13862 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13865 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13867 [(set_attr "type" "fpstore")
13868 (set_attr "length" "8")])
13870 (define_insn "*fusion_p9_<mode>_constant"
13871 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13872 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13873 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13874 UNSPEC_FUSION_P9))]
13877 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13878 return "ori %0,%0,%2";
13880 [(set_attr "type" "two")
13881 (set_attr "length" "8")])
13884 ;; Miscellaneous ISA 2.06 (power7) instructions
13885 (define_insn "addg6s"
13886 [(set (match_operand:SI 0 "register_operand" "=r")
13887 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13888 (match_operand:SI 2 "register_operand" "r")]
13892 [(set_attr "type" "integer")
13893 (set_attr "length" "4")])
13895 (define_insn "cdtbcd"
13896 [(set (match_operand:SI 0 "register_operand" "=r")
13897 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13901 [(set_attr "type" "integer")
13902 (set_attr "length" "4")])
13904 (define_insn "cbcdtd"
13905 [(set (match_operand:SI 0 "register_operand" "=r")
13906 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13910 [(set_attr "type" "integer")
13911 (set_attr "length" "4")])
13913 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13918 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13919 (UNSPEC_DIVEO "eo")
13920 (UNSPEC_DIVEU "eu")
13921 (UNSPEC_DIVEUO "euo")])
13923 (define_insn "div<div_extend>_<mode>"
13924 [(set (match_operand:GPR 0 "register_operand" "=r")
13925 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13926 (match_operand:GPR 2 "register_operand" "r")]
13927 UNSPEC_DIV_EXTEND))]
13929 "div<wd><div_extend> %0,%1,%2"
13930 [(set_attr "type" "div")
13931 (set_attr "size" "<bits>")])
13934 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13936 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13937 (define_mode_attr FP128_64 [(TF "DF")
13942 (define_expand "unpack<mode>"
13943 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13945 [(match_operand:FMOVE128 1 "register_operand" "")
13946 (match_operand:QI 2 "const_0_to_1_operand" "")]
13947 UNSPEC_UNPACK_128BIT))]
13948 "FLOAT128_2REG_P (<MODE>mode)"
13951 (define_insn_and_split "unpack<mode>_dm"
13952 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13954 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13955 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13956 UNSPEC_UNPACK_128BIT))]
13957 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13959 "&& reload_completed"
13960 [(set (match_dup 0) (match_dup 3))]
13962 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13964 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13966 emit_note (NOTE_INSN_DELETED);
13970 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13972 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13973 (set_attr "length" "4")])
13975 (define_insn_and_split "unpack<mode>_nodm"
13976 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13978 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13979 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13980 UNSPEC_UNPACK_128BIT))]
13981 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13983 "&& reload_completed"
13984 [(set (match_dup 0) (match_dup 3))]
13986 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13988 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13990 emit_note (NOTE_INSN_DELETED);
13994 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13996 [(set_attr "type" "fp,fpstore")
13997 (set_attr "length" "4")])
13999 (define_insn_and_split "pack<mode>"
14000 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14002 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14003 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14004 UNSPEC_PACK_128BIT))]
14005 "FLOAT128_2REG_P (<MODE>mode)"
14009 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14010 [(set (match_dup 3) (match_dup 1))
14011 (set (match_dup 4) (match_dup 2))]
14013 unsigned dest_hi = REGNO (operands[0]);
14014 unsigned dest_lo = dest_hi + 1;
14016 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14017 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14019 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14020 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14022 [(set_attr "type" "fpsimple,fp")
14023 (set_attr "length" "4,8")])
14025 (define_insn "unpack<mode>"
14026 [(set (match_operand:DI 0 "register_operand" "=d,d")
14027 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14028 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14029 UNSPEC_UNPACK_128BIT))]
14030 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14032 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14033 return ASM_COMMENT_START " xxpermdi to same register";
14035 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14036 return "xxpermdi %x0,%x1,%x1,%3";
14038 [(set_attr "type" "vecperm")])
14040 (define_insn "pack<mode>"
14041 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14042 (unspec:FMOVE128_VSX
14043 [(match_operand:DI 1 "register_operand" "d")
14044 (match_operand:DI 2 "register_operand" "d")]
14045 UNSPEC_PACK_128BIT))]
14047 "xxpermdi %x0,%x1,%x2,0"
14048 [(set_attr "type" "vecperm")])
14052 ;; ISA 2.08 IEEE 128-bit floating point support.
14054 (define_insn "add<mode>3"
14055 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14057 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14058 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14059 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14061 [(set_attr "type" "vecfloat")
14062 (set_attr "size" "128")])
14064 (define_insn "sub<mode>3"
14065 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14067 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14068 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14069 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14071 [(set_attr "type" "vecfloat")
14072 (set_attr "size" "128")])
14074 (define_insn "mul<mode>3"
14075 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14077 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14078 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14079 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14081 [(set_attr "type" "vecfloat")
14082 (set_attr "size" "128")])
14084 (define_insn "div<mode>3"
14085 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14087 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14088 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14089 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14091 [(set_attr "type" "vecdiv")
14092 (set_attr "size" "128")])
14094 (define_insn "sqrt<mode>2"
14095 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14097 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14098 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14100 [(set_attr "type" "vecdiv")
14101 (set_attr "size" "128")])
14103 (define_expand "copysign<mode>3"
14104 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14105 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14106 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14107 "FLOAT128_IEEE_P (<MODE>mode)"
14109 if (TARGET_FLOAT128_HW)
14110 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14114 rtx tmp = gen_reg_rtx (<MODE>mode);
14115 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14116 operands[2], tmp));
14121 (define_insn "copysign<mode>3_hard"
14122 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14124 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14125 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14127 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14128 "xscpsgnqp %0,%2,%1"
14129 [(set_attr "type" "vecmove")
14130 (set_attr "size" "128")])
14132 (define_insn "copysign<mode>3_soft"
14133 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14135 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14136 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14137 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14139 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14140 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14141 [(set_attr "type" "veccomplex")
14142 (set_attr "length" "8")])
14144 (define_insn "neg<mode>2_hw"
14145 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14147 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14148 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14150 [(set_attr "type" "vecmove")
14151 (set_attr "size" "128")])
14154 (define_insn "abs<mode>2_hw"
14155 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14157 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14158 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14160 [(set_attr "type" "vecmove")
14161 (set_attr "size" "128")])
14164 (define_insn "*nabs<mode>2_hw"
14165 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14168 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14169 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14171 [(set_attr "type" "vecmove")
14172 (set_attr "size" "128")])
14174 ;; Initially don't worry about doing fusion
14175 (define_insn "*fma<mode>4_hw"
14176 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14178 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14179 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14180 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14181 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14182 "xsmaddqp %0,%1,%2"
14183 [(set_attr "type" "vecfloat")
14184 (set_attr "size" "128")])
14186 (define_insn "*fms<mode>4_hw"
14187 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14189 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14190 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14192 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14193 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14194 "xsmsubqp %0,%1,%2"
14195 [(set_attr "type" "vecfloat")
14196 (set_attr "size" "128")])
14198 (define_insn "*nfma<mode>4_hw"
14199 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14202 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14203 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14204 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14205 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14206 "xsnmaddqp %0,%1,%2"
14207 [(set_attr "type" "vecfloat")
14208 (set_attr "size" "128")])
14210 (define_insn "*nfms<mode>4_hw"
14211 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14214 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14215 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14217 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14218 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14219 "xsnmsubqp %0,%1,%2"
14220 [(set_attr "type" "vecfloat")
14221 (set_attr "size" "128")])
14223 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14224 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14225 (float_extend:IEEE128
14226 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14227 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14229 [(set_attr "type" "vecfloat")
14230 (set_attr "size" "128")])
14232 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14233 ;; point is a simple copy.
14234 (define_insn_and_split "extendkftf2"
14235 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14236 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14237 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14241 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14244 emit_note (NOTE_INSN_DELETED);
14247 [(set_attr "type" "*,veclogical")
14248 (set_attr "length" "0,4")])
14250 (define_insn_and_split "trunctfkf2"
14251 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14252 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14253 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14257 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14260 emit_note (NOTE_INSN_DELETED);
14263 [(set_attr "type" "*,veclogical")
14264 (set_attr "length" "0,4")])
14266 (define_insn "trunc<mode>df2_hw"
14267 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14269 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14270 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14272 [(set_attr "type" "vecfloat")
14273 (set_attr "size" "128")])
14275 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14276 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14278 (define_insn_and_split "trunc<mode>sf2_hw"
14279 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14281 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14282 (clobber (match_scratch:DF 2 "=v"))]
14283 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14286 [(set (match_dup 2)
14287 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14289 (float_truncate:SF (match_dup 2)))]
14291 if (GET_CODE (operands[2]) == SCRATCH)
14292 operands[2] = gen_reg_rtx (DFmode);
14294 [(set_attr "type" "vecfloat")
14295 (set_attr "length" "8")])
14297 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
14298 ;; allowed in the traditional floating point registers. Use V2DImode so that
14299 ;; we can get a value in an Altivec register.
14301 (define_insn_and_split "fix<uns>_<mode>si2_hw"
14302 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
14303 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
14304 (clobber (match_scratch:V2DI 2 "=v,v"))]
14305 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14310 convert_float128_to_int (operands, <CODE>);
14313 [(set_attr "length" "8")
14314 (set_attr "type" "mftgpr,fpstore")])
14316 (define_insn_and_split "fix<uns>_<mode>di2_hw"
14317 [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
14318 (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
14319 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
14320 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14325 convert_float128_to_int (operands, <CODE>);
14328 [(set_attr "length" "8")
14329 (set_attr "type" "mftgpr,vecsimple,fpstore")])
14331 (define_insn_and_split "float<uns>_<mode>si2_hw"
14332 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
14333 (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
14334 (clobber (match_scratch:V2DI 2 "=v,v"))]
14335 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14340 convert_int_to_float128 (operands, <CODE>);
14343 [(set_attr "length" "8")
14344 (set_attr "type" "vecfloat")])
14346 (define_insn_and_split "float<uns>_<mode>di2_hw"
14347 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14348 (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
14349 (clobber (match_scratch:V2DI 2 "=v,v,v"))]
14350 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14355 convert_int_to_float128 (operands, <CODE>);
14358 [(set_attr "length" "8")
14359 (set_attr "type" "vecfloat")])
14361 ;; Integer conversion instructions, using V2DImode to get an Altivec register
14362 (define_insn "*xscvqp<su>wz_<mode>"
14363 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
14366 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
14367 UNSPEC_IEEE128_CONVERT))]
14368 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14369 "xscvqp<su>wz %0,%1"
14370 [(set_attr "type" "vecfloat")
14371 (set_attr "size" "128")])
14373 (define_insn "*xscvqp<su>dz_<mode>"
14374 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
14377 (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
14378 UNSPEC_IEEE128_CONVERT))]
14379 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14380 "xscvqp<su>dz %0,%1"
14381 [(set_attr "type" "vecfloat")
14382 (set_attr "size" "128")])
14384 (define_insn "*xscv<su>dqp_<mode>"
14385 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14387 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
14388 UNSPEC_IEEE128_CONVERT)))]
14389 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14390 "xscv<su>dqp %0,%1"
14391 [(set_attr "type" "vecfloat")
14392 (set_attr "size" "128")])
14394 (define_insn "*ieee128_mfvsrd_64bit"
14395 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
14396 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
14397 UNSPEC_IEEE128_MOVE))]
14398 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
14403 [(set_attr "type" "mftgpr,fpstore,veclogical")])
14406 (define_insn "*ieee128_mfvsrd_32bit"
14407 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
14408 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
14409 UNSPEC_IEEE128_MOVE))]
14410 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
14414 [(set_attr "type" "fpstore,veclogical")])
14416 (define_insn "*ieee128_mfvsrwz"
14417 [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
14418 (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
14419 UNSPEC_IEEE128_MOVE))]
14420 "TARGET_FLOAT128_HW"
14424 [(set_attr "type" "mftgpr,fpstore")])
14426 ;; 0 says do sign-extension, 1 says zero-extension
14427 (define_insn "*ieee128_mtvsrw"
14428 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
14429 (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
14430 (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
14431 UNSPEC_IEEE128_MOVE))]
14432 "TARGET_FLOAT128_HW"
14438 [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
14441 (define_insn "*ieee128_mtvsrd_64bit"
14442 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
14443 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
14444 UNSPEC_IEEE128_MOVE))]
14445 "TARGET_FLOAT128_HW && TARGET_POWERPC64"
14450 [(set_attr "type" "mffgpr,fpload,veclogical")])
14452 (define_insn "*ieee128_mtvsrd_32bit"
14453 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
14454 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
14455 UNSPEC_IEEE128_MOVE))]
14456 "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
14460 [(set_attr "type" "fpload,veclogical")])
14462 ;; IEEE 128-bit instructions with round to odd semantics
14463 (define_insn "*trunc<mode>df2_odd"
14464 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14465 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14466 UNSPEC_ROUND_TO_ODD))]
14467 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14469 [(set_attr "type" "vecfloat")
14470 (set_attr "size" "128")])
14472 ;; IEEE 128-bit comparisons
14473 (define_insn "*cmp<mode>_hw"
14474 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14475 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14476 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14477 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14478 "xscmpuqp %0,%1,%2"
14479 [(set_attr "type" "veccmp")
14480 (set_attr "size" "128")])
14484 (include "sync.md")
14485 (include "vector.md")
14487 (include "altivec.md")
14490 (include "paired.md")
14491 (include "crypto.md")