1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2018 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (STACK_POINTER_REGNUM 1)
31 (STATIC_CHAIN_REGNUM 11)
32 (HARD_FRAME_POINTER_REGNUM 31)
38 (ARG_POINTER_REGNUM 67)
49 (FIRST_ALTIVEC_REGNO 77)
50 (LAST_ALTIVEC_REGNO 108)
53 (FRAME_POINTER_REGNUM 111)
63 (define_c_enum "unspec"
64 [UNSPEC_FRSP ; frsp for POWER machines
65 UNSPEC_PROBE_STACK ; probe stack memory reference
66 UNSPEC_TOCPTR ; address of a word pointing to the TOC
67 UNSPEC_TOC ; address of the TOC (more-or-less)
68 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
70 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
77 UNSPEC_LD_MPIC ; load_macho_picbase
78 UNSPEC_RELD_MPIC ; re-load_macho_picbase
79 UNSPEC_MPIC_CORRECT ; macho_correct_pic
93 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
111 UNSPEC_MACHOPIC_OFFSET
125 UNSPEC_P8V_RELOAD_FROM_GPR
128 UNSPEC_P8V_RELOAD_FROM_VSX
143 UNSPEC_ADD_ROUND_TO_ODD
144 UNSPEC_SUB_ROUND_TO_ODD
145 UNSPEC_MUL_ROUND_TO_ODD
146 UNSPEC_DIV_ROUND_TO_ODD
147 UNSPEC_FMA_ROUND_TO_ODD
148 UNSPEC_SQRT_ROUND_TO_ODD
149 UNSPEC_TRUNC_ROUND_TO_ODD
156 ;; UNSPEC_VOLATILE usage
159 (define_c_enum "unspecv"
161 UNSPECV_LL ; load-locked
162 UNSPECV_SC ; store-conditional
163 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
164 UNSPECV_EH_RR ; eh_reg_restore
165 UNSPECV_ISYNC ; isync instruction
166 UNSPECV_MFTB ; move from time base
167 UNSPECV_NLGR ; non-local goto receiver
168 UNSPECV_MFFS ; Move from FPSCR
169 UNSPECV_MTFSF ; Move to FPSCR Fields
170 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
171 UNSPECV_SPEC_BARRIER ; Speculation barrier
175 ;; Define an insn type attribute. This is used in function unit delay
179 add,logical,shift,insert,
181 exts,cntlz,popcnt,isel,
182 load,store,fpload,fpstore,vecload,vecstore,
184 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
185 cr_logical,mfcr,mfcrf,mtcr,
186 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
187 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
188 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
189 veclogical,veccmpfx,vecexts,vecmove,
191 (const_string "integer"))
193 ;; What data size does this instruction work on?
194 ;; This is used for insert, mul and others as necessary.
195 (define_attr "size" "8,16,32,64,128" (const_string "32"))
197 ;; What is the insn_cost for this insn? The target hook can still override
198 ;; this. For optimizing for size the "length" attribute is used instead.
199 (define_attr "cost" "" (const_int 0))
201 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
202 ;; This is used for add, logical, shift, exts, mul.
203 (define_attr "dot" "no,yes" (const_string "no"))
205 ;; Does this instruction sign-extend its result?
206 ;; This is used for load insns.
207 (define_attr "sign_extend" "no,yes" (const_string "no"))
209 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
210 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
212 ;; Does this instruction use indexed (that is, reg+reg) addressing?
213 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
214 ;; it is automatically set based on that. If a load or store instruction
215 ;; has fewer than two operands it needs to set this attribute manually
216 ;; or the compiler will crash.
217 (define_attr "indexed" "no,yes"
218 (if_then_else (ior (match_operand 0 "indexed_address_mem")
219 (match_operand 1 "indexed_address_mem"))
221 (const_string "no")))
223 ;; Does this instruction use update addressing?
224 ;; This is used for load and store insns. See the comments for "indexed".
225 (define_attr "update" "no,yes"
226 (if_then_else (ior (match_operand 0 "update_address_mem")
227 (match_operand 1 "update_address_mem"))
229 (const_string "no")))
231 ;; Is this instruction using operands[2] as shift amount, and can that be a
233 ;; This is used for shift insns.
234 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
236 ;; Is this instruction using a shift amount from a register?
237 ;; This is used for shift insns.
238 (define_attr "var_shift" "no,yes"
239 (if_then_else (and (eq_attr "type" "shift")
240 (eq_attr "maybe_var_shift" "yes"))
241 (if_then_else (match_operand 2 "gpc_reg_operand")
244 (const_string "no")))
246 ;; Is copying of this instruction disallowed?
247 (define_attr "cannot_copy" "no,yes" (const_string "no"))
249 ;; Define floating point instruction sub-types for use with Xfpu.md
250 (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"))
252 ;; Length (in bytes).
253 ; '(pc)' in the following doesn't include the instruction itself; it is
254 ; calculated as if the instruction had zero size.
255 (define_attr "length" ""
256 (if_then_else (eq_attr "type" "branch")
257 (if_then_else (and (ge (minus (match_dup 0) (pc))
259 (lt (minus (match_dup 0) (pc))
265 ;; Processor type -- this attribute must exactly match the processor_type
266 ;; enumeration in rs6000-opts.h.
268 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
269 ppc750,ppc7400,ppc7450,
270 ppc403,ppc405,ppc440,ppc476,
271 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
272 power4,power5,power6,power7,power8,power9,
273 rs64a,mpccore,cell,ppca2,titan"
274 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
277 ;; If this instruction is microcoded on the CELL processor
278 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
279 (define_attr "cell_micro" "not,conditional,always"
280 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
281 (eq_attr "dot" "yes"))
282 (and (eq_attr "type" "load")
283 (eq_attr "sign_extend" "yes"))
284 (and (eq_attr "type" "shift")
285 (eq_attr "var_shift" "yes")))
286 (const_string "always")
287 (const_string "not")))
289 (automata_option "ndfa")
302 (include "e300c2c3.md")
303 (include "e500mc.md")
304 (include "e500mc64.md")
307 (include "power4.md")
308 (include "power5.md")
309 (include "power6.md")
310 (include "power7.md")
311 (include "power8.md")
312 (include "power9.md")
318 (include "predicates.md")
319 (include "constraints.md")
321 (include "darwin.md")
326 ; This mode iterator allows :GPR to be used to indicate the allowable size
327 ; of whole values in GPRs.
328 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
330 ; And again, for patterns that need two (potentially) different integer modes.
331 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
333 ; Any supported integer mode.
334 (define_mode_iterator INT [QI HI SI DI TI PTI])
336 ; Any supported integer mode that fits in one register.
337 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
339 ; Integer modes supported in VSX registers with ISA 3.0 instructions
340 (define_mode_iterator INT_ISA3 [QI HI SI DI])
342 ; Everything we can extend QImode to.
343 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
345 ; Everything we can extend HImode to.
346 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
348 ; Everything we can extend SImode to.
349 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
351 ; QImode or HImode for small integer moves and small atomic ops
352 (define_mode_iterator QHI [QI HI])
354 ; QImode, HImode, SImode for fused ops only for GPR loads
355 (define_mode_iterator QHSI [QI HI SI])
357 ; HImode or SImode for sign extended fusion ops
358 (define_mode_iterator HSI [HI SI])
360 ; SImode or DImode, even if DImode doesn't fit in GPRs.
361 (define_mode_iterator SDI [SI DI])
363 ; Types that can be fused with an ADDIS instruction to load or store a GPR
364 ; register that has reg+offset addressing.
365 (define_mode_iterator GPR_FUSION [QI
368 (DI "TARGET_POWERPC64")
370 (DF "TARGET_POWERPC64")])
372 ; Types that can be fused with an ADDIS instruction to load or store a FPR
373 ; register that has reg+offset addressing.
374 (define_mode_iterator FPR_FUSION [DI SF DF])
376 ; The size of a pointer. Also, the size of the value that a record-condition
377 ; (one with a '.') will compare; and the size used for arithmetic carries.
378 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
380 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
381 ; PTImode is GPR only)
382 (define_mode_iterator TI2 [TI PTI])
384 ; Any hardware-supported floating-point mode
385 (define_mode_iterator FP [
386 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
387 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
388 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
389 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
390 (KF "TARGET_FLOAT128_TYPE")
394 ; Any fma capable floating-point mode.
395 (define_mode_iterator FMA_F [
396 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
397 (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
398 || VECTOR_UNIT_VSX_P (DFmode)")
399 (V2SF "TARGET_PAIRED_FLOAT")
400 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
401 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
402 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
403 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
406 ; Floating point move iterators to combine binary and decimal moves
407 (define_mode_iterator FMOVE32 [SF SD])
408 (define_mode_iterator FMOVE64 [DF DD])
409 (define_mode_iterator FMOVE64X [DI DF DD])
410 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
411 (IF "FLOAT128_IBM_P (IFmode)")
412 (TD "TARGET_HARD_FLOAT")])
414 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
415 (IF "FLOAT128_2REG_P (IFmode)")
416 (TD "TARGET_HARD_FLOAT")])
418 ; Iterators for 128 bit types for direct move
419 (define_mode_iterator FMOVE128_GPR [TI
427 (KF "FLOAT128_VECTOR_P (KFmode)")
428 (TF "FLOAT128_VECTOR_P (TFmode)")])
430 ; Iterator for 128-bit VSX types for pack/unpack
431 (define_mode_iterator FMOVE128_VSX [V1TI KF])
433 ; Whether a floating point move is ok, don't allow SD without hardware FP
434 (define_mode_attr fmove_ok [(SF "")
436 (SD "TARGET_HARD_FLOAT")
439 ; Convert REAL_VALUE to the appropriate bits
440 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
441 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
442 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
443 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
445 ; Whether 0.0 has an all-zero bit pattern
446 (define_mode_attr zero_fp [(SF "j")
455 ; Definitions for 64-bit VSX
456 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
458 ; Definitions for 64-bit direct move
459 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
461 ; Definitions for 64-bit use of altivec registers
462 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
464 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
465 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
467 ; These modes do not fit in integer registers in 32-bit mode.
468 (define_mode_iterator DIFD [DI DF DD])
470 ; Iterator for reciprocal estimate instructions
471 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
473 ; Iterator for just SF/DF
474 (define_mode_iterator SFDF [SF DF])
476 ; Like SFDF, but a different name to match conditional move where the
477 ; comparison operands may be a different mode than the input operands.
478 (define_mode_iterator SFDF2 [SF DF])
480 ; Iterator for 128-bit floating point that uses the IBM double-double format
481 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
482 (TF "FLOAT128_IBM_P (TFmode)")])
484 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
485 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
486 (TF "FLOAT128_IEEE_P (TFmode)")])
488 ; Iterator for 128-bit floating point
489 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
490 (IF "TARGET_FLOAT128_TYPE")
491 (TF "TARGET_LONG_DOUBLE_128")])
493 ; Iterator for signbit on 64-bit machines with direct move
494 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
495 (TF "FLOAT128_VECTOR_P (TFmode)")])
497 ; Iterator for ISA 3.0 supported floating point types
498 (define_mode_iterator FP_ISA3 [SF DF])
500 ; SF/DF suffix for traditional floating instructions
501 (define_mode_attr Ftrad [(SF "s") (DF "")])
503 ; SF/DF suffix for VSX instructions
504 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
506 ; SF/DF constraint for arithmetic on traditional floating point registers
507 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
509 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
510 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
511 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
513 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
515 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
516 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
517 ; instructions added in ISA 2.07 (power8)
518 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
520 ; SF/DF constraint for arithmetic on altivec registers
521 (define_mode_attr Fa [(SF "wu") (DF "wv")])
523 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
524 (define_mode_attr Fs [(SF "s") (DF "d")])
527 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
528 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
530 ; Conditional returns.
531 (define_code_iterator any_return [return simple_return])
532 (define_code_attr return_pred [(return "direct_return ()")
533 (simple_return "1")])
534 (define_code_attr return_str [(return "") (simple_return "simple_")])
537 (define_code_iterator iorxor [ior xor])
538 (define_code_iterator and_ior_xor [and ior xor])
540 ; Signed/unsigned variants of ops.
541 (define_code_iterator any_extend [sign_extend zero_extend])
542 (define_code_iterator any_fix [fix unsigned_fix])
543 (define_code_iterator any_float [float unsigned_float])
545 (define_code_attr u [(sign_extend "")
550 (define_code_attr su [(sign_extend "s")
555 (unsigned_float "u")])
557 (define_code_attr az [(sign_extend "a")
562 (unsigned_float "z")])
564 (define_code_attr uns [(fix "")
567 (unsigned_float "uns")])
569 ; Various instructions that come in SI and DI forms.
570 ; A generic w/d attribute, for things like cmpw/cmpd.
571 (define_mode_attr wd [(QI "b")
582 ;; How many bits in this mode?
583 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
586 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
588 ;; Bitmask for shift instructions
589 (define_mode_attr hH [(SI "h") (DI "H")])
591 ;; A mode twice the size of the given mode
592 (define_mode_attr dmode [(SI "di") (DI "ti")])
593 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
595 ;; Suffix for reload patterns
596 (define_mode_attr ptrsize [(SI "32bit")
599 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
600 (DI "TARGET_64BIT")])
602 (define_mode_attr mptrsize [(SI "si")
605 (define_mode_attr ptrload [(SI "lwz")
608 (define_mode_attr ptrm [(SI "m")
611 (define_mode_attr rreg [(SF "f")
618 (define_mode_attr rreg2 [(SF "f")
621 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
622 (DF "TARGET_FCFID")])
624 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
625 (DF "TARGET_DOUBLE_FLOAT")])
627 ;; Mode iterator for logical operations on 128-bit types
628 (define_mode_iterator BOOL_128 [TI
630 (V16QI "TARGET_ALTIVEC")
631 (V8HI "TARGET_ALTIVEC")
632 (V4SI "TARGET_ALTIVEC")
633 (V4SF "TARGET_ALTIVEC")
634 (V2DI "TARGET_ALTIVEC")
635 (V2DF "TARGET_ALTIVEC")
636 (V1TI "TARGET_ALTIVEC")])
638 ;; For the GPRs we use 3 constraints for register outputs, two that are the
639 ;; same as the output register, and a third where the output register is an
640 ;; early clobber, so we don't have to deal with register overlaps. For the
641 ;; vector types, we prefer to use the vector registers. For TI mode, allow
644 ;; Mode attribute for boolean operation register constraints for output
645 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
647 (V16QI "wa,v,&?r,?r,?r")
648 (V8HI "wa,v,&?r,?r,?r")
649 (V4SI "wa,v,&?r,?r,?r")
650 (V4SF "wa,v,&?r,?r,?r")
651 (V2DI "wa,v,&?r,?r,?r")
652 (V2DF "wa,v,&?r,?r,?r")
653 (V1TI "wa,v,&?r,?r,?r")])
655 ;; Mode attribute for boolean operation register constraints for operand1
656 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
664 (V1TI "wa,v,r,0,r")])
666 ;; Mode attribute for boolean operation register constraints for operand2
667 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
675 (V1TI "wa,v,r,r,0")])
677 ;; Mode attribute for boolean operation register constraints for operand1
678 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
679 ;; is used for operand1 or operand2
680 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
688 (V1TI "wa,v,r,0,0")])
690 ;; Reload iterator for creating the function to allocate a base register to
691 ;; supplement addressing modes.
692 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
693 SF SD SI DF DD DI TI PTI KF IF TF])
695 ;; Iterate over smin, smax
696 (define_code_iterator fp_minmax [smin smax])
698 (define_code_attr minmax [(smin "min")
701 (define_code_attr SMINMAX [(smin "SMIN")
704 ;; Iterator to optimize the following cases:
705 ;; D-form load to FPR register & move to Altivec register
706 ;; Move Altivec register to FPR register and store
707 (define_mode_iterator ALTIVEC_DFORM [DF
708 (SF "TARGET_P8_VECTOR")
709 (DI "TARGET_POWERPC64")])
712 ;; Start with fixed-point load and store insns. Here we put only the more
713 ;; complex forms. Basic data transfer is done later.
715 (define_insn "zero_extendqi<mode>2"
716 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
717 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
724 [(set_attr "type" "load,shift,fpload,vecperm")])
726 (define_insn_and_split "*zero_extendqi<mode>2_dot"
727 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
728 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
730 (clobber (match_scratch:EXTQI 0 "=r,r"))]
735 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
737 (zero_extend:EXTQI (match_dup 1)))
739 (compare:CC (match_dup 0)
742 [(set_attr "type" "logical")
743 (set_attr "dot" "yes")
744 (set_attr "length" "4,8")])
746 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
747 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
748 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
750 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
751 (zero_extend:EXTQI (match_dup 1)))]
756 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
758 (zero_extend:EXTQI (match_dup 1)))
760 (compare:CC (match_dup 0)
763 [(set_attr "type" "logical")
764 (set_attr "dot" "yes")
765 (set_attr "length" "4,8")])
768 (define_insn "zero_extendhi<mode>2"
769 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
770 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
774 rlwinm %0,%1,0,0xffff
777 [(set_attr "type" "load,shift,fpload,vecperm")])
779 (define_insn_and_split "*zero_extendhi<mode>2_dot"
780 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
781 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
783 (clobber (match_scratch:EXTHI 0 "=r,r"))]
788 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
790 (zero_extend:EXTHI (match_dup 1)))
792 (compare:CC (match_dup 0)
795 [(set_attr "type" "logical")
796 (set_attr "dot" "yes")
797 (set_attr "length" "4,8")])
799 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
800 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
801 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
803 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
804 (zero_extend:EXTHI (match_dup 1)))]
809 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
811 (zero_extend:EXTHI (match_dup 1)))
813 (compare:CC (match_dup 0)
816 [(set_attr "type" "logical")
817 (set_attr "dot" "yes")
818 (set_attr "length" "4,8")])
821 (define_insn "zero_extendsi<mode>2"
822 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
823 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
832 xxextractuw %x0,%x1,4"
833 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
835 (define_insn_and_split "*zero_extendsi<mode>2_dot"
836 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
837 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
839 (clobber (match_scratch:EXTSI 0 "=r,r"))]
844 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
846 (zero_extend:DI (match_dup 1)))
848 (compare:CC (match_dup 0)
851 [(set_attr "type" "shift")
852 (set_attr "dot" "yes")
853 (set_attr "length" "4,8")])
855 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
856 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
857 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
859 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
860 (zero_extend:EXTSI (match_dup 1)))]
865 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
867 (zero_extend:EXTSI (match_dup 1)))
869 (compare:CC (match_dup 0)
872 [(set_attr "type" "shift")
873 (set_attr "dot" "yes")
874 (set_attr "length" "4,8")])
877 (define_insn "extendqi<mode>2"
878 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
879 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
884 [(set_attr "type" "exts,vecperm")])
886 (define_insn_and_split "*extendqi<mode>2_dot"
887 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
888 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
890 (clobber (match_scratch:EXTQI 0 "=r,r"))]
895 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
897 (sign_extend:EXTQI (match_dup 1)))
899 (compare:CC (match_dup 0)
902 [(set_attr "type" "exts")
903 (set_attr "dot" "yes")
904 (set_attr "length" "4,8")])
906 (define_insn_and_split "*extendqi<mode>2_dot2"
907 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
910 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
911 (sign_extend:EXTQI (match_dup 1)))]
916 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
918 (sign_extend:EXTQI (match_dup 1)))
920 (compare:CC (match_dup 0)
923 [(set_attr "type" "exts")
924 (set_attr "dot" "yes")
925 (set_attr "length" "4,8")])
928 (define_expand "extendhi<mode>2"
929 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
930 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
934 (define_insn "*extendhi<mode>2"
935 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
936 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
943 [(set_attr "type" "load,exts,fpload,vecperm")
944 (set_attr "sign_extend" "yes")
945 (set_attr "length" "4,4,8,4")])
948 [(set (match_operand:EXTHI 0 "altivec_register_operand")
950 (match_operand:HI 1 "indexed_or_indirect_operand")))]
951 "TARGET_P9_VECTOR && reload_completed"
955 (sign_extend:EXTHI (match_dup 2)))]
957 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
960 (define_insn_and_split "*extendhi<mode>2_dot"
961 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
962 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
964 (clobber (match_scratch:EXTHI 0 "=r,r"))]
969 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
971 (sign_extend:EXTHI (match_dup 1)))
973 (compare:CC (match_dup 0)
976 [(set_attr "type" "exts")
977 (set_attr "dot" "yes")
978 (set_attr "length" "4,8")])
980 (define_insn_and_split "*extendhi<mode>2_dot2"
981 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
982 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
984 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
985 (sign_extend:EXTHI (match_dup 1)))]
990 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
992 (sign_extend:EXTHI (match_dup 1)))
994 (compare:CC (match_dup 0)
997 [(set_attr "type" "exts")
998 (set_attr "dot" "yes")
999 (set_attr "length" "4,8")])
1002 (define_insn "extendsi<mode>2"
1003 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1004 "=r, r, wl, wu, wj, wK, wH, wr")
1006 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1007 "Y, r, Z, Z, r, wK, wH, ?wIwH")))]
1018 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1019 (set_attr "sign_extend" "yes")
1020 (set_attr "length" "4,4,4,4,4,4,8,8")])
1023 [(set (match_operand:EXTSI 0 "int_reg_operand")
1024 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1025 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1029 (sign_extend:DI (match_dup 2)))]
1031 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1035 [(set (match_operand:DI 0 "altivec_register_operand")
1036 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1037 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1040 rtx dest = operands[0];
1041 rtx src = operands[1];
1042 int dest_regno = REGNO (dest);
1043 int src_regno = REGNO (src);
1044 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1045 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1047 if (VECTOR_ELT_ORDER_BIG)
1049 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1050 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1054 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1055 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1060 (define_insn_and_split "*extendsi<mode>2_dot"
1061 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1062 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1064 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1069 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1071 (sign_extend:EXTSI (match_dup 1)))
1073 (compare:CC (match_dup 0)
1076 [(set_attr "type" "exts")
1077 (set_attr "dot" "yes")
1078 (set_attr "length" "4,8")])
1080 (define_insn_and_split "*extendsi<mode>2_dot2"
1081 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1082 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1084 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1085 (sign_extend:EXTSI (match_dup 1)))]
1090 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1092 (sign_extend:EXTSI (match_dup 1)))
1094 (compare:CC (match_dup 0)
1097 [(set_attr "type" "exts")
1098 (set_attr "dot" "yes")
1099 (set_attr "length" "4,8")])
1101 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1103 (define_insn "*macchwc"
1104 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1105 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1106 (match_operand:SI 2 "gpc_reg_operand" "r")
1109 (match_operand:HI 1 "gpc_reg_operand" "r")))
1110 (match_operand:SI 4 "gpc_reg_operand" "0"))
1112 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1113 (plus:SI (mult:SI (ashiftrt:SI
1121 [(set_attr "type" "halfmul")])
1123 (define_insn "*macchw"
1124 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1125 (plus:SI (mult:SI (ashiftrt:SI
1126 (match_operand:SI 2 "gpc_reg_operand" "r")
1129 (match_operand:HI 1 "gpc_reg_operand" "r")))
1130 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1133 [(set_attr "type" "halfmul")])
1135 (define_insn "*macchwuc"
1136 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1137 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1138 (match_operand:SI 2 "gpc_reg_operand" "r")
1141 (match_operand:HI 1 "gpc_reg_operand" "r")))
1142 (match_operand:SI 4 "gpc_reg_operand" "0"))
1144 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1145 (plus:SI (mult:SI (lshiftrt:SI
1153 [(set_attr "type" "halfmul")])
1155 (define_insn "*macchwu"
1156 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1157 (plus:SI (mult:SI (lshiftrt:SI
1158 (match_operand:SI 2 "gpc_reg_operand" "r")
1161 (match_operand:HI 1 "gpc_reg_operand" "r")))
1162 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1165 [(set_attr "type" "halfmul")])
1167 (define_insn "*machhwc"
1168 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1169 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1170 (match_operand:SI 1 "gpc_reg_operand" "%r")
1173 (match_operand:SI 2 "gpc_reg_operand" "r")
1175 (match_operand:SI 4 "gpc_reg_operand" "0"))
1177 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1178 (plus:SI (mult:SI (ashiftrt:SI
1187 [(set_attr "type" "halfmul")])
1189 (define_insn "*machhw"
1190 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1191 (plus:SI (mult:SI (ashiftrt:SI
1192 (match_operand:SI 1 "gpc_reg_operand" "%r")
1195 (match_operand:SI 2 "gpc_reg_operand" "r")
1197 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1200 [(set_attr "type" "halfmul")])
1202 (define_insn "*machhwuc"
1203 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1204 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1205 (match_operand:SI 1 "gpc_reg_operand" "%r")
1208 (match_operand:SI 2 "gpc_reg_operand" "r")
1210 (match_operand:SI 4 "gpc_reg_operand" "0"))
1212 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1213 (plus:SI (mult:SI (lshiftrt:SI
1222 [(set_attr "type" "halfmul")])
1224 (define_insn "*machhwu"
1225 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1226 (plus:SI (mult:SI (lshiftrt:SI
1227 (match_operand:SI 1 "gpc_reg_operand" "%r")
1230 (match_operand:SI 2 "gpc_reg_operand" "r")
1232 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1235 [(set_attr "type" "halfmul")])
1237 (define_insn "*maclhwc"
1238 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1239 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1240 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1242 (match_operand:HI 2 "gpc_reg_operand" "r")))
1243 (match_operand:SI 4 "gpc_reg_operand" "0"))
1245 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1246 (plus:SI (mult:SI (sign_extend:SI
1253 [(set_attr "type" "halfmul")])
1255 (define_insn "*maclhw"
1256 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1257 (plus:SI (mult:SI (sign_extend:SI
1258 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1260 (match_operand:HI 2 "gpc_reg_operand" "r")))
1261 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1264 [(set_attr "type" "halfmul")])
1266 (define_insn "*maclhwuc"
1267 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1268 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1269 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1271 (match_operand:HI 2 "gpc_reg_operand" "r")))
1272 (match_operand:SI 4 "gpc_reg_operand" "0"))
1274 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1275 (plus:SI (mult:SI (zero_extend:SI
1282 [(set_attr "type" "halfmul")])
1284 (define_insn "*maclhwu"
1285 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1286 (plus:SI (mult:SI (zero_extend:SI
1287 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1289 (match_operand:HI 2 "gpc_reg_operand" "r")))
1290 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1293 [(set_attr "type" "halfmul")])
1295 (define_insn "*nmacchwc"
1296 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1297 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1298 (mult:SI (ashiftrt:SI
1299 (match_operand:SI 2 "gpc_reg_operand" "r")
1302 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1304 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1305 (minus:SI (match_dup 4)
1306 (mult:SI (ashiftrt:SI
1313 [(set_attr "type" "halfmul")])
1315 (define_insn "*nmacchw"
1316 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1317 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1318 (mult:SI (ashiftrt:SI
1319 (match_operand:SI 2 "gpc_reg_operand" "r")
1322 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1325 [(set_attr "type" "halfmul")])
1327 (define_insn "*nmachhwc"
1328 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1329 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1330 (mult:SI (ashiftrt:SI
1331 (match_operand:SI 1 "gpc_reg_operand" "%r")
1334 (match_operand:SI 2 "gpc_reg_operand" "r")
1337 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1338 (minus:SI (match_dup 4)
1339 (mult:SI (ashiftrt:SI
1347 [(set_attr "type" "halfmul")])
1349 (define_insn "*nmachhw"
1350 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1351 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1352 (mult:SI (ashiftrt:SI
1353 (match_operand:SI 1 "gpc_reg_operand" "%r")
1356 (match_operand:SI 2 "gpc_reg_operand" "r")
1360 [(set_attr "type" "halfmul")])
1362 (define_insn "*nmaclhwc"
1363 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1364 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1365 (mult:SI (sign_extend:SI
1366 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1368 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1370 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1371 (minus:SI (match_dup 4)
1372 (mult:SI (sign_extend:SI
1378 [(set_attr "type" "halfmul")])
1380 (define_insn "*nmaclhw"
1381 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1382 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1383 (mult:SI (sign_extend:SI
1384 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1386 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1389 [(set_attr "type" "halfmul")])
1391 (define_insn "*mulchwc"
1392 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1393 (compare:CC (mult:SI (ashiftrt:SI
1394 (match_operand:SI 2 "gpc_reg_operand" "r")
1397 (match_operand:HI 1 "gpc_reg_operand" "r")))
1399 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400 (mult:SI (ashiftrt:SI
1407 [(set_attr "type" "halfmul")])
1409 (define_insn "*mulchw"
1410 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1411 (mult:SI (ashiftrt:SI
1412 (match_operand:SI 2 "gpc_reg_operand" "r")
1415 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1418 [(set_attr "type" "halfmul")])
1420 (define_insn "*mulchwuc"
1421 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1422 (compare:CC (mult:SI (lshiftrt:SI
1423 (match_operand:SI 2 "gpc_reg_operand" "r")
1426 (match_operand:HI 1 "gpc_reg_operand" "r")))
1428 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1429 (mult:SI (lshiftrt:SI
1436 [(set_attr "type" "halfmul")])
1438 (define_insn "*mulchwu"
1439 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1440 (mult:SI (lshiftrt:SI
1441 (match_operand:SI 2 "gpc_reg_operand" "r")
1444 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1447 [(set_attr "type" "halfmul")])
1449 (define_insn "*mulhhwc"
1450 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1451 (compare:CC (mult:SI (ashiftrt:SI
1452 (match_operand:SI 1 "gpc_reg_operand" "%r")
1455 (match_operand:SI 2 "gpc_reg_operand" "r")
1458 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1459 (mult:SI (ashiftrt:SI
1467 [(set_attr "type" "halfmul")])
1469 (define_insn "*mulhhw"
1470 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1471 (mult:SI (ashiftrt:SI
1472 (match_operand:SI 1 "gpc_reg_operand" "%r")
1475 (match_operand:SI 2 "gpc_reg_operand" "r")
1479 [(set_attr "type" "halfmul")])
1481 (define_insn "*mulhhwuc"
1482 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1483 (compare:CC (mult:SI (lshiftrt:SI
1484 (match_operand:SI 1 "gpc_reg_operand" "%r")
1487 (match_operand:SI 2 "gpc_reg_operand" "r")
1490 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1491 (mult:SI (lshiftrt:SI
1499 [(set_attr "type" "halfmul")])
1501 (define_insn "*mulhhwu"
1502 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1503 (mult:SI (lshiftrt:SI
1504 (match_operand:SI 1 "gpc_reg_operand" "%r")
1507 (match_operand:SI 2 "gpc_reg_operand" "r")
1511 [(set_attr "type" "halfmul")])
1513 (define_insn "*mullhwc"
1514 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1515 (compare:CC (mult:SI (sign_extend:SI
1516 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1518 (match_operand:HI 2 "gpc_reg_operand" "r")))
1520 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1521 (mult:SI (sign_extend:SI
1527 [(set_attr "type" "halfmul")])
1529 (define_insn "*mullhw"
1530 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1531 (mult:SI (sign_extend:SI
1532 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1534 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1537 [(set_attr "type" "halfmul")])
1539 (define_insn "*mullhwuc"
1540 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1541 (compare:CC (mult:SI (zero_extend:SI
1542 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1544 (match_operand:HI 2 "gpc_reg_operand" "r")))
1546 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1547 (mult:SI (zero_extend:SI
1553 [(set_attr "type" "halfmul")])
1555 (define_insn "*mullhwu"
1556 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1557 (mult:SI (zero_extend:SI
1558 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1560 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1563 [(set_attr "type" "halfmul")])
1565 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1566 (define_insn "dlmzb"
1567 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1568 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1569 (match_operand:SI 2 "gpc_reg_operand" "r")]
1571 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1572 (unspec:SI [(match_dup 1)
1578 (define_expand "strlensi"
1579 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1580 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1581 (match_operand:QI 2 "const_int_operand" "")
1582 (match_operand 3 "const_int_operand" "")]
1583 UNSPEC_DLMZB_STRLEN))
1584 (clobber (match_scratch:CC 4 "=x"))]
1585 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1587 rtx result = operands[0];
1588 rtx src = operands[1];
1589 rtx search_char = operands[2];
1590 rtx align = operands[3];
1591 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1592 rtx loop_label, end_label, mem, cr0, cond;
1593 if (search_char != const0_rtx
1594 || GET_CODE (align) != CONST_INT
1595 || INTVAL (align) < 8)
1597 word1 = gen_reg_rtx (SImode);
1598 word2 = gen_reg_rtx (SImode);
1599 scratch_dlmzb = gen_reg_rtx (SImode);
1600 scratch_string = gen_reg_rtx (Pmode);
1601 loop_label = gen_label_rtx ();
1602 end_label = gen_label_rtx ();
1603 addr = force_reg (Pmode, XEXP (src, 0));
1604 emit_move_insn (scratch_string, addr);
1605 emit_label (loop_label);
1606 mem = change_address (src, SImode, scratch_string);
1607 emit_move_insn (word1, mem);
1608 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1609 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1610 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1611 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1612 emit_jump_insn (gen_rtx_SET (pc_rtx,
1613 gen_rtx_IF_THEN_ELSE (VOIDmode,
1619 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1620 emit_jump_insn (gen_rtx_SET (pc_rtx,
1621 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1623 emit_label (end_label);
1624 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1625 emit_insn (gen_subsi3 (result, scratch_string, addr));
1626 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1630 ;; Fixed-point arithmetic insns.
1632 (define_expand "add<mode>3"
1633 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1634 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1635 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1638 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1640 rtx lo0 = gen_lowpart (SImode, operands[0]);
1641 rtx lo1 = gen_lowpart (SImode, operands[1]);
1642 rtx lo2 = gen_lowpart (SImode, operands[2]);
1643 rtx hi0 = gen_highpart (SImode, operands[0]);
1644 rtx hi1 = gen_highpart (SImode, operands[1]);
1645 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1647 if (!reg_or_short_operand (lo2, SImode))
1648 lo2 = force_reg (SImode, lo2);
1649 if (!adde_operand (hi2, SImode))
1650 hi2 = force_reg (SImode, hi2);
1652 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1653 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1657 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1659 rtx tmp = ((!can_create_pseudo_p ()
1660 || rtx_equal_p (operands[0], operands[1]))
1661 ? operands[0] : gen_reg_rtx (<MODE>mode));
1663 /* Adding a constant to r0 is not a valid insn, so use a different
1664 strategy in that case. */
1665 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1667 if (operands[0] == operands[1])
1669 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1670 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1674 HOST_WIDE_INT val = INTVAL (operands[2]);
1675 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1676 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1678 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1681 /* The ordering here is important for the prolog expander.
1682 When space is allocated from the stack, adding 'low' first may
1683 produce a temporary deallocation (which would be bad). */
1684 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1685 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1690 (define_insn "*add<mode>3"
1691 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1692 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1693 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1699 [(set_attr "type" "add")])
1701 (define_insn "addsi3_high"
1702 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1703 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1704 (high:SI (match_operand 2 "" ""))))]
1705 "TARGET_MACHO && !TARGET_64BIT"
1706 "addis %0,%1,ha16(%2)"
1707 [(set_attr "type" "add")])
1709 (define_insn_and_split "*add<mode>3_dot"
1710 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1711 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1712 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1714 (clobber (match_scratch:GPR 0 "=r,r"))]
1715 "<MODE>mode == Pmode"
1719 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1721 (plus:GPR (match_dup 1)
1724 (compare:CC (match_dup 0)
1727 [(set_attr "type" "add")
1728 (set_attr "dot" "yes")
1729 (set_attr "length" "4,8")])
1731 (define_insn_and_split "*add<mode>3_dot2"
1732 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1733 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1734 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1736 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1737 (plus:GPR (match_dup 1)
1739 "<MODE>mode == Pmode"
1743 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1745 (plus:GPR (match_dup 1)
1748 (compare:CC (match_dup 0)
1751 [(set_attr "type" "add")
1752 (set_attr "dot" "yes")
1753 (set_attr "length" "4,8")])
1755 (define_insn_and_split "*add<mode>3_imm_dot"
1756 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1757 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1758 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1760 (clobber (match_scratch:GPR 0 "=r,r"))
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 (define_insn_and_split "*add<mode>3_imm_dot2"
1779 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1780 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1781 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1783 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1784 (plus:GPR (match_dup 1)
1786 (clobber (reg:GPR CA_REGNO))]
1787 "<MODE>mode == Pmode"
1791 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1793 (plus:GPR (match_dup 1)
1796 (compare:CC (match_dup 0)
1799 [(set_attr "type" "add")
1800 (set_attr "dot" "yes")
1801 (set_attr "length" "4,8")])
1803 ;; Split an add that we can't do in one insn into two insns, each of which
1804 ;; does one 16-bit part. This is used by combine. Note that the low-order
1805 ;; add should be last in case the result gets used in an address.
1808 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1809 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1810 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1812 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1813 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1815 HOST_WIDE_INT val = INTVAL (operands[2]);
1816 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1817 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1819 operands[4] = GEN_INT (low);
1820 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1821 operands[3] = GEN_INT (rest);
1822 else if (can_create_pseudo_p ())
1824 operands[3] = gen_reg_rtx (DImode);
1825 emit_move_insn (operands[3], operands[2]);
1826 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1834 (define_insn "add<mode>3_carry"
1835 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1836 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1837 (match_operand:P 2 "reg_or_short_operand" "rI")))
1838 (set (reg:P CA_REGNO)
1839 (ltu:P (plus:P (match_dup 1)
1844 [(set_attr "type" "add")])
1846 (define_insn "*add<mode>3_imm_carry_pos"
1847 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1848 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1849 (match_operand:P 2 "short_cint_operand" "n")))
1850 (set (reg:P CA_REGNO)
1851 (geu:P (match_dup 1)
1852 (match_operand:P 3 "const_int_operand" "n")))]
1853 "INTVAL (operands[2]) > 0
1854 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1856 [(set_attr "type" "add")])
1858 (define_insn "*add<mode>3_imm_carry_0"
1859 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1860 (match_operand:P 1 "gpc_reg_operand" "r"))
1861 (set (reg:P CA_REGNO)
1865 [(set_attr "type" "add")])
1867 (define_insn "*add<mode>3_imm_carry_m1"
1868 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1869 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1871 (set (reg:P CA_REGNO)
1876 [(set_attr "type" "add")])
1878 (define_insn "*add<mode>3_imm_carry_neg"
1879 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1880 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1881 (match_operand:P 2 "short_cint_operand" "n")))
1882 (set (reg:P CA_REGNO)
1883 (gtu:P (match_dup 1)
1884 (match_operand:P 3 "const_int_operand" "n")))]
1885 "INTVAL (operands[2]) < 0
1886 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1888 [(set_attr "type" "add")])
1891 (define_expand "add<mode>3_carry_in"
1893 (set (match_operand:GPR 0 "gpc_reg_operand")
1894 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1895 (match_operand:GPR 2 "adde_operand"))
1896 (reg:GPR CA_REGNO)))
1897 (clobber (reg:GPR CA_REGNO))])]
1900 if (operands[2] == const0_rtx)
1902 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1905 if (operands[2] == constm1_rtx)
1907 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1912 (define_insn "*add<mode>3_carry_in_internal"
1913 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1914 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1915 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1916 (reg:GPR CA_REGNO)))
1917 (clobber (reg:GPR CA_REGNO))]
1920 [(set_attr "type" "add")])
1922 (define_insn "*add<mode>3_carry_in_internal2"
1923 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1924 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1926 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1927 (clobber (reg:GPR CA_REGNO))]
1930 [(set_attr "type" "add")])
1932 (define_insn "add<mode>3_carry_in_0"
1933 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1934 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1935 (reg:GPR CA_REGNO)))
1936 (clobber (reg:GPR CA_REGNO))]
1939 [(set_attr "type" "add")])
1941 (define_insn "add<mode>3_carry_in_m1"
1942 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1943 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1946 (clobber (reg:GPR CA_REGNO))]
1949 [(set_attr "type" "add")])
1952 (define_expand "one_cmpl<mode>2"
1953 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1954 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1957 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1959 rs6000_split_logical (operands, NOT, false, false, false);
1964 (define_insn "*one_cmpl<mode>2"
1965 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1966 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1970 (define_insn_and_split "*one_cmpl<mode>2_dot"
1971 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1972 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1974 (clobber (match_scratch:GPR 0 "=r,r"))]
1975 "<MODE>mode == Pmode"
1979 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1981 (not:GPR (match_dup 1)))
1983 (compare:CC (match_dup 0)
1986 [(set_attr "type" "logical")
1987 (set_attr "dot" "yes")
1988 (set_attr "length" "4,8")])
1990 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1991 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1992 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1994 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1995 (not:GPR (match_dup 1)))]
1996 "<MODE>mode == Pmode"
2000 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2002 (not:GPR (match_dup 1)))
2004 (compare:CC (match_dup 0)
2007 [(set_attr "type" "logical")
2008 (set_attr "dot" "yes")
2009 (set_attr "length" "4,8")])
2012 (define_expand "sub<mode>3"
2013 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2014 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
2015 (match_operand:SDI 2 "gpc_reg_operand" "")))]
2018 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2020 rtx lo0 = gen_lowpart (SImode, operands[0]);
2021 rtx lo1 = gen_lowpart (SImode, operands[1]);
2022 rtx lo2 = gen_lowpart (SImode, operands[2]);
2023 rtx hi0 = gen_highpart (SImode, operands[0]);
2024 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2025 rtx hi2 = gen_highpart (SImode, operands[2]);
2027 if (!reg_or_short_operand (lo1, SImode))
2028 lo1 = force_reg (SImode, lo1);
2029 if (!adde_operand (hi1, SImode))
2030 hi1 = force_reg (SImode, hi1);
2032 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2033 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2037 if (short_cint_operand (operands[1], <MODE>mode))
2039 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2044 (define_insn "*subf<mode>3"
2045 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2046 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2047 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2050 [(set_attr "type" "add")])
2052 (define_insn_and_split "*subf<mode>3_dot"
2053 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2054 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2055 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2057 (clobber (match_scratch:GPR 0 "=r,r"))]
2058 "<MODE>mode == Pmode"
2062 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2064 (minus:GPR (match_dup 2)
2067 (compare:CC (match_dup 0)
2070 [(set_attr "type" "add")
2071 (set_attr "dot" "yes")
2072 (set_attr "length" "4,8")])
2074 (define_insn_and_split "*subf<mode>3_dot2"
2075 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2076 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2077 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2079 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2080 (minus:GPR (match_dup 2)
2082 "<MODE>mode == Pmode"
2086 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2088 (minus:GPR (match_dup 2)
2091 (compare:CC (match_dup 0)
2094 [(set_attr "type" "add")
2095 (set_attr "dot" "yes")
2096 (set_attr "length" "4,8")])
2098 (define_insn "subf<mode>3_imm"
2099 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2100 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2101 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2102 (clobber (reg:GPR CA_REGNO))]
2105 [(set_attr "type" "add")])
2107 (define_insn_and_split "subf<mode>3_carry_dot2"
2108 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2109 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2110 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2112 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2113 (minus:P (match_dup 2)
2115 (set (reg:P CA_REGNO)
2116 (leu:P (match_dup 1)
2118 "<MODE>mode == Pmode"
2122 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2123 [(parallel [(set (match_dup 0)
2124 (minus:P (match_dup 2)
2126 (set (reg:P CA_REGNO)
2127 (leu:P (match_dup 1)
2130 (compare:CC (match_dup 0)
2133 [(set_attr "type" "add")
2134 (set_attr "dot" "yes")
2135 (set_attr "length" "4,8")])
2137 (define_insn "subf<mode>3_carry"
2138 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2139 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2140 (match_operand:P 1 "gpc_reg_operand" "r")))
2141 (set (reg:P CA_REGNO)
2142 (leu:P (match_dup 1)
2146 [(set_attr "type" "add")])
2148 (define_insn "*subf<mode>3_imm_carry_0"
2149 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2150 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2151 (set (reg:P CA_REGNO)
2156 [(set_attr "type" "add")])
2158 (define_insn "*subf<mode>3_imm_carry_m1"
2159 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2160 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2161 (set (reg:P CA_REGNO)
2165 [(set_attr "type" "add")])
2168 (define_expand "subf<mode>3_carry_in"
2170 (set (match_operand:GPR 0 "gpc_reg_operand")
2171 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2173 (match_operand:GPR 2 "adde_operand")))
2174 (clobber (reg:GPR CA_REGNO))])]
2177 if (operands[2] == const0_rtx)
2179 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2182 if (operands[2] == constm1_rtx)
2184 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2189 (define_insn "*subf<mode>3_carry_in_internal"
2190 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2191 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2193 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2194 (clobber (reg:GPR CA_REGNO))]
2197 [(set_attr "type" "add")])
2199 (define_insn "subf<mode>3_carry_in_0"
2200 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2201 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2202 (reg:GPR CA_REGNO)))
2203 (clobber (reg:GPR CA_REGNO))]
2206 [(set_attr "type" "add")])
2208 (define_insn "subf<mode>3_carry_in_m1"
2209 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2210 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2211 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2213 (clobber (reg:GPR CA_REGNO))]
2216 [(set_attr "type" "add")])
2218 (define_insn "subf<mode>3_carry_in_xx"
2219 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2220 (plus:GPR (reg:GPR CA_REGNO)
2222 (clobber (reg:GPR CA_REGNO))]
2225 [(set_attr "type" "add")])
2228 (define_insn "neg<mode>2"
2229 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2230 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2233 [(set_attr "type" "add")])
2235 (define_insn_and_split "*neg<mode>2_dot"
2236 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2237 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2239 (clobber (match_scratch:GPR 0 "=r,r"))]
2240 "<MODE>mode == Pmode"
2244 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2246 (neg:GPR (match_dup 1)))
2248 (compare:CC (match_dup 0)
2251 [(set_attr "type" "add")
2252 (set_attr "dot" "yes")
2253 (set_attr "length" "4,8")])
2255 (define_insn_and_split "*neg<mode>2_dot2"
2256 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2257 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2259 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2260 (neg:GPR (match_dup 1)))]
2261 "<MODE>mode == Pmode"
2265 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2267 (neg:GPR (match_dup 1)))
2269 (compare:CC (match_dup 0)
2272 [(set_attr "type" "add")
2273 (set_attr "dot" "yes")
2274 (set_attr "length" "4,8")])
2277 (define_insn "clz<mode>2"
2278 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2279 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2282 [(set_attr "type" "cntlz")])
2284 (define_expand "ctz<mode>2"
2285 [(set (match_operand:GPR 0 "gpc_reg_operand")
2286 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2291 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2295 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2296 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2297 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2301 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2302 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2303 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2304 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2308 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2309 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2310 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2311 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2317 (define_insn "ctz<mode>2_hw"
2318 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2319 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2322 [(set_attr "type" "cntlz")])
2324 (define_expand "ffs<mode>2"
2325 [(set (match_operand:GPR 0 "gpc_reg_operand")
2326 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2329 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2330 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2331 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2332 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2333 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2334 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2335 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2340 (define_expand "popcount<mode>2"
2341 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2342 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2343 "TARGET_POPCNTB || TARGET_POPCNTD"
2345 rs6000_emit_popcount (operands[0], operands[1]);
2349 (define_insn "popcntb<mode>2"
2350 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2351 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2355 [(set_attr "type" "popcnt")])
2357 (define_insn "popcntd<mode>2"
2358 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2359 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2362 [(set_attr "type" "popcnt")])
2365 (define_expand "parity<mode>2"
2366 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2367 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2370 rs6000_emit_parity (operands[0], operands[1]);
2374 (define_insn "parity<mode>2_cmpb"
2375 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2376 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2377 "TARGET_CMPB && TARGET_POPCNTB"
2379 [(set_attr "type" "popcnt")])
2381 (define_insn "cmpb<mode>3"
2382 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2383 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2384 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2387 [(set_attr "type" "cmp")])
2389 ;; Since the hardware zeros the upper part of the register, save generating the
2390 ;; AND immediate if we are converting to unsigned
2391 (define_insn "*bswap<mode>2_extenddi"
2392 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2394 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2397 [(set_attr "length" "4")
2398 (set_attr "type" "load")])
2400 (define_insn "*bswaphi2_extendsi"
2401 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2403 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2406 [(set_attr "length" "4")
2407 (set_attr "type" "load")])
2409 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2410 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2411 ;; load with byte swap, which can be slower than doing it in the registers. It
2412 ;; also prevents certain failures with the RELOAD register allocator.
2414 (define_expand "bswap<mode>2"
2415 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2416 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2419 rtx dest = operands[0];
2420 rtx src = operands[1];
2422 if (!REG_P (dest) && !REG_P (src))
2423 src = force_reg (<MODE>mode, src);
2426 emit_insn (gen_bswap<mode>2_load (dest, src));
2427 else if (MEM_P (dest))
2428 emit_insn (gen_bswap<mode>2_store (dest, src));
2430 emit_insn (gen_bswap<mode>2_reg (dest, src));
2434 (define_insn "bswap<mode>2_load"
2435 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2436 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2439 [(set_attr "type" "load")])
2441 (define_insn "bswap<mode>2_store"
2442 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2443 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2446 [(set_attr "type" "store")])
2448 (define_insn_and_split "bswaphi2_reg"
2449 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2451 (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2452 (clobber (match_scratch:SI 2 "=&r,X"))]
2457 "reload_completed && int_reg_operand (operands[0], HImode)"
2459 (and:SI (lshiftrt:SI (match_dup 4)
2463 (and:SI (ashift:SI (match_dup 4)
2465 (const_int 65280))) ;; 0xff00
2467 (ior:SI (match_dup 3)
2470 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2471 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2473 [(set_attr "length" "12,4")
2474 (set_attr "type" "*,vecperm")])
2476 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2477 ;; zero_extract insns do not change for -mlittle.
2478 (define_insn_and_split "bswapsi2_reg"
2479 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2481 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2486 "reload_completed && int_reg_operand (operands[0], SImode)"
2487 [(set (match_dup 0) ; DABC
2488 (rotate:SI (match_dup 1)
2490 (set (match_dup 0) ; DCBC
2491 (ior:SI (and:SI (ashift:SI (match_dup 1)
2493 (const_int 16711680))
2494 (and:SI (match_dup 0)
2495 (const_int -16711681))))
2496 (set (match_dup 0) ; DCBA
2497 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2500 (and:SI (match_dup 0)
2501 (const_int -256))))]
2503 [(set_attr "length" "12,4")
2504 (set_attr "type" "*,vecperm")])
2506 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2507 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2510 (define_expand "bswapdi2"
2511 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2513 (match_operand:DI 1 "reg_or_mem_operand" "")))
2514 (clobber (match_scratch:DI 2 ""))
2515 (clobber (match_scratch:DI 3 ""))])]
2518 rtx dest = operands[0];
2519 rtx src = operands[1];
2521 if (!REG_P (dest) && !REG_P (src))
2522 operands[1] = src = force_reg (DImode, src);
2524 if (TARGET_POWERPC64 && TARGET_LDBRX)
2527 emit_insn (gen_bswapdi2_load (dest, src));
2528 else if (MEM_P (dest))
2529 emit_insn (gen_bswapdi2_store (dest, src));
2530 else if (TARGET_P9_VECTOR)
2531 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2533 emit_insn (gen_bswapdi2_reg (dest, src));
2537 if (!TARGET_POWERPC64)
2539 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2540 that uses 64-bit registers needs the same scratch registers as 64-bit
2542 emit_insn (gen_bswapdi2_32bit (dest, src));
2547 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2548 (define_insn "bswapdi2_load"
2549 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2550 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2551 "TARGET_POWERPC64 && TARGET_LDBRX"
2553 [(set_attr "type" "load")])
2555 (define_insn "bswapdi2_store"
2556 [(set (match_operand:DI 0 "memory_operand" "=Z")
2557 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2558 "TARGET_POWERPC64 && TARGET_LDBRX"
2560 [(set_attr "type" "store")])
2562 (define_insn "bswapdi2_xxbrd"
2563 [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2564 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2567 [(set_attr "type" "vecperm")])
2569 (define_insn "bswapdi2_reg"
2570 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2571 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2572 (clobber (match_scratch:DI 2 "=&r"))
2573 (clobber (match_scratch:DI 3 "=&r"))]
2574 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2576 [(set_attr "length" "36")])
2578 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2579 (define_insn "*bswapdi2_64bit"
2580 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2581 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2582 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2583 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2584 "TARGET_POWERPC64 && !TARGET_LDBRX
2585 && (REG_P (operands[0]) || REG_P (operands[1]))
2586 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2587 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2589 [(set_attr "length" "16,12,36")])
2592 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2593 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2594 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2595 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2596 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2600 rtx dest = operands[0];
2601 rtx src = operands[1];
2602 rtx op2 = operands[2];
2603 rtx op3 = operands[3];
2604 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2605 BYTES_BIG_ENDIAN ? 4 : 0);
2606 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2607 BYTES_BIG_ENDIAN ? 4 : 0);
2613 addr1 = XEXP (src, 0);
2614 if (GET_CODE (addr1) == PLUS)
2616 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2617 if (TARGET_AVOID_XFORM)
2619 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2623 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2625 else if (TARGET_AVOID_XFORM)
2627 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2632 emit_move_insn (op2, GEN_INT (4));
2633 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2636 word1 = change_address (src, SImode, addr1);
2637 word2 = change_address (src, SImode, addr2);
2639 if (BYTES_BIG_ENDIAN)
2641 emit_insn (gen_bswapsi2 (op3_32, word2));
2642 emit_insn (gen_bswapsi2 (dest_32, word1));
2646 emit_insn (gen_bswapsi2 (op3_32, word1));
2647 emit_insn (gen_bswapsi2 (dest_32, word2));
2650 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2651 emit_insn (gen_iordi3 (dest, dest, op3));
2656 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2657 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2658 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2659 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2660 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2664 rtx dest = operands[0];
2665 rtx src = operands[1];
2666 rtx op2 = operands[2];
2667 rtx op3 = operands[3];
2668 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2669 BYTES_BIG_ENDIAN ? 4 : 0);
2670 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2671 BYTES_BIG_ENDIAN ? 4 : 0);
2677 addr1 = XEXP (dest, 0);
2678 if (GET_CODE (addr1) == PLUS)
2680 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2681 if (TARGET_AVOID_XFORM)
2683 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2687 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2689 else if (TARGET_AVOID_XFORM)
2691 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2696 emit_move_insn (op2, GEN_INT (4));
2697 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2700 word1 = change_address (dest, SImode, addr1);
2701 word2 = change_address (dest, SImode, addr2);
2703 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2705 if (BYTES_BIG_ENDIAN)
2707 emit_insn (gen_bswapsi2 (word1, src_si));
2708 emit_insn (gen_bswapsi2 (word2, op3_si));
2712 emit_insn (gen_bswapsi2 (word2, src_si));
2713 emit_insn (gen_bswapsi2 (word1, op3_si));
2719 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2720 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2721 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2722 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2723 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2727 rtx dest = operands[0];
2728 rtx src = operands[1];
2729 rtx op2 = operands[2];
2730 rtx op3 = operands[3];
2731 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2732 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2733 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2734 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2735 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2737 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2738 emit_insn (gen_bswapsi2 (dest_si, src_si));
2739 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2740 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2741 emit_insn (gen_iordi3 (dest, dest, op3));
2745 (define_insn "bswapdi2_32bit"
2746 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2747 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2748 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2749 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2751 [(set_attr "length" "16,12,36")])
2754 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2755 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2756 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2757 "!TARGET_POWERPC64 && reload_completed"
2761 rtx dest = operands[0];
2762 rtx src = operands[1];
2763 rtx op2 = operands[2];
2764 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2765 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2771 addr1 = XEXP (src, 0);
2772 if (GET_CODE (addr1) == PLUS)
2774 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2775 if (TARGET_AVOID_XFORM
2776 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2778 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2782 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2784 else if (TARGET_AVOID_XFORM
2785 || REGNO (addr1) == REGNO (dest2))
2787 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2792 emit_move_insn (op2, GEN_INT (4));
2793 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2796 word1 = change_address (src, SImode, addr1);
2797 word2 = change_address (src, SImode, addr2);
2799 emit_insn (gen_bswapsi2 (dest2, word1));
2800 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2801 thus allowing us to omit an early clobber on the output. */
2802 emit_insn (gen_bswapsi2 (dest1, word2));
2807 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2808 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2809 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2810 "!TARGET_POWERPC64 && reload_completed"
2814 rtx dest = operands[0];
2815 rtx src = operands[1];
2816 rtx op2 = operands[2];
2817 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2818 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2824 addr1 = XEXP (dest, 0);
2825 if (GET_CODE (addr1) == PLUS)
2827 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2828 if (TARGET_AVOID_XFORM)
2830 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2834 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2836 else if (TARGET_AVOID_XFORM)
2838 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2843 emit_move_insn (op2, GEN_INT (4));
2844 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2847 word1 = change_address (dest, SImode, addr1);
2848 word2 = change_address (dest, SImode, addr2);
2850 emit_insn (gen_bswapsi2 (word2, src1));
2851 emit_insn (gen_bswapsi2 (word1, src2));
2856 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2857 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2858 (clobber (match_operand:SI 2 "" ""))]
2859 "!TARGET_POWERPC64 && reload_completed"
2863 rtx dest = operands[0];
2864 rtx src = operands[1];
2865 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2866 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2867 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2868 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2870 emit_insn (gen_bswapsi2 (dest1, src2));
2871 emit_insn (gen_bswapsi2 (dest2, src1));
2876 (define_insn "mul<mode>3"
2877 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2878 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2879 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2884 [(set_attr "type" "mul")
2886 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2888 (match_operand:GPR 2 "short_cint_operand" "")
2889 (const_string "16")]
2890 (const_string "<bits>")))])
2892 (define_insn_and_split "*mul<mode>3_dot"
2893 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2894 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2895 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2897 (clobber (match_scratch:GPR 0 "=r,r"))]
2898 "<MODE>mode == Pmode"
2902 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2904 (mult:GPR (match_dup 1)
2907 (compare:CC (match_dup 0)
2910 [(set_attr "type" "mul")
2911 (set_attr "size" "<bits>")
2912 (set_attr "dot" "yes")
2913 (set_attr "length" "4,8")])
2915 (define_insn_and_split "*mul<mode>3_dot2"
2916 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2917 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2918 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2920 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2921 (mult:GPR (match_dup 1)
2923 "<MODE>mode == Pmode"
2927 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2929 (mult:GPR (match_dup 1)
2932 (compare:CC (match_dup 0)
2935 [(set_attr "type" "mul")
2936 (set_attr "size" "<bits>")
2937 (set_attr "dot" "yes")
2938 (set_attr "length" "4,8")])
2941 (define_expand "<su>mul<mode>3_highpart"
2942 [(set (match_operand:GPR 0 "gpc_reg_operand")
2944 (mult:<DMODE> (any_extend:<DMODE>
2945 (match_operand:GPR 1 "gpc_reg_operand"))
2947 (match_operand:GPR 2 "gpc_reg_operand")))
2951 if (<MODE>mode == SImode && TARGET_POWERPC64)
2953 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2958 if (!WORDS_BIG_ENDIAN)
2960 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2966 (define_insn "*<su>mul<mode>3_highpart"
2967 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2969 (mult:<DMODE> (any_extend:<DMODE>
2970 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2972 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2974 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2975 "mulh<wd><u> %0,%1,%2"
2976 [(set_attr "type" "mul")
2977 (set_attr "size" "<bits>")])
2979 (define_insn "<su>mulsi3_highpart_le"
2980 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2982 (mult:DI (any_extend:DI
2983 (match_operand:SI 1 "gpc_reg_operand" "r"))
2985 (match_operand:SI 2 "gpc_reg_operand" "r")))
2987 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2989 [(set_attr "type" "mul")])
2991 (define_insn "<su>muldi3_highpart_le"
2992 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2994 (mult:TI (any_extend:TI
2995 (match_operand:DI 1 "gpc_reg_operand" "r"))
2997 (match_operand:DI 2 "gpc_reg_operand" "r")))
2999 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3001 [(set_attr "type" "mul")
3002 (set_attr "size" "64")])
3004 (define_insn "<su>mulsi3_highpart_64"
3005 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3008 (mult:DI (any_extend:DI
3009 (match_operand:SI 1 "gpc_reg_operand" "r"))
3011 (match_operand:SI 2 "gpc_reg_operand" "r")))
3015 [(set_attr "type" "mul")])
3017 (define_expand "<u>mul<mode><dmode>3"
3018 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3019 (mult:<DMODE> (any_extend:<DMODE>
3020 (match_operand:GPR 1 "gpc_reg_operand"))
3022 (match_operand:GPR 2 "gpc_reg_operand"))))]
3023 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3025 rtx l = gen_reg_rtx (<MODE>mode);
3026 rtx h = gen_reg_rtx (<MODE>mode);
3027 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3028 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3029 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3030 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3034 (define_insn "*maddld4"
3035 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3036 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3037 (match_operand:DI 2 "gpc_reg_operand" "r"))
3038 (match_operand:DI 3 "gpc_reg_operand" "r")))]
3040 "maddld %0,%1,%2,%3"
3041 [(set_attr "type" "mul")])
3043 (define_insn "udiv<mode>3"
3044 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3045 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3046 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3049 [(set_attr "type" "div")
3050 (set_attr "size" "<bits>")])
3053 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3054 ;; modulus. If it isn't a power of two, force operands into register and do
3056 (define_expand "div<mode>3"
3057 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3058 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3059 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3062 if (CONST_INT_P (operands[2])
3063 && INTVAL (operands[2]) > 0
3064 && exact_log2 (INTVAL (operands[2])) >= 0)
3066 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3070 operands[2] = force_reg (<MODE>mode, operands[2]);
3073 (define_insn "*div<mode>3"
3074 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3075 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3076 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3079 [(set_attr "type" "div")
3080 (set_attr "size" "<bits>")])
3082 (define_insn "div<mode>3_sra"
3083 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3084 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3085 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3086 (clobber (reg:GPR CA_REGNO))]
3088 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3089 [(set_attr "type" "two")
3090 (set_attr "length" "8")])
3092 (define_insn_and_split "*div<mode>3_sra_dot"
3093 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3094 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3095 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3097 (clobber (match_scratch:GPR 0 "=r,r"))
3098 (clobber (reg:GPR CA_REGNO))]
3099 "<MODE>mode == Pmode"
3101 sra<wd>i %0,%1,%p2\;addze. %0,%0
3103 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3104 [(parallel [(set (match_dup 0)
3105 (div:GPR (match_dup 1)
3107 (clobber (reg:GPR CA_REGNO))])
3109 (compare:CC (match_dup 0)
3112 [(set_attr "type" "two")
3113 (set_attr "length" "8,12")
3114 (set_attr "cell_micro" "not")])
3116 (define_insn_and_split "*div<mode>3_sra_dot2"
3117 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3118 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3119 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3121 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3122 (div:GPR (match_dup 1)
3124 (clobber (reg:GPR CA_REGNO))]
3125 "<MODE>mode == Pmode"
3127 sra<wd>i %0,%1,%p2\;addze. %0,%0
3129 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3130 [(parallel [(set (match_dup 0)
3131 (div:GPR (match_dup 1)
3133 (clobber (reg:GPR CA_REGNO))])
3135 (compare:CC (match_dup 0)
3138 [(set_attr "type" "two")
3139 (set_attr "length" "8,12")
3140 (set_attr "cell_micro" "not")])
3142 (define_expand "mod<mode>3"
3143 [(set (match_operand:GPR 0 "gpc_reg_operand")
3144 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3145 (match_operand:GPR 2 "reg_or_cint_operand")))]
3152 if (GET_CODE (operands[2]) != CONST_INT
3153 || INTVAL (operands[2]) <= 0
3154 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3159 operands[2] = force_reg (<MODE>mode, operands[2]);
3163 temp1 = gen_reg_rtx (<MODE>mode);
3164 temp2 = gen_reg_rtx (<MODE>mode);
3166 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3167 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3168 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3173 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3174 ;; mod, prefer putting the result of mod into a different register
3175 (define_insn "*mod<mode>3"
3176 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3177 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3178 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3181 [(set_attr "type" "div")
3182 (set_attr "size" "<bits>")])
3185 (define_insn "umod<mode>3"
3186 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3187 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3188 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3191 [(set_attr "type" "div")
3192 (set_attr "size" "<bits>")])
3194 ;; On machines with modulo support, do a combined div/mod the old fashioned
3195 ;; method, since the multiply/subtract is faster than doing the mod instruction
3199 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3200 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3201 (match_operand:GPR 2 "gpc_reg_operand" "")))
3202 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3203 (mod:GPR (match_dup 1)
3206 && ! reg_mentioned_p (operands[0], operands[1])
3207 && ! reg_mentioned_p (operands[0], operands[2])
3208 && ! reg_mentioned_p (operands[3], operands[1])
3209 && ! reg_mentioned_p (operands[3], operands[2])"
3211 (div:GPR (match_dup 1)
3214 (mult:GPR (match_dup 0)
3217 (minus:GPR (match_dup 1)
3221 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3222 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3223 (match_operand:GPR 2 "gpc_reg_operand" "")))
3224 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3225 (umod:GPR (match_dup 1)
3228 && ! reg_mentioned_p (operands[0], operands[1])
3229 && ! reg_mentioned_p (operands[0], operands[2])
3230 && ! reg_mentioned_p (operands[3], operands[1])
3231 && ! reg_mentioned_p (operands[3], operands[2])"
3233 (udiv:GPR (match_dup 1)
3236 (mult:GPR (match_dup 0)
3239 (minus:GPR (match_dup 1)
3243 ;; Logical instructions
3244 ;; The logical instructions are mostly combined by using match_operator,
3245 ;; but the plain AND insns are somewhat different because there is no
3246 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3247 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3249 (define_expand "and<mode>3"
3250 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3251 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3252 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3255 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3257 rs6000_split_logical (operands, AND, false, false, false);
3261 if (CONST_INT_P (operands[2]))
3263 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3265 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3269 if (logical_const_operand (operands[2], <MODE>mode))
3271 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3275 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3277 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3281 operands[2] = force_reg (<MODE>mode, operands[2]);
3286 (define_insn "and<mode>3_imm"
3287 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3288 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3289 (match_operand:GPR 2 "logical_const_operand" "n")))
3290 (clobber (match_scratch:CC 3 "=x"))]
3291 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3292 "andi%e2. %0,%1,%u2"
3293 [(set_attr "type" "logical")
3294 (set_attr "dot" "yes")])
3296 (define_insn_and_split "*and<mode>3_imm_dot"
3297 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3298 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3299 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3301 (clobber (match_scratch:GPR 0 "=r,r"))
3302 (clobber (match_scratch:CC 4 "=X,x"))]
3303 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3304 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3308 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3309 [(parallel [(set (match_dup 0)
3310 (and:GPR (match_dup 1)
3312 (clobber (match_dup 4))])
3314 (compare:CC (match_dup 0)
3317 [(set_attr "type" "logical")
3318 (set_attr "dot" "yes")
3319 (set_attr "length" "4,8")])
3321 (define_insn_and_split "*and<mode>3_imm_dot2"
3322 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3323 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3324 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3326 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3327 (and:GPR (match_dup 1)
3329 (clobber (match_scratch:CC 4 "=X,x"))]
3330 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3331 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3335 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3336 [(parallel [(set (match_dup 0)
3337 (and:GPR (match_dup 1)
3339 (clobber (match_dup 4))])
3341 (compare:CC (match_dup 0)
3344 [(set_attr "type" "logical")
3345 (set_attr "dot" "yes")
3346 (set_attr "length" "4,8")])
3348 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3349 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3350 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3351 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3353 (clobber (match_scratch:GPR 0 "=r,r"))]
3354 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3355 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3359 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3361 (and:GPR (match_dup 1)
3364 (compare:CC (match_dup 0)
3367 [(set_attr "type" "logical")
3368 (set_attr "dot" "yes")
3369 (set_attr "length" "4,8")])
3371 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3372 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3373 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3374 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3376 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3377 (and:GPR (match_dup 1)
3379 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3380 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3384 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3386 (and:GPR (match_dup 1)
3389 (compare:CC (match_dup 0)
3392 [(set_attr "type" "logical")
3393 (set_attr "dot" "yes")
3394 (set_attr "length" "4,8")])
3396 (define_insn "*and<mode>3_imm_dot_shifted"
3397 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3400 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3401 (match_operand:SI 4 "const_int_operand" "n"))
3402 (match_operand:GPR 2 "const_int_operand" "n"))
3404 (clobber (match_scratch:GPR 0 "=r"))]
3405 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3406 << INTVAL (operands[4])),
3408 && (<MODE>mode == Pmode
3409 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3411 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3412 return "andi%e2. %0,%1,%u2";
3414 [(set_attr "type" "logical")
3415 (set_attr "dot" "yes")])
3418 (define_insn "and<mode>3_mask"
3419 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3420 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3421 (match_operand:GPR 2 "const_int_operand" "n")))]
3422 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3424 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3426 [(set_attr "type" "shift")])
3428 (define_insn_and_split "*and<mode>3_mask_dot"
3429 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3430 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3431 (match_operand:GPR 2 "const_int_operand" "n,n"))
3433 (clobber (match_scratch:GPR 0 "=r,r"))]
3434 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3435 && !logical_const_operand (operands[2], <MODE>mode)
3436 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3438 if (which_alternative == 0)
3439 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3443 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3445 (and:GPR (match_dup 1)
3448 (compare:CC (match_dup 0)
3451 [(set_attr "type" "shift")
3452 (set_attr "dot" "yes")
3453 (set_attr "length" "4,8")])
3455 (define_insn_and_split "*and<mode>3_mask_dot2"
3456 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3457 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3458 (match_operand:GPR 2 "const_int_operand" "n,n"))
3460 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3461 (and:GPR (match_dup 1)
3463 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3464 && !logical_const_operand (operands[2], <MODE>mode)
3465 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3467 if (which_alternative == 0)
3468 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3472 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3474 (and:GPR (match_dup 1)
3477 (compare:CC (match_dup 0)
3480 [(set_attr "type" "shift")
3481 (set_attr "dot" "yes")
3482 (set_attr "length" "4,8")])
3485 (define_insn_and_split "*and<mode>3_2insn"
3486 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3487 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3488 (match_operand:GPR 2 "const_int_operand" "n")))]
3489 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3490 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3491 || logical_const_operand (operands[2], <MODE>mode))"
3496 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3499 [(set_attr "type" "shift")
3500 (set_attr "length" "8")])
3502 (define_insn_and_split "*and<mode>3_2insn_dot"
3503 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3504 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3505 (match_operand:GPR 2 "const_int_operand" "n,n"))
3507 (clobber (match_scratch:GPR 0 "=r,r"))]
3508 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3509 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3510 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3511 || logical_const_operand (operands[2], <MODE>mode))"
3513 "&& reload_completed"
3516 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3519 [(set_attr "type" "shift")
3520 (set_attr "dot" "yes")
3521 (set_attr "length" "8,12")])
3523 (define_insn_and_split "*and<mode>3_2insn_dot2"
3524 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3525 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3526 (match_operand:GPR 2 "const_int_operand" "n,n"))
3528 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3529 (and:GPR (match_dup 1)
3531 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3532 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3533 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3534 || logical_const_operand (operands[2], <MODE>mode))"
3536 "&& reload_completed"
3539 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3542 [(set_attr "type" "shift")
3543 (set_attr "dot" "yes")
3544 (set_attr "length" "8,12")])
3547 (define_expand "<code><mode>3"
3548 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3549 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3550 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3553 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3555 rs6000_split_logical (operands, <CODE>, false, false, false);
3559 if (non_logical_cint_operand (operands[2], <MODE>mode))
3561 rtx tmp = ((!can_create_pseudo_p ()
3562 || rtx_equal_p (operands[0], operands[1]))
3563 ? operands[0] : gen_reg_rtx (<MODE>mode));
3565 HOST_WIDE_INT value = INTVAL (operands[2]);
3566 HOST_WIDE_INT lo = value & 0xffff;
3567 HOST_WIDE_INT hi = value - lo;
3569 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3570 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3574 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3575 operands[2] = force_reg (<MODE>mode, operands[2]);
3579 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3580 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3581 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3584 (iorxor:GPR (match_dup 1)
3587 (iorxor:GPR (match_dup 3)
3590 operands[3] = ((!can_create_pseudo_p ()
3591 || rtx_equal_p (operands[0], operands[1]))
3592 ? operands[0] : gen_reg_rtx (<MODE>mode));
3594 HOST_WIDE_INT value = INTVAL (operands[2]);
3595 HOST_WIDE_INT lo = value & 0xffff;
3596 HOST_WIDE_INT hi = value - lo;
3598 operands[4] = GEN_INT (hi);
3599 operands[5] = GEN_INT (lo);
3602 (define_insn "*bool<mode>3_imm"
3603 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3604 (match_operator:GPR 3 "boolean_or_operator"
3605 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3606 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3609 [(set_attr "type" "logical")])
3611 (define_insn "*bool<mode>3"
3612 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3613 (match_operator:GPR 3 "boolean_operator"
3614 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3615 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3618 [(set_attr "type" "logical")])
3620 (define_insn_and_split "*bool<mode>3_dot"
3621 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3622 (compare:CC (match_operator:GPR 3 "boolean_operator"
3623 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3624 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3626 (clobber (match_scratch:GPR 0 "=r,r"))]
3627 "<MODE>mode == Pmode"
3631 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3635 (compare:CC (match_dup 0)
3638 [(set_attr "type" "logical")
3639 (set_attr "dot" "yes")
3640 (set_attr "length" "4,8")])
3642 (define_insn_and_split "*bool<mode>3_dot2"
3643 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3644 (compare:CC (match_operator:GPR 3 "boolean_operator"
3645 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3646 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3648 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3650 "<MODE>mode == Pmode"
3654 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3658 (compare:CC (match_dup 0)
3661 [(set_attr "type" "logical")
3662 (set_attr "dot" "yes")
3663 (set_attr "length" "4,8")])
3666 (define_insn "*boolc<mode>3"
3667 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3668 (match_operator:GPR 3 "boolean_operator"
3669 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3670 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3673 [(set_attr "type" "logical")])
3675 (define_insn_and_split "*boolc<mode>3_dot"
3676 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3677 (compare:CC (match_operator:GPR 3 "boolean_operator"
3678 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3679 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3681 (clobber (match_scratch:GPR 0 "=r,r"))]
3682 "<MODE>mode == Pmode"
3686 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3690 (compare:CC (match_dup 0)
3693 [(set_attr "type" "logical")
3694 (set_attr "dot" "yes")
3695 (set_attr "length" "4,8")])
3697 (define_insn_and_split "*boolc<mode>3_dot2"
3698 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3699 (compare:CC (match_operator:GPR 3 "boolean_operator"
3700 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3701 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3703 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3705 "<MODE>mode == Pmode"
3709 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3713 (compare:CC (match_dup 0)
3716 [(set_attr "type" "logical")
3717 (set_attr "dot" "yes")
3718 (set_attr "length" "4,8")])
3721 (define_insn "*boolcc<mode>3"
3722 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3723 (match_operator:GPR 3 "boolean_operator"
3724 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3725 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3728 [(set_attr "type" "logical")])
3730 (define_insn_and_split "*boolcc<mode>3_dot"
3731 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3732 (compare:CC (match_operator:GPR 3 "boolean_operator"
3733 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3734 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3736 (clobber (match_scratch:GPR 0 "=r,r"))]
3737 "<MODE>mode == Pmode"
3741 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3745 (compare:CC (match_dup 0)
3748 [(set_attr "type" "logical")
3749 (set_attr "dot" "yes")
3750 (set_attr "length" "4,8")])
3752 (define_insn_and_split "*boolcc<mode>3_dot2"
3753 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3754 (compare:CC (match_operator:GPR 3 "boolean_operator"
3755 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3756 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3758 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3760 "<MODE>mode == Pmode"
3764 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3768 (compare:CC (match_dup 0)
3771 [(set_attr "type" "logical")
3772 (set_attr "dot" "yes")
3773 (set_attr "length" "4,8")])
3776 ;; TODO: Should have dots of this as well.
3777 (define_insn "*eqv<mode>3"
3778 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3779 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3780 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3783 [(set_attr "type" "logical")])
3785 ;; Rotate-and-mask and insert.
3787 (define_insn "*rotl<mode>3_mask"
3788 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3789 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3790 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3791 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3792 (match_operand:GPR 3 "const_int_operand" "n")))]
3793 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3795 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3797 [(set_attr "type" "shift")
3798 (set_attr "maybe_var_shift" "yes")])
3800 (define_insn_and_split "*rotl<mode>3_mask_dot"
3801 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3803 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3804 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3805 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3806 (match_operand:GPR 3 "const_int_operand" "n,n"))
3808 (clobber (match_scratch:GPR 0 "=r,r"))]
3809 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3810 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3812 if (which_alternative == 0)
3813 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3817 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3819 (and:GPR (match_dup 4)
3822 (compare:CC (match_dup 0)
3825 [(set_attr "type" "shift")
3826 (set_attr "maybe_var_shift" "yes")
3827 (set_attr "dot" "yes")
3828 (set_attr "length" "4,8")])
3830 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3831 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3833 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3834 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3835 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3836 (match_operand:GPR 3 "const_int_operand" "n,n"))
3838 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3839 (and:GPR (match_dup 4)
3841 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3842 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3844 if (which_alternative == 0)
3845 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3849 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3851 (and:GPR (match_dup 4)
3854 (compare:CC (match_dup 0)
3857 [(set_attr "type" "shift")
3858 (set_attr "maybe_var_shift" "yes")
3859 (set_attr "dot" "yes")
3860 (set_attr "length" "4,8")])
3862 ; Special case for less-than-0. We can do it with just one machine
3863 ; instruction, but the generic optimizers do not realise it is cheap.
3864 (define_insn "*lt0_<mode>di"
3865 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3870 [(set_attr "type" "shift")])
3872 (define_insn "*lt0_<mode>si"
3873 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3874 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3877 "rlwinm %0,%1,1,31,31"
3878 [(set_attr "type" "shift")])
3882 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3883 ; both are an AND so are the same precedence).
3884 (define_insn "*rotl<mode>3_insert"
3885 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3886 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3887 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3888 (match_operand:SI 2 "const_int_operand" "n")])
3889 (match_operand:GPR 3 "const_int_operand" "n"))
3890 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3891 (match_operand:GPR 6 "const_int_operand" "n"))))]
3892 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3893 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3895 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3897 [(set_attr "type" "insert")])
3898 ; FIXME: this needs an attr "size", so that the scheduler can see the
3899 ; difference between rlwimi and rldimi. We also might want dot forms,
3900 ; but not for rlwimi on POWER4 and similar processors.
3902 (define_insn "*rotl<mode>3_insert_2"
3903 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3904 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3905 (match_operand:GPR 6 "const_int_operand" "n"))
3906 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3907 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3908 (match_operand:SI 2 "const_int_operand" "n")])
3909 (match_operand:GPR 3 "const_int_operand" "n"))))]
3910 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3911 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3913 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3915 [(set_attr "type" "insert")])
3917 ; There are also some forms without one of the ANDs.
3918 (define_insn "*rotl<mode>3_insert_3"
3919 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3920 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3921 (match_operand:GPR 4 "const_int_operand" "n"))
3922 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3923 (match_operand:SI 2 "const_int_operand" "n"))))]
3924 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3926 if (<MODE>mode == SImode)
3927 return "rlwimi %0,%1,%h2,0,31-%h2";
3929 return "rldimi %0,%1,%H2,0";
3931 [(set_attr "type" "insert")])
3933 (define_insn "*rotl<mode>3_insert_4"
3934 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3935 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3936 (match_operand:GPR 4 "const_int_operand" "n"))
3937 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3938 (match_operand:SI 2 "const_int_operand" "n"))))]
3939 "<MODE>mode == SImode &&
3940 GET_MODE_PRECISION (<MODE>mode)
3941 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3943 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3944 - INTVAL (operands[2]));
3945 if (<MODE>mode == SImode)
3946 return "rlwimi %0,%1,%h2,32-%h2,31";
3948 return "rldimi %0,%1,%H2,64-%H2";
3950 [(set_attr "type" "insert")])
3952 (define_insn "*rotlsi3_insert_5"
3953 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3954 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3955 (match_operand:SI 2 "const_int_operand" "n,n"))
3956 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3957 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3958 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3959 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3960 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3964 [(set_attr "type" "insert")])
3966 (define_insn "*rotldi3_insert_6"
3967 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3968 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3969 (match_operand:DI 2 "const_int_operand" "n"))
3970 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3971 (match_operand:DI 4 "const_int_operand" "n"))))]
3972 "exact_log2 (-UINTVAL (operands[2])) > 0
3973 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3975 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3976 return "rldimi %0,%3,0,%5";
3978 [(set_attr "type" "insert")
3979 (set_attr "size" "64")])
3981 (define_insn "*rotldi3_insert_7"
3982 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3983 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3984 (match_operand:DI 4 "const_int_operand" "n"))
3985 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3986 (match_operand:DI 2 "const_int_operand" "n"))))]
3987 "exact_log2 (-UINTVAL (operands[2])) > 0
3988 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3990 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3991 return "rldimi %0,%3,0,%5";
3993 [(set_attr "type" "insert")
3994 (set_attr "size" "64")])
3997 ; This handles the important case of multiple-precision shifts. There is
3998 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4000 [(set (match_operand:GPR 0 "gpc_reg_operand")
4001 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4002 (match_operand:SI 3 "const_int_operand"))
4003 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4004 (match_operand:SI 4 "const_int_operand"))))]
4005 "can_create_pseudo_p ()
4006 && INTVAL (operands[3]) + INTVAL (operands[4])
4007 >= GET_MODE_PRECISION (<MODE>mode)"
4009 (lshiftrt:GPR (match_dup 2)
4012 (ior:GPR (and:GPR (match_dup 5)
4014 (ashift:GPR (match_dup 1)
4017 unsigned HOST_WIDE_INT mask = 1;
4018 mask = (mask << INTVAL (operands[3])) - 1;
4019 operands[5] = gen_reg_rtx (<MODE>mode);
4020 operands[6] = GEN_INT (mask);
4024 [(set (match_operand:GPR 0 "gpc_reg_operand")
4025 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4026 (match_operand:SI 4 "const_int_operand"))
4027 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4028 (match_operand:SI 3 "const_int_operand"))))]
4029 "can_create_pseudo_p ()
4030 && INTVAL (operands[3]) + INTVAL (operands[4])
4031 >= GET_MODE_PRECISION (<MODE>mode)"
4033 (lshiftrt:GPR (match_dup 2)
4036 (ior:GPR (and:GPR (match_dup 5)
4038 (ashift:GPR (match_dup 1)
4041 unsigned HOST_WIDE_INT mask = 1;
4042 mask = (mask << INTVAL (operands[3])) - 1;
4043 operands[5] = gen_reg_rtx (<MODE>mode);
4044 operands[6] = GEN_INT (mask);
4048 ; Another important case is setting some bits to 1; we can do that with
4049 ; an insert instruction, in many cases.
4050 (define_insn_and_split "*ior<mode>_mask"
4051 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4052 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4053 (match_operand:GPR 2 "const_int_operand" "n")))
4054 (clobber (match_scratch:GPR 3 "=r"))]
4055 "!logical_const_operand (operands[2], <MODE>mode)
4056 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4062 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4065 (and:GPR (match_dup 1)
4069 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4070 if (GET_CODE (operands[3]) == SCRATCH)
4071 operands[3] = gen_reg_rtx (<MODE>mode);
4072 operands[4] = GEN_INT (ne);
4073 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4075 [(set_attr "type" "two")
4076 (set_attr "length" "8")])
4079 ;; Now the simple shifts.
4081 (define_insn "rotl<mode>3"
4082 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4083 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4084 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4086 "rotl<wd>%I2 %0,%1,%<hH>2"
4087 [(set_attr "type" "shift")
4088 (set_attr "maybe_var_shift" "yes")])
4090 (define_insn "*rotlsi3_64"
4091 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4093 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4094 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4096 "rotlw%I2 %0,%1,%h2"
4097 [(set_attr "type" "shift")
4098 (set_attr "maybe_var_shift" "yes")])
4100 (define_insn_and_split "*rotl<mode>3_dot"
4101 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4102 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4103 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4105 (clobber (match_scratch:GPR 0 "=r,r"))]
4106 "<MODE>mode == Pmode"
4108 rotl<wd>%I2. %0,%1,%<hH>2
4110 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4112 (rotate:GPR (match_dup 1)
4115 (compare:CC (match_dup 0)
4118 [(set_attr "type" "shift")
4119 (set_attr "maybe_var_shift" "yes")
4120 (set_attr "dot" "yes")
4121 (set_attr "length" "4,8")])
4123 (define_insn_and_split "*rotl<mode>3_dot2"
4124 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4125 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4126 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4128 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4129 (rotate:GPR (match_dup 1)
4131 "<MODE>mode == Pmode"
4133 rotl<wd>%I2. %0,%1,%<hH>2
4135 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4137 (rotate:GPR (match_dup 1)
4140 (compare:CC (match_dup 0)
4143 [(set_attr "type" "shift")
4144 (set_attr "maybe_var_shift" "yes")
4145 (set_attr "dot" "yes")
4146 (set_attr "length" "4,8")])
4149 (define_insn "ashl<mode>3"
4150 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4151 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4152 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4154 "sl<wd>%I2 %0,%1,%<hH>2"
4155 [(set_attr "type" "shift")
4156 (set_attr "maybe_var_shift" "yes")])
4158 (define_insn "*ashlsi3_64"
4159 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4161 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4162 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4165 [(set_attr "type" "shift")
4166 (set_attr "maybe_var_shift" "yes")])
4168 (define_insn_and_split "*ashl<mode>3_dot"
4169 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4170 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4171 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4173 (clobber (match_scratch:GPR 0 "=r,r"))]
4174 "<MODE>mode == Pmode"
4176 sl<wd>%I2. %0,%1,%<hH>2
4178 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4180 (ashift:GPR (match_dup 1)
4183 (compare:CC (match_dup 0)
4186 [(set_attr "type" "shift")
4187 (set_attr "maybe_var_shift" "yes")
4188 (set_attr "dot" "yes")
4189 (set_attr "length" "4,8")])
4191 (define_insn_and_split "*ashl<mode>3_dot2"
4192 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4193 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4194 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4196 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4197 (ashift:GPR (match_dup 1)
4199 "<MODE>mode == Pmode"
4201 sl<wd>%I2. %0,%1,%<hH>2
4203 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4205 (ashift:GPR (match_dup 1)
4208 (compare:CC (match_dup 0)
4211 [(set_attr "type" "shift")
4212 (set_attr "maybe_var_shift" "yes")
4213 (set_attr "dot" "yes")
4214 (set_attr "length" "4,8")])
4216 ;; Pretend we have a memory form of extswsli until register allocation is done
4217 ;; so that we use LWZ to load the value from memory, instead of LWA.
4218 (define_insn_and_split "ashdi3_extswsli"
4219 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4221 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4222 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4227 "&& reload_completed && MEM_P (operands[1])"
4231 (ashift:DI (sign_extend:DI (match_dup 3))
4234 operands[3] = gen_lowpart (SImode, operands[0]);
4236 [(set_attr "type" "shift")
4237 (set_attr "maybe_var_shift" "no")])
4240 (define_insn_and_split "ashdi3_extswsli_dot"
4241 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4244 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4245 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4247 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4254 "&& reload_completed
4255 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4256 || memory_operand (operands[1], SImode))"
4259 rtx dest = operands[0];
4260 rtx src = operands[1];
4261 rtx shift = operands[2];
4262 rtx cr = operands[3];
4269 src2 = gen_lowpart (SImode, dest);
4270 emit_move_insn (src2, src);
4273 if (REGNO (cr) == CR0_REGNO)
4275 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4279 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4280 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4283 [(set_attr "type" "shift")
4284 (set_attr "maybe_var_shift" "no")
4285 (set_attr "dot" "yes")
4286 (set_attr "length" "4,8,8,12")])
4288 (define_insn_and_split "ashdi3_extswsli_dot2"
4289 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4292 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4293 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4295 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4296 (ashift:DI (sign_extend:DI (match_dup 1))
4304 "&& reload_completed
4305 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4306 || memory_operand (operands[1], SImode))"
4309 rtx dest = operands[0];
4310 rtx src = operands[1];
4311 rtx shift = operands[2];
4312 rtx cr = operands[3];
4319 src2 = gen_lowpart (SImode, dest);
4320 emit_move_insn (src2, src);
4323 if (REGNO (cr) == CR0_REGNO)
4325 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4329 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4330 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4333 [(set_attr "type" "shift")
4334 (set_attr "maybe_var_shift" "no")
4335 (set_attr "dot" "yes")
4336 (set_attr "length" "4,8,8,12")])
4338 (define_insn "lshr<mode>3"
4339 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4340 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4341 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4343 "sr<wd>%I2 %0,%1,%<hH>2"
4344 [(set_attr "type" "shift")
4345 (set_attr "maybe_var_shift" "yes")])
4347 (define_insn "*lshrsi3_64"
4348 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4350 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4351 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4354 [(set_attr "type" "shift")
4355 (set_attr "maybe_var_shift" "yes")])
4357 (define_insn_and_split "*lshr<mode>3_dot"
4358 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4359 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4360 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4362 (clobber (match_scratch:GPR 0 "=r,r"))]
4363 "<MODE>mode == Pmode"
4365 sr<wd>%I2. %0,%1,%<hH>2
4367 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4369 (lshiftrt:GPR (match_dup 1)
4372 (compare:CC (match_dup 0)
4375 [(set_attr "type" "shift")
4376 (set_attr "maybe_var_shift" "yes")
4377 (set_attr "dot" "yes")
4378 (set_attr "length" "4,8")])
4380 (define_insn_and_split "*lshr<mode>3_dot2"
4381 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4382 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4383 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4385 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4386 (lshiftrt:GPR (match_dup 1)
4388 "<MODE>mode == Pmode"
4390 sr<wd>%I2. %0,%1,%<hH>2
4392 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4394 (lshiftrt:GPR (match_dup 1)
4397 (compare:CC (match_dup 0)
4400 [(set_attr "type" "shift")
4401 (set_attr "maybe_var_shift" "yes")
4402 (set_attr "dot" "yes")
4403 (set_attr "length" "4,8")])
4406 (define_insn "ashr<mode>3"
4407 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4408 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4409 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4410 (clobber (reg:GPR CA_REGNO))]
4412 "sra<wd>%I2 %0,%1,%<hH>2"
4413 [(set_attr "type" "shift")
4414 (set_attr "maybe_var_shift" "yes")])
4416 (define_insn "*ashrsi3_64"
4417 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4419 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4420 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4421 (clobber (reg:SI CA_REGNO))]
4424 [(set_attr "type" "shift")
4425 (set_attr "maybe_var_shift" "yes")])
4427 (define_insn_and_split "*ashr<mode>3_dot"
4428 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4429 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4430 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4432 (clobber (match_scratch:GPR 0 "=r,r"))
4433 (clobber (reg:GPR CA_REGNO))]
4434 "<MODE>mode == Pmode"
4436 sra<wd>%I2. %0,%1,%<hH>2
4438 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4439 [(parallel [(set (match_dup 0)
4440 (ashiftrt:GPR (match_dup 1)
4442 (clobber (reg:GPR CA_REGNO))])
4444 (compare:CC (match_dup 0)
4447 [(set_attr "type" "shift")
4448 (set_attr "maybe_var_shift" "yes")
4449 (set_attr "dot" "yes")
4450 (set_attr "length" "4,8")])
4452 (define_insn_and_split "*ashr<mode>3_dot2"
4453 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4454 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4455 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4457 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4458 (ashiftrt:GPR (match_dup 1)
4460 (clobber (reg:GPR CA_REGNO))]
4461 "<MODE>mode == Pmode"
4463 sra<wd>%I2. %0,%1,%<hH>2
4465 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4466 [(parallel [(set (match_dup 0)
4467 (ashiftrt:GPR (match_dup 1)
4469 (clobber (reg:GPR CA_REGNO))])
4471 (compare:CC (match_dup 0)
4474 [(set_attr "type" "shift")
4475 (set_attr "maybe_var_shift" "yes")
4476 (set_attr "dot" "yes")
4477 (set_attr "length" "4,8")])
4479 ;; Builtins to replace a division to generate FRE reciprocal estimate
4480 ;; instructions and the necessary fixup instructions
4481 (define_expand "recip<mode>3"
4482 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4483 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4484 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4485 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4487 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4491 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4492 ;; hardware division. This is only done before register allocation and with
4493 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4494 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4495 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4497 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4498 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4499 (match_operand 2 "gpc_reg_operand" "")))]
4500 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4501 && can_create_pseudo_p () && flag_finite_math_only
4502 && !flag_trapping_math && flag_reciprocal_math"
4505 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4509 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4510 ;; appropriate fixup.
4511 (define_expand "rsqrt<mode>2"
4512 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4513 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4514 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4516 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4520 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4521 ;; modes here, and also add in conditional vsx/power8-vector support to access
4522 ;; values in the traditional Altivec registers if the appropriate
4523 ;; -mupper-regs-{df,sf} option is enabled.
4525 (define_expand "abs<mode>2"
4526 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4527 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4528 "TARGET_<MODE>_INSN"
4531 (define_insn "*abs<mode>2_fpr"
4532 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4533 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4538 [(set_attr "type" "fpsimple")
4539 (set_attr "fp_type" "fp_addsub_<Fs>")])
4541 (define_insn "*nabs<mode>2_fpr"
4542 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4545 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4550 [(set_attr "type" "fpsimple")
4551 (set_attr "fp_type" "fp_addsub_<Fs>")])
4553 (define_expand "neg<mode>2"
4554 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4555 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4556 "TARGET_<MODE>_INSN"
4559 (define_insn "*neg<mode>2_fpr"
4560 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4561 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4566 [(set_attr "type" "fpsimple")
4567 (set_attr "fp_type" "fp_addsub_<Fs>")])
4569 (define_expand "add<mode>3"
4570 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4571 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4572 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4573 "TARGET_<MODE>_INSN"
4576 (define_insn "*add<mode>3_fpr"
4577 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4578 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4579 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4582 fadd<Ftrad> %0,%1,%2
4583 xsadd<Fvsx> %x0,%x1,%x2"
4584 [(set_attr "type" "fp")
4585 (set_attr "fp_type" "fp_addsub_<Fs>")])
4587 (define_expand "sub<mode>3"
4588 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4589 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4590 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4591 "TARGET_<MODE>_INSN"
4594 (define_insn "*sub<mode>3_fpr"
4595 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4596 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4597 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4600 fsub<Ftrad> %0,%1,%2
4601 xssub<Fvsx> %x0,%x1,%x2"
4602 [(set_attr "type" "fp")
4603 (set_attr "fp_type" "fp_addsub_<Fs>")])
4605 (define_expand "mul<mode>3"
4606 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4607 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4608 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4609 "TARGET_<MODE>_INSN"
4612 (define_insn "*mul<mode>3_fpr"
4613 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4614 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4615 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4618 fmul<Ftrad> %0,%1,%2
4619 xsmul<Fvsx> %x0,%x1,%x2"
4620 [(set_attr "type" "dmul")
4621 (set_attr "fp_type" "fp_mul_<Fs>")])
4623 (define_expand "div<mode>3"
4624 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4625 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4626 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4627 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4629 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4630 && can_create_pseudo_p () && flag_finite_math_only
4631 && !flag_trapping_math && flag_reciprocal_math)
4633 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4638 (define_insn "*div<mode>3_fpr"
4639 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4640 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4641 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4642 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4644 fdiv<Ftrad> %0,%1,%2
4645 xsdiv<Fvsx> %x0,%x1,%x2"
4646 [(set_attr "type" "<Fs>div")
4647 (set_attr "fp_type" "fp_div_<Fs>")])
4649 (define_insn "*sqrt<mode>2_internal"
4650 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4651 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4652 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4653 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4656 xssqrt<Fvsx> %x0,%x1"
4657 [(set_attr "type" "<Fs>sqrt")
4658 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4660 (define_expand "sqrt<mode>2"
4661 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4662 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4663 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4664 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4666 if (<MODE>mode == SFmode
4667 && TARGET_RECIP_PRECISION
4668 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4669 && !optimize_function_for_size_p (cfun)
4670 && flag_finite_math_only && !flag_trapping_math
4671 && flag_unsafe_math_optimizations)
4673 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4678 ;; Floating point reciprocal approximation
4679 (define_insn "fre<Fs>"
4680 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4681 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4687 [(set_attr "type" "fp")])
4689 (define_insn "*rsqrt<mode>2"
4690 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4691 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4693 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4695 frsqrte<Ftrad> %0,%1
4696 xsrsqrte<Fvsx> %x0,%x1"
4697 [(set_attr "type" "fp")])
4699 ;; Floating point comparisons
4700 (define_insn "*cmp<mode>_fpr"
4701 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4702 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4703 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4707 xscmpudp %0,%x1,%x2"
4708 [(set_attr "type" "fpcompare")])
4710 ;; Floating point conversions
4711 (define_expand "extendsfdf2"
4712 [(set (match_operand:DF 0 "gpc_reg_operand")
4713 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4714 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4716 if (HONOR_SNANS (SFmode))
4717 operands[1] = force_reg (SFmode, operands[1]);
4720 (define_insn_and_split "*extendsfdf2_fpr"
4721 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4722 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4723 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4729 xscpsgndp %x0,%x1,%x1
4732 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4735 emit_note (NOTE_INSN_DELETED);
4738 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4740 (define_insn "*extendsfdf2_snan"
4741 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4742 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4743 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4747 [(set_attr "type" "fp")])
4749 (define_expand "truncdfsf2"
4750 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4751 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4752 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4755 (define_insn "*truncdfsf2_fpr"
4756 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4757 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4758 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4762 [(set_attr "type" "fp")])
4764 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4765 ;; builtins.c and optabs.c that are not correct for IBM long double
4766 ;; when little-endian.
4767 (define_expand "signbit<mode>2"
4769 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4771 (subreg:DI (match_dup 2) 0))
4774 (set (match_operand:SI 0 "gpc_reg_operand" "")
4777 && (!FLOAT128_IEEE_P (<MODE>mode)
4778 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4780 if (FLOAT128_IEEE_P (<MODE>mode))
4782 if (<MODE>mode == KFmode)
4783 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4784 else if (<MODE>mode == TFmode)
4785 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4790 operands[2] = gen_reg_rtx (DFmode);
4791 operands[3] = gen_reg_rtx (DImode);
4792 if (TARGET_POWERPC64)
4794 operands[4] = gen_reg_rtx (DImode);
4795 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4796 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4797 WORDS_BIG_ENDIAN ? 4 : 0);
4801 operands[4] = gen_reg_rtx (SImode);
4802 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4803 WORDS_BIG_ENDIAN ? 0 : 4);
4804 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4808 (define_expand "copysign<mode>3"
4810 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4812 (neg:SFDF (abs:SFDF (match_dup 1))))
4813 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4814 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4818 "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4819 && ((TARGET_PPC_GFXOPT
4820 && !HONOR_NANS (<MODE>mode)
4821 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4823 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4825 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4827 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4832 operands[3] = gen_reg_rtx (<MODE>mode);
4833 operands[4] = gen_reg_rtx (<MODE>mode);
4834 operands[5] = CONST0_RTX (<MODE>mode);
4837 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4839 (define_insn_and_split "signbit<mode>2_dm"
4840 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4842 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4844 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4846 "&& reload_completed"
4849 rs6000_split_signbit (operands[0], operands[1]);
4852 [(set_attr "length" "8,8,4")
4853 (set_attr "type" "mftgpr,load,integer")])
4855 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4856 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4859 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4861 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4863 "&& reload_completed"
4866 rs6000_split_signbit (operands[0], operands[1]);
4869 [(set_attr "length" "8,8,4")
4870 (set_attr "type" "mftgpr,load,integer")])
4872 ;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various
4873 ;; floating point types, which makes normal SUBREG's problematical. Instead
4874 ;; use a special pattern to avoid using a normal movdi.
4875 (define_insn "signbit<mode>2_dm2"
4876 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4877 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4880 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4882 [(set_attr "type" "mftgpr")])
4885 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4886 ;; compiler from optimizing -0.0
4887 (define_insn "copysign<mode>3_fcpsgn"
4888 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4889 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4890 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4892 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4895 xscpsgndp %x0,%x2,%x1"
4896 [(set_attr "type" "fpsimple")])
4898 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4899 ;; fsel instruction and some auxiliary computations. Then we just have a
4900 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4902 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4903 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4904 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4905 ;; define_splits to make them if made by combine. On VSX machines we have the
4906 ;; min/max instructions.
4908 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4909 ;; to allow either DF/SF to use only traditional registers.
4911 (define_expand "s<minmax><mode>3"
4912 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4913 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4914 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4915 "TARGET_MINMAX_<MODE>"
4917 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4921 (define_insn "*s<minmax><mode>3_vsx"
4922 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4923 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4924 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4925 "TARGET_VSX && TARGET_<MODE>_FPR"
4927 return (TARGET_P9_MINMAX
4928 ? "xs<minmax>cdp %x0,%x1,%x2"
4929 : "xs<minmax>dp %x0,%x1,%x2");
4931 [(set_attr "type" "fp")])
4933 ;; The conditional move instructions allow us to perform max and min operations
4934 ;; even when we don't have the appropriate max/min instruction using the FSEL
4937 (define_insn_and_split "*s<minmax><mode>3_fpr"
4938 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4939 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4940 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4941 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4946 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4950 (define_expand "mov<mode>cc"
4951 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4952 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4953 (match_operand:GPR 2 "gpc_reg_operand" "")
4954 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4958 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4964 ;; We use the BASE_REGS for the isel input operands because, if rA is
4965 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4966 ;; because we may switch the operands and rB may end up being rA.
4968 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4969 ;; leave out the mode in operand 4 and use one pattern, but reload can
4970 ;; change the mode underneath our feet and then gets confused trying
4971 ;; to reload the value.
4972 (define_insn "isel_signed_<mode>"
4973 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4975 (match_operator 1 "scc_comparison_operator"
4976 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4978 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4979 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4982 [(set_attr "type" "isel")])
4984 (define_insn "isel_unsigned_<mode>"
4985 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4987 (match_operator 1 "scc_comparison_operator"
4988 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4990 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4991 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4994 [(set_attr "type" "isel")])
4996 ;; These patterns can be useful for combine; they let combine know that
4997 ;; isel can handle reversed comparisons so long as the operands are
5000 (define_insn "*isel_reversed_signed_<mode>"
5001 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5003 (match_operator 1 "scc_rev_comparison_operator"
5004 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5006 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5007 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5010 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5011 return "isel %0,%3,%2,%j1";
5013 [(set_attr "type" "isel")])
5015 (define_insn "*isel_reversed_unsigned_<mode>"
5016 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5018 (match_operator 1 "scc_rev_comparison_operator"
5019 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5021 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5022 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5025 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5026 return "isel %0,%3,%2,%j1";
5028 [(set_attr "type" "isel")])
5030 ;; Floating point conditional move
5031 (define_expand "mov<mode>cc"
5032 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5033 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
5034 (match_operand:SFDF 2 "gpc_reg_operand" "")
5035 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
5036 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5039 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5045 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5046 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5048 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5049 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5050 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5051 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5052 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5054 [(set_attr "type" "fp")])
5056 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5057 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5059 (match_operator:CCFP 1 "fpmask_comparison_operator"
5060 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5061 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5062 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5063 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5064 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5069 (if_then_else:V2DI (match_dup 1)
5073 (if_then_else:SFDF (ne (match_dup 6)
5078 if (GET_CODE (operands[6]) == SCRATCH)
5079 operands[6] = gen_reg_rtx (V2DImode);
5081 operands[7] = CONSTM1_RTX (V2DImode);
5082 operands[8] = CONST0_RTX (V2DImode);
5084 [(set_attr "length" "8")
5085 (set_attr "type" "vecperm")])
5087 ;; Handle inverting the fpmask comparisons.
5088 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5089 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5091 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5092 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5093 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5094 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5095 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5096 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5101 (if_then_else:V2DI (match_dup 9)
5105 (if_then_else:SFDF (ne (match_dup 6)
5110 rtx op1 = operands[1];
5111 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5113 if (GET_CODE (operands[6]) == SCRATCH)
5114 operands[6] = gen_reg_rtx (V2DImode);
5116 operands[7] = CONSTM1_RTX (V2DImode);
5117 operands[8] = CONST0_RTX (V2DImode);
5119 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5121 [(set_attr "length" "8")
5122 (set_attr "type" "vecperm")])
5124 (define_insn "*fpmask<mode>"
5125 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5127 (match_operator:CCFP 1 "fpmask_comparison_operator"
5128 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5129 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5130 (match_operand:V2DI 4 "all_ones_constant" "")
5131 (match_operand:V2DI 5 "zero_constant" "")))]
5133 "xscmp%V1dp %x0,%x2,%x3"
5134 [(set_attr "type" "fpcompare")])
5136 (define_insn "*xxsel<mode>"
5137 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5138 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5139 (match_operand:V2DI 2 "zero_constant" ""))
5140 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5141 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5143 "xxsel %x0,%x4,%x3,%x1"
5144 [(set_attr "type" "vecmove")])
5147 ;; Conversions to and from floating-point.
5149 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5150 ; don't want to support putting SImode in FPR registers.
5151 (define_insn "lfiwax"
5152 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5153 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5155 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5161 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5163 ; This split must be run before register allocation because it allocates the
5164 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5165 ; it earlier to allow for the combiner to merge insns together where it might
5166 ; not be needed and also in case the insns are deleted as dead code.
5168 (define_insn_and_split "floatsi<mode>2_lfiwax"
5169 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5170 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5171 (clobber (match_scratch:DI 2 "=wi"))]
5172 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5173 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5179 rtx dest = operands[0];
5180 rtx src = operands[1];
5183 if (!MEM_P (src) && TARGET_POWERPC64
5184 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5185 tmp = convert_to_mode (DImode, src, false);
5189 if (GET_CODE (tmp) == SCRATCH)
5190 tmp = gen_reg_rtx (DImode);
5193 src = rs6000_address_for_fpconvert (src);
5194 emit_insn (gen_lfiwax (tmp, src));
5198 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5199 emit_move_insn (stack, src);
5200 emit_insn (gen_lfiwax (tmp, stack));
5203 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5206 [(set_attr "length" "12")
5207 (set_attr "type" "fpload")])
5209 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5210 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5213 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5214 (clobber (match_scratch:DI 2 "=wi"))]
5215 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5221 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5222 if (GET_CODE (operands[2]) == SCRATCH)
5223 operands[2] = gen_reg_rtx (DImode);
5224 if (TARGET_P8_VECTOR)
5225 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5227 emit_insn (gen_lfiwax (operands[2], operands[1]));
5228 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5231 [(set_attr "length" "8")
5232 (set_attr "type" "fpload")])
5234 (define_insn "lfiwzx"
5235 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5236 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5238 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5243 xxextractuw %x0,%x1,4"
5244 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5246 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5247 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5248 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5249 (clobber (match_scratch:DI 2 "=wi"))]
5250 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5256 rtx dest = operands[0];
5257 rtx src = operands[1];
5260 if (!MEM_P (src) && TARGET_POWERPC64
5261 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5262 tmp = convert_to_mode (DImode, src, true);
5266 if (GET_CODE (tmp) == SCRATCH)
5267 tmp = gen_reg_rtx (DImode);
5270 src = rs6000_address_for_fpconvert (src);
5271 emit_insn (gen_lfiwzx (tmp, src));
5275 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5276 emit_move_insn (stack, src);
5277 emit_insn (gen_lfiwzx (tmp, stack));
5280 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5283 [(set_attr "length" "12")
5284 (set_attr "type" "fpload")])
5286 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5287 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5288 (unsigned_float:SFDF
5290 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5291 (clobber (match_scratch:DI 2 "=wi"))]
5292 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5298 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5299 if (GET_CODE (operands[2]) == SCRATCH)
5300 operands[2] = gen_reg_rtx (DImode);
5301 if (TARGET_P8_VECTOR)
5302 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5304 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5305 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5308 [(set_attr "length" "8")
5309 (set_attr "type" "fpload")])
5311 ; For each of these conversions, there is a define_expand, a define_insn
5312 ; with a '#' template, and a define_split (with C code). The idea is
5313 ; to allow constant folding with the template of the define_insn,
5314 ; then to have the insns split later (between sched1 and final).
5316 (define_expand "floatsidf2"
5317 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5318 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5321 (clobber (match_dup 4))
5322 (clobber (match_dup 5))
5323 (clobber (match_dup 6))])]
5324 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5327 if (TARGET_LFIWAX && TARGET_FCFID)
5329 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5332 else if (TARGET_FCFID)
5334 rtx dreg = operands[1];
5336 dreg = force_reg (SImode, dreg);
5337 dreg = convert_to_mode (DImode, dreg, false);
5338 emit_insn (gen_floatdidf2 (operands[0], dreg));
5342 if (!REG_P (operands[1]))
5343 operands[1] = force_reg (SImode, operands[1]);
5344 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5345 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5346 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5347 operands[5] = gen_reg_rtx (DFmode);
5348 operands[6] = gen_reg_rtx (SImode);
5351 (define_insn_and_split "*floatsidf2_internal"
5352 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5353 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5354 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5355 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5356 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5357 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5358 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5359 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5365 rtx lowword, highword;
5366 gcc_assert (MEM_P (operands[4]));
5367 highword = adjust_address (operands[4], SImode, 0);
5368 lowword = adjust_address (operands[4], SImode, 4);
5369 if (! WORDS_BIG_ENDIAN)
5370 std::swap (lowword, highword);
5372 emit_insn (gen_xorsi3 (operands[6], operands[1],
5373 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5374 emit_move_insn (lowword, operands[6]);
5375 emit_move_insn (highword, operands[2]);
5376 emit_move_insn (operands[5], operands[4]);
5377 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5380 [(set_attr "length" "24")
5381 (set_attr "type" "fp")])
5383 ;; If we don't have a direct conversion to single precision, don't enable this
5384 ;; conversion for 32-bit without fast math, because we don't have the insn to
5385 ;; generate the fixup swizzle to avoid double rounding problems.
5386 (define_expand "floatunssisf2"
5387 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5388 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5389 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5390 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5391 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5392 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5395 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5397 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5402 rtx dreg = operands[1];
5404 dreg = force_reg (SImode, dreg);
5405 dreg = convert_to_mode (DImode, dreg, true);
5406 emit_insn (gen_floatdisf2 (operands[0], dreg));
5411 (define_expand "floatunssidf2"
5412 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5413 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5416 (clobber (match_dup 4))
5417 (clobber (match_dup 5))])]
5418 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5421 if (TARGET_LFIWZX && TARGET_FCFID)
5423 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5426 else if (TARGET_FCFID)
5428 rtx dreg = operands[1];
5430 dreg = force_reg (SImode, dreg);
5431 dreg = convert_to_mode (DImode, dreg, true);
5432 emit_insn (gen_floatdidf2 (operands[0], dreg));
5436 if (!REG_P (operands[1]))
5437 operands[1] = force_reg (SImode, operands[1]);
5438 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5439 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5440 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5441 operands[5] = gen_reg_rtx (DFmode);
5444 (define_insn_and_split "*floatunssidf2_internal"
5445 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5446 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5447 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5448 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5449 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5450 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5451 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5452 && !(TARGET_FCFID && TARGET_POWERPC64)"
5458 rtx lowword, highword;
5459 gcc_assert (MEM_P (operands[4]));
5460 highword = adjust_address (operands[4], SImode, 0);
5461 lowword = adjust_address (operands[4], SImode, 4);
5462 if (! WORDS_BIG_ENDIAN)
5463 std::swap (lowword, highword);
5465 emit_move_insn (lowword, operands[1]);
5466 emit_move_insn (highword, operands[2]);
5467 emit_move_insn (operands[5], operands[4]);
5468 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5471 [(set_attr "length" "20")
5472 (set_attr "type" "fp")])
5474 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5475 ;; vector registers. These insns favor doing the sign/zero extension in
5476 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5477 ;; extension and then a direct move.
5479 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5480 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5482 (match_operand:QHI 1 "input_operand")))
5483 (clobber (match_scratch:DI 2))
5484 (clobber (match_scratch:DI 3))
5485 (clobber (match_scratch:<QHI:MODE> 4))])]
5486 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5488 if (MEM_P (operands[1]))
5489 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5492 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5493 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5495 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5496 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5497 (clobber (match_scratch:DI 3 "=X,r,X"))
5498 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5499 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5501 "&& reload_completed"
5504 rtx result = operands[0];
5505 rtx input = operands[1];
5506 rtx di = operands[2];
5510 rtx tmp = operands[3];
5511 if (altivec_register_operand (input, <QHI:MODE>mode))
5512 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5513 else if (GET_CODE (tmp) == SCRATCH)
5514 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5517 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5518 emit_move_insn (di, tmp);
5523 rtx tmp = operands[4];
5524 emit_move_insn (tmp, input);
5525 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5528 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5532 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5533 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5534 (unsigned_float:FP_ISA3
5535 (match_operand:QHI 1 "input_operand" "")))
5536 (clobber (match_scratch:DI 2 ""))
5537 (clobber (match_scratch:DI 3 ""))])]
5538 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5540 if (MEM_P (operands[1]))
5541 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5544 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5545 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5546 (unsigned_float:FP_ISA3
5547 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5548 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5549 (clobber (match_scratch:DI 3 "=X,r,X"))]
5550 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5552 "&& reload_completed"
5555 rtx result = operands[0];
5556 rtx input = operands[1];
5557 rtx di = operands[2];
5559 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5560 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5563 rtx tmp = operands[3];
5564 if (GET_CODE (tmp) == SCRATCH)
5565 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5568 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5569 emit_move_insn (di, tmp);
5573 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5577 (define_expand "fix_trunc<mode>si2"
5578 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5579 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5580 "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5583 if (!TARGET_P8_VECTOR)
5585 rtx src = force_reg (<MODE>mode, operands[1]);
5588 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5591 rtx tmp = gen_reg_rtx (DImode);
5592 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5593 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5600 ; Like the convert to float patterns, this insn must be split before
5601 ; register allocation so that it can allocate the memory slot if it
5603 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5604 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5605 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5606 (clobber (match_scratch:DI 2 "=d"))]
5607 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5608 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5609 && TARGET_STFIWX && can_create_pseudo_p ()
5610 && !TARGET_P8_VECTOR"
5615 rtx dest = operands[0];
5616 rtx src = operands[1];
5617 rtx tmp = operands[2];
5619 if (GET_CODE (tmp) == SCRATCH)
5620 tmp = gen_reg_rtx (DImode);
5622 emit_insn (gen_fctiwz_<mode> (tmp, src));
5625 dest = rs6000_address_for_fpconvert (dest);
5626 emit_insn (gen_stfiwx (dest, tmp));
5629 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5631 dest = gen_lowpart (DImode, dest);
5632 emit_move_insn (dest, tmp);
5637 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5638 emit_insn (gen_stfiwx (stack, tmp));
5639 emit_move_insn (dest, stack);
5643 [(set_attr "length" "12")
5644 (set_attr "type" "fp")])
5646 (define_insn_and_split "fix_trunc<mode>si2_internal"
5647 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5648 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5649 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5650 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5651 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
5658 gcc_assert (MEM_P (operands[3]));
5659 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5661 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5662 emit_move_insn (operands[3], operands[2]);
5663 emit_move_insn (operands[0], lowword);
5666 [(set_attr "length" "16")
5667 (set_attr "type" "fp")])
5669 (define_expand "fix_trunc<mode>di2"
5670 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5671 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5672 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5675 (define_insn "*fix_trunc<mode>di2_fctidz"
5676 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5677 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5678 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5682 [(set_attr "type" "fp")])
5684 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5685 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5686 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5687 (clobber (match_scratch:DI 2))])]
5688 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5690 if (MEM_P (operands[0]))
5691 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5694 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5695 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5697 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5698 (clobber (match_scratch:DI 2 "=X,wi"))]
5699 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5701 "&& reload_completed"
5704 rtx dest = operands[0];
5705 rtx src = operands[1];
5707 if (vsx_register_operand (dest, <QHI:MODE>mode))
5709 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5710 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5714 rtx tmp = operands[2];
5715 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5717 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5718 emit_move_insn (dest, tmp2);
5723 (define_expand "fixuns_trunc<mode>si2"
5724 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5725 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5726 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5729 if (!TARGET_P8_VECTOR)
5731 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5736 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5737 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5738 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5739 (clobber (match_scratch:DI 2 "=d"))]
5740 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5741 && TARGET_STFIWX && can_create_pseudo_p ()
5742 && !TARGET_P8_VECTOR"
5747 rtx dest = operands[0];
5748 rtx src = operands[1];
5749 rtx tmp = operands[2];
5751 if (GET_CODE (tmp) == SCRATCH)
5752 tmp = gen_reg_rtx (DImode);
5754 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5757 dest = rs6000_address_for_fpconvert (dest);
5758 emit_insn (gen_stfiwx (dest, tmp));
5761 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5763 dest = gen_lowpart (DImode, dest);
5764 emit_move_insn (dest, tmp);
5769 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5770 emit_insn (gen_stfiwx (stack, tmp));
5771 emit_move_insn (dest, stack);
5775 [(set_attr "length" "12")
5776 (set_attr "type" "fp")])
5778 (define_insn "fixuns_trunc<mode>di2"
5779 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5780 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5781 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5785 [(set_attr "type" "fp")])
5787 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5788 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5789 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5790 (clobber (match_scratch:DI 2))])]
5791 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5793 if (MEM_P (operands[0]))
5794 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5797 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5798 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5800 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5801 (clobber (match_scratch:DI 2 "=X,wi"))]
5802 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5804 "&& reload_completed"
5807 rtx dest = operands[0];
5808 rtx src = operands[1];
5810 if (vsx_register_operand (dest, <QHI:MODE>mode))
5812 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5813 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5817 rtx tmp = operands[2];
5818 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5820 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5821 emit_move_insn (dest, tmp2);
5826 ;; If -mvsx-small-integer, we can represent the FIX operation directly. On
5827 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5828 ;; to another location, since SImode is not allowed in vector registers.
5829 (define_insn "*fctiw<u>z_<mode>_smallint"
5830 [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5831 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5832 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5835 xscvdp<su>xws %x0,%x1"
5836 [(set_attr "type" "fp")])
5838 ;; Combiner pattern to prevent moving the result of converting a floating point
5839 ;; value to 32-bit integer to GPR in order to save it.
5840 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5841 [(set (match_operand:SI 0 "memory_operand" "=Z")
5842 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5843 (clobber (match_scratch:SI 2 "=wa"))]
5844 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5846 "&& reload_completed"
5848 (any_fix:SI (match_dup 1)))
5852 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5853 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5854 ;; because the first makes it clear that operand 0 is not live
5855 ;; before the instruction.
5856 (define_insn "fctiwz_<mode>"
5857 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5859 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5861 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5865 [(set_attr "type" "fp")])
5867 (define_insn "fctiwuz_<mode>"
5868 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5869 (unspec:DI [(unsigned_fix:SI
5870 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5872 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5876 [(set_attr "type" "fp")])
5878 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5879 ;; since the friz instruction does not truncate the value if the floating
5880 ;; point value is < LONG_MIN or > LONG_MAX.
5881 (define_insn "*friz"
5882 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5883 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5884 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5885 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5889 [(set_attr "type" "fp")])
5891 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5892 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5893 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5894 ;; extend it, store it back on the stack from the GPR, load it back into the
5895 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5896 ;; disable using store and load to sign/zero extend the value.
5897 (define_insn_and_split "*round32<mode>2_fprs"
5898 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5900 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5901 (clobber (match_scratch:DI 2 "=d"))
5902 (clobber (match_scratch:DI 3 "=d"))]
5903 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5904 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5905 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5910 rtx dest = operands[0];
5911 rtx src = operands[1];
5912 rtx tmp1 = operands[2];
5913 rtx tmp2 = operands[3];
5914 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5916 if (GET_CODE (tmp1) == SCRATCH)
5917 tmp1 = gen_reg_rtx (DImode);
5918 if (GET_CODE (tmp2) == SCRATCH)
5919 tmp2 = gen_reg_rtx (DImode);
5921 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5922 emit_insn (gen_stfiwx (stack, tmp1));
5923 emit_insn (gen_lfiwax (tmp2, stack));
5924 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5927 [(set_attr "type" "fpload")
5928 (set_attr "length" "16")])
5930 (define_insn_and_split "*roundu32<mode>2_fprs"
5931 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5932 (unsigned_float:SFDF
5933 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5934 (clobber (match_scratch:DI 2 "=d"))
5935 (clobber (match_scratch:DI 3 "=d"))]
5936 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5937 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5938 && can_create_pseudo_p ()"
5943 rtx dest = operands[0];
5944 rtx src = operands[1];
5945 rtx tmp1 = operands[2];
5946 rtx tmp2 = operands[3];
5947 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5949 if (GET_CODE (tmp1) == SCRATCH)
5950 tmp1 = gen_reg_rtx (DImode);
5951 if (GET_CODE (tmp2) == SCRATCH)
5952 tmp2 = gen_reg_rtx (DImode);
5954 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5955 emit_insn (gen_stfiwx (stack, tmp1));
5956 emit_insn (gen_lfiwzx (tmp2, stack));
5957 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5960 [(set_attr "type" "fpload")
5961 (set_attr "length" "16")])
5963 (define_insn "lrintsfsi2"
5964 [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
5965 (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")]
5967 "TARGET_SF_FPR && TARGET_FPRND"
5969 [(set_attr "type" "fp")])
5971 ;; No VSX equivalent to fctid
5972 (define_insn "lrint<mode>di2"
5973 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5974 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5976 "TARGET_<MODE>_FPR && TARGET_FPRND"
5978 [(set_attr "type" "fp")])
5980 (define_insn "btrunc<mode>2"
5981 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5982 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5984 "TARGET_<MODE>_FPR && TARGET_FPRND"
5988 [(set_attr "type" "fp")
5989 (set_attr "fp_type" "fp_addsub_<Fs>")])
5991 (define_insn "ceil<mode>2"
5992 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5993 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5995 "TARGET_<MODE>_FPR && TARGET_FPRND"
5999 [(set_attr "type" "fp")
6000 (set_attr "fp_type" "fp_addsub_<Fs>")])
6002 (define_insn "floor<mode>2"
6003 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6004 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6006 "TARGET_<MODE>_FPR && TARGET_FPRND"
6010 [(set_attr "type" "fp")
6011 (set_attr "fp_type" "fp_addsub_<Fs>")])
6013 ;; No VSX equivalent to frin
6014 (define_insn "round<mode>2"
6015 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6016 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6018 "TARGET_<MODE>_FPR && TARGET_FPRND"
6020 [(set_attr "type" "fp")
6021 (set_attr "fp_type" "fp_addsub_<Fs>")])
6023 (define_insn "*xsrdpi<mode>2"
6024 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6025 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6027 "TARGET_<MODE>_FPR && TARGET_VSX"
6029 [(set_attr "type" "fp")
6030 (set_attr "fp_type" "fp_addsub_<Fs>")])
6032 (define_expand "lround<mode>di2"
6034 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6036 (set (match_operand:DI 0 "gpc_reg_operand" "")
6037 (unspec:DI [(match_dup 2)]
6039 "TARGET_<MODE>_FPR && TARGET_VSX"
6041 operands[2] = gen_reg_rtx (<MODE>mode);
6044 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6045 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6046 ; is only generated for Power8 or later.
6047 (define_insn "stfiwx"
6048 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6049 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6055 [(set_attr "type" "fpstore")])
6057 ;; If we don't have a direct conversion to single precision, don't enable this
6058 ;; conversion for 32-bit without fast math, because we don't have the insn to
6059 ;; generate the fixup swizzle to avoid double rounding problems.
6060 (define_expand "floatsisf2"
6061 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6062 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6063 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6064 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6065 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6066 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6069 if (TARGET_FCFIDS && TARGET_LFIWAX)
6071 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6074 else if (TARGET_FCFID && TARGET_LFIWAX)
6076 rtx dfreg = gen_reg_rtx (DFmode);
6077 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6078 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6083 rtx dreg = operands[1];
6085 dreg = force_reg (SImode, dreg);
6086 dreg = convert_to_mode (DImode, dreg, false);
6087 emit_insn (gen_floatdisf2 (operands[0], dreg));
6092 (define_insn "floatdidf2"
6093 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6094 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6095 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6099 [(set_attr "type" "fp")])
6101 ; Allow the combiner to merge source memory operands to the conversion so that
6102 ; the optimizer/register allocator doesn't try to load the value too early in a
6103 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6104 ; hit. We will split after reload to avoid the trip through the GPRs
6106 (define_insn_and_split "*floatdidf2_mem"
6107 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6108 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6109 (clobber (match_scratch:DI 2 "=d,wi"))]
6110 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6112 "&& reload_completed"
6113 [(set (match_dup 2) (match_dup 1))
6114 (set (match_dup 0) (float:DF (match_dup 2)))]
6116 [(set_attr "length" "8")
6117 (set_attr "type" "fpload")])
6119 (define_expand "floatunsdidf2"
6120 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6122 (match_operand:DI 1 "gpc_reg_operand" "")))]
6123 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6126 (define_insn "*floatunsdidf2_fcfidu"
6127 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6128 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6129 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6133 [(set_attr "type" "fp")
6134 (set_attr "length" "4")])
6136 (define_insn_and_split "*floatunsdidf2_mem"
6137 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6138 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6139 (clobber (match_scratch:DI 2 "=d,wi"))]
6140 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6142 "&& reload_completed"
6143 [(set (match_dup 2) (match_dup 1))
6144 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6146 [(set_attr "length" "8")
6147 (set_attr "type" "fpload")])
6149 (define_expand "floatdisf2"
6150 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6151 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6152 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6153 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6158 rtx val = operands[1];
6159 if (!flag_unsafe_math_optimizations)
6161 rtx label = gen_label_rtx ();
6162 val = gen_reg_rtx (DImode);
6163 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6166 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6171 (define_insn "floatdisf2_fcfids"
6172 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6173 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6174 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6175 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6179 [(set_attr "type" "fp")])
6181 (define_insn_and_split "*floatdisf2_mem"
6182 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6183 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6184 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6185 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6186 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6188 "&& reload_completed"
6192 emit_move_insn (operands[2], operands[1]);
6193 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6196 [(set_attr "length" "8")])
6198 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6199 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6200 ;; from double rounding.
6201 ;; Instead of creating a new cpu type for two FP operations, just use fp
6202 (define_insn_and_split "floatdisf2_internal1"
6203 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6204 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6205 (clobber (match_scratch:DF 2 "=d"))]
6206 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6208 "&& reload_completed"
6210 (float:DF (match_dup 1)))
6212 (float_truncate:SF (match_dup 2)))]
6214 [(set_attr "length" "8")
6215 (set_attr "type" "fp")])
6217 ;; Twiddles bits to avoid double rounding.
6218 ;; Bits that might be truncated when converting to DFmode are replaced
6219 ;; by a bit that won't be lost at that stage, but is below the SFmode
6220 ;; rounding position.
6221 (define_expand "floatdisf2_internal2"
6222 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6224 (clobber (reg:DI CA_REGNO))])
6225 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6227 (set (match_dup 3) (plus:DI (match_dup 3)
6229 (set (match_dup 0) (plus:DI (match_dup 0)
6231 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6233 (set (match_dup 0) (ior:DI (match_dup 0)
6235 (set (match_dup 0) (and:DI (match_dup 0)
6237 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6238 (label_ref (match_operand:DI 2 "" ""))
6240 (set (match_dup 0) (match_dup 1))]
6241 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6245 operands[3] = gen_reg_rtx (DImode);
6246 operands[4] = gen_reg_rtx (CCUNSmode);
6249 (define_expand "floatunsdisf2"
6250 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6251 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6252 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6253 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6256 (define_insn "floatunsdisf2_fcfidus"
6257 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6258 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6259 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6260 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6264 [(set_attr "type" "fp")])
6266 (define_insn_and_split "*floatunsdisf2_mem"
6267 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6268 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6269 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6270 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6271 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6273 "&& reload_completed"
6277 emit_move_insn (operands[2], operands[1]);
6278 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6281 [(set_attr "length" "8")
6282 (set_attr "type" "fpload")])
6284 ;; Define the TImode operations that can be done in a small number
6285 ;; of instructions. The & constraints are to prevent the register
6286 ;; allocator from allocating registers that overlap with the inputs
6287 ;; (for example, having an input in 7,8 and an output in 6,7). We
6288 ;; also allow for the output being the same as one of the inputs.
6290 (define_expand "addti3"
6291 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6292 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6293 (match_operand:TI 2 "reg_or_short_operand" "")))]
6296 rtx lo0 = gen_lowpart (DImode, operands[0]);
6297 rtx lo1 = gen_lowpart (DImode, operands[1]);
6298 rtx lo2 = gen_lowpart (DImode, operands[2]);
6299 rtx hi0 = gen_highpart (DImode, operands[0]);
6300 rtx hi1 = gen_highpart (DImode, operands[1]);
6301 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6303 if (!reg_or_short_operand (lo2, DImode))
6304 lo2 = force_reg (DImode, lo2);
6305 if (!adde_operand (hi2, DImode))
6306 hi2 = force_reg (DImode, hi2);
6308 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6309 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6313 (define_expand "subti3"
6314 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6315 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6316 (match_operand:TI 2 "gpc_reg_operand" "")))]
6319 rtx lo0 = gen_lowpart (DImode, operands[0]);
6320 rtx lo1 = gen_lowpart (DImode, operands[1]);
6321 rtx lo2 = gen_lowpart (DImode, operands[2]);
6322 rtx hi0 = gen_highpart (DImode, operands[0]);
6323 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6324 rtx hi2 = gen_highpart (DImode, operands[2]);
6326 if (!reg_or_short_operand (lo1, DImode))
6327 lo1 = force_reg (DImode, lo1);
6328 if (!adde_operand (hi1, DImode))
6329 hi1 = force_reg (DImode, hi1);
6331 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6332 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6336 ;; 128-bit logical operations expanders
6338 (define_expand "and<mode>3"
6339 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6340 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6341 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6345 (define_expand "ior<mode>3"
6346 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6347 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6348 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6352 (define_expand "xor<mode>3"
6353 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6354 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6355 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6359 (define_expand "one_cmpl<mode>2"
6360 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6361 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6365 (define_expand "nor<mode>3"
6366 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6368 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6369 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6373 (define_expand "andc<mode>3"
6374 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6376 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6377 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6381 ;; Power8 vector logical instructions.
6382 (define_expand "eqv<mode>3"
6383 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6385 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6386 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6387 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6390 ;; Rewrite nand into canonical form
6391 (define_expand "nand<mode>3"
6392 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6394 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6395 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6396 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6399 ;; The canonical form is to have the negated element first, so we need to
6400 ;; reverse arguments.
6401 (define_expand "orc<mode>3"
6402 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6404 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6405 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6406 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6409 ;; 128-bit logical operations insns and split operations
6410 (define_insn_and_split "*and<mode>3_internal"
6411 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6413 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6414 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6417 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6418 return "xxland %x0,%x1,%x2";
6420 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6421 return "vand %0,%1,%2";
6425 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6428 rs6000_split_logical (operands, AND, false, false, false);
6433 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6434 (const_string "veclogical")
6435 (const_string "integer")))
6436 (set (attr "length")
6438 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6441 (match_test "TARGET_POWERPC64")
6443 (const_string "16"))))])
6446 (define_insn_and_split "*bool<mode>3_internal"
6447 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6448 (match_operator:BOOL_128 3 "boolean_or_operator"
6449 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6450 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6453 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6454 return "xxl%q3 %x0,%x1,%x2";
6456 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6457 return "v%q3 %0,%1,%2";
6461 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6464 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6469 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6470 (const_string "veclogical")
6471 (const_string "integer")))
6472 (set (attr "length")
6474 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6477 (match_test "TARGET_POWERPC64")
6479 (const_string "16"))))])
6482 (define_insn_and_split "*boolc<mode>3_internal1"
6483 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6484 (match_operator:BOOL_128 3 "boolean_operator"
6486 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6487 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6488 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6490 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6491 return "xxl%q3 %x0,%x1,%x2";
6493 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6494 return "v%q3 %0,%1,%2";
6498 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6499 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6502 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6507 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6508 (const_string "veclogical")
6509 (const_string "integer")))
6510 (set (attr "length")
6512 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6515 (match_test "TARGET_POWERPC64")
6517 (const_string "16"))))])
6519 (define_insn_and_split "*boolc<mode>3_internal2"
6520 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6521 (match_operator:TI2 3 "boolean_operator"
6523 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6524 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6525 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6527 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6530 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6533 [(set_attr "type" "integer")
6534 (set (attr "length")
6536 (match_test "TARGET_POWERPC64")
6538 (const_string "16")))])
6541 (define_insn_and_split "*boolcc<mode>3_internal1"
6542 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6543 (match_operator:BOOL_128 3 "boolean_operator"
6545 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6547 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6548 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6550 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6551 return "xxl%q3 %x0,%x1,%x2";
6553 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6554 return "v%q3 %0,%1,%2";
6558 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6559 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6562 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6567 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6568 (const_string "veclogical")
6569 (const_string "integer")))
6570 (set (attr "length")
6572 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6575 (match_test "TARGET_POWERPC64")
6577 (const_string "16"))))])
6579 (define_insn_and_split "*boolcc<mode>3_internal2"
6580 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6581 (match_operator:TI2 3 "boolean_operator"
6583 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6585 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6586 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6588 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6591 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6594 [(set_attr "type" "integer")
6595 (set (attr "length")
6597 (match_test "TARGET_POWERPC64")
6599 (const_string "16")))])
6603 (define_insn_and_split "*eqv<mode>3_internal1"
6604 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6607 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6608 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6611 if (vsx_register_operand (operands[0], <MODE>mode))
6612 return "xxleqv %x0,%x1,%x2";
6616 "TARGET_P8_VECTOR && reload_completed
6617 && int_reg_operand (operands[0], <MODE>mode)"
6620 rs6000_split_logical (operands, XOR, true, false, false);
6625 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6626 (const_string "veclogical")
6627 (const_string "integer")))
6628 (set (attr "length")
6630 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6633 (match_test "TARGET_POWERPC64")
6635 (const_string "16"))))])
6637 (define_insn_and_split "*eqv<mode>3_internal2"
6638 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6641 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6642 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6645 "reload_completed && !TARGET_P8_VECTOR"
6648 rs6000_split_logical (operands, XOR, true, false, false);
6651 [(set_attr "type" "integer")
6652 (set (attr "length")
6654 (match_test "TARGET_POWERPC64")
6656 (const_string "16")))])
6658 ;; 128-bit one's complement
6659 (define_insn_and_split "*one_cmpl<mode>3_internal"
6660 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6662 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6665 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6666 return "xxlnor %x0,%x1,%x1";
6668 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6669 return "vnor %0,%1,%1";
6673 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6676 rs6000_split_logical (operands, NOT, false, false, false);
6681 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6682 (const_string "veclogical")
6683 (const_string "integer")))
6684 (set (attr "length")
6686 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6689 (match_test "TARGET_POWERPC64")
6691 (const_string "16"))))])
6694 ;; Now define ways of moving data around.
6696 ;; Set up a register with a value from the GOT table
6698 (define_expand "movsi_got"
6699 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6700 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6701 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6702 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6705 if (GET_CODE (operands[1]) == CONST)
6707 rtx offset = const0_rtx;
6708 HOST_WIDE_INT value;
6710 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6711 value = INTVAL (offset);
6714 rtx tmp = (!can_create_pseudo_p ()
6716 : gen_reg_rtx (Pmode));
6717 emit_insn (gen_movsi_got (tmp, operands[1]));
6718 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6723 operands[2] = rs6000_got_register (operands[1]);
6726 (define_insn "*movsi_got_internal"
6727 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6728 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6729 (match_operand:SI 2 "gpc_reg_operand" "b")]
6731 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6732 "lwz %0,%a1@got(%2)"
6733 [(set_attr "type" "load")])
6735 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6736 ;; didn't get allocated to a hard register.
6738 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6739 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6740 (match_operand:SI 2 "memory_operand" "")]
6742 "DEFAULT_ABI == ABI_V4
6744 && reload_completed"
6745 [(set (match_dup 0) (match_dup 2))
6746 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6750 ;; For SI, we special-case integers that can't be loaded in one insn. We
6751 ;; do the load 16-bits at a time. We could do this by loading from memory,
6752 ;; and this is even supposed to be faster, but it is simpler not to get
6753 ;; integers in the TOC.
6754 (define_insn "movsi_low"
6755 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6756 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6757 (match_operand 2 "" ""))))]
6758 "TARGET_MACHO && ! TARGET_64BIT"
6759 "lwz %0,lo16(%2)(%1)"
6760 [(set_attr "type" "load")
6761 (set_attr "length" "4")])
6763 ;; MR LA LWZ LFIWZX LXSIWZX
6764 ;; STW STFIWX STXSIWX LI LIS
6765 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6766 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6767 ;; MF%1 MT%0 MT%0 NOP
6768 (define_insn "*movsi_internal1"
6769 [(set (match_operand:SI 0 "nonimmediate_operand"
6770 "=r, r, r, ?*wI, ?*wH,
6772 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6773 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6776 (match_operand:SI 1 "input_operand"
6783 "!TARGET_SINGLE_FPU &&
6784 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6811 "*, *, load, fpload, fpload,
6812 store, fpstore, fpstore, *, *,
6813 *, veclogical, vecsimple, vecsimple, vecsimple,
6814 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6824 (define_insn "*movsi_internal1_single"
6825 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6826 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6827 "TARGET_SINGLE_FPU &&
6828 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6843 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6844 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6846 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6847 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6849 ;; Because SF values are actually stored as DF values within the vector
6850 ;; registers, we need to convert the value to the vector SF format when
6851 ;; we need to use the bits in a union or similar cases. We only need
6852 ;; to do this transformation when the value is a vector register. Loads,
6853 ;; stores, and transfers within GPRs are assumed to be safe.
6855 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6856 ;; no alternatives, because the call is created as part of secondary_reload,
6857 ;; and operand #2's register class is used to allocate the temporary register.
6858 ;; This function is called before reload, and it creates the temporary as
6861 ;; MR LWZ LFIWZX LXSIWZX STW
6862 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6865 (define_insn_and_split "movsi_from_sf"
6866 [(set (match_operand:SI 0 "nonimmediate_operand"
6867 "=r, r, ?*wI, ?*wH, m,
6868 m, wY, Z, r, ?*wIwH,
6871 (unspec:SI [(match_operand:SF 1 "input_operand"
6873 f, wb, wu, wIwH, wIwH,
6877 (clobber (match_scratch:V4SF 2
6882 "TARGET_NO_SF_SUBREG
6883 && (register_operand (operands[0], SImode)
6884 || register_operand (operands[1], SFmode))"
6897 "&& reload_completed
6898 && int_reg_operand (operands[0], SImode)
6899 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6902 rtx op0 = operands[0];
6903 rtx op1 = operands[1];
6904 rtx op2 = operands[2];
6905 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6906 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6908 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6909 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6913 "*, load, fpload, fpload, store,
6914 fpstore, fpstore, fpstore, mftgpr, fp,
6922 ;; movsi_from_sf with zero extension
6924 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6927 (define_insn_and_split "*movdi_from_sf_zero_ext"
6928 [(set (match_operand:DI 0 "gpc_reg_operand"
6929 "=r, r, ?*wI, ?*wH, r,
6933 (unspec:SI [(match_operand:SF 1 "input_operand"
6936 UNSPEC_SI_FROM_SF)))
6938 (clobber (match_scratch:V4SF 2
6942 "TARGET_DIRECT_MOVE_64BIT
6943 && (register_operand (operands[0], DImode)
6944 || register_operand (operands[1], SImode))"
6953 "&& reload_completed
6954 && register_operand (operands[0], DImode)
6955 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6958 rtx op0 = operands[0];
6959 rtx op1 = operands[1];
6960 rtx op2 = operands[2];
6961 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6963 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6964 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6968 "*, load, fpload, fpload, two,
6975 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6976 ;; moving it to SImode. We can do a SFmode store without having to do the
6977 ;; conversion explicitly. If we are doing a register->register conversion, use
6978 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6979 ;; input will not fit in a SFmode, and the later assumes the value has already
6981 (define_insn "*movsi_from_df"
6982 [(set (match_operand:SI 0 "nonimmediate_operand" "=wa,m,wY,Z")
6983 (unspec:SI [(float_truncate:SF
6984 (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6985 UNSPEC_SI_FROM_SF))]
6987 "TARGET_NO_SF_SUBREG"
6993 [(set_attr "type" "fp,fpstore,fpstore,fpstore")])
6995 ;; Split a load of a large constant into the appropriate two-insn
6999 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7000 (match_operand:SI 1 "const_int_operand" ""))]
7001 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7002 && (INTVAL (operands[1]) & 0xffff) != 0"
7006 (ior:SI (match_dup 0)
7010 if (rs6000_emit_set_const (operands[0], operands[1]))
7016 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7018 [(set (match_operand:DI 0 "altivec_register_operand")
7019 (match_operand:DI 1 "xxspltib_constant_split"))]
7020 "TARGET_P9_VECTOR && reload_completed"
7023 rtx op0 = operands[0];
7024 rtx op1 = operands[1];
7025 int r = REGNO (op0);
7026 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7028 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7029 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7033 (define_insn "*mov<mode>_internal2"
7034 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7035 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7037 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7043 [(set_attr "type" "cmp,logical,cmp")
7044 (set_attr "dot" "yes")
7045 (set_attr "length" "4,4,8")])
7048 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7049 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7051 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7053 [(set (match_dup 0) (match_dup 1))
7055 (compare:CC (match_dup 0)
7059 (define_expand "mov<mode>"
7060 [(set (match_operand:INT 0 "general_operand" "")
7061 (match_operand:INT 1 "any_operand" ""))]
7063 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7065 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7066 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7067 ;; MTVSRWZ MF%1 MT%1 NOP
7068 (define_insn "*mov<mode>_internal"
7069 [(set (match_operand:QHI 0 "nonimmediate_operand"
7070 "=r, r, ?*wJwK, m, Z, r,
7071 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7072 ?*wJwK, r, *c*l, *h")
7074 (match_operand:QHI 1 "input_operand"
7075 "r, m, Z, r, wJwK, i,
7076 wJwK, O, wM, wB, wS, ?*wJwK,
7079 "gpc_reg_operand (operands[0], <MODE>mode)
7080 || gpc_reg_operand (operands[1], <MODE>mode)"
7099 "*, load, fpload, store, fpstore, *,
7100 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7101 mffgpr, mfjmpr, mtjmpr, *")
7109 ;; Here is how to move condition codes around. When we store CC data in
7110 ;; an integer register or memory, we store just the high-order 4 bits.
7111 ;; This lets us not shift in the most common case of CR0.
7112 (define_expand "movcc"
7113 [(set (match_operand:CC 0 "nonimmediate_operand" "")
7114 (match_operand:CC 1 "nonimmediate_operand" ""))]
7118 (define_insn "*movcc_internal1"
7119 [(set (match_operand:CC 0 "nonimmediate_operand"
7120 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7121 (match_operand:CC 1 "general_operand"
7122 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7123 "register_operand (operands[0], CCmode)
7124 || register_operand (operands[1], CCmode)"
7128 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7131 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7139 (cond [(eq_attr "alternative" "0,3")
7140 (const_string "cr_logical")
7141 (eq_attr "alternative" "1,2")
7142 (const_string "mtcr")
7143 (eq_attr "alternative" "6,7")
7144 (const_string "integer")
7145 (eq_attr "alternative" "8")
7146 (const_string "mfjmpr")
7147 (eq_attr "alternative" "9")
7148 (const_string "mtjmpr")
7149 (eq_attr "alternative" "10")
7150 (const_string "load")
7151 (eq_attr "alternative" "11")
7152 (const_string "store")
7153 (match_test "TARGET_MFCRF")
7154 (const_string "mfcrf")
7156 (const_string "mfcr")))
7157 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7159 ;; For floating-point, we normally deal with the floating-point registers
7160 ;; unless -msoft-float is used. The sole exception is that parameter passing
7161 ;; can produce floating-point values in fixed-point registers. Unless the
7162 ;; value is a simple constant or already in memory, we deal with this by
7163 ;; allocating memory and copying the value explicitly via that memory location.
7165 ;; Move 32-bit binary/decimal floating point
7166 (define_expand "mov<mode>"
7167 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7168 (match_operand:FMOVE32 1 "any_operand" ""))]
7170 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7173 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7174 (match_operand:FMOVE32 1 "const_double_operand" ""))]
7176 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7177 || (GET_CODE (operands[0]) == SUBREG
7178 && GET_CODE (SUBREG_REG (operands[0])) == REG
7179 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7180 [(set (match_dup 2) (match_dup 3))]
7185 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7187 if (! TARGET_POWERPC64)
7188 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7190 operands[2] = gen_lowpart (SImode, operands[0]);
7192 operands[3] = gen_int_mode (l, SImode);
7195 ;; Originally, we tried to keep movsf and movsd common, but the differences
7196 ;; addressing was making it rather difficult to hide with mode attributes. In
7197 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7198 ;; before the VSX stores meant that the register allocator would tend to do a
7199 ;; direct move to the GPR (which involves conversion from scalar to
7200 ;; vector/memory formats) to save values in the traditional Altivec registers,
7201 ;; while SDmode had problems on power6 if the GPR store was not first due to
7202 ;; the power6 not having an integer store operation.
7204 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7205 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7206 ;; MR MT<x> MF<x> NOP
7208 (define_insn "movsf_hardfloat"
7209 [(set (match_operand:SF 0 "nonimmediate_operand"
7210 "=!r, f, wb, wu, m, wY,
7211 Z, m, ww, !r, f, ww,
7213 (match_operand:SF 1 "input_operand"
7214 "m, m, wY, Z, f, wb,
7217 "(register_operand (operands[0], SFmode)
7218 || register_operand (operands[1], SFmode))
7219 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7220 && (TARGET_ALLOW_SF_SUBREG
7221 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7234 xscpsgndp %x0,%x1,%x1
7240 "load, fpload, fpload, fpload, fpstore, fpstore,
7241 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7242 *, mtjmpr, mfjmpr, *")])
7244 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7245 ;; FMR MR MT%0 MF%1 NOP
7246 (define_insn "movsd_hardfloat"
7247 [(set (match_operand:SD 0 "nonimmediate_operand"
7248 "=!r, wz, m, Z, ?wh, ?r,
7249 f, !r, *c*l, !r, *h")
7250 (match_operand:SD 1 "input_operand"
7251 "m, Z, r, wx, r, wh,
7253 "(register_operand (operands[0], SDmode)
7254 || register_operand (operands[1], SDmode))
7255 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7269 "load, fpload, store, fpstore, mffgpr, mftgpr,
7270 fpsimple, *, mtjmpr, mfjmpr, *")])
7272 (define_insn "*mov<mode>_softfloat"
7273 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7274 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7275 "(gpc_reg_operand (operands[0], <MODE>mode)
7276 || gpc_reg_operand (operands[1], <MODE>mode))
7277 && TARGET_SOFT_FLOAT"
7289 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7290 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7292 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7293 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7295 ;; Because SF values are actually stored as DF values within the vector
7296 ;; registers, we need to convert the value to the vector SF format when
7297 ;; we need to use the bits in a union or similar cases. We only need
7298 ;; to do this transformation when the value is a vector register. Loads,
7299 ;; stores, and transfers within GPRs are assumed to be safe.
7301 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7302 ;; no alternatives, because the call is created as part of secondary_reload,
7303 ;; and operand #2's register class is used to allocate the temporary register.
7304 ;; This function is called before reload, and it creates the temporary as
7307 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7308 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7309 (define_insn_and_split "movsf_from_si"
7310 [(set (match_operand:SF 0 "nonimmediate_operand"
7311 "=!r, f, wb, wu, m, Z,
7314 (unspec:SF [(match_operand:SI 1 "input_operand"
7319 (clobber (match_scratch:DI 2
7323 "TARGET_NO_SF_SUBREG
7324 && (register_operand (operands[0], SFmode)
7325 || register_operand (operands[1], SImode))"
7338 "&& reload_completed
7339 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7340 && int_reg_operand_not_pseudo (operands[1], SImode)"
7343 rtx op0 = operands[0];
7344 rtx op1 = operands[1];
7345 rtx op2 = operands[2];
7346 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7348 /* Move SF value to upper 32-bits for xscvspdpn. */
7349 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7350 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7351 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7358 "load, fpload, fpload, fpload, store, fpstore,
7359 fpstore, vecfloat, mffgpr, *")])
7362 ;; Move 64-bit binary/decimal floating point
7363 (define_expand "mov<mode>"
7364 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7365 (match_operand:FMOVE64 1 "any_operand" ""))]
7367 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7370 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7371 (match_operand:FMOVE64 1 "const_int_operand" ""))]
7372 "! TARGET_POWERPC64 && reload_completed
7373 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7374 || (GET_CODE (operands[0]) == SUBREG
7375 && GET_CODE (SUBREG_REG (operands[0])) == REG
7376 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7377 [(set (match_dup 2) (match_dup 4))
7378 (set (match_dup 3) (match_dup 1))]
7381 int endian = (WORDS_BIG_ENDIAN == 0);
7382 HOST_WIDE_INT value = INTVAL (operands[1]);
7384 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7385 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7386 operands[4] = GEN_INT (value >> 32);
7387 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7391 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7392 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7393 "! TARGET_POWERPC64 && reload_completed
7394 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7395 || (GET_CODE (operands[0]) == SUBREG
7396 && GET_CODE (SUBREG_REG (operands[0])) == REG
7397 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7398 [(set (match_dup 2) (match_dup 4))
7399 (set (match_dup 3) (match_dup 5))]
7402 int endian = (WORDS_BIG_ENDIAN == 0);
7405 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7407 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7408 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7409 operands[4] = gen_int_mode (l[endian], SImode);
7410 operands[5] = gen_int_mode (l[1 - endian], SImode);
7414 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7415 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7416 "TARGET_POWERPC64 && reload_completed
7417 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7418 || (GET_CODE (operands[0]) == SUBREG
7419 && GET_CODE (SUBREG_REG (operands[0])) == REG
7420 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7421 [(set (match_dup 2) (match_dup 3))]
7424 int endian = (WORDS_BIG_ENDIAN == 0);
7428 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7430 operands[2] = gen_lowpart (DImode, operands[0]);
7431 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7432 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7433 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7435 operands[3] = gen_int_mode (val, DImode);
7438 ;; Don't have reload use general registers to load a constant. It is
7439 ;; less efficient than loading the constant into an FP register, since
7440 ;; it will probably be used there.
7442 ;; The move constraints are ordered to prefer floating point registers before
7443 ;; general purpose registers to avoid doing a store and a load to get the value
7444 ;; into a floating point register when it is needed for a floating point
7445 ;; operation. Prefer traditional floating point registers over VSX registers,
7446 ;; since the D-form version of the memory instructions does not need a GPR for
7447 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7450 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7451 ;; except for 0.0 which can be created on VSX with an xor instruction.
7453 (define_insn "*mov<mode>_hardfloat32"
7454 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7455 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7456 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7457 && (gpc_reg_operand (operands[0], <MODE>mode)
7458 || gpc_reg_operand (operands[1], <MODE>mode))"
7473 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7474 (set_attr "size" "64")
7475 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7477 (define_insn "*mov<mode>_softfloat32"
7478 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7479 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7481 && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7482 && (gpc_reg_operand (operands[0], <MODE>mode)
7483 || gpc_reg_operand (operands[1], <MODE>mode))"
7485 [(set_attr "type" "store,load,two,*,*,*")
7486 (set_attr "length" "8,8,8,8,12,16")])
7488 ; ld/std require word-aligned displacements -> 'Y' constraint.
7489 ; List Y->r and r->Y before r->r for reload.
7490 (define_insn "*mov<mode>_hardfloat64"
7491 [(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>")
7492 (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"))]
7493 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7494 && (gpc_reg_operand (operands[0], <MODE>mode)
7495 || gpc_reg_operand (operands[1], <MODE>mode))"
7517 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7518 (set_attr "size" "64")
7519 (set_attr "length" "4")])
7521 (define_insn "*mov<mode>_softfloat64"
7522 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7523 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7524 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7525 && (gpc_reg_operand (operands[0], <MODE>mode)
7526 || gpc_reg_operand (operands[1], <MODE>mode))"
7537 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7538 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7540 (define_expand "mov<mode>"
7541 [(set (match_operand:FMOVE128 0 "general_operand" "")
7542 (match_operand:FMOVE128 1 "any_operand" ""))]
7544 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7546 ;; It's important to list Y->r and r->Y before r->r because otherwise
7547 ;; reload, given m->r, will try to pick r->r and reload it, which
7548 ;; doesn't make progress.
7550 ;; We can't split little endian direct moves of TDmode, because the words are
7551 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7552 ;; problematical. Don't allow direct move for this case.
7554 (define_insn_and_split "*mov<mode>_64bit_dm"
7555 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7556 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7557 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7558 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7559 && (gpc_reg_operand (operands[0], <MODE>mode)
7560 || gpc_reg_operand (operands[1], <MODE>mode))"
7562 "&& reload_completed"
7564 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7565 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7567 (define_insn_and_split "*movtd_64bit_nodm"
7568 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7569 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7570 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7571 && (gpc_reg_operand (operands[0], TDmode)
7572 || gpc_reg_operand (operands[1], TDmode))"
7574 "&& reload_completed"
7576 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7577 [(set_attr "length" "8,8,8,12,12,8")])
7579 (define_insn_and_split "*mov<mode>_32bit"
7580 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7581 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7582 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7583 && (FLOAT128_2REG_P (<MODE>mode)
7584 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7585 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7586 && (gpc_reg_operand (operands[0], <MODE>mode)
7587 || gpc_reg_operand (operands[1], <MODE>mode))"
7589 "&& reload_completed"
7591 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7592 [(set_attr "length" "8,8,8,8,20,20,16")])
7594 (define_insn_and_split "*mov<mode>_softfloat"
7595 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7596 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7598 && (gpc_reg_operand (operands[0], <MODE>mode)
7599 || gpc_reg_operand (operands[1], <MODE>mode))"
7601 "&& reload_completed"
7603 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7604 [(set_attr "length" "20,20,16")])
7606 (define_expand "extenddf<mode>2"
7607 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7608 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7609 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7611 if (FLOAT128_IEEE_P (<MODE>mode))
7612 rs6000_expand_float128_convert (operands[0], operands[1], false);
7613 else if (TARGET_VSX)
7615 if (<MODE>mode == TFmode)
7616 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7617 else if (<MODE>mode == IFmode)
7618 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7624 rtx zero = gen_reg_rtx (DFmode);
7625 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7627 if (<MODE>mode == TFmode)
7628 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7629 else if (<MODE>mode == IFmode)
7630 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7637 ;; Allow memory operands for the source to be created by the combiner.
7638 (define_insn_and_split "extenddf<mode>2_fprs"
7639 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7640 (float_extend:IBM128
7641 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7642 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7643 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7644 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7646 "&& reload_completed"
7647 [(set (match_dup 3) (match_dup 1))
7648 (set (match_dup 4) (match_dup 2))]
7650 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7651 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7653 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7654 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7657 (define_insn_and_split "extenddf<mode>2_vsx"
7658 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7659 (float_extend:IBM128
7660 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7661 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7663 "&& reload_completed"
7664 [(set (match_dup 2) (match_dup 1))
7665 (set (match_dup 3) (match_dup 4))]
7667 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7668 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7670 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7671 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7672 operands[4] = CONST0_RTX (DFmode);
7675 (define_expand "extendsf<mode>2"
7676 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7677 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7678 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7680 if (FLOAT128_IEEE_P (<MODE>mode))
7681 rs6000_expand_float128_convert (operands[0], operands[1], false);
7684 rtx tmp = gen_reg_rtx (DFmode);
7685 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7686 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7691 (define_expand "trunc<mode>df2"
7692 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7693 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7694 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7696 if (FLOAT128_IEEE_P (<MODE>mode))
7698 rs6000_expand_float128_convert (operands[0], operands[1], false);
7703 (define_insn_and_split "trunc<mode>df2_internal1"
7704 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7706 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7707 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7708 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7712 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7715 emit_note (NOTE_INSN_DELETED);
7718 [(set_attr "type" "fpsimple")])
7720 (define_insn "trunc<mode>df2_internal2"
7721 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7722 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7723 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7724 && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7726 [(set_attr "type" "fp")
7727 (set_attr "fp_type" "fp_addsub_d")])
7729 (define_expand "trunc<mode>sf2"
7730 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7731 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7732 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7734 if (FLOAT128_IEEE_P (<MODE>mode))
7735 rs6000_expand_float128_convert (operands[0], operands[1], false);
7736 else if (<MODE>mode == TFmode)
7737 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7738 else if (<MODE>mode == IFmode)
7739 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7745 (define_insn_and_split "trunc<mode>sf2_fprs"
7746 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7747 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7748 (clobber (match_scratch:DF 2 "=d"))]
7749 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7750 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7752 "&& reload_completed"
7754 (float_truncate:DF (match_dup 1)))
7756 (float_truncate:SF (match_dup 2)))]
7759 (define_expand "floatsi<mode>2"
7760 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7761 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7762 (clobber (match_scratch:DI 2))])]
7763 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7765 rtx op0 = operands[0];
7766 rtx op1 = operands[1];
7768 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7770 else if (FLOAT128_IEEE_P (<MODE>mode))
7772 rs6000_expand_float128_convert (op0, op1, false);
7777 rtx tmp = gen_reg_rtx (DFmode);
7778 expand_float (tmp, op1, false);
7779 if (<MODE>mode == TFmode)
7780 emit_insn (gen_extenddftf2 (op0, tmp));
7781 else if (<MODE>mode == IFmode)
7782 emit_insn (gen_extenddfif2 (op0, tmp));
7789 ; fadd, but rounding towards zero.
7790 ; This is probably not the optimal code sequence.
7791 (define_insn "fix_trunc_helper<mode>"
7792 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7793 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7794 UNSPEC_FIX_TRUNC_TF))
7795 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7796 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7797 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7798 [(set_attr "type" "fp")
7799 (set_attr "length" "20")])
7801 (define_expand "fix_trunc<mode>si2"
7802 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7803 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7804 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7806 rtx op0 = operands[0];
7807 rtx op1 = operands[1];
7809 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7813 if (FLOAT128_IEEE_P (<MODE>mode))
7814 rs6000_expand_float128_convert (op0, op1, false);
7815 else if (<MODE>mode == TFmode)
7816 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7817 else if (<MODE>mode == IFmode)
7818 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7825 (define_expand "fix_trunc<mode>si2_fprs"
7826 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7827 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7828 (clobber (match_dup 2))
7829 (clobber (match_dup 3))
7830 (clobber (match_dup 4))
7831 (clobber (match_dup 5))])]
7832 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7834 operands[2] = gen_reg_rtx (DFmode);
7835 operands[3] = gen_reg_rtx (DFmode);
7836 operands[4] = gen_reg_rtx (DImode);
7837 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7840 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7841 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7842 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7843 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7844 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7845 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7846 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7847 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7853 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7856 gcc_assert (MEM_P (operands[5]));
7857 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7859 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7860 emit_move_insn (operands[5], operands[4]);
7861 emit_move_insn (operands[0], lowword);
7865 (define_expand "fix_trunc<mode>di2"
7866 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7867 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7868 "TARGET_FLOAT128_TYPE"
7870 if (!TARGET_FLOAT128_HW)
7872 rs6000_expand_float128_convert (operands[0], operands[1], false);
7877 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7878 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7879 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7880 "TARGET_FLOAT128_TYPE"
7882 rs6000_expand_float128_convert (operands[0], operands[1], true);
7886 (define_expand "floatdi<mode>2"
7887 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7888 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7889 "TARGET_FLOAT128_TYPE"
7891 if (!TARGET_FLOAT128_HW)
7893 rs6000_expand_float128_convert (operands[0], operands[1], false);
7898 (define_expand "floatunsdi<IEEE128:mode>2"
7899 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7900 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7901 "TARGET_FLOAT128_TYPE"
7903 if (!TARGET_FLOAT128_HW)
7905 rs6000_expand_float128_convert (operands[0], operands[1], true);
7910 (define_expand "floatuns<IEEE128:mode>2"
7911 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7912 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7913 "TARGET_FLOAT128_TYPE"
7915 rtx op0 = operands[0];
7916 rtx op1 = operands[1];
7918 if (TARGET_FLOAT128_HW)
7919 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7921 rs6000_expand_float128_convert (op0, op1, true);
7925 (define_expand "neg<mode>2"
7926 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7927 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7928 "FLOAT128_IEEE_P (<MODE>mode)
7929 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7932 if (FLOAT128_IEEE_P (<MODE>mode))
7934 if (TARGET_FLOAT128_HW)
7936 if (<MODE>mode == TFmode)
7937 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7938 else if (<MODE>mode == KFmode)
7939 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7943 else if (TARGET_FLOAT128_TYPE)
7945 if (<MODE>mode == TFmode)
7946 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7947 else if (<MODE>mode == KFmode)
7948 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7954 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7955 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7957 operands[1], <MODE>mode);
7959 if (target && !rtx_equal_p (target, operands[0]))
7960 emit_move_insn (operands[0], target);
7966 (define_insn "neg<mode>2_internal"
7967 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7968 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7969 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7972 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7973 return \"fneg %L0,%L1\;fneg %0,%1\";
7975 return \"fneg %0,%1\;fneg %L0,%L1\";
7977 [(set_attr "type" "fpsimple")
7978 (set_attr "length" "8")])
7980 (define_expand "abs<mode>2"
7981 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7982 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7983 "FLOAT128_IEEE_P (<MODE>mode)
7984 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7989 if (FLOAT128_IEEE_P (<MODE>mode))
7991 if (TARGET_FLOAT128_HW)
7993 if (<MODE>mode == TFmode)
7994 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7995 else if (<MODE>mode == KFmode)
7996 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8001 else if (TARGET_FLOAT128_TYPE)
8003 if (<MODE>mode == TFmode)
8004 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8005 else if (<MODE>mode == KFmode)
8006 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8015 label = gen_label_rtx ();
8016 if (<MODE>mode == TFmode)
8017 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8018 else if (<MODE>mode == TFmode)
8019 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8026 (define_expand "abs<mode>2_internal"
8027 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
8028 (match_operand:IBM128 1 "gpc_reg_operand" ""))
8029 (set (match_dup 3) (match_dup 5))
8030 (set (match_dup 5) (abs:DF (match_dup 5)))
8031 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8032 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8033 (label_ref (match_operand 2 "" ""))
8035 (set (match_dup 6) (neg:DF (match_dup 6)))]
8036 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
8039 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8040 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8041 operands[3] = gen_reg_rtx (DFmode);
8042 operands[4] = gen_reg_rtx (CCFPmode);
8043 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8044 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8048 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8051 (define_expand "ieee_128bit_negative_zero"
8052 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8053 "TARGET_FLOAT128_TYPE"
8055 rtvec v = rtvec_alloc (16);
8058 for (i = 0; i < 16; i++)
8059 RTVEC_ELT (v, i) = const0_rtx;
8061 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8062 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8064 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8068 ;; IEEE 128-bit negate
8070 ;; We have 2 insns here for negate and absolute value. The first uses
8071 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8072 ;; insns, and second insn after the first split pass loads up the bit to
8073 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8074 ;; neg/abs to create the constant just once.
8076 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8077 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8078 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8079 (clobber (match_scratch:V16QI 2 "=v"))]
8080 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8083 [(parallel [(set (match_dup 0)
8084 (neg:IEEE128 (match_dup 1)))
8085 (use (match_dup 2))])]
8087 if (GET_CODE (operands[2]) == SCRATCH)
8088 operands[2] = gen_reg_rtx (V16QImode);
8090 operands[3] = gen_reg_rtx (V16QImode);
8091 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8093 [(set_attr "length" "8")
8094 (set_attr "type" "vecsimple")])
8096 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8097 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8098 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8099 (use (match_operand:V16QI 2 "register_operand" "v"))]
8100 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8101 "xxlxor %x0,%x1,%x2"
8102 [(set_attr "type" "veclogical")])
8104 ;; IEEE 128-bit absolute value
8105 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8106 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8107 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8108 (clobber (match_scratch:V16QI 2 "=v"))]
8109 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8112 [(parallel [(set (match_dup 0)
8113 (abs:IEEE128 (match_dup 1)))
8114 (use (match_dup 2))])]
8116 if (GET_CODE (operands[2]) == SCRATCH)
8117 operands[2] = gen_reg_rtx (V16QImode);
8119 operands[3] = gen_reg_rtx (V16QImode);
8120 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8122 [(set_attr "length" "8")
8123 (set_attr "type" "vecsimple")])
8125 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8126 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8127 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8128 (use (match_operand:V16QI 2 "register_operand" "v"))]
8129 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8130 "xxlandc %x0,%x1,%x2"
8131 [(set_attr "type" "veclogical")])
8133 ;; IEEE 128-bit negative absolute value
8134 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8135 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8138 (match_operand:IEEE128 1 "register_operand" "wa"))))
8139 (clobber (match_scratch:V16QI 2 "=v"))]
8140 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8141 && FLOAT128_IEEE_P (<MODE>mode)"
8144 [(parallel [(set (match_dup 0)
8145 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8146 (use (match_dup 2))])]
8148 if (GET_CODE (operands[2]) == SCRATCH)
8149 operands[2] = gen_reg_rtx (V16QImode);
8151 operands[3] = gen_reg_rtx (V16QImode);
8152 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8154 [(set_attr "length" "8")
8155 (set_attr "type" "vecsimple")])
8157 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8158 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8161 (match_operand:IEEE128 1 "register_operand" "wa"))))
8162 (use (match_operand:V16QI 2 "register_operand" "v"))]
8163 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8165 [(set_attr "type" "veclogical")])
8167 ;; Float128 conversion functions. These expand to library function calls.
8168 ;; We use expand to convert from IBM double double to IEEE 128-bit
8169 ;; and trunc for the opposite.
8170 (define_expand "extendiftf2"
8171 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8172 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8173 "TARGET_FLOAT128_TYPE"
8175 rs6000_expand_float128_convert (operands[0], operands[1], false);
8179 (define_expand "extendifkf2"
8180 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8181 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8182 "TARGET_FLOAT128_TYPE"
8184 rs6000_expand_float128_convert (operands[0], operands[1], false);
8188 (define_expand "extendtfkf2"
8189 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8190 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8191 "TARGET_FLOAT128_TYPE"
8193 rs6000_expand_float128_convert (operands[0], operands[1], false);
8197 (define_expand "trunciftf2"
8198 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8199 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8200 "TARGET_FLOAT128_TYPE"
8202 rs6000_expand_float128_convert (operands[0], operands[1], false);
8206 (define_expand "truncifkf2"
8207 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8208 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8209 "TARGET_FLOAT128_TYPE"
8211 rs6000_expand_float128_convert (operands[0], operands[1], false);
8215 (define_expand "trunckftf2"
8216 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8217 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8218 "TARGET_FLOAT128_TYPE"
8220 rs6000_expand_float128_convert (operands[0], operands[1], false);
8224 (define_expand "trunctfif2"
8225 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8226 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8227 "TARGET_FLOAT128_TYPE"
8229 rs6000_expand_float128_convert (operands[0], operands[1], false);
8234 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8235 ;; must have 3 arguments, and scratch register constraint must be a single
8238 ;; Reload patterns to support gpr load/store with misaligned mem.
8239 ;; and multiple gpr load/store at offset >= 0xfffc
8240 (define_expand "reload_<mode>_store"
8241 [(parallel [(match_operand 0 "memory_operand" "=m")
8242 (match_operand 1 "gpc_reg_operand" "r")
8243 (match_operand:GPR 2 "register_operand" "=&b")])]
8246 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8250 (define_expand "reload_<mode>_load"
8251 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8252 (match_operand 1 "memory_operand" "m")
8253 (match_operand:GPR 2 "register_operand" "=b")])]
8256 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8261 ;; Reload patterns for various types using the vector registers. We may need
8262 ;; an additional base register to convert the reg+offset addressing to reg+reg
8263 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8264 ;; index register for gpr registers.
8265 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8266 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8267 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8268 (match_operand:P 2 "register_operand" "=b")])]
8271 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8275 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8276 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8277 (match_operand:RELOAD 1 "memory_operand" "m")
8278 (match_operand:P 2 "register_operand" "=b")])]
8281 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8286 ;; Reload sometimes tries to move the address to a GPR, and can generate
8287 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8288 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8290 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8291 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8292 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8293 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8295 "TARGET_ALTIVEC && reload_completed"
8297 "&& reload_completed"
8299 (plus:P (match_dup 1)
8302 (and:P (match_dup 0)
8305 ;; Power8 merge instructions to allow direct move to/from floating point
8306 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8307 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8308 ;; value, since it is allocated in reload and not all of the flow information
8309 ;; is setup for it. We have two patterns to do the two moves between gprs and
8310 ;; fprs. There isn't a dependancy between the two, but we could potentially
8311 ;; schedule other instructions between the two instructions.
8313 (define_insn "p8_fmrgow_<mode>"
8314 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8316 (match_operand:DF 1 "register_operand" "d")
8317 (match_operand:DF 2 "register_operand" "d")]
8318 UNSPEC_P8V_FMRGOW))]
8319 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8321 [(set_attr "type" "fpsimple")])
8323 (define_insn "p8_mtvsrwz"
8324 [(set (match_operand:DF 0 "register_operand" "=d")
8325 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8326 UNSPEC_P8V_MTVSRWZ))]
8327 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8329 [(set_attr "type" "mftgpr")])
8331 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8332 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8333 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8334 UNSPEC_P8V_RELOAD_FROM_GPR))
8335 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8336 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8338 "&& reload_completed"
8341 rtx dest = operands[0];
8342 rtx src = operands[1];
8343 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8344 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8345 rtx gpr_hi_reg = gen_highpart (SImode, src);
8346 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8348 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8349 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8350 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8353 [(set_attr "length" "12")
8354 (set_attr "type" "three")])
8356 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8357 (define_insn "p8_mtvsrd_df"
8358 [(set (match_operand:DF 0 "register_operand" "=wa")
8359 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8360 UNSPEC_P8V_MTVSRD))]
8361 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8363 [(set_attr "type" "mftgpr")])
8365 (define_insn "p8_xxpermdi_<mode>"
8366 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8367 (unspec:FMOVE128_GPR [
8368 (match_operand:DF 1 "register_operand" "wa")
8369 (match_operand:DF 2 "register_operand" "wa")]
8370 UNSPEC_P8V_XXPERMDI))]
8371 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8372 "xxpermdi %x0,%x1,%x2,0"
8373 [(set_attr "type" "vecperm")])
8375 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8376 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8377 (unspec:FMOVE128_GPR
8378 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8379 UNSPEC_P8V_RELOAD_FROM_GPR))
8380 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8381 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8383 "&& reload_completed"
8386 rtx dest = operands[0];
8387 rtx src = operands[1];
8388 /* You might think that we could use op0 as one temp and a DF clobber
8389 as op2, but you'd be wrong. Secondary reload move patterns don't
8390 check for overlap of the clobber and the destination. */
8391 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8392 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8393 rtx gpr_hi_reg = gen_highpart (DImode, src);
8394 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8396 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8397 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8398 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8401 [(set_attr "length" "12")
8402 (set_attr "type" "three")])
8405 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8406 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8408 && (int_reg_operand (operands[0], <MODE>mode)
8409 || int_reg_operand (operands[1], <MODE>mode))
8410 && (!TARGET_DIRECT_MOVE_128
8411 || (!vsx_register_operand (operands[0], <MODE>mode)
8412 && !vsx_register_operand (operands[1], <MODE>mode)))"
8414 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8416 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8417 ;; type is stored internally as double precision in the VSX registers, we have
8418 ;; to convert it from the vector format.
8419 (define_insn "p8_mtvsrd_sf"
8420 [(set (match_operand:SF 0 "register_operand" "=wa")
8421 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8422 UNSPEC_P8V_MTVSRD))]
8423 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8425 [(set_attr "type" "mftgpr")])
8427 (define_insn_and_split "reload_vsx_from_gprsf"
8428 [(set (match_operand:SF 0 "register_operand" "=wa")
8429 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8430 UNSPEC_P8V_RELOAD_FROM_GPR))
8431 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8432 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8434 "&& reload_completed"
8437 rtx op0 = operands[0];
8438 rtx op1 = operands[1];
8439 rtx op2 = operands[2];
8440 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8442 /* Move SF value to upper 32-bits for xscvspdpn. */
8443 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8444 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8445 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8448 [(set_attr "length" "8")
8449 (set_attr "type" "two")])
8451 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8452 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8453 ;; and then doing a move of that.
8454 (define_insn "p8_mfvsrd_3_<mode>"
8455 [(set (match_operand:DF 0 "register_operand" "=r")
8456 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8457 UNSPEC_P8V_RELOAD_FROM_VSX))]
8458 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8460 [(set_attr "type" "mftgpr")])
8462 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8463 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8464 (unspec:FMOVE128_GPR
8465 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8466 UNSPEC_P8V_RELOAD_FROM_VSX))
8467 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8468 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8470 "&& reload_completed"
8473 rtx dest = operands[0];
8474 rtx src = operands[1];
8475 rtx tmp = operands[2];
8476 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8477 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8479 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8480 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8481 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8484 [(set_attr "length" "12")
8485 (set_attr "type" "three")])
8487 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8488 ;; type is stored internally as double precision, we have to convert it to the
8491 (define_insn_and_split "reload_gpr_from_vsxsf"
8492 [(set (match_operand:SF 0 "register_operand" "=r")
8493 (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8494 UNSPEC_P8V_RELOAD_FROM_VSX))
8495 (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8496 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8498 "&& reload_completed"
8501 rtx op0 = operands[0];
8502 rtx op1 = operands[1];
8503 rtx op2 = operands[2];
8504 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8505 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8507 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8508 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8511 [(set_attr "length" "8")
8512 (set_attr "type" "two")])
8515 ;; Next come the multi-word integer load and store and the load and store
8518 ;; List r->r after r->Y, otherwise reload will try to reload a
8519 ;; non-offsettable address by using r->r which won't make progress.
8520 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8521 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8523 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8524 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8525 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8528 (define_insn "*movdi_internal32"
8529 [(set (match_operand:DI 0 "nonimmediate_operand"
8530 "=Y, r, r, ^m, ^d, ^d,
8531 r, ^wY, $Z, ^wb, $wv, ^wi,
8532 *wo, *wo, *wv, *wi, *wi, *wv,
8535 (match_operand:DI 1 "input_operand"
8537 IJKnGHF, wb, wv, wY, Z, wi,
8538 Oj, wM, OjwM, Oj, wM, wS,
8542 && (gpc_reg_operand (operands[0], DImode)
8543 || gpc_reg_operand (operands[1], DImode))"
8565 "store, load, *, fpstore, fpload, fpsimple,
8566 *, fpstore, fpstore, fpload, fpload, veclogical,
8567 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8569 (set_attr "size" "64")])
8572 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8573 (match_operand:DI 1 "const_int_operand" ""))]
8574 "! TARGET_POWERPC64 && reload_completed
8575 && gpr_or_gpr_p (operands[0], operands[1])
8576 && !direct_move_p (operands[0], operands[1])"
8577 [(set (match_dup 2) (match_dup 4))
8578 (set (match_dup 3) (match_dup 1))]
8581 HOST_WIDE_INT value = INTVAL (operands[1]);
8582 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8584 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8586 operands[4] = GEN_INT (value >> 32);
8587 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8591 [(set (match_operand:DIFD 0 "nonimmediate_operand" "")
8592 (match_operand:DIFD 1 "input_operand" ""))]
8593 "reload_completed && !TARGET_POWERPC64
8594 && gpr_or_gpr_p (operands[0], operands[1])
8595 && !direct_move_p (operands[0], operands[1])"
8597 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8599 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8600 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8601 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8602 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8603 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8604 (define_insn "*movdi_internal64"
8605 [(set (match_operand:DI 0 "nonimmediate_operand"
8607 ^m, ^d, ^d, ^wY, $Z, $wb,
8608 $wv, ^wi, *wo, *wo, *wv, *wi,
8609 *wi, *wv, *wv, r, *h, *h,
8610 ?*r, ?*wg, ?*r, ?*wj")
8612 (match_operand:DI 1 "input_operand"
8614 d, m, d, wb, wv, wY,
8615 Z, wi, Oj, wM, OjwM, Oj,
8616 wM, wS, wB, *h, r, 0,
8620 && (gpc_reg_operand (operands[0], DImode)
8621 || gpc_reg_operand (operands[1], DImode))"
8652 "store, load, *, *, *, *,
8653 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8654 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8655 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8656 mftgpr, mffgpr, mftgpr, mffgpr")
8658 (set_attr "size" "64")
8666 ; Some DImode loads are best done as a load of -1 followed by a mask
8669 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8670 (match_operand:DI 1 "const_int_operand"))]
8672 && num_insns_constant (operands[1], DImode) > 1
8673 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8674 && rs6000_is_valid_and_mask (operands[1], DImode)"
8678 (and:DI (match_dup 0)
8682 ;; Split a load of a large constant into the appropriate five-instruction
8683 ;; sequence. Handle anything in a constant number of insns.
8684 ;; When non-easy constants can go in the TOC, this should use
8685 ;; easy_fp_constant predicate.
8687 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8688 (match_operand:DI 1 "const_int_operand" ""))]
8689 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8690 [(set (match_dup 0) (match_dup 2))
8691 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8694 if (rs6000_emit_set_const (operands[0], operands[1]))
8701 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8702 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8703 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8704 [(set (match_dup 0) (match_dup 2))
8705 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8708 if (rs6000_emit_set_const (operands[0], operands[1]))
8715 [(set (match_operand:DI 0 "altivec_register_operand" "")
8716 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8717 "TARGET_VSX && reload_completed"
8720 rtx op0 = operands[0];
8721 rtx op1 = operands[1];
8722 int r = REGNO (op0);
8723 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8725 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8726 if (op1 != const0_rtx && op1 != constm1_rtx)
8728 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8729 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8734 ;; Split integer constants that can be loaded with XXSPLTIB and a
8735 ;; sign extend operation.
8737 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8738 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8739 "TARGET_P9_VECTOR && reload_completed"
8742 rtx op0 = operands[0];
8743 rtx op1 = operands[1];
8744 int r = REGNO (op0);
8745 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8747 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8748 if (<MODE>mode == DImode)
8749 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8750 else if (<MODE>mode == SImode)
8751 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8752 else if (<MODE>mode == HImode)
8754 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8755 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8761 ;; TImode/PTImode is similar, except that we usually want to compute the
8762 ;; address into a register and use lsi/stsi (the exception is during reload).
8764 (define_insn "*mov<mode>_string"
8765 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8766 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8768 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8769 && (gpc_reg_operand (operands[0], <MODE>mode)
8770 || gpc_reg_operand (operands[1], <MODE>mode))"
8772 [(set_attr "type" "store,store,load,load,*,*")
8773 (set_attr "update" "yes")
8774 (set_attr "indexed" "yes")
8775 (set_attr "cell_micro" "conditional")])
8777 (define_insn "*mov<mode>_ppc64"
8778 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8779 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8780 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8781 && (gpc_reg_operand (operands[0], <MODE>mode)
8782 || gpc_reg_operand (operands[1], <MODE>mode)))"
8784 return rs6000_output_move_128bit (operands);
8786 [(set_attr "type" "store,store,load,load,*,*")
8787 (set_attr "length" "8")])
8790 [(set (match_operand:TI2 0 "int_reg_operand" "")
8791 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8793 && (VECTOR_MEM_NONE_P (<MODE>mode)
8794 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8795 [(set (match_dup 2) (match_dup 4))
8796 (set (match_dup 3) (match_dup 5))]
8799 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8801 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8803 if (CONST_WIDE_INT_P (operands[1]))
8805 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8806 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8808 else if (CONST_INT_P (operands[1]))
8810 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8811 operands[5] = operands[1];
8818 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8819 (match_operand:TI2 1 "input_operand" ""))]
8821 && gpr_or_gpr_p (operands[0], operands[1])
8822 && !direct_move_p (operands[0], operands[1])
8823 && !quad_load_store_p (operands[0], operands[1])"
8825 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8827 (define_expand "setmemsi"
8828 [(parallel [(set (match_operand:BLK 0 "" "")
8829 (match_operand 2 "const_int_operand" ""))
8830 (use (match_operand:SI 1 "" ""))
8831 (use (match_operand:SI 3 "" ""))])]
8835 /* If value to set is not zero, use the library routine. */
8836 if (operands[2] != const0_rtx)
8839 if (expand_block_clear (operands))
8845 ;; String compare N insn.
8846 ;; Argument 0 is the target (result)
8847 ;; Argument 1 is the destination
8848 ;; Argument 2 is the source
8849 ;; Argument 3 is the length
8850 ;; Argument 4 is the alignment
8852 (define_expand "cmpstrnsi"
8853 [(parallel [(set (match_operand:SI 0)
8854 (compare:SI (match_operand:BLK 1)
8855 (match_operand:BLK 2)))
8856 (use (match_operand:SI 3))
8857 (use (match_operand:SI 4))])]
8858 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8860 if (optimize_insn_for_size_p ())
8863 if (expand_strn_compare (operands, 0))
8869 ;; String compare insn.
8870 ;; Argument 0 is the target (result)
8871 ;; Argument 1 is the destination
8872 ;; Argument 2 is the source
8873 ;; Argument 3 is the alignment
8875 (define_expand "cmpstrsi"
8876 [(parallel [(set (match_operand:SI 0)
8877 (compare:SI (match_operand:BLK 1)
8878 (match_operand:BLK 2)))
8879 (use (match_operand:SI 3))])]
8880 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8882 if (optimize_insn_for_size_p ())
8885 if (expand_strn_compare (operands, 1))
8891 ;; Block compare insn.
8892 ;; Argument 0 is the target (result)
8893 ;; Argument 1 is the destination
8894 ;; Argument 2 is the source
8895 ;; Argument 3 is the length
8896 ;; Argument 4 is the alignment
8898 (define_expand "cmpmemsi"
8899 [(parallel [(set (match_operand:SI 0)
8900 (compare:SI (match_operand:BLK 1)
8901 (match_operand:BLK 2)))
8902 (use (match_operand:SI 3))
8903 (use (match_operand:SI 4))])]
8906 if (expand_block_compare (operands))
8912 ;; String/block move insn.
8913 ;; Argument 0 is the destination
8914 ;; Argument 1 is the source
8915 ;; Argument 2 is the length
8916 ;; Argument 3 is the alignment
8918 (define_expand "movmemsi"
8919 [(parallel [(set (match_operand:BLK 0 "" "")
8920 (match_operand:BLK 1 "" ""))
8921 (use (match_operand:SI 2 "" ""))
8922 (use (match_operand:SI 3 "" ""))])]
8926 if (expand_block_move (operands))
8932 ;; Define insns that do load or store with update. Some of these we can
8933 ;; get by using pre-decrement or pre-increment, but the hardware can also
8934 ;; do cases where the increment is not the size of the object.
8936 ;; In all these cases, we use operands 0 and 1 for the register being
8937 ;; incremented because those are the operands that local-alloc will
8938 ;; tie and these are the pair most likely to be tieable (and the ones
8939 ;; that will benefit the most).
8941 (define_insn "*movdi_update1"
8942 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8943 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8944 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8945 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8946 (plus:DI (match_dup 1) (match_dup 2)))]
8947 "TARGET_POWERPC64 && TARGET_UPDATE
8948 && (!avoiding_indexed_address_p (DImode)
8949 || !gpc_reg_operand (operands[2], DImode))"
8953 [(set_attr "type" "load")
8954 (set_attr "update" "yes")
8955 (set_attr "indexed" "yes,no")])
8957 (define_insn "movdi_<mode>_update"
8958 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8959 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8960 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8961 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8962 (plus:P (match_dup 1) (match_dup 2)))]
8963 "TARGET_POWERPC64 && TARGET_UPDATE
8964 && (!avoiding_indexed_address_p (Pmode)
8965 || !gpc_reg_operand (operands[2], Pmode)
8966 || (REG_P (operands[0])
8967 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8971 [(set_attr "type" "store")
8972 (set_attr "update" "yes")
8973 (set_attr "indexed" "yes,no")])
8975 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8976 ;; needed for stack allocation, even if the user passes -mno-update.
8977 (define_insn "movdi_<mode>_update_stack"
8978 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8979 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8980 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8981 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8982 (plus:P (match_dup 1) (match_dup 2)))]
8987 [(set_attr "type" "store")
8988 (set_attr "update" "yes")
8989 (set_attr "indexed" "yes,no")])
8991 (define_insn "*movsi_update1"
8992 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8993 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8994 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8995 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8996 (plus:SI (match_dup 1) (match_dup 2)))]
8998 && (!avoiding_indexed_address_p (SImode)
8999 || !gpc_reg_operand (operands[2], SImode))"
9003 [(set_attr "type" "load")
9004 (set_attr "update" "yes")
9005 (set_attr "indexed" "yes,no")])
9007 (define_insn "*movsi_update2"
9008 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9010 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9011 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9012 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9013 (plus:DI (match_dup 1) (match_dup 2)))]
9014 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9016 [(set_attr "type" "load")
9017 (set_attr "sign_extend" "yes")
9018 (set_attr "update" "yes")
9019 (set_attr "indexed" "yes")])
9021 (define_insn "movsi_update"
9022 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9023 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9024 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9025 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9026 (plus:SI (match_dup 1) (match_dup 2)))]
9028 && (!avoiding_indexed_address_p (SImode)
9029 || !gpc_reg_operand (operands[2], SImode)
9030 || (REG_P (operands[0])
9031 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9035 [(set_attr "type" "store")
9036 (set_attr "update" "yes")
9037 (set_attr "indexed" "yes,no")])
9039 ;; This is an unconditional pattern; needed for stack allocation, even
9040 ;; if the user passes -mno-update.
9041 (define_insn "movsi_update_stack"
9042 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9043 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9044 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9045 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9046 (plus:SI (match_dup 1) (match_dup 2)))]
9051 [(set_attr "type" "store")
9052 (set_attr "update" "yes")
9053 (set_attr "indexed" "yes,no")])
9055 (define_insn "*movhi_update1"
9056 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9057 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9058 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9059 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9060 (plus:SI (match_dup 1) (match_dup 2)))]
9062 && (!avoiding_indexed_address_p (SImode)
9063 || !gpc_reg_operand (operands[2], SImode))"
9067 [(set_attr "type" "load")
9068 (set_attr "update" "yes")
9069 (set_attr "indexed" "yes,no")])
9071 (define_insn "*movhi_update2"
9072 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9074 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9075 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9076 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9077 (plus:SI (match_dup 1) (match_dup 2)))]
9079 && (!avoiding_indexed_address_p (SImode)
9080 || !gpc_reg_operand (operands[2], SImode))"
9084 [(set_attr "type" "load")
9085 (set_attr "update" "yes")
9086 (set_attr "indexed" "yes,no")])
9088 (define_insn "*movhi_update3"
9089 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9091 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9092 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9093 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9094 (plus:SI (match_dup 1) (match_dup 2)))]
9096 && !(avoiding_indexed_address_p (SImode)
9097 && gpc_reg_operand (operands[2], SImode))"
9101 [(set_attr "type" "load")
9102 (set_attr "sign_extend" "yes")
9103 (set_attr "update" "yes")
9104 (set_attr "indexed" "yes,no")])
9106 (define_insn "*movhi_update4"
9107 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9108 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9109 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9110 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9111 (plus:SI (match_dup 1) (match_dup 2)))]
9113 && (!avoiding_indexed_address_p (SImode)
9114 || !gpc_reg_operand (operands[2], SImode))"
9118 [(set_attr "type" "store")
9119 (set_attr "update" "yes")
9120 (set_attr "indexed" "yes,no")])
9122 (define_insn "*movqi_update1"
9123 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9124 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9125 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9126 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9127 (plus:SI (match_dup 1) (match_dup 2)))]
9129 && (!avoiding_indexed_address_p (SImode)
9130 || !gpc_reg_operand (operands[2], SImode))"
9134 [(set_attr "type" "load")
9135 (set_attr "update" "yes")
9136 (set_attr "indexed" "yes,no")])
9138 (define_insn "*movqi_update2"
9139 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9141 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9142 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9143 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9144 (plus:SI (match_dup 1) (match_dup 2)))]
9146 && (!avoiding_indexed_address_p (SImode)
9147 || !gpc_reg_operand (operands[2], SImode))"
9151 [(set_attr "type" "load")
9152 (set_attr "update" "yes")
9153 (set_attr "indexed" "yes,no")])
9155 (define_insn "*movqi_update3"
9156 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9157 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9158 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9159 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9160 (plus:SI (match_dup 1) (match_dup 2)))]
9162 && (!avoiding_indexed_address_p (SImode)
9163 || !gpc_reg_operand (operands[2], SImode))"
9167 [(set_attr "type" "store")
9168 (set_attr "update" "yes")
9169 (set_attr "indexed" "yes,no")])
9171 (define_insn "*movsf_update1"
9172 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9173 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9174 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9175 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9176 (plus:SI (match_dup 1) (match_dup 2)))]
9177 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9178 && (!avoiding_indexed_address_p (SImode)
9179 || !gpc_reg_operand (operands[2], SImode))"
9183 [(set_attr "type" "fpload")
9184 (set_attr "update" "yes")
9185 (set_attr "indexed" "yes,no")])
9187 (define_insn "*movsf_update2"
9188 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9189 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9190 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9191 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9192 (plus:SI (match_dup 1) (match_dup 2)))]
9193 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9194 && (!avoiding_indexed_address_p (SImode)
9195 || !gpc_reg_operand (operands[2], SImode))"
9199 [(set_attr "type" "fpstore")
9200 (set_attr "update" "yes")
9201 (set_attr "indexed" "yes,no")])
9203 (define_insn "*movsf_update3"
9204 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9205 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9206 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9207 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9208 (plus:SI (match_dup 1) (match_dup 2)))]
9209 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9210 && (!avoiding_indexed_address_p (SImode)
9211 || !gpc_reg_operand (operands[2], SImode))"
9215 [(set_attr "type" "load")
9216 (set_attr "update" "yes")
9217 (set_attr "indexed" "yes,no")])
9219 (define_insn "*movsf_update4"
9220 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9221 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9222 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9223 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9224 (plus:SI (match_dup 1) (match_dup 2)))]
9225 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9226 && (!avoiding_indexed_address_p (SImode)
9227 || !gpc_reg_operand (operands[2], SImode))"
9231 [(set_attr "type" "store")
9232 (set_attr "update" "yes")
9233 (set_attr "indexed" "yes,no")])
9235 (define_insn "*movdf_update1"
9236 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9237 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9238 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9239 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9240 (plus:SI (match_dup 1) (match_dup 2)))]
9241 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9242 && (!avoiding_indexed_address_p (SImode)
9243 || !gpc_reg_operand (operands[2], SImode))"
9247 [(set_attr "type" "fpload")
9248 (set_attr "update" "yes")
9249 (set_attr "indexed" "yes,no")
9250 (set_attr "size" "64")])
9252 (define_insn "*movdf_update2"
9253 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9254 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9255 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9256 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9257 (plus:SI (match_dup 1) (match_dup 2)))]
9258 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9259 && (!avoiding_indexed_address_p (SImode)
9260 || !gpc_reg_operand (operands[2], SImode))"
9264 [(set_attr "type" "fpstore")
9265 (set_attr "update" "yes")
9266 (set_attr "indexed" "yes,no")])
9269 ;; After inserting conditional returns we can sometimes have
9270 ;; unnecessary register moves. Unfortunately we cannot have a
9271 ;; modeless peephole here, because some single SImode sets have early
9272 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9273 ;; sequences, using get_attr_length here will smash the operands
9274 ;; array. Neither is there an early_cobbler_p predicate.
9275 ;; Also this optimization interferes with scalars going into
9276 ;; altivec registers (the code does reloading through the FPRs).
9278 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9279 (match_operand:DF 1 "any_operand" ""))
9280 (set (match_operand:DF 2 "gpc_reg_operand" "")
9283 && peep2_reg_dead_p (2, operands[0])"
9284 [(set (match_dup 2) (match_dup 1))])
9287 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9288 (match_operand:SF 1 "any_operand" ""))
9289 (set (match_operand:SF 2 "gpc_reg_operand" "")
9292 && peep2_reg_dead_p (2, operands[0])"
9293 [(set (match_dup 2) (match_dup 1))])
9298 ;; Mode attributes for different ABIs.
9299 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9300 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9301 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9302 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9304 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9305 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9306 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9307 (match_operand 4 "" "g")))
9308 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9309 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9311 (clobber (reg:SI LR_REGNO))]
9312 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9314 if (TARGET_CMODEL != CMODEL_SMALL)
9315 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9318 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9320 "&& TARGET_TLS_MARKERS"
9322 (unspec:TLSmode [(match_dup 1)
9325 (parallel [(set (match_dup 0)
9326 (call (mem:TLSmode (match_dup 3))
9328 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9329 (clobber (reg:SI LR_REGNO))])]
9331 [(set_attr "type" "two")
9332 (set (attr "length")
9333 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9337 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9338 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9339 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9340 (match_operand 4 "" "g")))
9341 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9342 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9344 (clobber (reg:SI LR_REGNO))]
9345 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9349 if (TARGET_SECURE_PLT && flag_pic == 2)
9350 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9352 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9355 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9357 "&& TARGET_TLS_MARKERS"
9359 (unspec:TLSmode [(match_dup 1)
9362 (parallel [(set (match_dup 0)
9363 (call (mem:TLSmode (match_dup 3))
9365 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9366 (clobber (reg:SI LR_REGNO))])]
9368 [(set_attr "type" "two")
9369 (set_attr "length" "8")])
9371 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9372 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9373 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9374 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9376 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9377 "addi %0,%1,%2@got@tlsgd"
9378 "&& TARGET_CMODEL != CMODEL_SMALL"
9381 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9383 (lo_sum:TLSmode (match_dup 3)
9384 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9387 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9389 [(set (attr "length")
9390 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9394 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9395 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9397 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9398 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9400 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9401 "addis %0,%1,%2@got@tlsgd@ha"
9402 [(set_attr "length" "4")])
9404 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9405 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9406 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9407 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9408 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9410 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9411 "addi %0,%1,%2@got@tlsgd@l"
9412 [(set_attr "length" "4")])
9414 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9415 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9416 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9417 (match_operand 2 "" "g")))
9418 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9420 (clobber (reg:SI LR_REGNO))]
9421 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9422 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9423 "bl %z1(%3@tlsgd)\;nop"
9424 [(set_attr "type" "branch")
9425 (set_attr "length" "8")])
9427 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9428 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9429 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9430 (match_operand 2 "" "g")))
9431 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9433 (clobber (reg:SI LR_REGNO))]
9434 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9438 if (TARGET_SECURE_PLT && flag_pic == 2)
9439 return "bl %z1+32768(%3@tlsgd)@plt";
9440 return "bl %z1(%3@tlsgd)@plt";
9442 return "bl %z1(%3@tlsgd)";
9444 [(set_attr "type" "branch")
9445 (set_attr "length" "4")])
9447 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9448 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9449 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9450 (match_operand 3 "" "g")))
9451 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9453 (clobber (reg:SI LR_REGNO))]
9454 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9456 if (TARGET_CMODEL != CMODEL_SMALL)
9457 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9460 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9462 "&& TARGET_TLS_MARKERS"
9464 (unspec:TLSmode [(match_dup 1)]
9466 (parallel [(set (match_dup 0)
9467 (call (mem:TLSmode (match_dup 2))
9469 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9470 (clobber (reg:SI LR_REGNO))])]
9472 [(set_attr "type" "two")
9473 (set (attr "length")
9474 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9478 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9479 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9480 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9481 (match_operand 3 "" "g")))
9482 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9484 (clobber (reg:SI LR_REGNO))]
9485 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9489 if (TARGET_SECURE_PLT && flag_pic == 2)
9490 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9492 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9495 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9497 "&& TARGET_TLS_MARKERS"
9499 (unspec:TLSmode [(match_dup 1)]
9501 (parallel [(set (match_dup 0)
9502 (call (mem:TLSmode (match_dup 2))
9504 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9505 (clobber (reg:SI LR_REGNO))])]
9507 [(set_attr "length" "8")])
9509 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9510 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9511 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9513 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9514 "addi %0,%1,%&@got@tlsld"
9515 "&& TARGET_CMODEL != CMODEL_SMALL"
9518 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9520 (lo_sum:TLSmode (match_dup 2)
9521 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9524 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9526 [(set (attr "length")
9527 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9531 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9532 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9534 (unspec:TLSmode [(const_int 0)
9535 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9537 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9538 "addis %0,%1,%&@got@tlsld@ha"
9539 [(set_attr "length" "4")])
9541 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9542 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9543 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9544 (unspec:TLSmode [(const_int 0)
9545 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9547 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9548 "addi %0,%1,%&@got@tlsld@l"
9549 [(set_attr "length" "4")])
9551 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9552 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9553 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9554 (match_operand 2 "" "g")))
9555 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9556 (clobber (reg:SI LR_REGNO))]
9557 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9558 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9559 "bl %z1(%&@tlsld)\;nop"
9560 [(set_attr "type" "branch")
9561 (set_attr "length" "8")])
9563 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9564 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9565 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9566 (match_operand 2 "" "g")))
9567 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9568 (clobber (reg:SI LR_REGNO))]
9569 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9573 if (TARGET_SECURE_PLT && flag_pic == 2)
9574 return "bl %z1+32768(%&@tlsld)@plt";
9575 return "bl %z1(%&@tlsld)@plt";
9577 return "bl %z1(%&@tlsld)";
9579 [(set_attr "type" "branch")
9580 (set_attr "length" "4")])
9582 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9583 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9584 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9585 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9588 "addi %0,%1,%2@dtprel")
9590 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9591 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9592 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9593 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9594 UNSPEC_TLSDTPRELHA))]
9596 "addis %0,%1,%2@dtprel@ha")
9598 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9599 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9600 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9601 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9602 UNSPEC_TLSDTPRELLO))]
9604 "addi %0,%1,%2@dtprel@l")
9606 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9607 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9608 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9609 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9610 UNSPEC_TLSGOTDTPREL))]
9612 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9613 "&& TARGET_CMODEL != CMODEL_SMALL"
9616 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9618 (lo_sum:TLSmode (match_dup 3)
9619 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9622 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9624 [(set (attr "length")
9625 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9629 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9630 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9632 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9633 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9634 UNSPEC_TLSGOTDTPREL)))]
9635 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9636 "addis %0,%1,%2@got@dtprel@ha"
9637 [(set_attr "length" "4")])
9639 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9640 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9641 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9642 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9643 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9644 UNSPEC_TLSGOTDTPREL)))]
9645 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9646 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9647 [(set_attr "length" "4")])
9649 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9650 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9651 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9652 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9655 "addi %0,%1,%2@tprel")
9657 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9658 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9659 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9660 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9661 UNSPEC_TLSTPRELHA))]
9663 "addis %0,%1,%2@tprel@ha")
9665 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9666 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9667 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9668 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9669 UNSPEC_TLSTPRELLO))]
9671 "addi %0,%1,%2@tprel@l")
9673 ;; "b" output constraint here and on tls_tls input to support linker tls
9674 ;; optimization. The linker may edit the instructions emitted by a
9675 ;; tls_got_tprel/tls_tls pair to addis,addi.
9676 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9677 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9678 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9679 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9680 UNSPEC_TLSGOTTPREL))]
9682 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9683 "&& TARGET_CMODEL != CMODEL_SMALL"
9686 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9688 (lo_sum:TLSmode (match_dup 3)
9689 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9692 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9694 [(set (attr "length")
9695 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9699 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9700 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9702 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9703 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9704 UNSPEC_TLSGOTTPREL)))]
9705 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9706 "addis %0,%1,%2@got@tprel@ha"
9707 [(set_attr "length" "4")])
9709 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9710 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9711 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9712 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9713 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9714 UNSPEC_TLSGOTTPREL)))]
9715 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9716 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9717 [(set_attr "length" "4")])
9719 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9720 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9721 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9722 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9724 "TARGET_ELF && HAVE_AS_TLS"
9727 (define_expand "tls_get_tpointer"
9728 [(set (match_operand:SI 0 "gpc_reg_operand" "")
9729 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9730 "TARGET_XCOFF && HAVE_AS_TLS"
9733 emit_insn (gen_tls_get_tpointer_internal ());
9734 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9738 (define_insn "tls_get_tpointer_internal"
9740 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9741 (clobber (reg:SI LR_REGNO))]
9742 "TARGET_XCOFF && HAVE_AS_TLS"
9743 "bla __get_tpointer")
9745 (define_expand "tls_get_addr<mode>"
9746 [(set (match_operand:P 0 "gpc_reg_operand" "")
9747 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9748 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9749 "TARGET_XCOFF && HAVE_AS_TLS"
9752 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9753 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9754 emit_insn (gen_tls_get_addr_internal<mode> ());
9755 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9759 (define_insn "tls_get_addr_internal<mode>"
9761 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9765 (clobber (reg:P 11))
9766 (clobber (reg:CC CR0_REGNO))
9767 (clobber (reg:P LR_REGNO))]
9768 "TARGET_XCOFF && HAVE_AS_TLS"
9769 "bla __tls_get_addr")
9771 ;; Next come insns related to the calling sequence.
9773 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9774 ;; We move the back-chain and decrement the stack pointer.
9776 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9777 ;; constant alloca, using that predicate will force the generic code to put
9778 ;; the constant size into a register before calling the expander.
9780 ;; As a result the expander would not have the constant size information
9781 ;; in those cases and would have to generate less efficient code.
9783 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9784 ;; the constant size. The value is forced into a register if necessary.
9786 (define_expand "allocate_stack"
9787 [(set (match_operand 0 "gpc_reg_operand" "")
9788 (minus (reg 1) (match_operand 1 "reg_or_cint_operand" "")))
9790 (minus (reg 1) (match_dup 1)))]
9793 { rtx chain = gen_reg_rtx (Pmode);
9794 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9796 rtx insn, par, set, mem;
9798 /* By allowing reg_or_cint_operand as the predicate we can get
9799 better code for stack-clash-protection because we do not lose
9800 size information. But the rest of the code expects the operand
9801 to be reg_or_short_operand. If it isn't, then force it into
9803 rtx orig_op1 = operands[1];
9804 if (!reg_or_short_operand (operands[1], Pmode))
9805 operands[1] = force_reg (Pmode, operands[1]);
9807 emit_move_insn (chain, stack_bot);
9809 /* Check stack bounds if necessary. */
9810 if (crtl->limit_stack)
9813 available = expand_binop (Pmode, sub_optab,
9814 stack_pointer_rtx, stack_limit_rtx,
9815 NULL_RTX, 1, OPTAB_WIDEN);
9816 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9819 /* Allocate and probe if requested.
9820 This may look similar to the loop we use for prologue allocations,
9821 but it is critically different. For the former we know the loop
9822 will iterate, but do not know that generally here. The former
9823 uses that knowledge to rotate the loop. Combining them would be
9824 possible with some performance cost. */
9825 if (flag_stack_clash_protection)
9827 rtx rounded_size, last_addr, residual;
9828 HOST_WIDE_INT probe_interval;
9829 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9830 &residual, &probe_interval,
9833 /* We do occasionally get in here with constant sizes, we might
9834 as well do a reasonable job when we obviously can. */
9835 if (rounded_size != const0_rtx)
9837 rtx loop_lab, end_loop;
9838 bool rotated = CONST_INT_P (rounded_size);
9839 rtx update = GEN_INT (-probe_interval);
9840 if (probe_interval > 32768)
9841 update = force_reg (Pmode, update);
9843 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9844 last_addr, rotated);
9846 if (Pmode == SImode)
9847 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9851 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9854 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9855 last_addr, rotated);
9858 /* Now handle residuals. We just have to set operands[1] correctly
9859 and let the rest of the expander run. */
9860 operands[1] = residual;
9861 if (!CONST_INT_P (residual))
9862 operands[1] = force_reg (Pmode, operands[1]);
9865 if (GET_CODE (operands[1]) != CONST_INT
9866 || INTVAL (operands[1]) < -32767
9867 || INTVAL (operands[1]) > 32768)
9869 neg_op0 = gen_reg_rtx (Pmode);
9871 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9873 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9876 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9878 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9879 : gen_movdi_di_update_stack))
9880 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9882 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9883 it now and set the alias set/attributes. The above gen_*_update
9884 calls will generate a PARALLEL with the MEM set being the first
9886 par = PATTERN (insn);
9887 gcc_assert (GET_CODE (par) == PARALLEL);
9888 set = XVECEXP (par, 0, 0);
9889 gcc_assert (GET_CODE (set) == SET);
9890 mem = SET_DEST (set);
9891 gcc_assert (MEM_P (mem));
9892 MEM_NOTRAP_P (mem) = 1;
9893 set_mem_alias_set (mem, get_frame_alias_set ());
9895 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9899 ;; These patterns say how to save and restore the stack pointer. We need not
9900 ;; save the stack pointer at function level since we are careful to
9901 ;; preserve the backchain. At block level, we have to restore the backchain
9902 ;; when we restore the stack pointer.
9904 ;; For nonlocal gotos, we must save both the stack pointer and its
9905 ;; backchain and restore both. Note that in the nonlocal case, the
9906 ;; save area is a memory location.
9908 (define_expand "save_stack_function"
9909 [(match_operand 0 "any_operand" "")
9910 (match_operand 1 "any_operand" "")]
9914 (define_expand "restore_stack_function"
9915 [(match_operand 0 "any_operand" "")
9916 (match_operand 1 "any_operand" "")]
9920 ;; Adjust stack pointer (op0) to a new value (op1).
9921 ;; First copy old stack backchain to new location, and ensure that the
9922 ;; scheduler won't reorder the sp assignment before the backchain write.
9923 (define_expand "restore_stack_block"
9924 [(set (match_dup 2) (match_dup 3))
9925 (set (match_dup 4) (match_dup 2))
9927 (set (match_operand 0 "register_operand" "")
9928 (match_operand 1 "register_operand" ""))]
9934 operands[1] = force_reg (Pmode, operands[1]);
9935 operands[2] = gen_reg_rtx (Pmode);
9936 operands[3] = gen_frame_mem (Pmode, operands[0]);
9937 operands[4] = gen_frame_mem (Pmode, operands[1]);
9938 p = rtvec_alloc (1);
9939 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9941 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9944 (define_expand "save_stack_nonlocal"
9945 [(set (match_dup 3) (match_dup 4))
9946 (set (match_operand 0 "memory_operand" "") (match_dup 3))
9947 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9951 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9953 /* Copy the backchain to the first word, sp to the second. */
9954 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9955 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9956 operands[3] = gen_reg_rtx (Pmode);
9957 operands[4] = gen_frame_mem (Pmode, operands[1]);
9960 (define_expand "restore_stack_nonlocal"
9961 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9962 (set (match_dup 3) (match_dup 4))
9963 (set (match_dup 5) (match_dup 2))
9965 (set (match_operand 0 "register_operand" "") (match_dup 3))]
9969 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9972 /* Restore the backchain from the first word, sp from the second. */
9973 operands[2] = gen_reg_rtx (Pmode);
9974 operands[3] = gen_reg_rtx (Pmode);
9975 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9976 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9977 operands[5] = gen_frame_mem (Pmode, operands[3]);
9978 p = rtvec_alloc (1);
9979 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9981 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9984 ;; TOC register handling.
9986 ;; Code to initialize the TOC register...
9988 (define_insn "load_toc_aix_si"
9989 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9990 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9992 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9996 extern int need_toc_init;
9998 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9999 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10000 operands[2] = gen_rtx_REG (Pmode, 2);
10001 return \"lwz %0,%1(%2)\";
10003 [(set_attr "type" "load")
10004 (set_attr "update" "no")
10005 (set_attr "indexed" "no")])
10007 (define_insn "load_toc_aix_di"
10008 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10009 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10010 (use (reg:DI 2))])]
10011 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10015 extern int need_toc_init;
10017 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10018 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10020 strcat (buf, \"@toc\");
10021 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10022 operands[2] = gen_rtx_REG (Pmode, 2);
10023 return \"ld %0,%1(%2)\";
10025 [(set_attr "type" "load")
10026 (set_attr "update" "no")
10027 (set_attr "indexed" "no")])
10029 (define_insn "load_toc_v4_pic_si"
10030 [(set (reg:SI LR_REGNO)
10031 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10032 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10033 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10034 [(set_attr "type" "branch")
10035 (set_attr "length" "4")])
10037 (define_expand "load_toc_v4_PIC_1"
10038 [(parallel [(set (reg:SI LR_REGNO)
10039 (match_operand:SI 0 "immediate_operand" "s"))
10040 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10041 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10042 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10045 (define_insn "load_toc_v4_PIC_1_normal"
10046 [(set (reg:SI LR_REGNO)
10047 (match_operand:SI 0 "immediate_operand" "s"))
10048 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10049 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10050 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10051 "bcl 20,31,%0\\n%0:"
10052 [(set_attr "type" "branch")
10053 (set_attr "length" "4")
10054 (set_attr "cannot_copy" "yes")])
10056 (define_insn "load_toc_v4_PIC_1_476"
10057 [(set (reg:SI LR_REGNO)
10058 (match_operand:SI 0 "immediate_operand" "s"))
10059 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10060 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10061 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10065 static char templ[32];
10067 get_ppc476_thunk_name (name);
10068 sprintf (templ, \"bl %s\\n%%0:\", name);
10071 [(set_attr "type" "branch")
10072 (set_attr "length" "4")
10073 (set_attr "cannot_copy" "yes")])
10075 (define_expand "load_toc_v4_PIC_1b"
10076 [(parallel [(set (reg:SI LR_REGNO)
10077 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10078 (label_ref (match_operand 1 "" ""))]
10081 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10084 (define_insn "load_toc_v4_PIC_1b_normal"
10085 [(set (reg:SI LR_REGNO)
10086 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10087 (label_ref (match_operand 1 "" ""))]
10090 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10091 "bcl 20,31,$+8\;.long %0-$"
10092 [(set_attr "type" "branch")
10093 (set_attr "length" "8")])
10095 (define_insn "load_toc_v4_PIC_1b_476"
10096 [(set (reg:SI LR_REGNO)
10097 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10098 (label_ref (match_operand 1 "" ""))]
10101 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10105 static char templ[32];
10107 get_ppc476_thunk_name (name);
10108 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10111 [(set_attr "type" "branch")
10112 (set_attr "length" "16")])
10114 (define_insn "load_toc_v4_PIC_2"
10115 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10117 (match_operand:SI 1 "gpc_reg_operand" "b")
10119 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10120 (match_operand:SI 3 "immediate_operand" "s"))))))]
10121 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10123 [(set_attr "type" "load")])
10125 (define_insn "load_toc_v4_PIC_3b"
10126 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10128 (match_operand:SI 1 "gpc_reg_operand" "b")
10131 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10132 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10133 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10134 "addis %0,%1,%2-%3@ha")
10136 (define_insn "load_toc_v4_PIC_3c"
10137 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10139 (match_operand:SI 1 "gpc_reg_operand" "b")
10141 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10142 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10143 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10144 "addi %0,%1,%2-%3@l")
10146 ;; If the TOC is shared over a translation unit, as happens with all
10147 ;; the kinds of PIC that we support, we need to restore the TOC
10148 ;; pointer only when jumping over units of translation.
10149 ;; On Darwin, we need to reload the picbase.
10151 (define_expand "builtin_setjmp_receiver"
10152 [(use (label_ref (match_operand 0 "" "")))]
10153 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10154 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10155 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10159 if (DEFAULT_ABI == ABI_DARWIN)
10161 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10162 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10166 crtl->uses_pic_offset_table = 1;
10167 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10168 CODE_LABEL_NUMBER (operands[0]));
10169 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10171 emit_insn (gen_load_macho_picbase (tmplabrtx));
10172 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10173 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10177 rs6000_emit_load_toc_table (FALSE);
10181 ;; Largetoc support
10182 (define_insn "*largetoc_high"
10183 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10185 (unspec [(match_operand:DI 1 "" "")
10186 (match_operand:DI 2 "gpc_reg_operand" "b")]
10188 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10189 "addis %0,%2,%1@toc@ha")
10191 (define_insn "*largetoc_high_aix<mode>"
10192 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10194 (unspec [(match_operand:P 1 "" "")
10195 (match_operand:P 2 "gpc_reg_operand" "b")]
10197 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10198 "addis %0,%1@u(%2)")
10200 (define_insn "*largetoc_high_plus"
10201 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10204 (unspec [(match_operand:DI 1 "" "")
10205 (match_operand:DI 2 "gpc_reg_operand" "b")]
10207 (match_operand:DI 3 "add_cint_operand" "n"))))]
10208 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10209 "addis %0,%2,%1+%3@toc@ha")
10211 (define_insn "*largetoc_high_plus_aix<mode>"
10212 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10215 (unspec [(match_operand:P 1 "" "")
10216 (match_operand:P 2 "gpc_reg_operand" "b")]
10218 (match_operand:P 3 "add_cint_operand" "n"))))]
10219 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10220 "addis %0,%1+%3@u(%2)")
10222 (define_insn "*largetoc_low"
10223 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10224 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10225 (match_operand:DI 2 "" "")))]
10226 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10229 (define_insn "*largetoc_low_aix<mode>"
10230 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10231 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10232 (match_operand:P 2 "" "")))]
10233 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10236 (define_insn_and_split "*tocref<mode>"
10237 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10238 (match_operand:P 1 "small_toc_ref" "R"))]
10241 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10242 [(set (match_dup 0) (high:P (match_dup 1)))
10243 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10245 ;; Elf specific ways of loading addresses for non-PIC code.
10246 ;; The output of this could be r0, but we make a very strong
10247 ;; preference for a base register because it will usually
10248 ;; be needed there.
10249 (define_insn "elf_high"
10250 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10251 (high:SI (match_operand 1 "" "")))]
10252 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10255 (define_insn "elf_low"
10256 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10257 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10258 (match_operand 2 "" "")))]
10259 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10262 ;; Call and call_value insns
10263 (define_expand "call"
10264 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10265 (match_operand 1 "" ""))
10266 (use (match_operand 2 "" ""))
10267 (clobber (reg:SI LR_REGNO))])]
10272 if (MACHOPIC_INDIRECT)
10273 operands[0] = machopic_indirect_call_target (operands[0]);
10276 gcc_assert (GET_CODE (operands[0]) == MEM);
10277 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10279 operands[0] = XEXP (operands[0], 0);
10281 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10283 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10287 if (GET_CODE (operands[0]) != SYMBOL_REF
10288 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10290 if (INTVAL (operands[2]) & CALL_LONG)
10291 operands[0] = rs6000_longcall_ref (operands[0]);
10293 switch (DEFAULT_ABI)
10297 operands[0] = force_reg (Pmode, operands[0]);
10301 gcc_unreachable ();
10306 (define_expand "call_value"
10307 [(parallel [(set (match_operand 0 "" "")
10308 (call (mem:SI (match_operand 1 "address_operand" ""))
10309 (match_operand 2 "" "")))
10310 (use (match_operand 3 "" ""))
10311 (clobber (reg:SI LR_REGNO))])]
10316 if (MACHOPIC_INDIRECT)
10317 operands[1] = machopic_indirect_call_target (operands[1]);
10320 gcc_assert (GET_CODE (operands[1]) == MEM);
10321 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10323 operands[1] = XEXP (operands[1], 0);
10325 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10327 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10331 if (GET_CODE (operands[1]) != SYMBOL_REF
10332 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10334 if (INTVAL (operands[3]) & CALL_LONG)
10335 operands[1] = rs6000_longcall_ref (operands[1]);
10337 switch (DEFAULT_ABI)
10341 operands[1] = force_reg (Pmode, operands[1]);
10345 gcc_unreachable ();
10350 ;; Call to function in current module. No TOC pointer reload needed.
10351 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10352 ;; either the function was not prototyped, or it was prototyped as a
10353 ;; variable argument function. It is > 0 if FP registers were passed
10354 ;; and < 0 if they were not.
10356 (define_insn "*call_local32"
10357 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10358 (match_operand 1 "" "g,g"))
10359 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10360 (clobber (reg:SI LR_REGNO))]
10361 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10364 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10365 output_asm_insn (\"crxor 6,6,6\", operands);
10367 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10368 output_asm_insn (\"creqv 6,6,6\", operands);
10370 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10372 [(set_attr "type" "branch")
10373 (set_attr "length" "4,8")])
10375 (define_insn "*call_local64"
10376 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10377 (match_operand 1 "" "g,g"))
10378 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10379 (clobber (reg:SI LR_REGNO))]
10380 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10383 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10384 output_asm_insn (\"crxor 6,6,6\", operands);
10386 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10387 output_asm_insn (\"creqv 6,6,6\", operands);
10389 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10391 [(set_attr "type" "branch")
10392 (set_attr "length" "4,8")])
10394 (define_insn "*call_value_local32"
10395 [(set (match_operand 0 "" "")
10396 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10397 (match_operand 2 "" "g,g")))
10398 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10399 (clobber (reg:SI LR_REGNO))]
10400 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10403 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10404 output_asm_insn (\"crxor 6,6,6\", operands);
10406 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10407 output_asm_insn (\"creqv 6,6,6\", operands);
10409 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10411 [(set_attr "type" "branch")
10412 (set_attr "length" "4,8")])
10415 (define_insn "*call_value_local64"
10416 [(set (match_operand 0 "" "")
10417 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10418 (match_operand 2 "" "g,g")))
10419 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10420 (clobber (reg:SI LR_REGNO))]
10421 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10424 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10425 output_asm_insn (\"crxor 6,6,6\", operands);
10427 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10428 output_asm_insn (\"creqv 6,6,6\", operands);
10430 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10432 [(set_attr "type" "branch")
10433 (set_attr "length" "4,8")])
10436 ;; A function pointer under System V is just a normal pointer
10437 ;; operands[0] is the function pointer
10438 ;; operands[1] is the stack size to clean up
10439 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10440 ;; which indicates how to set cr1
10442 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10443 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10444 (match_operand 1 "" "g,g,g,g"))
10445 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10446 (clobber (reg:SI LR_REGNO))]
10447 "DEFAULT_ABI == ABI_V4
10448 || DEFAULT_ABI == ABI_DARWIN"
10450 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10451 output_asm_insn ("crxor 6,6,6", operands);
10453 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10454 output_asm_insn ("creqv 6,6,6", operands);
10456 if (rs6000_speculate_indirect_jumps
10457 || which_alternative == 1 || which_alternative == 3)
10460 return "crset 2\;beq%T0l-";
10462 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10463 (set (attr "length")
10464 (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10465 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10468 (and (eq (symbol_ref "which_alternative") (const_int 0))
10469 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10472 (eq (symbol_ref "which_alternative") (const_int 1))
10474 (and (eq (symbol_ref "which_alternative") (const_int 2))
10475 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10478 (and (eq (symbol_ref "which_alternative") (const_int 2))
10479 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10481 (const_string "12")
10482 (eq (symbol_ref "which_alternative") (const_int 3))
10483 (const_string "8")]
10484 (const_string "4")))])
10486 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10487 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10488 (match_operand 1 "" "g,g"))
10489 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10490 (clobber (reg:SI LR_REGNO))]
10491 "(DEFAULT_ABI == ABI_DARWIN
10492 || (DEFAULT_ABI == ABI_V4
10493 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10495 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10496 output_asm_insn ("crxor 6,6,6", operands);
10498 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10499 output_asm_insn ("creqv 6,6,6", operands);
10502 return output_call(insn, operands, 0, 2);
10504 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10506 gcc_assert (!TARGET_SECURE_PLT);
10507 return "bl %z0@plt";
10513 "DEFAULT_ABI == ABI_V4
10514 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10515 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10516 [(parallel [(call (mem:SI (match_dup 0))
10518 (use (match_dup 2))
10519 (use (match_dup 3))
10520 (clobber (reg:SI LR_REGNO))])]
10522 operands[3] = pic_offset_table_rtx;
10524 [(set_attr "type" "branch,branch")
10525 (set_attr "length" "4,8")])
10527 (define_insn "*call_nonlocal_sysv_secure<mode>"
10528 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10529 (match_operand 1 "" "g,g"))
10530 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10531 (use (match_operand:SI 3 "register_operand" "r,r"))
10532 (clobber (reg:SI LR_REGNO))]
10533 "(DEFAULT_ABI == ABI_V4
10534 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10535 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10537 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10538 output_asm_insn ("crxor 6,6,6", operands);
10540 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10541 output_asm_insn ("creqv 6,6,6", operands);
10544 /* The magic 32768 offset here and in the other sysv call insns
10545 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10546 See sysv4.h:toc_section. */
10547 return "bl %z0+32768@plt";
10549 return "bl %z0@plt";
10551 [(set_attr "type" "branch,branch")
10552 (set_attr "length" "4,8")])
10554 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10555 [(set (match_operand 0 "" "")
10556 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10557 (match_operand 2 "" "g,g,g,g")))
10558 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10559 (clobber (reg:SI LR_REGNO))]
10560 "DEFAULT_ABI == ABI_V4
10561 || DEFAULT_ABI == ABI_DARWIN"
10563 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10564 output_asm_insn ("crxor 6,6,6", operands);
10566 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10567 output_asm_insn ("creqv 6,6,6", operands);
10569 if (rs6000_speculate_indirect_jumps
10570 || which_alternative == 1 || which_alternative == 3)
10573 return "crset 2\;beq%T1l-";
10575 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10576 (set (attr "length")
10577 (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10578 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10581 (and (eq (symbol_ref "which_alternative") (const_int 0))
10582 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10585 (eq (symbol_ref "which_alternative") (const_int 1))
10587 (and (eq (symbol_ref "which_alternative") (const_int 2))
10588 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10591 (and (eq (symbol_ref "which_alternative") (const_int 2))
10592 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10594 (const_string "12")
10595 (eq (symbol_ref "which_alternative") (const_int 3))
10596 (const_string "8")]
10597 (const_string "4")))])
10599 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10600 [(set (match_operand 0 "" "")
10601 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10602 (match_operand 2 "" "g,g")))
10603 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10604 (clobber (reg:SI LR_REGNO))]
10605 "(DEFAULT_ABI == ABI_DARWIN
10606 || (DEFAULT_ABI == ABI_V4
10607 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10609 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10610 output_asm_insn ("crxor 6,6,6", operands);
10612 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10613 output_asm_insn ("creqv 6,6,6", operands);
10616 return output_call(insn, operands, 1, 3);
10618 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10620 gcc_assert (!TARGET_SECURE_PLT);
10621 return "bl %z1@plt";
10627 "DEFAULT_ABI == ABI_V4
10628 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10629 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10630 [(parallel [(set (match_dup 0)
10631 (call (mem:SI (match_dup 1))
10633 (use (match_dup 3))
10634 (use (match_dup 4))
10635 (clobber (reg:SI LR_REGNO))])]
10637 operands[4] = pic_offset_table_rtx;
10639 [(set_attr "type" "branch,branch")
10640 (set_attr "length" "4,8")])
10642 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10643 [(set (match_operand 0 "" "")
10644 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10645 (match_operand 2 "" "g,g")))
10646 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10647 (use (match_operand:SI 4 "register_operand" "r,r"))
10648 (clobber (reg:SI LR_REGNO))]
10649 "(DEFAULT_ABI == ABI_V4
10650 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10651 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10653 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10654 output_asm_insn ("crxor 6,6,6", operands);
10656 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10657 output_asm_insn ("creqv 6,6,6", operands);
10660 return "bl %z1+32768@plt";
10662 return "bl %z1@plt";
10664 [(set_attr "type" "branch,branch")
10665 (set_attr "length" "4,8")])
10668 ;; Call to AIX abi function in the same module.
10670 (define_insn "*call_local_aix<mode>"
10671 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10672 (match_operand 1 "" "g"))
10673 (clobber (reg:P LR_REGNO))]
10674 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10676 [(set_attr "type" "branch")
10677 (set_attr "length" "4")])
10679 (define_insn "*call_value_local_aix<mode>"
10680 [(set (match_operand 0 "" "")
10681 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10682 (match_operand 2 "" "g")))
10683 (clobber (reg:P LR_REGNO))]
10684 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10686 [(set_attr "type" "branch")
10687 (set_attr "length" "4")])
10689 ;; Call to AIX abi function which may be in another module.
10690 ;; Restore the TOC pointer (r2) after the call.
10692 (define_insn "*call_nonlocal_aix<mode>"
10693 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10694 (match_operand 1 "" "g"))
10695 (clobber (reg:P LR_REGNO))]
10696 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10698 [(set_attr "type" "branch")
10699 (set_attr "length" "8")])
10701 (define_insn "*call_value_nonlocal_aix<mode>"
10702 [(set (match_operand 0 "" "")
10703 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10704 (match_operand 2 "" "g")))
10705 (clobber (reg:P LR_REGNO))]
10706 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10708 [(set_attr "type" "branch")
10709 (set_attr "length" "8")])
10711 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10712 ;; Operand0 is the addresss of the function to call
10713 ;; Operand2 is the location in the function descriptor to load r2 from
10714 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10716 (define_insn "*call_indirect_aix<mode>"
10717 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10718 (match_operand 1 "" "g,g"))
10719 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10720 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10721 (clobber (reg:P LR_REGNO))]
10722 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10723 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10724 [(set_attr "type" "jmpreg")
10725 (set_attr "length" "12")])
10727 (define_insn "*call_indirect_aix<mode>_nospec"
10728 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10729 (match_operand 1 "" "g,g"))
10730 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10731 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10732 (clobber (reg:P LR_REGNO))]
10733 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10734 "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10735 [(set_attr "type" "jmpreg")
10736 (set_attr "length" "16")])
10738 (define_insn "*call_value_indirect_aix<mode>"
10739 [(set (match_operand 0 "" "")
10740 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10741 (match_operand 2 "" "g,g")))
10742 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10743 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10744 (clobber (reg:P LR_REGNO))]
10745 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10746 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10747 [(set_attr "type" "jmpreg")
10748 (set_attr "length" "12")])
10750 (define_insn "*call_value_indirect_aix<mode>_nospec"
10751 [(set (match_operand 0 "" "")
10752 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10753 (match_operand 2 "" "g,g")))
10754 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10755 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10756 (clobber (reg:P LR_REGNO))]
10757 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10758 "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10759 [(set_attr "type" "jmpreg")
10760 (set_attr "length" "16")])
10762 ;; Call to indirect functions with the ELFv2 ABI.
10763 ;; Operand0 is the addresss of the function to call
10764 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10766 (define_insn "*call_indirect_elfv2<mode>"
10767 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10768 (match_operand 1 "" "g,g"))
10769 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10770 (clobber (reg:P LR_REGNO))]
10771 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10772 "b%T0l\;<ptrload> 2,%2(1)"
10773 [(set_attr "type" "jmpreg")
10774 (set_attr "length" "8")])
10776 ;; Variant with deliberate misprediction.
10777 (define_insn "*call_indirect_elfv2<mode>_nospec"
10778 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10779 (match_operand 1 "" "g,g"))
10780 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10781 (clobber (reg:P LR_REGNO))]
10782 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10783 "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10784 [(set_attr "type" "jmpreg")
10785 (set_attr "length" "12")])
10787 (define_insn "*call_value_indirect_elfv2<mode>"
10788 [(set (match_operand 0 "" "")
10789 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10790 (match_operand 2 "" "g,g")))
10791 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10792 (clobber (reg:P LR_REGNO))]
10793 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10794 "b%T1l\;<ptrload> 2,%3(1)"
10795 [(set_attr "type" "jmpreg")
10796 (set_attr "length" "8")])
10798 ; Variant with deliberate misprediction.
10799 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10800 [(set (match_operand 0 "" "")
10801 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10802 (match_operand 2 "" "g,g")))
10803 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10804 (clobber (reg:P LR_REGNO))]
10805 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10806 "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10807 [(set_attr "type" "jmpreg")
10808 (set_attr "length" "12")])
10810 ;; Call subroutine returning any type.
10811 (define_expand "untyped_call"
10812 [(parallel [(call (match_operand 0 "" "")
10814 (match_operand 1 "" "")
10815 (match_operand 2 "" "")])]
10821 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10823 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10825 rtx set = XVECEXP (operands[2], 0, i);
10826 emit_move_insn (SET_DEST (set), SET_SRC (set));
10829 /* The optimizer does not know that the call sets the function value
10830 registers we stored in the result block. We avoid problems by
10831 claiming that all hard registers are used and clobbered at this
10833 emit_insn (gen_blockage ());
10838 ;; sibling call patterns
10839 (define_expand "sibcall"
10840 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10841 (match_operand 1 "" ""))
10842 (use (match_operand 2 "" ""))
10848 if (MACHOPIC_INDIRECT)
10849 operands[0] = machopic_indirect_call_target (operands[0]);
10852 gcc_assert (GET_CODE (operands[0]) == MEM);
10853 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10855 operands[0] = XEXP (operands[0], 0);
10857 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10859 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10864 (define_expand "sibcall_value"
10865 [(parallel [(set (match_operand 0 "register_operand" "")
10866 (call (mem:SI (match_operand 1 "address_operand" ""))
10867 (match_operand 2 "" "")))
10868 (use (match_operand 3 "" ""))
10874 if (MACHOPIC_INDIRECT)
10875 operands[1] = machopic_indirect_call_target (operands[1]);
10878 gcc_assert (GET_CODE (operands[1]) == MEM);
10879 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10881 operands[1] = XEXP (operands[1], 0);
10883 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10885 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10890 (define_insn "*sibcall_local32"
10891 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10892 (match_operand 1 "" "g,g"))
10893 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10895 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10898 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10899 output_asm_insn (\"crxor 6,6,6\", operands);
10901 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10902 output_asm_insn (\"creqv 6,6,6\", operands);
10904 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10906 [(set_attr "type" "branch")
10907 (set_attr "length" "4,8")])
10909 (define_insn "*sibcall_local64"
10910 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10911 (match_operand 1 "" "g,g"))
10912 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10914 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10917 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10918 output_asm_insn (\"crxor 6,6,6\", operands);
10920 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10921 output_asm_insn (\"creqv 6,6,6\", operands);
10923 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10925 [(set_attr "type" "branch")
10926 (set_attr "length" "4,8")])
10928 (define_insn "*sibcall_value_local32"
10929 [(set (match_operand 0 "" "")
10930 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10931 (match_operand 2 "" "g,g")))
10932 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10934 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10937 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10938 output_asm_insn (\"crxor 6,6,6\", operands);
10940 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10941 output_asm_insn (\"creqv 6,6,6\", operands);
10943 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10945 [(set_attr "type" "branch")
10946 (set_attr "length" "4,8")])
10948 (define_insn "*sibcall_value_local64"
10949 [(set (match_operand 0 "" "")
10950 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10951 (match_operand 2 "" "g,g")))
10952 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10954 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10957 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10958 output_asm_insn (\"crxor 6,6,6\", operands);
10960 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10961 output_asm_insn (\"creqv 6,6,6\", operands);
10963 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10965 [(set_attr "type" "branch")
10966 (set_attr "length" "4,8")])
10968 (define_insn "*sibcall_nonlocal_sysv<mode>"
10969 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10970 (match_operand 1 "" ""))
10971 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10973 "(DEFAULT_ABI == ABI_DARWIN
10974 || DEFAULT_ABI == ABI_V4)
10975 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10978 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10979 output_asm_insn (\"crxor 6,6,6\", operands);
10981 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10982 output_asm_insn (\"creqv 6,6,6\", operands);
10984 if (which_alternative >= 2)
10986 if (rs6000_speculate_indirect_jumps)
10989 /* Can use CR0 since it is volatile across sibcalls. */
10990 return \"crset 2\;beq%T0-\;b $\";
10992 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10994 gcc_assert (!TARGET_SECURE_PLT);
10995 return \"b %z0@plt\";
11000 [(set_attr "type" "branch")
11001 (set (attr "length")
11002 (cond [(eq (symbol_ref "which_alternative") (const_int 0))
11004 (eq (symbol_ref "which_alternative") (const_int 1))
11006 (and (eq (symbol_ref "which_alternative") (const_int 2))
11007 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11010 (and (eq (symbol_ref "which_alternative") (const_int 2))
11011 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11013 (const_string "12")
11014 (and (eq (symbol_ref "which_alternative") (const_int 3))
11015 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11018 (and (eq (symbol_ref "which_alternative") (const_int 3))
11019 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11021 (const_string "16")]
11022 (const_string "4")))])
11024 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11025 [(set (match_operand 0 "" "")
11026 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11027 (match_operand 2 "" "")))
11028 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11030 "(DEFAULT_ABI == ABI_DARWIN
11031 || DEFAULT_ABI == ABI_V4)
11032 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11035 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11036 output_asm_insn (\"crxor 6,6,6\", operands);
11038 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11039 output_asm_insn (\"creqv 6,6,6\", operands);
11041 if (which_alternative >= 2)
11043 if (rs6000_speculate_indirect_jumps)
11046 /* Can use CR0 since it is volatile across sibcalls. */
11047 return \"crset 2\;beq%T1-\;b $\";
11049 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11051 gcc_assert (!TARGET_SECURE_PLT);
11052 return \"b %z1@plt\";
11057 [(set_attr "type" "branch")
11058 (set (attr "length")
11059 (cond [(eq (symbol_ref "which_alternative") (const_int 0))
11061 (eq (symbol_ref "which_alternative") (const_int 1))
11063 (and (eq (symbol_ref "which_alternative") (const_int 2))
11064 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11067 (and (eq (symbol_ref "which_alternative") (const_int 2))
11068 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11070 (const_string "12")
11071 (and (eq (symbol_ref "which_alternative") (const_int 3))
11072 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11075 (and (eq (symbol_ref "which_alternative") (const_int 3))
11076 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11078 (const_string "16")]
11079 (const_string "4")))])
11081 ;; AIX ABI sibling call patterns.
11083 (define_insn "*sibcall_aix<mode>"
11084 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11085 (match_operand 1 "" "g,g"))
11087 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11091 [(set_attr "type" "branch")
11092 (set_attr "length" "4")])
11094 (define_insn "*sibcall_value_aix<mode>"
11095 [(set (match_operand 0 "" "")
11096 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11097 (match_operand 2 "" "g,g")))
11099 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11103 [(set_attr "type" "branch")
11104 (set_attr "length" "4")])
11106 (define_expand "sibcall_epilogue"
11107 [(use (const_int 0))]
11110 if (!TARGET_SCHED_PROLOG)
11111 emit_insn (gen_blockage ());
11112 rs6000_emit_epilogue (TRUE);
11116 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11117 ;; all of memory. This blocks insns from being moved across this point.
11119 (define_insn "blockage"
11120 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11124 (define_expand "probe_stack_address"
11125 [(use (match_operand 0 "address_operand"))]
11128 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11129 MEM_VOLATILE_P (operands[0]) = 1;
11132 emit_insn (gen_probe_stack_di (operands[0]));
11134 emit_insn (gen_probe_stack_si (operands[0]));
11138 (define_insn "probe_stack_<mode>"
11139 [(set (match_operand:P 0 "memory_operand" "=m")
11140 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11143 operands[1] = gen_rtx_REG (Pmode, 0);
11144 return "st<wd>%U0%X0 %1,%0";
11146 [(set_attr "type" "store")
11147 (set (attr "update")
11148 (if_then_else (match_operand 0 "update_address_mem")
11149 (const_string "yes")
11150 (const_string "no")))
11151 (set (attr "indexed")
11152 (if_then_else (match_operand 0 "indexed_address_mem")
11153 (const_string "yes")
11154 (const_string "no")))
11155 (set_attr "length" "4")])
11157 (define_insn "probe_stack_range<P:mode>"
11158 [(set (match_operand:P 0 "register_operand" "=&r")
11159 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11160 (match_operand:P 2 "register_operand" "r")
11161 (match_operand:P 3 "register_operand" "r")]
11162 UNSPECV_PROBE_STACK_RANGE))]
11164 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11165 [(set_attr "type" "three")])
11167 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11168 ;; signed & unsigned, and one type of branch.
11170 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11171 ;; insns, and branches.
11173 (define_expand "cbranch<mode>4"
11174 [(use (match_operator 0 "comparison_operator"
11175 [(match_operand:GPR 1 "gpc_reg_operand" "")
11176 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11177 (use (match_operand 3 ""))]
11181 /* Take care of the possibility that operands[2] might be negative but
11182 this might be a logical operation. That insn doesn't exist. */
11183 if (GET_CODE (operands[2]) == CONST_INT
11184 && INTVAL (operands[2]) < 0)
11186 operands[2] = force_reg (<MODE>mode, operands[2]);
11187 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11188 GET_MODE (operands[0]),
11189 operands[1], operands[2]);
11192 rs6000_emit_cbranch (<MODE>mode, operands);
11196 (define_expand "cbranch<mode>4"
11197 [(use (match_operator 0 "comparison_operator"
11198 [(match_operand:FP 1 "gpc_reg_operand" "")
11199 (match_operand:FP 2 "gpc_reg_operand" "")]))
11200 (use (match_operand 3 ""))]
11204 rs6000_emit_cbranch (<MODE>mode, operands);
11208 (define_expand "cstore<mode>4_signed"
11209 [(use (match_operator 1 "signed_comparison_operator"
11210 [(match_operand:P 2 "gpc_reg_operand")
11211 (match_operand:P 3 "gpc_reg_operand")]))
11212 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11215 enum rtx_code cond_code = GET_CODE (operands[1]);
11217 rtx op0 = operands[0];
11218 rtx op1 = operands[2];
11219 rtx op2 = operands[3];
11221 if (cond_code == GE || cond_code == LT)
11223 cond_code = swap_condition (cond_code);
11224 std::swap (op1, op2);
11227 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11228 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11229 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11231 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11232 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11233 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11235 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11237 if (cond_code == LE)
11238 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11241 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11242 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11243 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11249 (define_expand "cstore<mode>4_unsigned"
11250 [(use (match_operator 1 "unsigned_comparison_operator"
11251 [(match_operand:P 2 "gpc_reg_operand")
11252 (match_operand:P 3 "reg_or_short_operand")]))
11253 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11256 enum rtx_code cond_code = GET_CODE (operands[1]);
11258 rtx op0 = operands[0];
11259 rtx op1 = operands[2];
11260 rtx op2 = operands[3];
11262 if (cond_code == GEU || cond_code == LTU)
11264 cond_code = swap_condition (cond_code);
11265 std::swap (op1, op2);
11268 if (!gpc_reg_operand (op1, <MODE>mode))
11269 op1 = force_reg (<MODE>mode, op1);
11270 if (!reg_or_short_operand (op2, <MODE>mode))
11271 op2 = force_reg (<MODE>mode, op2);
11273 rtx tmp = gen_reg_rtx (<MODE>mode);
11274 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11276 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11277 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11279 if (cond_code == LEU)
11280 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11282 emit_insn (gen_neg<mode>2 (op0, tmp2));
11287 (define_expand "cstore_si_as_di"
11288 [(use (match_operator 1 "unsigned_comparison_operator"
11289 [(match_operand:SI 2 "gpc_reg_operand")
11290 (match_operand:SI 3 "reg_or_short_operand")]))
11291 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11294 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11295 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11297 operands[2] = force_reg (SImode, operands[2]);
11298 operands[3] = force_reg (SImode, operands[3]);
11299 rtx op1 = gen_reg_rtx (DImode);
11300 rtx op2 = gen_reg_rtx (DImode);
11301 convert_move (op1, operands[2], uns_flag);
11302 convert_move (op2, operands[3], uns_flag);
11304 if (cond_code == GT || cond_code == LE)
11306 cond_code = swap_condition (cond_code);
11307 std::swap (op1, op2);
11310 rtx tmp = gen_reg_rtx (DImode);
11311 rtx tmp2 = gen_reg_rtx (DImode);
11312 emit_insn (gen_subdi3 (tmp, op1, op2));
11313 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11319 gcc_unreachable ();
11324 tmp3 = gen_reg_rtx (DImode);
11325 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11329 convert_move (operands[0], tmp3, 1);
11334 (define_expand "cstore<mode>4_signed_imm"
11335 [(use (match_operator 1 "signed_comparison_operator"
11336 [(match_operand:GPR 2 "gpc_reg_operand")
11337 (match_operand:GPR 3 "immediate_operand")]))
11338 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11341 bool invert = false;
11343 enum rtx_code cond_code = GET_CODE (operands[1]);
11345 rtx op0 = operands[0];
11346 rtx op1 = operands[2];
11347 HOST_WIDE_INT val = INTVAL (operands[3]);
11349 if (cond_code == GE || cond_code == GT)
11351 cond_code = reverse_condition (cond_code);
11355 if (cond_code == LE)
11358 rtx tmp = gen_reg_rtx (<MODE>mode);
11359 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11360 rtx x = gen_reg_rtx (<MODE>mode);
11362 emit_insn (gen_and<mode>3 (x, op1, tmp));
11364 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11368 rtx tmp = gen_reg_rtx (<MODE>mode);
11369 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11373 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11374 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11379 (define_expand "cstore<mode>4_unsigned_imm"
11380 [(use (match_operator 1 "unsigned_comparison_operator"
11381 [(match_operand:GPR 2 "gpc_reg_operand")
11382 (match_operand:GPR 3 "immediate_operand")]))
11383 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11386 bool invert = false;
11388 enum rtx_code cond_code = GET_CODE (operands[1]);
11390 rtx op0 = operands[0];
11391 rtx op1 = operands[2];
11392 HOST_WIDE_INT val = INTVAL (operands[3]);
11394 if (cond_code == GEU || cond_code == GTU)
11396 cond_code = reverse_condition (cond_code);
11400 if (cond_code == LEU)
11403 rtx tmp = gen_reg_rtx (<MODE>mode);
11404 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11405 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11406 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11407 rtx x = gen_reg_rtx (<MODE>mode);
11409 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11411 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11415 rtx tmp = gen_reg_rtx (<MODE>mode);
11416 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11420 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11421 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11426 (define_expand "cstore<mode>4"
11427 [(use (match_operator 1 "comparison_operator"
11428 [(match_operand:GPR 2 "gpc_reg_operand")
11429 (match_operand:GPR 3 "reg_or_short_operand")]))
11430 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11433 /* Expanding EQ and NE directly to some machine instructions does not help
11434 but does hurt combine. So don't. */
11435 if (GET_CODE (operands[1]) == EQ)
11436 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11437 else if (<MODE>mode == Pmode
11438 && GET_CODE (operands[1]) == NE)
11439 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11440 else if (GET_CODE (operands[1]) == NE)
11442 rtx tmp = gen_reg_rtx (<MODE>mode);
11443 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11444 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11447 /* If ISEL is fast, expand to it. */
11448 else if (TARGET_ISEL)
11449 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11451 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11452 etc. combinations magically work out just right. */
11453 else if (<MODE>mode == Pmode
11454 && unsigned_comparison_operator (operands[1], VOIDmode))
11455 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11456 operands[2], operands[3]));
11458 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11459 else if (<MODE>mode == SImode && Pmode == DImode)
11460 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11461 operands[2], operands[3]));
11463 /* For signed comparisons against a constant, we can do some simple
11465 else if (signed_comparison_operator (operands[1], VOIDmode)
11466 && CONST_INT_P (operands[3]))
11467 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11468 operands[2], operands[3]));
11470 /* And similarly for unsigned comparisons. */
11471 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11472 && CONST_INT_P (operands[3]))
11473 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11474 operands[2], operands[3]));
11476 /* We also do not want to use mfcr for signed comparisons. */
11477 else if (<MODE>mode == Pmode
11478 && signed_comparison_operator (operands[1], VOIDmode))
11479 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11480 operands[2], operands[3]));
11482 /* Everything else, use the mfcr brute force. */
11484 rs6000_emit_sCOND (<MODE>mode, operands);
11489 (define_expand "cstore<mode>4"
11490 [(use (match_operator 1 "comparison_operator"
11491 [(match_operand:FP 2 "gpc_reg_operand")
11492 (match_operand:FP 3 "gpc_reg_operand")]))
11493 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11496 rs6000_emit_sCOND (<MODE>mode, operands);
11501 (define_expand "stack_protect_set"
11502 [(match_operand 0 "memory_operand")
11503 (match_operand 1 "memory_operand")]
11506 if (rs6000_stack_protector_guard == SSP_TLS)
11508 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11509 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11510 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11511 operands[1] = gen_rtx_MEM (Pmode, addr);
11515 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11517 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11522 (define_insn "stack_protect_setsi"
11523 [(set (match_operand:SI 0 "memory_operand" "=m")
11524 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11525 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11527 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11528 [(set_attr "type" "three")
11529 (set_attr "length" "12")])
11531 (define_insn "stack_protect_setdi"
11532 [(set (match_operand:DI 0 "memory_operand" "=Y")
11533 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11534 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11536 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11537 [(set_attr "type" "three")
11538 (set_attr "length" "12")])
11540 (define_expand "stack_protect_test"
11541 [(match_operand 0 "memory_operand")
11542 (match_operand 1 "memory_operand")
11543 (match_operand 2 "")]
11546 rtx guard = operands[1];
11548 if (rs6000_stack_protector_guard == SSP_TLS)
11550 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11551 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11552 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11553 guard = gen_rtx_MEM (Pmode, addr);
11556 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11557 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11558 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11559 emit_jump_insn (jump);
11564 (define_insn "stack_protect_testsi"
11565 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11566 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11567 (match_operand:SI 2 "memory_operand" "m,m")]
11569 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11570 (clobber (match_scratch:SI 3 "=&r,&r"))]
11573 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11574 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11575 [(set_attr "length" "16,20")])
11577 (define_insn "stack_protect_testdi"
11578 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11579 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11580 (match_operand:DI 2 "memory_operand" "Y,Y")]
11582 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11583 (clobber (match_scratch:DI 3 "=&r,&r"))]
11586 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11587 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11588 [(set_attr "length" "16,20")])
11591 ;; Here are the actual compare insns.
11592 (define_insn "*cmp<mode>_signed"
11593 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11594 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11595 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11597 "cmp<wd>%I2 %0,%1,%2"
11598 [(set_attr "type" "cmp")])
11600 (define_insn "*cmp<mode>_unsigned"
11601 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11602 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11603 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11605 "cmpl<wd>%I2 %0,%1,%2"
11606 [(set_attr "type" "cmp")])
11608 ;; If we are comparing a register for equality with a large constant,
11609 ;; we can do this with an XOR followed by a compare. But this is profitable
11610 ;; only if the large constant is only used for the comparison (and in this
11611 ;; case we already have a register to reuse as scratch).
11613 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11614 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11617 [(set (match_operand:SI 0 "register_operand")
11618 (match_operand:SI 1 "logical_const_operand" ""))
11619 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11621 (match_operand:SI 2 "logical_const_operand" "")]))
11622 (set (match_operand:CC 4 "cc_reg_operand" "")
11623 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11626 (if_then_else (match_operator 6 "equality_operator"
11627 [(match_dup 4) (const_int 0)])
11628 (match_operand 7 "" "")
11629 (match_operand 8 "" "")))]
11630 "peep2_reg_dead_p (3, operands[0])
11631 && peep2_reg_dead_p (4, operands[4])
11632 && REGNO (operands[0]) != REGNO (operands[5])"
11633 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11634 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11635 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11638 /* Get the constant we are comparing against, and see what it looks like
11639 when sign-extended from 16 to 32 bits. Then see what constant we could
11640 XOR with SEXTC to get the sign-extended value. */
11641 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11643 operands[1], operands[2]);
11644 HOST_WIDE_INT c = INTVAL (cnst);
11645 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11646 HOST_WIDE_INT xorv = c ^ sextc;
11648 operands[9] = GEN_INT (xorv);
11649 operands[10] = GEN_INT (sextc);
11652 ;; The following two insns don't exist as single insns, but if we provide
11653 ;; them, we can swap an add and compare, which will enable us to overlap more
11654 ;; of the required delay between a compare and branch. We generate code for
11655 ;; them by splitting.
11658 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11659 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11660 (match_operand:SI 2 "short_cint_operand" "i")))
11661 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11662 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11665 [(set_attr "length" "8")])
11668 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11669 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11670 (match_operand:SI 2 "u_short_cint_operand" "i")))
11671 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11672 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11675 [(set_attr "length" "8")])
11678 [(set (match_operand:CC 3 "cc_reg_operand" "")
11679 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11680 (match_operand:SI 2 "short_cint_operand" "")))
11681 (set (match_operand:SI 0 "gpc_reg_operand" "")
11682 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11684 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11685 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11688 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11689 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11690 (match_operand:SI 2 "u_short_cint_operand" "")))
11691 (set (match_operand:SI 0 "gpc_reg_operand" "")
11692 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11694 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11695 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11697 ;; Only need to compare second words if first words equal
11698 (define_insn "*cmp<mode>_internal1"
11699 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11700 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11701 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11702 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11703 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11704 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11705 [(set_attr "type" "fpcompare")
11706 (set_attr "length" "12")])
11708 (define_insn_and_split "*cmp<mode>_internal2"
11709 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11710 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11711 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11712 (clobber (match_scratch:DF 3 "=d"))
11713 (clobber (match_scratch:DF 4 "=d"))
11714 (clobber (match_scratch:DF 5 "=d"))
11715 (clobber (match_scratch:DF 6 "=d"))
11716 (clobber (match_scratch:DF 7 "=d"))
11717 (clobber (match_scratch:DF 8 "=d"))
11718 (clobber (match_scratch:DF 9 "=d"))
11719 (clobber (match_scratch:DF 10 "=d"))
11720 (clobber (match_scratch:GPR 11 "=b"))]
11721 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11722 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11724 "&& reload_completed"
11725 [(set (match_dup 3) (match_dup 14))
11726 (set (match_dup 4) (match_dup 15))
11727 (set (match_dup 9) (abs:DF (match_dup 5)))
11728 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11729 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11730 (label_ref (match_dup 12))
11732 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11733 (set (pc) (label_ref (match_dup 13)))
11735 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11736 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11737 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11738 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11741 REAL_VALUE_TYPE rv;
11742 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11743 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11745 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11746 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11747 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11748 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11749 operands[12] = gen_label_rtx ();
11750 operands[13] = gen_label_rtx ();
11752 operands[14] = force_const_mem (DFmode,
11753 const_double_from_real_value (rv, DFmode));
11754 operands[15] = force_const_mem (DFmode,
11755 const_double_from_real_value (dconst0,
11760 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11761 operands[14] = gen_const_mem (DFmode, tocref);
11762 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11763 operands[15] = gen_const_mem (DFmode, tocref);
11764 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11765 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11769 ;; Now we have the scc insns. We can do some combinations because of the
11770 ;; way the machine works.
11772 ;; Note that this is probably faster if we can put an insn between the
11773 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11774 ;; cases the insns below which don't use an intermediate CR field will
11775 ;; be used instead.
11777 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11778 (match_operator:SI 1 "scc_comparison_operator"
11779 [(match_operand 2 "cc_reg_operand" "y")
11782 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11783 [(set (attr "type")
11784 (cond [(match_test "TARGET_MFCRF")
11785 (const_string "mfcrf")
11787 (const_string "mfcr")))
11788 (set_attr "length" "8")])
11790 ;; Same as above, but get the OV/ORDERED bit.
11791 (define_insn "move_from_CR_ov_bit"
11792 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11793 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11795 "TARGET_PAIRED_FLOAT"
11796 "mfcr %0\;rlwinm %0,%0,%t1,1"
11797 [(set_attr "type" "mfcr")
11798 (set_attr "length" "8")])
11801 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11802 (match_operator:DI 1 "scc_comparison_operator"
11803 [(match_operand 2 "cc_reg_operand" "y")
11806 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11807 [(set (attr "type")
11808 (cond [(match_test "TARGET_MFCRF")
11809 (const_string "mfcrf")
11811 (const_string "mfcr")))
11812 (set_attr "length" "8")])
11815 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11816 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11817 [(match_operand 2 "cc_reg_operand" "y,y")
11820 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11821 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11824 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11826 [(set_attr "type" "shift")
11827 (set_attr "dot" "yes")
11828 (set_attr "length" "8,16")])
11831 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11832 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11833 [(match_operand 2 "cc_reg_operand" "")
11836 (set (match_operand:SI 3 "gpc_reg_operand" "")
11837 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11838 "TARGET_32BIT && reload_completed"
11839 [(set (match_dup 3)
11840 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11842 (compare:CC (match_dup 3)
11847 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11848 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11849 [(match_operand 2 "cc_reg_operand" "y")
11851 (match_operand:SI 3 "const_int_operand" "n")))]
11855 int is_bit = ccr_bit (operands[1], 1);
11856 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11859 if (is_bit >= put_bit)
11860 count = is_bit - put_bit;
11862 count = 32 - (put_bit - is_bit);
11864 operands[4] = GEN_INT (count);
11865 operands[5] = GEN_INT (put_bit);
11867 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11869 [(set (attr "type")
11870 (cond [(match_test "TARGET_MFCRF")
11871 (const_string "mfcrf")
11873 (const_string "mfcr")))
11874 (set_attr "length" "8")])
11877 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11879 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11880 [(match_operand 2 "cc_reg_operand" "y,y")
11882 (match_operand:SI 3 "const_int_operand" "n,n"))
11884 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11885 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11890 int is_bit = ccr_bit (operands[1], 1);
11891 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11894 /* Force split for non-cc0 compare. */
11895 if (which_alternative == 1)
11898 if (is_bit >= put_bit)
11899 count = is_bit - put_bit;
11901 count = 32 - (put_bit - is_bit);
11903 operands[5] = GEN_INT (count);
11904 operands[6] = GEN_INT (put_bit);
11906 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11908 [(set_attr "type" "shift")
11909 (set_attr "dot" "yes")
11910 (set_attr "length" "8,16")])
11913 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11915 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11916 [(match_operand 2 "cc_reg_operand")
11918 (match_operand:SI 3 "const_int_operand"))
11920 (set (match_operand:SI 4 "gpc_reg_operand")
11921 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11924 [(set (match_dup 4)
11925 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11928 (compare:CC (match_dup 4)
11933 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11934 (define_code_attr UNS [(eq "CC")
11936 (lt "CC") (ltu "CCUNS")
11937 (gt "CC") (gtu "CCUNS")
11938 (le "CC") (leu "CCUNS")
11939 (ge "CC") (geu "CCUNS")])
11940 (define_code_attr UNSu_ [(eq "")
11945 (ge "") (geu "u_")])
11946 (define_code_attr UNSIK [(eq "I")
11951 (ge "I") (geu "K")])
11953 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11954 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11955 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11956 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11957 (clobber (match_scratch:GPR 3 "=r"))
11958 (clobber (match_scratch:GPR 4 "=r"))
11959 (clobber (match_scratch:<UNS> 5 "=y"))]
11961 && !(<CODE> == EQ && operands[2] == const0_rtx)
11962 && !(<CODE> == NE && operands[2] == const0_rtx
11963 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11968 rtx_code code = <CODE>;
11969 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11971 HOST_WIDE_INT val = INTVAL (operands[2]);
11972 if (code == LT && val != -0x8000)
11977 if (code == GT && val != 0x7fff)
11982 if (code == LTU && val != 0)
11987 if (code == GTU && val != 0xffff)
11992 operands[2] = GEN_INT (val);
11995 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11996 operands[3] = const0_rtx;
11999 if (GET_CODE (operands[3]) == SCRATCH)
12000 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
12001 emit_move_insn (operands[3], const0_rtx);
12004 if (GET_CODE (operands[4]) == SCRATCH)
12005 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12006 emit_move_insn (operands[4], const1_rtx);
12008 if (GET_CODE (operands[5]) == SCRATCH)
12009 operands[5] = gen_reg_rtx (<UNS>mode);
12011 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12012 emit_insn (gen_rtx_SET (operands[5], c1));
12014 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12015 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12016 emit_move_insn (operands[0], x);
12020 [(set (attr "cost")
12021 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12023 || <CODE> == LE || <CODE> == GE
12024 || <CODE> == LEU || <CODE> == GEU")
12026 (const_string "10")))])
12028 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12031 (define_expand "eq<mode>3"
12033 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12034 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12035 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12036 (clobber (match_scratch:GPR 3 "=r"))
12037 (clobber (match_scratch:GPR 4 "=r"))])]
12040 if (TARGET_ISEL && operands[2] != const0_rtx)
12042 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12048 (define_insn_and_split "*eq<mode>3"
12049 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12050 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12051 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12052 (clobber (match_scratch:GPR 3 "=r"))
12053 (clobber (match_scratch:GPR 4 "=r"))]
12054 "!(TARGET_ISEL && operands[2] != const0_rtx)"
12057 [(set (match_dup 4)
12058 (clz:GPR (match_dup 3)))
12060 (lshiftrt:GPR (match_dup 4)
12063 operands[3] = rs6000_emit_eqne (<MODE>mode,
12064 operands[1], operands[2], operands[3]);
12066 if (GET_CODE (operands[4]) == SCRATCH)
12067 operands[4] = gen_reg_rtx (<MODE>mode);
12069 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12071 [(set (attr "length")
12072 (if_then_else (match_test "operands[2] == const0_rtx")
12074 (const_string "12")))])
12076 (define_expand "ne<mode>3"
12078 (set (match_operand:P 0 "gpc_reg_operand" "=r")
12079 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12080 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12081 (clobber (match_scratch:P 3 "=r"))
12082 (clobber (match_scratch:P 4 "=r"))
12083 (clobber (reg:P CA_REGNO))])]
12086 if (TARGET_ISEL && operands[2] != const0_rtx)
12088 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12094 (define_insn_and_split "*ne<mode>3"
12095 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12096 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12097 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12098 (clobber (match_scratch:P 3 "=r"))
12099 (clobber (match_scratch:P 4 "=r"))
12100 (clobber (reg:P CA_REGNO))]
12101 "!(TARGET_ISEL && operands[2] != const0_rtx)"
12104 [(parallel [(set (match_dup 4)
12105 (plus:P (match_dup 3)
12107 (set (reg:P CA_REGNO)
12108 (ne:P (match_dup 3)
12110 (parallel [(set (match_dup 0)
12111 (plus:P (plus:P (not:P (match_dup 4))
12114 (clobber (reg:P CA_REGNO))])]
12116 operands[3] = rs6000_emit_eqne (<MODE>mode,
12117 operands[1], operands[2], operands[3]);
12119 if (GET_CODE (operands[4]) == SCRATCH)
12120 operands[4] = gen_reg_rtx (<MODE>mode);
12122 [(set (attr "length")
12123 (if_then_else (match_test "operands[2] == const0_rtx")
12125 (const_string "12")))])
12127 (define_insn_and_split "*neg_eq_<mode>"
12128 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12129 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12130 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12131 (clobber (match_scratch:P 3 "=r"))
12132 (clobber (match_scratch:P 4 "=r"))
12133 (clobber (reg:P CA_REGNO))]
12137 [(parallel [(set (match_dup 4)
12138 (plus:P (match_dup 3)
12140 (set (reg:P CA_REGNO)
12141 (ne:P (match_dup 3)
12143 (parallel [(set (match_dup 0)
12144 (plus:P (reg:P CA_REGNO)
12146 (clobber (reg:P CA_REGNO))])]
12148 operands[3] = rs6000_emit_eqne (<MODE>mode,
12149 operands[1], operands[2], operands[3]);
12151 if (GET_CODE (operands[4]) == SCRATCH)
12152 operands[4] = gen_reg_rtx (<MODE>mode);
12154 [(set (attr "length")
12155 (if_then_else (match_test "operands[2] == const0_rtx")
12157 (const_string "12")))])
12159 (define_insn_and_split "*neg_ne_<mode>"
12160 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12161 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12162 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12163 (clobber (match_scratch:P 3 "=r"))
12164 (clobber (match_scratch:P 4 "=r"))
12165 (clobber (reg:P CA_REGNO))]
12169 [(parallel [(set (match_dup 4)
12170 (neg:P (match_dup 3)))
12171 (set (reg:P CA_REGNO)
12172 (eq:P (match_dup 3)
12174 (parallel [(set (match_dup 0)
12175 (plus:P (reg:P CA_REGNO)
12177 (clobber (reg:P CA_REGNO))])]
12179 operands[3] = rs6000_emit_eqne (<MODE>mode,
12180 operands[1], operands[2], operands[3]);
12182 if (GET_CODE (operands[4]) == SCRATCH)
12183 operands[4] = gen_reg_rtx (<MODE>mode);
12185 [(set (attr "length")
12186 (if_then_else (match_test "operands[2] == const0_rtx")
12188 (const_string "12")))])
12190 (define_insn_and_split "*plus_eq_<mode>"
12191 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12192 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12193 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12194 (match_operand:P 3 "gpc_reg_operand" "r")))
12195 (clobber (match_scratch:P 4 "=r"))
12196 (clobber (match_scratch:P 5 "=r"))
12197 (clobber (reg:P CA_REGNO))]
12201 [(parallel [(set (match_dup 5)
12202 (neg:P (match_dup 4)))
12203 (set (reg:P CA_REGNO)
12204 (eq:P (match_dup 4)
12206 (parallel [(set (match_dup 0)
12207 (plus:P (match_dup 3)
12209 (clobber (reg:P CA_REGNO))])]
12211 operands[4] = rs6000_emit_eqne (<MODE>mode,
12212 operands[1], operands[2], operands[4]);
12214 if (GET_CODE (operands[5]) == SCRATCH)
12215 operands[5] = gen_reg_rtx (<MODE>mode);
12217 [(set (attr "length")
12218 (if_then_else (match_test "operands[2] == const0_rtx")
12220 (const_string "12")))])
12222 (define_insn_and_split "*plus_ne_<mode>"
12223 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12224 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12225 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12226 (match_operand:P 3 "gpc_reg_operand" "r")))
12227 (clobber (match_scratch:P 4 "=r"))
12228 (clobber (match_scratch:P 5 "=r"))
12229 (clobber (reg:P CA_REGNO))]
12233 [(parallel [(set (match_dup 5)
12234 (plus:P (match_dup 4)
12236 (set (reg:P CA_REGNO)
12237 (ne:P (match_dup 4)
12239 (parallel [(set (match_dup 0)
12240 (plus:P (match_dup 3)
12242 (clobber (reg:P CA_REGNO))])]
12244 operands[4] = rs6000_emit_eqne (<MODE>mode,
12245 operands[1], operands[2], operands[4]);
12247 if (GET_CODE (operands[5]) == SCRATCH)
12248 operands[5] = gen_reg_rtx (<MODE>mode);
12250 [(set (attr "length")
12251 (if_then_else (match_test "operands[2] == const0_rtx")
12253 (const_string "12")))])
12255 (define_insn_and_split "*minus_eq_<mode>"
12256 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12257 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12258 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12259 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12260 (clobber (match_scratch:P 4 "=r"))
12261 (clobber (match_scratch:P 5 "=r"))
12262 (clobber (reg:P CA_REGNO))]
12266 [(parallel [(set (match_dup 5)
12267 (plus:P (match_dup 4)
12269 (set (reg:P CA_REGNO)
12270 (ne:P (match_dup 4)
12272 (parallel [(set (match_dup 0)
12273 (plus:P (plus:P (match_dup 3)
12276 (clobber (reg:P CA_REGNO))])]
12278 operands[4] = rs6000_emit_eqne (<MODE>mode,
12279 operands[1], operands[2], operands[4]);
12281 if (GET_CODE (operands[5]) == SCRATCH)
12282 operands[5] = gen_reg_rtx (<MODE>mode);
12284 [(set (attr "length")
12285 (if_then_else (match_test "operands[2] == const0_rtx")
12287 (const_string "12")))])
12289 (define_insn_and_split "*minus_ne_<mode>"
12290 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12291 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12292 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12293 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12294 (clobber (match_scratch:P 4 "=r"))
12295 (clobber (match_scratch:P 5 "=r"))
12296 (clobber (reg:P CA_REGNO))]
12300 [(parallel [(set (match_dup 5)
12301 (neg:P (match_dup 4)))
12302 (set (reg:P CA_REGNO)
12303 (eq:P (match_dup 4)
12305 (parallel [(set (match_dup 0)
12306 (plus:P (plus:P (match_dup 3)
12309 (clobber (reg:P CA_REGNO))])]
12311 operands[4] = rs6000_emit_eqne (<MODE>mode,
12312 operands[1], operands[2], operands[4]);
12314 if (GET_CODE (operands[5]) == SCRATCH)
12315 operands[5] = gen_reg_rtx (<MODE>mode);
12317 [(set (attr "length")
12318 (if_then_else (match_test "operands[2] == const0_rtx")
12320 (const_string "12")))])
12322 (define_insn_and_split "*eqsi3_ext<mode>"
12323 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12324 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12325 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12326 (clobber (match_scratch:SI 3 "=r"))
12327 (clobber (match_scratch:SI 4 "=r"))]
12331 [(set (match_dup 4)
12332 (clz:SI (match_dup 3)))
12335 (lshiftrt:SI (match_dup 4)
12338 operands[3] = rs6000_emit_eqne (SImode,
12339 operands[1], operands[2], operands[3]);
12341 if (GET_CODE (operands[4]) == SCRATCH)
12342 operands[4] = gen_reg_rtx (SImode);
12344 [(set (attr "length")
12345 (if_then_else (match_test "operands[2] == const0_rtx")
12347 (const_string "12")))])
12349 (define_insn_and_split "*nesi3_ext<mode>"
12350 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12351 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12352 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12353 (clobber (match_scratch:SI 3 "=r"))
12354 (clobber (match_scratch:SI 4 "=r"))
12355 (clobber (match_scratch:EXTSI 5 "=r"))]
12359 [(set (match_dup 4)
12360 (clz:SI (match_dup 3)))
12363 (lshiftrt:SI (match_dup 4)
12366 (xor:EXTSI (match_dup 5)
12369 operands[3] = rs6000_emit_eqne (SImode,
12370 operands[1], operands[2], operands[3]);
12372 if (GET_CODE (operands[4]) == SCRATCH)
12373 operands[4] = gen_reg_rtx (SImode);
12374 if (GET_CODE (operands[5]) == SCRATCH)
12375 operands[5] = gen_reg_rtx (<MODE>mode);
12377 [(set (attr "length")
12378 (if_then_else (match_test "operands[2] == const0_rtx")
12379 (const_string "12")
12380 (const_string "16")))])
12382 ;; Define both directions of branch and return. If we need a reload
12383 ;; register, we'd rather use CR0 since it is much easier to copy a
12384 ;; register CC value to there.
12388 (if_then_else (match_operator 1 "branch_comparison_operator"
12389 [(match_operand 2 "cc_reg_operand" "y")
12391 (label_ref (match_operand 0))
12395 return output_cbranch (operands[1], "%l0", 0, insn);
12397 [(set_attr "type" "branch")])
12401 (if_then_else (match_operator 0 "branch_comparison_operator"
12402 [(match_operand 1 "cc_reg_operand" "y")
12408 return output_cbranch (operands[0], NULL, 0, insn);
12410 [(set_attr "type" "jmpreg")
12411 (set_attr "length" "4")])
12413 ;; Logic on condition register values.
12415 ; This pattern matches things like
12416 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12417 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12419 ; which are generated by the branch logic.
12420 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12422 (define_insn "cceq_ior_compare"
12423 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12424 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12425 [(match_operator:SI 2
12426 "branch_positive_comparison_operator"
12428 "cc_reg_operand" "y,y")
12430 (match_operator:SI 4
12431 "branch_positive_comparison_operator"
12433 "cc_reg_operand" "0,y")
12437 "cr%q1 %E0,%j2,%j4"
12438 [(set_attr "type" "cr_logical")
12439 (set_attr "cr_logical_3op" "no,yes")])
12441 ; Why is the constant -1 here, but 1 in the previous pattern?
12442 ; Because ~1 has all but the low bit set.
12443 (define_insn "cceq_ior_compare_complement"
12444 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12445 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12446 [(not:SI (match_operator:SI 2
12447 "branch_positive_comparison_operator"
12449 "cc_reg_operand" "y,y")
12451 (match_operator:SI 4
12452 "branch_positive_comparison_operator"
12454 "cc_reg_operand" "0,y")
12458 "cr%q1 %E0,%j2,%j4"
12459 [(set_attr "type" "cr_logical")
12460 (set_attr "cr_logical_3op" "no,yes")])
12462 (define_insn "*cceq_rev_compare"
12463 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12464 (compare:CCEQ (match_operator:SI 1
12465 "branch_positive_comparison_operator"
12467 "cc_reg_operand" "0,y")
12472 [(set_attr "type" "cr_logical")
12473 (set_attr "cr_logical_3op" "no,yes")])
12475 ;; If we are comparing the result of two comparisons, this can be done
12476 ;; using creqv or crxor.
12478 (define_insn_and_split ""
12479 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12480 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12481 [(match_operand 2 "cc_reg_operand" "y")
12483 (match_operator 3 "branch_comparison_operator"
12484 [(match_operand 4 "cc_reg_operand" "y")
12489 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12493 int positive_1, positive_2;
12495 positive_1 = branch_positive_comparison_operator (operands[1],
12496 GET_MODE (operands[1]));
12497 positive_2 = branch_positive_comparison_operator (operands[3],
12498 GET_MODE (operands[3]));
12501 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12502 GET_CODE (operands[1])),
12504 operands[2], const0_rtx);
12505 else if (GET_MODE (operands[1]) != SImode)
12506 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12507 operands[2], const0_rtx);
12510 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12511 GET_CODE (operands[3])),
12513 operands[4], const0_rtx);
12514 else if (GET_MODE (operands[3]) != SImode)
12515 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12516 operands[4], const0_rtx);
12518 if (positive_1 == positive_2)
12520 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12521 operands[5] = constm1_rtx;
12525 operands[5] = const1_rtx;
12529 ;; Unconditional branch and return.
12531 (define_insn "jump"
12533 (label_ref (match_operand 0)))]
12536 [(set_attr "type" "branch")])
12538 (define_insn "<return_str>return"
12542 [(set_attr "type" "jmpreg")])
12544 (define_expand "indirect_jump"
12545 [(set (pc) (match_operand 0 "register_operand"))]
12548 if (!rs6000_speculate_indirect_jumps) {
12549 rtx ccreg = gen_reg_rtx (CCmode);
12550 if (Pmode == DImode)
12551 emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12553 emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12558 (define_insn "*indirect_jump<mode>"
12560 (match_operand:P 0 "register_operand" "c,*l"))]
12561 "rs6000_speculate_indirect_jumps"
12563 [(set_attr "type" "jmpreg")])
12565 (define_insn "indirect_jump<mode>_nospec"
12566 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12567 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12568 "!rs6000_speculate_indirect_jumps"
12569 "crset %E1\;beq%T0- %1\;b $"
12570 [(set_attr "type" "jmpreg")
12571 (set_attr "length" "12")])
12573 ;; Table jump for switch statements:
12574 (define_expand "tablejump"
12575 [(use (match_operand 0))
12576 (use (label_ref (match_operand 1)))]
12579 if (rs6000_speculate_indirect_jumps)
12582 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12584 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12588 rtx ccreg = gen_reg_rtx (CCmode);
12591 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12593 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12594 emit_jump_insn (jump);
12599 (define_expand "tablejumpsi"
12600 [(set (match_dup 3)
12601 (plus:SI (match_operand:SI 0)
12603 (parallel [(set (pc)
12605 (use (label_ref (match_operand 1)))])]
12606 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12608 operands[0] = force_reg (SImode, operands[0]);
12609 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12610 operands[3] = gen_reg_rtx (SImode);
12613 (define_expand "tablejumpsi_nospec"
12614 [(set (match_dup 4)
12615 (plus:SI (match_operand:SI 0)
12617 (parallel [(set (pc)
12619 (use (label_ref (match_operand 1)))
12620 (clobber (match_operand 2))])]
12621 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12623 operands[0] = force_reg (SImode, operands[0]);
12624 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12625 operands[4] = gen_reg_rtx (SImode);
12628 (define_expand "tablejumpdi"
12629 [(set (match_dup 4)
12630 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12632 (plus:DI (match_dup 4)
12634 (parallel [(set (pc)
12636 (use (label_ref (match_operand 1)))])]
12637 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12639 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12640 operands[3] = gen_reg_rtx (DImode);
12641 operands[4] = gen_reg_rtx (DImode);
12644 (define_expand "tablejumpdi_nospec"
12645 [(set (match_dup 5)
12646 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12648 (plus:DI (match_dup 5)
12650 (parallel [(set (pc)
12652 (use (label_ref (match_operand 1)))
12653 (clobber (match_operand 2))])]
12654 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12656 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12657 operands[4] = gen_reg_rtx (DImode);
12658 operands[5] = gen_reg_rtx (DImode);
12661 (define_insn "*tablejump<mode>_internal1"
12663 (match_operand:P 0 "register_operand" "c,*l"))
12664 (use (label_ref (match_operand 1)))]
12665 "rs6000_speculate_indirect_jumps"
12667 [(set_attr "type" "jmpreg")])
12669 (define_insn "*tablejump<mode>_internal1_nospec"
12671 (match_operand:P 0 "register_operand" "c,*l"))
12672 (use (label_ref (match_operand 1)))
12673 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12674 "!rs6000_speculate_indirect_jumps"
12675 "crset %E2\;beq%T0- %2\;b $"
12676 [(set_attr "type" "jmpreg")
12677 (set_attr "length" "12")])
12680 [(unspec [(const_int 0)] UNSPEC_NOP)]
12684 (define_insn "group_ending_nop"
12685 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12688 if (rs6000_tune == PROCESSOR_POWER6)
12689 return "ori 1,1,0";
12690 return "ori 2,2,0";
12693 (define_insn "rs6000_speculation_barrier"
12694 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12698 ;; Define the subtract-one-and-jump insns, starting with the template
12699 ;; so loop.c knows what to generate.
12701 (define_expand "doloop_end"
12702 [(use (match_operand 0)) ; loop pseudo
12703 (use (match_operand 1))] ; label
12708 if (GET_MODE (operands[0]) != DImode)
12710 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12714 if (GET_MODE (operands[0]) != SImode)
12716 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12721 (define_expand "ctr<mode>"
12722 [(parallel [(set (pc)
12723 (if_then_else (ne (match_operand:P 0 "register_operand")
12725 (label_ref (match_operand 1))
12728 (plus:P (match_dup 0)
12730 (clobber (match_scratch:CC 2))
12731 (clobber (match_scratch:P 3))])]
12735 ;; We need to be able to do this for any operand, including MEM, or we
12736 ;; will cause reload to blow up since we don't allow output reloads on
12738 ;; For the length attribute to be calculated correctly, the
12739 ;; label MUST be operand 0.
12740 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12741 ;; the ctr<mode> insns.
12743 (define_code_iterator eqne [eq ne])
12744 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12745 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12747 (define_insn "<bd>_<mode>"
12749 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12751 (label_ref (match_operand 0))
12753 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12754 (plus:P (match_dup 1)
12756 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12757 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12760 if (which_alternative != 0)
12762 else if (get_attr_length (insn) == 4)
12765 return "<bd_neg> $+8\;b %l0";
12767 [(set_attr "type" "branch")
12768 (set_attr "length" "*,16,20,20")])
12770 ;; Now the splitter if we could not allocate the CTR register
12773 (if_then_else (match_operator 2 "comparison_operator"
12774 [(match_operand:P 1 "gpc_reg_operand")
12777 (match_operand 6)))
12778 (set (match_operand:P 0 "nonimmediate_operand")
12779 (plus:P (match_dup 1)
12781 (clobber (match_scratch:CC 3))
12782 (clobber (match_scratch:P 4))]
12785 (if_then_else (match_dup 7)
12789 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12791 emit_insn (gen_rtx_SET (operands[3],
12792 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12793 if (gpc_reg_operand (operands[0], <MODE>mode))
12794 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12797 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12798 emit_move_insn (operands[0], operands[4]);
12800 /* No DONE so branch comes from the pattern. */
12803 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12804 ;; Note that in the case of long branches we have to decompose this into
12805 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12806 ;; and the CR bit, which means there is no way to conveniently invert the
12807 ;; comparison as is done with plain bdnz/bdz.
12809 (define_insn "<bd>tf_<mode>"
12813 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12815 (match_operator 3 "branch_comparison_operator"
12816 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12818 (label_ref (match_operand 0))
12820 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12821 (plus:P (match_dup 1)
12823 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12824 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12825 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12828 if (which_alternative != 0)
12830 else if (get_attr_length (insn) == 4)
12832 if (branch_positive_comparison_operator (operands[3],
12833 GET_MODE (operands[3])))
12834 return "<bd>t %j3,%l0";
12836 return "<bd>f %j3,%l0";
12840 static char seq[96];
12841 char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12842 sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12846 [(set_attr "type" "branch")
12847 (set_attr "length" "*,16,20,20")])
12849 ;; Now the splitter if we could not allocate the CTR register
12854 (match_operator 1 "comparison_operator"
12855 [(match_operand:P 0 "gpc_reg_operand")
12857 (match_operator 3 "branch_comparison_operator"
12858 [(match_operand 2 "cc_reg_operand")
12861 (match_operand 5)))
12862 (set (match_operand:P 6 "int_reg_operand")
12863 (plus:P (match_dup 0)
12865 (clobber (match_scratch:P 7))
12866 (clobber (match_scratch:CC 8))
12867 (clobber (match_scratch:CCEQ 9))]
12871 rtx ctr = operands[0];
12872 rtx ctrcmp = operands[1];
12873 rtx ccin = operands[2];
12874 rtx cccmp = operands[3];
12875 rtx dst1 = operands[4];
12876 rtx dst2 = operands[5];
12877 rtx ctrout = operands[6];
12878 rtx ctrtmp = operands[7];
12879 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12880 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12882 cmpcode = reverse_condition (cmpcode);
12883 /* Generate crand/crandc here. */
12884 emit_insn (gen_rtx_SET (operands[8],
12885 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12886 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12888 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12890 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12891 operands[8], cccmp, ccin));
12893 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12894 operands[8], cccmp, ccin));
12895 if (gpc_reg_operand (operands[0], <MODE>mode))
12896 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12899 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12900 emit_move_insn (ctrout, ctrtmp);
12902 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12903 emit_jump_insn (gen_rtx_SET (pc_rtx,
12904 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12910 (define_insn "trap"
12911 [(trap_if (const_int 1) (const_int 0))]
12914 [(set_attr "type" "trap")])
12916 (define_expand "ctrap<mode>4"
12917 [(trap_if (match_operator 0 "ordered_comparison_operator"
12918 [(match_operand:GPR 1 "register_operand")
12919 (match_operand:GPR 2 "reg_or_short_operand")])
12920 (match_operand 3 "zero_constant" ""))]
12925 [(trap_if (match_operator 0 "ordered_comparison_operator"
12926 [(match_operand:GPR 1 "register_operand" "r")
12927 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12930 "t<wd>%V0%I2 %1,%2"
12931 [(set_attr "type" "trap")])
12933 ;; Insns related to generating the function prologue and epilogue.
12935 (define_expand "prologue"
12936 [(use (const_int 0))]
12939 rs6000_emit_prologue ();
12940 if (!TARGET_SCHED_PROLOG)
12941 emit_insn (gen_blockage ());
12945 (define_insn "*movesi_from_cr_one"
12946 [(match_parallel 0 "mfcr_operation"
12947 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12948 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12949 (match_operand 3 "immediate_operand" "n")]
12950 UNSPEC_MOVESI_FROM_CR))])]
12956 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12958 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12959 operands[4] = GEN_INT (mask);
12960 output_asm_insn (\"mfcr %1,%4\", operands);
12964 [(set_attr "type" "mfcrf")])
12966 ;; Don't include the volatile CRs since their values are not used wrt CR save
12967 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12968 ;; prologue past an insn (early exit test) that defines a register used in the
12970 (define_insn "prologue_movesi_from_cr"
12971 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12972 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12973 (reg:CC CR4_REGNO)]
12974 UNSPEC_MOVESI_FROM_CR))]
12977 [(set_attr "type" "mfcr")])
12979 (define_insn "*crsave"
12980 [(match_parallel 0 "crsave_operation"
12981 [(set (match_operand:SI 1 "memory_operand" "=m")
12982 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12985 [(set_attr "type" "store")])
12987 (define_insn "*stmw"
12988 [(match_parallel 0 "stmw_operation"
12989 [(set (match_operand:SI 1 "memory_operand" "=m")
12990 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12993 [(set_attr "type" "store")
12994 (set_attr "update" "yes")
12995 (set_attr "indexed" "yes")])
12997 ; The following comment applies to:
13001 ; return_and_restore_gpregs*
13002 ; return_and_restore_fpregs*
13003 ; return_and_restore_fpregs_aix*
13005 ; The out-of-line save / restore functions expects one input argument.
13006 ; Since those are not standard call_insn's, we must avoid using
13007 ; MATCH_OPERAND for that argument. That way the register rename
13008 ; optimization will not try to rename this register.
13009 ; Each pattern is repeated for each possible register number used in
13010 ; various ABIs (r11, r1, and for some functions r12)
13012 (define_insn "*save_gpregs_<mode>_r11"
13013 [(match_parallel 0 "any_parallel_operand"
13014 [(clobber (reg:P LR_REGNO))
13015 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13017 (set (match_operand:P 2 "memory_operand" "=m")
13018 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13021 [(set_attr "type" "branch")
13022 (set_attr "length" "4")])
13024 (define_insn "*save_gpregs_<mode>_r12"
13025 [(match_parallel 0 "any_parallel_operand"
13026 [(clobber (reg:P LR_REGNO))
13027 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13029 (set (match_operand:P 2 "memory_operand" "=m")
13030 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13033 [(set_attr "type" "branch")
13034 (set_attr "length" "4")])
13036 (define_insn "*save_gpregs_<mode>_r1"
13037 [(match_parallel 0 "any_parallel_operand"
13038 [(clobber (reg:P LR_REGNO))
13039 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13041 (set (match_operand:P 2 "memory_operand" "=m")
13042 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13045 [(set_attr "type" "branch")
13046 (set_attr "length" "4")])
13048 (define_insn "*save_fpregs_<mode>_r11"
13049 [(match_parallel 0 "any_parallel_operand"
13050 [(clobber (reg:P LR_REGNO))
13051 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13053 (set (match_operand:DF 2 "memory_operand" "=m")
13054 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13057 [(set_attr "type" "branch")
13058 (set_attr "length" "4")])
13060 (define_insn "*save_fpregs_<mode>_r12"
13061 [(match_parallel 0 "any_parallel_operand"
13062 [(clobber (reg:P LR_REGNO))
13063 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13065 (set (match_operand:DF 2 "memory_operand" "=m")
13066 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13069 [(set_attr "type" "branch")
13070 (set_attr "length" "4")])
13072 (define_insn "*save_fpregs_<mode>_r1"
13073 [(match_parallel 0 "any_parallel_operand"
13074 [(clobber (reg:P LR_REGNO))
13075 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13077 (set (match_operand:DF 2 "memory_operand" "=m")
13078 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13081 [(set_attr "type" "branch")
13082 (set_attr "length" "4")])
13084 ; This is to explain that changes to the stack pointer should
13085 ; not be moved over loads from or stores to stack memory.
13086 (define_insn "stack_tie"
13087 [(match_parallel 0 "tie_operand"
13088 [(set (mem:BLK (reg 1)) (const_int 0))])]
13091 [(set_attr "length" "0")])
13093 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13094 ; stay behind all restores from the stack, it cannot be reordered to before
13095 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
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 (scratch)) (const_int 0))]
13105 [(set_attr "type" "*,add")])
13107 (define_expand "epilogue"
13108 [(use (const_int 0))]
13111 if (!TARGET_SCHED_PROLOG)
13112 emit_insn (gen_blockage ());
13113 rs6000_emit_epilogue (FALSE);
13117 ; On some processors, doing the mtcrf one CC register at a time is
13118 ; faster (like on the 604e). On others, doing them all at once is
13119 ; faster; for instance, on the 601 and 750.
13121 (define_expand "movsi_to_cr_one"
13122 [(set (match_operand:CC 0 "cc_reg_operand" "")
13123 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13124 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13126 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13128 (define_insn "*movsi_to_cr"
13129 [(match_parallel 0 "mtcrf_operation"
13130 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13131 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13132 (match_operand 3 "immediate_operand" "n")]
13133 UNSPEC_MOVESI_TO_CR))])]
13139 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13140 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13141 operands[4] = GEN_INT (mask);
13142 return \"mtcrf %4,%2\";
13144 [(set_attr "type" "mtcr")])
13146 (define_insn "*mtcrfsi"
13147 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13148 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13149 (match_operand 2 "immediate_operand" "n")]
13150 UNSPEC_MOVESI_TO_CR))]
13151 "GET_CODE (operands[0]) == REG
13152 && CR_REGNO_P (REGNO (operands[0]))
13153 && GET_CODE (operands[2]) == CONST_INT
13154 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13156 [(set_attr "type" "mtcr")])
13158 ; The load-multiple instructions have similar properties.
13159 ; Note that "load_multiple" is a name known to the machine-independent
13160 ; code that actually corresponds to the PowerPC load-string.
13162 (define_insn "*lmw"
13163 [(match_parallel 0 "lmw_operation"
13164 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13165 (match_operand:SI 2 "memory_operand" "m"))])]
13168 [(set_attr "type" "load")
13169 (set_attr "update" "yes")
13170 (set_attr "indexed" "yes")
13171 (set_attr "cell_micro" "always")])
13173 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13174 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13176 ; The following comment applies to:
13180 ; return_and_restore_gpregs*
13181 ; return_and_restore_fpregs*
13182 ; return_and_restore_fpregs_aix*
13184 ; The out-of-line save / restore functions expects one input argument.
13185 ; Since those are not standard call_insn's, we must avoid using
13186 ; MATCH_OPERAND for that argument. That way the register rename
13187 ; optimization will not try to rename this register.
13188 ; Each pattern is repeated for each possible register number used in
13189 ; various ABIs (r11, r1, and for some functions r12)
13191 (define_insn "*restore_gpregs_<mode>_r11"
13192 [(match_parallel 0 "any_parallel_operand"
13193 [(clobber (reg:P LR_REGNO))
13194 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13196 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13197 (match_operand:P 3 "memory_operand" "m"))])]
13200 [(set_attr "type" "branch")
13201 (set_attr "length" "4")])
13203 (define_insn "*restore_gpregs_<mode>_r12"
13204 [(match_parallel 0 "any_parallel_operand"
13205 [(clobber (reg:P LR_REGNO))
13206 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13208 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13209 (match_operand:P 3 "memory_operand" "m"))])]
13212 [(set_attr "type" "branch")
13213 (set_attr "length" "4")])
13215 (define_insn "*restore_gpregs_<mode>_r1"
13216 [(match_parallel 0 "any_parallel_operand"
13217 [(clobber (reg:P LR_REGNO))
13218 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13220 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13221 (match_operand:P 3 "memory_operand" "m"))])]
13224 [(set_attr "type" "branch")
13225 (set_attr "length" "4")])
13227 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13228 [(match_parallel 0 "any_parallel_operand"
13230 (clobber (reg:P LR_REGNO))
13231 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13233 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13234 (match_operand:P 3 "memory_operand" "m"))])]
13237 [(set_attr "type" "branch")
13238 (set_attr "length" "4")])
13240 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13241 [(match_parallel 0 "any_parallel_operand"
13243 (clobber (reg:P LR_REGNO))
13244 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13246 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13247 (match_operand:P 3 "memory_operand" "m"))])]
13250 [(set_attr "type" "branch")
13251 (set_attr "length" "4")])
13253 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13254 [(match_parallel 0 "any_parallel_operand"
13256 (clobber (reg:P LR_REGNO))
13257 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13259 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13260 (match_operand:P 3 "memory_operand" "m"))])]
13263 [(set_attr "type" "branch")
13264 (set_attr "length" "4")])
13266 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13267 [(match_parallel 0 "any_parallel_operand"
13269 (clobber (reg:P LR_REGNO))
13270 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13272 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13273 (match_operand:DF 3 "memory_operand" "m"))])]
13276 [(set_attr "type" "branch")
13277 (set_attr "length" "4")])
13279 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13280 [(match_parallel 0 "any_parallel_operand"
13282 (clobber (reg:P LR_REGNO))
13283 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13285 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13286 (match_operand:DF 3 "memory_operand" "m"))])]
13289 [(set_attr "type" "branch")
13290 (set_attr "length" "4")])
13292 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13293 [(match_parallel 0 "any_parallel_operand"
13295 (clobber (reg:P LR_REGNO))
13296 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13298 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13299 (match_operand:DF 3 "memory_operand" "m"))])]
13302 [(set_attr "type" "branch")
13303 (set_attr "length" "4")])
13305 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13306 [(match_parallel 0 "any_parallel_operand"
13308 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13310 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13311 (match_operand:DF 3 "memory_operand" "m"))])]
13314 [(set_attr "type" "branch")
13315 (set_attr "length" "4")])
13317 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13318 [(match_parallel 0 "any_parallel_operand"
13320 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13322 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13323 (match_operand:DF 3 "memory_operand" "m"))])]
13326 [(set_attr "type" "branch")
13327 (set_attr "length" "4")])
13329 ; This is used in compiling the unwind routines.
13330 (define_expand "eh_return"
13331 [(use (match_operand 0 "general_operand" ""))]
13336 emit_insn (gen_eh_set_lr_si (operands[0]));
13338 emit_insn (gen_eh_set_lr_di (operands[0]));
13342 ; We can't expand this before we know where the link register is stored.
13343 (define_insn "eh_set_lr_<mode>"
13344 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13346 (clobber (match_scratch:P 1 "=&b"))]
13351 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13352 (clobber (match_scratch 1 ""))]
13357 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13361 (define_insn "prefetch"
13362 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13363 (match_operand:SI 1 "const_int_operand" "n")
13364 (match_operand:SI 2 "const_int_operand" "n"))]
13368 if (GET_CODE (operands[0]) == REG)
13369 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13370 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13372 [(set_attr "type" "load")])
13374 ;; Handle -fsplit-stack.
13376 (define_expand "split_stack_prologue"
13380 rs6000_expand_split_stack_prologue ();
13384 (define_expand "load_split_stack_limit"
13385 [(set (match_operand 0)
13386 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13389 emit_insn (gen_rtx_SET (operands[0],
13390 gen_rtx_UNSPEC (Pmode,
13391 gen_rtvec (1, const0_rtx),
13392 UNSPEC_STACK_CHECK)));
13396 (define_insn "load_split_stack_limit_di"
13397 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13398 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13400 "ld %0,-0x7040(13)"
13401 [(set_attr "type" "load")
13402 (set_attr "update" "no")
13403 (set_attr "indexed" "no")])
13405 (define_insn "load_split_stack_limit_si"
13406 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13407 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13409 "lwz %0,-0x7020(2)"
13410 [(set_attr "type" "load")
13411 (set_attr "update" "no")
13412 (set_attr "indexed" "no")])
13414 ;; A return instruction which the middle-end doesn't see.
13415 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13416 ;; after the call to __morestack.
13417 (define_insn "split_stack_return"
13418 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13421 [(set_attr "type" "jmpreg")])
13423 ;; If there are operand 0 bytes available on the stack, jump to
13425 (define_expand "split_stack_space_check"
13426 [(set (match_dup 2)
13427 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13429 (minus (reg STACK_POINTER_REGNUM)
13430 (match_operand 0)))
13431 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13432 (set (pc) (if_then_else
13433 (geu (match_dup 4) (const_int 0))
13434 (label_ref (match_operand 1))
13438 rs6000_split_stack_space_check (operands[0], operands[1]);
13442 (define_insn "bpermd_<mode>"
13443 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13444 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13445 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13448 [(set_attr "type" "popcnt")])
13451 ;; Builtin fma support. Handle
13452 ;; Note that the conditions for expansion are in the FMA_F iterator.
13454 (define_expand "fma<mode>4"
13455 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13457 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13458 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13459 (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13463 (define_insn "*fma<mode>4_fpr"
13464 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13466 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13467 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13468 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13469 "TARGET_<MODE>_FPR"
13471 fmadd<Ftrad> %0,%1,%2,%3
13472 xsmadda<Fvsx> %x0,%x1,%x2
13473 xsmaddm<Fvsx> %x0,%x1,%x3"
13474 [(set_attr "type" "fp")
13475 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13477 ; Altivec only has fma and nfms.
13478 (define_expand "fms<mode>4"
13479 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13481 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13482 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13483 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13484 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13487 (define_insn "*fms<mode>4_fpr"
13488 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13490 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13491 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13492 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13493 "TARGET_<MODE>_FPR"
13495 fmsub<Ftrad> %0,%1,%2,%3
13496 xsmsuba<Fvsx> %x0,%x1,%x2
13497 xsmsubm<Fvsx> %x0,%x1,%x3"
13498 [(set_attr "type" "fp")
13499 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13501 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13502 (define_expand "fnma<mode>4"
13503 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13506 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13507 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13508 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13509 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13512 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13513 (define_expand "fnms<mode>4"
13514 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13517 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13518 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13519 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13520 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13523 ; Not an official optab name, but used from builtins.
13524 (define_expand "nfma<mode>4"
13525 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13528 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13529 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13530 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13531 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13534 (define_insn "*nfma<mode>4_fpr"
13535 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13538 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13539 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13540 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13541 "TARGET_<MODE>_FPR"
13543 fnmadd<Ftrad> %0,%1,%2,%3
13544 xsnmadda<Fvsx> %x0,%x1,%x2
13545 xsnmaddm<Fvsx> %x0,%x1,%x3"
13546 [(set_attr "type" "fp")
13547 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13549 ; Not an official optab name, but used from builtins.
13550 (define_expand "nfms<mode>4"
13551 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13554 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13555 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13556 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13560 (define_insn "*nfmssf4_fpr"
13561 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13564 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13565 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13567 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13568 "TARGET_<MODE>_FPR"
13570 fnmsub<Ftrad> %0,%1,%2,%3
13571 xsnmsuba<Fvsx> %x0,%x1,%x2
13572 xsnmsubm<Fvsx> %x0,%x1,%x3"
13573 [(set_attr "type" "fp")
13574 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13577 (define_expand "rs6000_get_timebase"
13578 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13581 if (TARGET_POWERPC64)
13582 emit_insn (gen_rs6000_mftb_di (operands[0]));
13584 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13588 (define_insn "rs6000_get_timebase_ppc32"
13589 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13590 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13591 (clobber (match_scratch:SI 1 "=r"))
13592 (clobber (match_scratch:CC 2 "=y"))]
13593 "!TARGET_POWERPC64"
13595 if (WORDS_BIG_ENDIAN)
13598 return "mfspr %0,269\;"
13606 return "mftbu %0\;"
13615 return "mfspr %L0,269\;"
13623 return "mftbu %L0\;"
13630 [(set_attr "length" "20")])
13632 (define_insn "rs6000_mftb_<mode>"
13633 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13634 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13638 return "mfspr %0,268";
13644 (define_insn "rs6000_mffs"
13645 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13646 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13647 "TARGET_HARD_FLOAT"
13650 (define_insn "rs6000_mtfsf"
13651 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13652 (match_operand:DF 1 "gpc_reg_operand" "d")]
13654 "TARGET_HARD_FLOAT"
13658 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13659 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13660 ;; register that is being loaded. The fused ops must be physically adjacent.
13662 ;; There are two parts to addis fusion. The support for fused TOCs occur
13663 ;; before register allocation, and is meant to reduce the lifetime for the
13664 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13665 ;; to use the register that is being load. The peephole2 then gathers any
13666 ;; other fused possibilities that it can find after register allocation. If
13667 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13669 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13670 ;; before register allocation, so that we can avoid allocating a temporary base
13671 ;; register that won't be used, and that we try to load into base registers,
13672 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13673 ;; (addis followed by load) even on power8.
13676 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13677 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13678 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13679 [(parallel [(set (match_dup 0) (match_dup 2))
13680 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13681 (use (match_dup 3))
13682 (clobber (scratch:DI))])]
13684 operands[2] = fusion_wrap_memory_address (operands[1]);
13685 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13688 (define_insn "*toc_fusionload_<mode>"
13689 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13690 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13691 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13692 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13693 (clobber (match_scratch:DI 3 "=X,&b"))]
13694 "TARGET_TOC_FUSION_INT"
13696 if (base_reg_operand (operands[0], <MODE>mode))
13697 return emit_fusion_gpr_load (operands[0], operands[1]);
13699 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13701 [(set_attr "type" "load")
13702 (set_attr "length" "8")])
13704 (define_insn "*toc_fusionload_di"
13705 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13706 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13707 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13708 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13709 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13710 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13711 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13713 if (base_reg_operand (operands[0], DImode))
13714 return emit_fusion_gpr_load (operands[0], operands[1]);
13716 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13718 [(set_attr "type" "load")
13719 (set_attr "length" "8")])
13722 ;; Find cases where the addis that feeds into a load instruction is either used
13723 ;; once or is the same as the target register, and replace it with the fusion
13727 [(set (match_operand:P 0 "base_reg_operand" "")
13728 (match_operand:P 1 "fusion_gpr_addis" ""))
13729 (set (match_operand:INT1 2 "base_reg_operand" "")
13730 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13732 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13736 expand_fusion_gpr_load (operands);
13740 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13743 (define_insn "fusion_gpr_load_<mode>"
13744 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13745 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13746 UNSPEC_FUSION_GPR))]
13749 return emit_fusion_gpr_load (operands[0], operands[1]);
13751 [(set_attr "type" "load")
13752 (set_attr "length" "8")])
13755 ;; ISA 3.0 (power9) fusion support
13756 ;; Merge addis with floating load/store to FPRs (or GPRs).
13758 [(set (match_operand:P 0 "base_reg_operand" "")
13759 (match_operand:P 1 "fusion_gpr_addis" ""))
13760 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13761 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13762 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13763 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13766 expand_fusion_p9_load (operands);
13771 [(set (match_operand:P 0 "base_reg_operand" "")
13772 (match_operand:P 1 "fusion_gpr_addis" ""))
13773 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13774 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13775 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13776 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13777 && !rtx_equal_p (operands[0], operands[3])"
13780 expand_fusion_p9_store (operands);
13785 [(set (match_operand:SDI 0 "int_reg_operand" "")
13786 (match_operand:SDI 1 "upper16_cint_operand" ""))
13788 (ior:SDI (match_dup 0)
13789 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13791 [(set (match_dup 0)
13792 (unspec:SDI [(match_dup 1)
13793 (match_dup 2)] UNSPEC_FUSION_P9))])
13796 [(set (match_operand:SDI 0 "int_reg_operand" "")
13797 (match_operand:SDI 1 "upper16_cint_operand" ""))
13798 (set (match_operand:SDI 2 "int_reg_operand" "")
13799 (ior:SDI (match_dup 0)
13800 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13802 && !rtx_equal_p (operands[0], operands[2])
13803 && peep2_reg_dead_p (2, operands[0])"
13804 [(set (match_dup 2)
13805 (unspec:SDI [(match_dup 1)
13806 (match_dup 3)] UNSPEC_FUSION_P9))])
13808 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13809 ;; reload). Because we want to eventually have secondary_reload generate
13810 ;; these, they have to have a single alternative that gives the register
13811 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13812 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13813 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13815 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13817 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13820 /* This insn is a secondary reload insn, which cannot have alternatives.
13821 If we are not loading up register 0, use the power8 fusion instead. */
13822 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13823 return emit_fusion_gpr_load (operands[0], operands[1]);
13825 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13827 [(set_attr "type" "load")
13828 (set_attr "length" "8")])
13830 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13831 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13833 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13835 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13838 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13840 [(set_attr "type" "store")
13841 (set_attr "length" "8")])
13843 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13844 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13846 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13848 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13851 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13853 [(set_attr "type" "fpload")
13854 (set_attr "length" "8")])
13856 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13857 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13859 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13861 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13864 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13866 [(set_attr "type" "fpstore")
13867 (set_attr "length" "8")])
13869 (define_insn "*fusion_p9_<mode>_constant"
13870 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13871 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13872 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13873 UNSPEC_FUSION_P9))]
13876 emit_fusion_addis (operands[0], operands[1]);
13877 return "ori %0,%0,%2";
13879 [(set_attr "type" "two")
13880 (set_attr "length" "8")])
13883 ;; Optimize cases where we want to do a D-form load (register+offset) on
13884 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13889 ;; and we change this to:
13894 [(match_scratch:P 0 "b")
13895 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13896 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13897 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13899 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13900 [(set (match_dup 0)
13905 rtx tmp_reg = operands[0];
13906 rtx mem = operands[2];
13907 rtx addr = XEXP (mem, 0);
13908 rtx add_op0, add_op1, new_addr;
13910 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13911 add_op0 = XEXP (addr, 0);
13912 add_op1 = XEXP (addr, 1);
13913 gcc_assert (REG_P (add_op0));
13914 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13916 operands[4] = add_op1;
13917 operands[5] = change_address (mem, <MODE>mode, new_addr);
13920 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13921 ;; Altivec register, and the register allocator has generated:
13925 ;; and we change this to:
13930 [(match_scratch:P 0 "b")
13931 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13932 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13933 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13935 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13936 [(set (match_dup 0)
13941 rtx tmp_reg = operands[0];
13942 rtx mem = operands[3];
13943 rtx addr = XEXP (mem, 0);
13944 rtx add_op0, add_op1, new_addr;
13946 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13947 add_op0 = XEXP (addr, 0);
13948 add_op1 = XEXP (addr, 1);
13949 gcc_assert (REG_P (add_op0));
13950 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13952 operands[4] = add_op1;
13953 operands[5] = change_address (mem, <MODE>mode, new_addr);
13957 ;; Miscellaneous ISA 2.06 (power7) instructions
13958 (define_insn "addg6s"
13959 [(set (match_operand:SI 0 "register_operand" "=r")
13960 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13961 (match_operand:SI 2 "register_operand" "r")]
13965 [(set_attr "type" "integer")
13966 (set_attr "length" "4")])
13968 (define_insn "cdtbcd"
13969 [(set (match_operand:SI 0 "register_operand" "=r")
13970 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13974 [(set_attr "type" "integer")
13975 (set_attr "length" "4")])
13977 (define_insn "cbcdtd"
13978 [(set (match_operand:SI 0 "register_operand" "=r")
13979 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13983 [(set_attr "type" "integer")
13984 (set_attr "length" "4")])
13986 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13991 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13992 (UNSPEC_DIVEO "eo")
13993 (UNSPEC_DIVEU "eu")
13994 (UNSPEC_DIVEUO "euo")])
13996 (define_insn "div<div_extend>_<mode>"
13997 [(set (match_operand:GPR 0 "register_operand" "=r")
13998 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13999 (match_operand:GPR 2 "register_operand" "r")]
14000 UNSPEC_DIV_EXTEND))]
14002 "div<wd><div_extend> %0,%1,%2"
14003 [(set_attr "type" "div")
14004 (set_attr "size" "<bits>")])
14007 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14009 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14010 (define_mode_attr FP128_64 [(TF "DF")
14015 (define_expand "unpack<mode>"
14016 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14018 [(match_operand:FMOVE128 1 "register_operand" "")
14019 (match_operand:QI 2 "const_0_to_1_operand" "")]
14020 UNSPEC_UNPACK_128BIT))]
14021 "FLOAT128_2REG_P (<MODE>mode)"
14024 (define_insn_and_split "unpack<mode>_dm"
14025 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14027 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14028 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14029 UNSPEC_UNPACK_128BIT))]
14030 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14032 "&& reload_completed"
14033 [(set (match_dup 0) (match_dup 3))]
14035 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14037 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14039 emit_note (NOTE_INSN_DELETED);
14043 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14045 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14046 (set_attr "length" "4")])
14048 (define_insn_and_split "unpack<mode>_nodm"
14049 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14051 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14052 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14053 UNSPEC_UNPACK_128BIT))]
14054 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14056 "&& reload_completed"
14057 [(set (match_dup 0) (match_dup 3))]
14059 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14061 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14063 emit_note (NOTE_INSN_DELETED);
14067 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14069 [(set_attr "type" "fp,fpstore")
14070 (set_attr "length" "4")])
14072 (define_insn_and_split "pack<mode>"
14073 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14075 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14076 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14077 UNSPEC_PACK_128BIT))]
14078 "FLOAT128_2REG_P (<MODE>mode)"
14082 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14083 [(set (match_dup 3) (match_dup 1))
14084 (set (match_dup 4) (match_dup 2))]
14086 unsigned dest_hi = REGNO (operands[0]);
14087 unsigned dest_lo = dest_hi + 1;
14089 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14090 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14092 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14093 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14095 [(set_attr "type" "fpsimple,fp")
14096 (set_attr "length" "4,8")])
14098 (define_insn "unpack<mode>"
14099 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14100 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14101 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14102 UNSPEC_UNPACK_128BIT))]
14103 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14105 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14106 return ASM_COMMENT_START " xxpermdi to same register";
14108 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14109 return "xxpermdi %x0,%x1,%x1,%3";
14111 [(set_attr "type" "vecperm")])
14113 (define_insn "pack<mode>"
14114 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14115 (unspec:FMOVE128_VSX
14116 [(match_operand:DI 1 "register_operand" "wa")
14117 (match_operand:DI 2 "register_operand" "wa")]
14118 UNSPEC_PACK_128BIT))]
14120 "xxpermdi %x0,%x1,%x2,0"
14121 [(set_attr "type" "vecperm")])
14125 ;; ISA 2.08 IEEE 128-bit floating point support.
14127 (define_insn "add<mode>3"
14128 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14130 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14131 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14132 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14134 [(set_attr "type" "vecfloat")
14135 (set_attr "size" "128")])
14137 (define_insn "sub<mode>3"
14138 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14140 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14141 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14142 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14144 [(set_attr "type" "vecfloat")
14145 (set_attr "size" "128")])
14147 (define_insn "mul<mode>3"
14148 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14150 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14151 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14152 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14154 [(set_attr "type" "qmul")
14155 (set_attr "size" "128")])
14157 (define_insn "div<mode>3"
14158 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14160 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14161 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14162 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14164 [(set_attr "type" "vecdiv")
14165 (set_attr "size" "128")])
14167 (define_insn "sqrt<mode>2"
14168 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14170 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14171 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14173 [(set_attr "type" "vecdiv")
14174 (set_attr "size" "128")])
14176 (define_expand "copysign<mode>3"
14177 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14178 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14179 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14180 "FLOAT128_IEEE_P (<MODE>mode)"
14182 if (TARGET_FLOAT128_HW)
14183 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14187 rtx tmp = gen_reg_rtx (<MODE>mode);
14188 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14189 operands[2], tmp));
14194 (define_insn "copysign<mode>3_hard"
14195 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14197 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14198 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14200 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14201 "xscpsgnqp %0,%2,%1"
14202 [(set_attr "type" "vecmove")
14203 (set_attr "size" "128")])
14205 (define_insn "copysign<mode>3_soft"
14206 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14208 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14209 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14210 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14212 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14213 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14214 [(set_attr "type" "veccomplex")
14215 (set_attr "length" "8")])
14217 (define_insn "neg<mode>2_hw"
14218 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14220 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14221 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14223 [(set_attr "type" "vecmove")
14224 (set_attr "size" "128")])
14227 (define_insn "abs<mode>2_hw"
14228 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14230 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14231 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14233 [(set_attr "type" "vecmove")
14234 (set_attr "size" "128")])
14237 (define_insn "*nabs<mode>2_hw"
14238 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14241 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14242 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14244 [(set_attr "type" "vecmove")
14245 (set_attr "size" "128")])
14247 ;; Initially don't worry about doing fusion
14248 (define_insn "fma<mode>4_hw"
14249 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14251 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14252 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14253 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14254 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14255 "xsmaddqp %0,%1,%2"
14256 [(set_attr "type" "qmul")
14257 (set_attr "size" "128")])
14259 (define_insn "*fms<mode>4_hw"
14260 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14262 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14263 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14265 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14266 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14267 "xsmsubqp %0,%1,%2"
14268 [(set_attr "type" "qmul")
14269 (set_attr "size" "128")])
14271 (define_insn "*nfma<mode>4_hw"
14272 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14275 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14276 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14277 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14278 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14279 "xsnmaddqp %0,%1,%2"
14280 [(set_attr "type" "qmul")
14281 (set_attr "size" "128")])
14283 (define_insn "*nfms<mode>4_hw"
14284 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14287 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14288 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14290 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14291 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14292 "xsnmsubqp %0,%1,%2"
14293 [(set_attr "type" "qmul")
14294 (set_attr "size" "128")])
14296 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14297 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14298 (float_extend:IEEE128
14299 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14300 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14302 [(set_attr "type" "vecfloat")
14303 (set_attr "size" "128")])
14305 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14306 ;; point is a simple copy.
14307 (define_insn_and_split "extendkftf2"
14308 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14309 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14310 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14314 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14317 emit_note (NOTE_INSN_DELETED);
14320 [(set_attr "type" "*,veclogical")
14321 (set_attr "length" "0,4")])
14323 (define_insn_and_split "trunctfkf2"
14324 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14325 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14326 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14330 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14333 emit_note (NOTE_INSN_DELETED);
14336 [(set_attr "type" "*,veclogical")
14337 (set_attr "length" "0,4")])
14339 (define_insn "trunc<mode>df2_hw"
14340 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14342 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14343 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14345 [(set_attr "type" "vecfloat")
14346 (set_attr "size" "128")])
14348 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14349 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14351 (define_insn_and_split "trunc<mode>sf2_hw"
14352 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14354 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14355 (clobber (match_scratch:DF 2 "=v"))]
14356 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14359 [(set (match_dup 2)
14360 (unspec:DF [(match_dup 1)]
14361 UNSPEC_TRUNC_ROUND_TO_ODD))
14363 (float_truncate:SF (match_dup 2)))]
14365 if (GET_CODE (operands[2]) == SCRATCH)
14366 operands[2] = gen_reg_rtx (DFmode);
14368 [(set_attr "type" "vecfloat")
14369 (set_attr "length" "8")])
14371 ;; Conversion between IEEE 128-bit and integer types
14372 (define_insn "fix_<mode>di2_hw"
14373 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14374 (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14375 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14377 [(set_attr "type" "vecfloat")
14378 (set_attr "size" "128")])
14380 (define_insn "fixuns_<mode>di2_hw"
14381 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14382 (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14383 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14385 [(set_attr "type" "vecfloat")
14386 (set_attr "size" "128")])
14388 (define_insn "fix_<mode>si2_hw"
14389 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14390 (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14391 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14393 [(set_attr "type" "vecfloat")
14394 (set_attr "size" "128")])
14396 (define_insn "fixuns_<mode>si2_hw"
14397 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14398 (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14399 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14401 [(set_attr "type" "vecfloat")
14402 (set_attr "size" "128")])
14404 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14405 ;; floating point value to 32-bit integer to GPR in order to save it.
14406 (define_insn_and_split "*fix<uns>_<mode>_mem"
14407 [(set (match_operand:SI 0 "memory_operand" "=Z")
14408 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14409 (clobber (match_scratch:SI 2 "=v"))]
14410 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14412 "&& reload_completed"
14413 [(set (match_dup 2)
14414 (any_fix:SI (match_dup 1)))
14418 (define_insn "float_<mode>di2_hw"
14419 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14420 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14421 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14423 [(set_attr "type" "vecfloat")
14424 (set_attr "size" "128")])
14426 (define_insn_and_split "float_<mode>si2_hw"
14427 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14428 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14429 (clobber (match_scratch:DI 2 "=v"))]
14430 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14433 [(set (match_dup 2)
14434 (sign_extend:DI (match_dup 1)))
14436 (float:IEEE128 (match_dup 2)))]
14438 if (GET_CODE (operands[2]) == SCRATCH)
14439 operands[2] = gen_reg_rtx (DImode);
14441 if (MEM_P (operands[1]))
14442 operands[1] = rs6000_address_for_fpconvert (operands[1]);
14445 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14446 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14447 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14448 (clobber (match_scratch:DI 2 "=X,r,X"))]
14449 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14451 "&& reload_completed"
14454 rtx dest = operands[0];
14455 rtx src = operands[1];
14456 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14458 if (altivec_register_operand (src, <QHI:MODE>mode))
14459 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14460 else if (int_reg_operand (src, <QHI:MODE>mode))
14462 rtx ext_di = operands[2];
14463 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14464 emit_move_insn (dest_di, ext_di);
14466 else if (MEM_P (src))
14468 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14469 emit_move_insn (dest_qhi, src);
14470 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14473 gcc_unreachable ();
14475 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14478 [(set_attr "length" "8,12,12")
14479 (set_attr "type" "vecfloat")
14480 (set_attr "size" "128")])
14482 (define_insn "floatuns_<mode>di2_hw"
14483 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14484 (unsigned_float:IEEE128
14485 (match_operand:DI 1 "altivec_register_operand" "v")))]
14486 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14488 [(set_attr "type" "vecfloat")
14489 (set_attr "size" "128")])
14491 (define_insn_and_split "floatuns_<mode>si2_hw"
14492 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14493 (unsigned_float:IEEE128
14494 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14495 (clobber (match_scratch:DI 2 "=v"))]
14496 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14499 [(set (match_dup 2)
14500 (zero_extend:DI (match_dup 1)))
14502 (float:IEEE128 (match_dup 2)))]
14504 if (GET_CODE (operands[2]) == SCRATCH)
14505 operands[2] = gen_reg_rtx (DImode);
14507 if (MEM_P (operands[1]))
14508 operands[1] = rs6000_address_for_fpconvert (operands[1]);
14511 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14512 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14513 (unsigned_float:IEEE128
14514 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14515 (clobber (match_scratch:DI 2 "=X,r,X"))]
14516 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14518 "&& reload_completed"
14521 rtx dest = operands[0];
14522 rtx src = operands[1];
14523 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14525 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14526 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14527 else if (int_reg_operand (src, <QHI:MODE>mode))
14529 rtx ext_di = operands[2];
14530 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14531 emit_move_insn (dest_di, ext_di);
14534 gcc_unreachable ();
14536 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14539 [(set_attr "length" "8,12,8")
14540 (set_attr "type" "vecfloat")
14541 (set_attr "size" "128")])
14543 ;; IEEE 128-bit round to integer built-in functions
14544 (define_insn "floor<mode>2"
14545 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14547 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14549 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14551 [(set_attr "type" "vecfloat")
14552 (set_attr "size" "128")])
14554 (define_insn "ceil<mode>2"
14555 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14557 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14559 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14561 [(set_attr "type" "vecfloat")
14562 (set_attr "size" "128")])
14564 (define_insn "btrunc<mode>2"
14565 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14567 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14569 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14571 [(set_attr "type" "vecfloat")
14572 (set_attr "size" "128")])
14574 (define_insn "round<mode>2"
14575 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14577 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14579 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14581 [(set_attr "type" "vecfloat")
14582 (set_attr "size" "128")])
14584 ;; IEEE 128-bit instructions with round to odd semantics
14585 (define_insn "add<mode>3_odd"
14586 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14588 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14589 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14590 UNSPEC_ADD_ROUND_TO_ODD))]
14591 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14592 "xsaddqpo %0,%1,%2"
14593 [(set_attr "type" "vecfloat")
14594 (set_attr "size" "128")])
14596 (define_insn "sub<mode>3_odd"
14597 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14599 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14600 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14601 UNSPEC_SUB_ROUND_TO_ODD))]
14602 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14603 "xssubqpo %0,%1,%2"
14604 [(set_attr "type" "vecfloat")
14605 (set_attr "size" "128")])
14607 (define_insn "mul<mode>3_odd"
14608 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14610 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14611 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14612 UNSPEC_MUL_ROUND_TO_ODD))]
14613 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14614 "xsmulqpo %0,%1,%2"
14615 [(set_attr "type" "qmul")
14616 (set_attr "size" "128")])
14618 (define_insn "div<mode>3_odd"
14619 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14621 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14622 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14623 UNSPEC_DIV_ROUND_TO_ODD))]
14624 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14625 "xsdivqpo %0,%1,%2"
14626 [(set_attr "type" "vecdiv")
14627 (set_attr "size" "128")])
14629 (define_insn "sqrt<mode>2_odd"
14630 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14632 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14633 UNSPEC_SQRT_ROUND_TO_ODD))]
14634 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14636 [(set_attr "type" "vecdiv")
14637 (set_attr "size" "128")])
14639 (define_insn "fma<mode>4_odd"
14640 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14642 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14643 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14644 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14645 UNSPEC_FMA_ROUND_TO_ODD))]
14646 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14647 "xsmaddqpo %0,%1,%2"
14648 [(set_attr "type" "qmul")
14649 (set_attr "size" "128")])
14651 (define_insn "*fms<mode>4_odd"
14652 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14654 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14655 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14657 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14658 UNSPEC_FMA_ROUND_TO_ODD))]
14659 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14660 "xsmsubqpo %0,%1,%2"
14661 [(set_attr "type" "qmul")
14662 (set_attr "size" "128")])
14664 (define_insn "*nfma<mode>4_odd"
14665 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14668 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14669 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14670 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14671 UNSPEC_FMA_ROUND_TO_ODD)))]
14672 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14673 "xsnmaddqpo %0,%1,%2"
14674 [(set_attr "type" "qmul")
14675 (set_attr "size" "128")])
14677 (define_insn "*nfms<mode>4_odd"
14678 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14681 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14682 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14684 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14685 UNSPEC_FMA_ROUND_TO_ODD)))]
14686 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14687 "xsnmsubqpo %0,%1,%2"
14688 [(set_attr "type" "qmul")
14689 (set_attr "size" "128")])
14691 (define_insn "trunc<mode>df2_odd"
14692 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14693 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14694 UNSPEC_TRUNC_ROUND_TO_ODD))]
14695 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14697 [(set_attr "type" "vecfloat")
14698 (set_attr "size" "128")])
14700 ;; IEEE 128-bit comparisons
14701 (define_insn "*cmp<mode>_hw"
14702 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14703 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14704 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14705 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14706 "xscmpuqp %0,%1,%2"
14707 [(set_attr "type" "veccmp")
14708 (set_attr "size" "128")])
14712 (include "sync.md")
14713 (include "vector.md")
14715 (include "altivec.md")
14717 (include "paired.md")
14718 (include "crypto.md")