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
141 UNSPEC_ADD_ROUND_TO_ODD
142 UNSPEC_SUB_ROUND_TO_ODD
143 UNSPEC_MUL_ROUND_TO_ODD
144 UNSPEC_DIV_ROUND_TO_ODD
145 UNSPEC_FMA_ROUND_TO_ODD
146 UNSPEC_SQRT_ROUND_TO_ODD
147 UNSPEC_TRUNC_ROUND_TO_ODD
154 ;; UNSPEC_VOLATILE usage
157 (define_c_enum "unspecv"
159 UNSPECV_LL ; load-locked
160 UNSPECV_SC ; store-conditional
161 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
162 UNSPECV_EH_RR ; eh_reg_restore
163 UNSPECV_ISYNC ; isync instruction
164 UNSPECV_MFTB ; move from time base
165 UNSPECV_NLGR ; non-local goto receiver
166 UNSPECV_MFFS ; Move from FPSCR
167 UNSPECV_MTFSF ; Move to FPSCR Fields
168 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
169 UNSPECV_SPEC_BARRIER ; Speculation barrier
173 ;; Define an insn type attribute. This is used in function unit delay
177 add,logical,shift,insert,
179 exts,cntlz,popcnt,isel,
180 load,store,fpload,fpstore,vecload,vecstore,
182 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183 cr_logical,mfcr,mfcrf,mtcr,
184 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
185 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
186 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
187 veclogical,veccmpfx,vecexts,vecmove,
189 (const_string "integer"))
191 ;; What data size does this instruction work on?
192 ;; This is used for insert, mul and others as necessary.
193 (define_attr "size" "8,16,32,64,128" (const_string "32"))
195 ;; What is the insn_cost for this insn? The target hook can still override
196 ;; this. For optimizing for size the "length" attribute is used instead.
197 (define_attr "cost" "" (const_int 0))
199 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
200 ;; This is used for add, logical, shift, exts, mul.
201 (define_attr "dot" "no,yes" (const_string "no"))
203 ;; Does this instruction sign-extend its result?
204 ;; This is used for load insns.
205 (define_attr "sign_extend" "no,yes" (const_string "no"))
207 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
208 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
210 ;; Does this instruction use indexed (that is, reg+reg) addressing?
211 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
212 ;; it is automatically set based on that. If a load or store instruction
213 ;; has fewer than two operands it needs to set this attribute manually
214 ;; or the compiler will crash.
215 (define_attr "indexed" "no,yes"
216 (if_then_else (ior (match_operand 0 "indexed_address_mem")
217 (match_operand 1 "indexed_address_mem"))
219 (const_string "no")))
221 ;; Does this instruction use update addressing?
222 ;; This is used for load and store insns. See the comments for "indexed".
223 (define_attr "update" "no,yes"
224 (if_then_else (ior (match_operand 0 "update_address_mem")
225 (match_operand 1 "update_address_mem"))
227 (const_string "no")))
229 ;; Is this instruction using operands[2] as shift amount, and can that be a
231 ;; This is used for shift insns.
232 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
234 ;; Is this instruction using a shift amount from a register?
235 ;; This is used for shift insns.
236 (define_attr "var_shift" "no,yes"
237 (if_then_else (and (eq_attr "type" "shift")
238 (eq_attr "maybe_var_shift" "yes"))
239 (if_then_else (match_operand 2 "gpc_reg_operand")
242 (const_string "no")))
244 ;; Is copying of this instruction disallowed?
245 (define_attr "cannot_copy" "no,yes" (const_string "no"))
247 ;; Length (in bytes).
248 ; '(pc)' in the following doesn't include the instruction itself; it is
249 ; calculated as if the instruction had zero size.
250 (define_attr "length" ""
251 (if_then_else (eq_attr "type" "branch")
252 (if_then_else (and (ge (minus (match_dup 0) (pc))
254 (lt (minus (match_dup 0) (pc))
260 ;; Processor type -- this attribute must exactly match the processor_type
261 ;; enumeration in rs6000-opts.h.
263 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
264 ppc750,ppc7400,ppc7450,
265 ppc403,ppc405,ppc440,ppc476,
266 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
267 power4,power5,power6,power7,power8,power9,
268 rs64a,mpccore,cell,ppca2,titan"
269 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
272 ;; If this instruction is microcoded on the CELL processor
273 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
274 (define_attr "cell_micro" "not,conditional,always"
275 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
276 (eq_attr "dot" "yes"))
277 (and (eq_attr "type" "load")
278 (eq_attr "sign_extend" "yes"))
279 (and (eq_attr "type" "shift")
280 (eq_attr "var_shift" "yes")))
281 (const_string "always")
282 (const_string "not")))
284 (automata_option "ndfa")
297 (include "e300c2c3.md")
298 (include "e500mc.md")
299 (include "e500mc64.md")
302 (include "power4.md")
303 (include "power5.md")
304 (include "power6.md")
305 (include "power7.md")
306 (include "power8.md")
307 (include "power9.md")
312 (include "predicates.md")
313 (include "constraints.md")
315 (include "darwin.md")
320 ; This mode iterator allows :GPR to be used to indicate the allowable size
321 ; of whole values in GPRs.
322 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
324 ; And again, for patterns that need two (potentially) different integer modes.
325 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
327 ; Any supported integer mode.
328 (define_mode_iterator INT [QI HI SI DI TI PTI])
330 ; Any supported integer mode that fits in one register.
331 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
333 ; Integer modes supported in VSX registers with ISA 3.0 instructions
334 (define_mode_iterator INT_ISA3 [QI HI SI DI])
336 ; Everything we can extend QImode to.
337 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
339 ; Everything we can extend HImode to.
340 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
342 ; Everything we can extend SImode to.
343 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
345 ; QImode or HImode for small integer moves and small atomic ops
346 (define_mode_iterator QHI [QI HI])
348 ; QImode, HImode, SImode for fused ops only for GPR loads
349 (define_mode_iterator QHSI [QI HI SI])
351 ; HImode or SImode for sign extended fusion ops
352 (define_mode_iterator HSI [HI SI])
354 ; SImode or DImode, even if DImode doesn't fit in GPRs.
355 (define_mode_iterator SDI [SI DI])
357 ; Types that can be fused with an ADDIS instruction to load or store a GPR
358 ; register that has reg+offset addressing.
359 (define_mode_iterator GPR_FUSION [QI
362 (DI "TARGET_POWERPC64")
364 (DF "TARGET_POWERPC64")])
366 ; Types that can be fused with an ADDIS instruction to load or store a FPR
367 ; register that has reg+offset addressing.
368 (define_mode_iterator FPR_FUSION [DI SF DF])
370 ; The size of a pointer. Also, the size of the value that a record-condition
371 ; (one with a '.') will compare; and the size used for arithmetic carries.
372 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
374 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
375 ; PTImode is GPR only)
376 (define_mode_iterator TI2 [TI PTI])
378 ; Any hardware-supported floating-point mode
379 (define_mode_iterator FP [
380 (SF "TARGET_HARD_FLOAT")
381 (DF "TARGET_HARD_FLOAT")
382 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
383 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
384 (KF "TARGET_FLOAT128_TYPE")
388 ; Any fma capable floating-point mode.
389 (define_mode_iterator FMA_F [
390 (SF "TARGET_HARD_FLOAT")
391 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
392 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
393 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
394 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
395 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
398 ; Floating point move iterators to combine binary and decimal moves
399 (define_mode_iterator FMOVE32 [SF SD])
400 (define_mode_iterator FMOVE64 [DF DD])
401 (define_mode_iterator FMOVE64X [DI DF DD])
402 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
403 (IF "FLOAT128_IBM_P (IFmode)")
404 (TD "TARGET_HARD_FLOAT")])
406 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
407 (IF "FLOAT128_2REG_P (IFmode)")
408 (TD "TARGET_HARD_FLOAT")])
410 ; Iterators for 128 bit types for direct move
411 (define_mode_iterator FMOVE128_GPR [TI
419 (KF "FLOAT128_VECTOR_P (KFmode)")
420 (TF "FLOAT128_VECTOR_P (TFmode)")])
422 ; Iterator for 128-bit VSX types for pack/unpack
423 (define_mode_iterator FMOVE128_VSX [V1TI KF])
425 ; Whether a floating point move is ok, don't allow SD without hardware FP
426 (define_mode_attr fmove_ok [(SF "")
428 (SD "TARGET_HARD_FLOAT")
431 ; Convert REAL_VALUE to the appropriate bits
432 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
433 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
434 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
435 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
437 ; Whether 0.0 has an all-zero bit pattern
438 (define_mode_attr zero_fp [(SF "j")
447 ; Definitions for 64-bit VSX
448 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
450 ; Definitions for 64-bit direct move
451 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
453 ; Definitions for 64-bit use of altivec registers
454 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
456 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
457 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
459 ; These modes do not fit in integer registers in 32-bit mode.
460 (define_mode_iterator DIFD [DI DF DD])
462 ; Iterator for reciprocal estimate instructions
463 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
465 ; Iterator for just SF/DF
466 (define_mode_iterator SFDF [SF DF])
468 ; Like SFDF, but a different name to match conditional move where the
469 ; comparison operands may be a different mode than the input operands.
470 (define_mode_iterator SFDF2 [SF DF])
472 ; Iterator for 128-bit floating point that uses the IBM double-double format
473 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
474 (TF "FLOAT128_IBM_P (TFmode)")])
476 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
477 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
478 (TF "FLOAT128_IEEE_P (TFmode)")])
480 ; Iterator for 128-bit floating point
481 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
482 (IF "TARGET_FLOAT128_TYPE")
483 (TF "TARGET_LONG_DOUBLE_128")])
485 ; Iterator for signbit on 64-bit machines with direct move
486 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
487 (TF "FLOAT128_VECTOR_P (TFmode)")])
489 ; Iterator for ISA 3.0 supported floating point types
490 (define_mode_iterator FP_ISA3 [SF DF])
492 ; SF/DF suffix for traditional floating instructions
493 (define_mode_attr Ftrad [(SF "s") (DF "")])
495 ; SF/DF suffix for VSX instructions
496 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
498 ; SF/DF constraint for arithmetic on traditional floating point registers
499 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
501 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
502 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
503 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
505 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
507 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
508 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
509 ; instructions added in ISA 2.07 (power8)
510 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
512 ; SF/DF constraint for arithmetic on altivec registers
513 (define_mode_attr Fa [(SF "wu") (DF "wv")])
515 ; s/d suffix for things like sdiv/ddiv
516 (define_mode_attr Fs [(SF "s") (DF "d")])
519 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
520 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
522 ; Conditional returns.
523 (define_code_iterator any_return [return simple_return])
524 (define_code_attr return_pred [(return "direct_return ()")
525 (simple_return "1")])
526 (define_code_attr return_str [(return "") (simple_return "simple_")])
529 (define_code_iterator iorxor [ior xor])
530 (define_code_iterator and_ior_xor [and ior xor])
532 ; Signed/unsigned variants of ops.
533 (define_code_iterator any_extend [sign_extend zero_extend])
534 (define_code_iterator any_fix [fix unsigned_fix])
535 (define_code_iterator any_float [float unsigned_float])
537 (define_code_attr u [(sign_extend "")
542 (define_code_attr su [(sign_extend "s")
547 (unsigned_float "u")])
549 (define_code_attr az [(sign_extend "a")
554 (unsigned_float "z")])
556 (define_code_attr uns [(fix "")
559 (unsigned_float "uns")])
561 ; Various instructions that come in SI and DI forms.
562 ; A generic w/d attribute, for things like cmpw/cmpd.
563 (define_mode_attr wd [(QI "b")
574 ;; How many bits in this mode?
575 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
578 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
580 ;; Bitmask for shift instructions
581 (define_mode_attr hH [(SI "h") (DI "H")])
583 ;; A mode twice the size of the given mode
584 (define_mode_attr dmode [(SI "di") (DI "ti")])
585 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
587 ;; Suffix for reload patterns
588 (define_mode_attr ptrsize [(SI "32bit")
591 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
592 (DI "TARGET_64BIT")])
594 (define_mode_attr mptrsize [(SI "si")
597 (define_mode_attr ptrload [(SI "lwz")
600 (define_mode_attr ptrm [(SI "m")
603 (define_mode_attr rreg [(SF "f")
610 (define_mode_attr rreg2 [(SF "f")
613 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
614 (DF "TARGET_FCFID")])
616 ;; Mode iterator for logical operations on 128-bit types
617 (define_mode_iterator BOOL_128 [TI
619 (V16QI "TARGET_ALTIVEC")
620 (V8HI "TARGET_ALTIVEC")
621 (V4SI "TARGET_ALTIVEC")
622 (V4SF "TARGET_ALTIVEC")
623 (V2DI "TARGET_ALTIVEC")
624 (V2DF "TARGET_ALTIVEC")
625 (V1TI "TARGET_ALTIVEC")])
627 ;; For the GPRs we use 3 constraints for register outputs, two that are the
628 ;; same as the output register, and a third where the output register is an
629 ;; early clobber, so we don't have to deal with register overlaps. For the
630 ;; vector types, we prefer to use the vector registers. For TI mode, allow
633 ;; Mode attribute for boolean operation register constraints for output
634 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
636 (V16QI "wa,v,&?r,?r,?r")
637 (V8HI "wa,v,&?r,?r,?r")
638 (V4SI "wa,v,&?r,?r,?r")
639 (V4SF "wa,v,&?r,?r,?r")
640 (V2DI "wa,v,&?r,?r,?r")
641 (V2DF "wa,v,&?r,?r,?r")
642 (V1TI "wa,v,&?r,?r,?r")])
644 ;; Mode attribute for boolean operation register constraints for operand1
645 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
653 (V1TI "wa,v,r,0,r")])
655 ;; Mode attribute for boolean operation register constraints for operand2
656 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
664 (V1TI "wa,v,r,r,0")])
666 ;; Mode attribute for boolean operation register constraints for operand1
667 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
668 ;; is used for operand1 or operand2
669 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
677 (V1TI "wa,v,r,0,0")])
679 ;; Reload iterator for creating the function to allocate a base register to
680 ;; supplement addressing modes.
681 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
682 SF SD SI DF DD DI TI PTI KF IF TF])
684 ;; Iterate over smin, smax
685 (define_code_iterator fp_minmax [smin smax])
687 (define_code_attr minmax [(smin "min")
690 (define_code_attr SMINMAX [(smin "SMIN")
693 ;; Iterator to optimize the following cases:
694 ;; D-form load to FPR register & move to Altivec register
695 ;; Move Altivec register to FPR register and store
696 (define_mode_iterator ALTIVEC_DFORM [DF
697 (SF "TARGET_P8_VECTOR")
698 (DI "TARGET_POWERPC64")])
701 ;; Start with fixed-point load and store insns. Here we put only the more
702 ;; complex forms. Basic data transfer is done later.
704 (define_insn "zero_extendqi<mode>2"
705 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
706 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
713 [(set_attr "type" "load,shift,fpload,vecperm")])
715 (define_insn_and_split "*zero_extendqi<mode>2_dot"
716 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
717 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
719 (clobber (match_scratch:EXTQI 0 "=r,r"))]
724 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
726 (zero_extend:EXTQI (match_dup 1)))
728 (compare:CC (match_dup 0)
731 [(set_attr "type" "logical")
732 (set_attr "dot" "yes")
733 (set_attr "length" "4,8")])
735 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
736 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
737 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
739 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
740 (zero_extend:EXTQI (match_dup 1)))]
745 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
747 (zero_extend:EXTQI (match_dup 1)))
749 (compare:CC (match_dup 0)
752 [(set_attr "type" "logical")
753 (set_attr "dot" "yes")
754 (set_attr "length" "4,8")])
757 (define_insn "zero_extendhi<mode>2"
758 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
759 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
763 rlwinm %0,%1,0,0xffff
766 [(set_attr "type" "load,shift,fpload,vecperm")])
768 (define_insn_and_split "*zero_extendhi<mode>2_dot"
769 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
770 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
772 (clobber (match_scratch:EXTHI 0 "=r,r"))]
777 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
779 (zero_extend:EXTHI (match_dup 1)))
781 (compare:CC (match_dup 0)
784 [(set_attr "type" "logical")
785 (set_attr "dot" "yes")
786 (set_attr "length" "4,8")])
788 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
789 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
790 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
792 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
793 (zero_extend:EXTHI (match_dup 1)))]
798 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
800 (zero_extend:EXTHI (match_dup 1)))
802 (compare:CC (match_dup 0)
805 [(set_attr "type" "logical")
806 (set_attr "dot" "yes")
807 (set_attr "length" "4,8")])
810 (define_insn "zero_extendsi<mode>2"
811 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
812 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
821 xxextractuw %x0,%x1,4"
822 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
824 (define_insn_and_split "*zero_extendsi<mode>2_dot"
825 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
826 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
828 (clobber (match_scratch:EXTSI 0 "=r,r"))]
833 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
835 (zero_extend:DI (match_dup 1)))
837 (compare:CC (match_dup 0)
840 [(set_attr "type" "shift")
841 (set_attr "dot" "yes")
842 (set_attr "length" "4,8")])
844 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
845 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
846 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
848 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
849 (zero_extend:EXTSI (match_dup 1)))]
854 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
856 (zero_extend:EXTSI (match_dup 1)))
858 (compare:CC (match_dup 0)
861 [(set_attr "type" "shift")
862 (set_attr "dot" "yes")
863 (set_attr "length" "4,8")])
866 (define_insn "extendqi<mode>2"
867 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
868 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
873 [(set_attr "type" "exts,vecperm")])
875 (define_insn_and_split "*extendqi<mode>2_dot"
876 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
877 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
879 (clobber (match_scratch:EXTQI 0 "=r,r"))]
884 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
886 (sign_extend:EXTQI (match_dup 1)))
888 (compare:CC (match_dup 0)
891 [(set_attr "type" "exts")
892 (set_attr "dot" "yes")
893 (set_attr "length" "4,8")])
895 (define_insn_and_split "*extendqi<mode>2_dot2"
896 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
897 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
899 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
900 (sign_extend:EXTQI (match_dup 1)))]
905 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
907 (sign_extend:EXTQI (match_dup 1)))
909 (compare:CC (match_dup 0)
912 [(set_attr "type" "exts")
913 (set_attr "dot" "yes")
914 (set_attr "length" "4,8")])
917 (define_expand "extendhi<mode>2"
918 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
919 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
923 (define_insn "*extendhi<mode>2"
924 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
925 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
932 [(set_attr "type" "load,exts,fpload,vecperm")
933 (set_attr "sign_extend" "yes")
934 (set_attr "length" "4,4,8,4")])
937 [(set (match_operand:EXTHI 0 "altivec_register_operand")
939 (match_operand:HI 1 "indexed_or_indirect_operand")))]
940 "TARGET_P9_VECTOR && reload_completed"
944 (sign_extend:EXTHI (match_dup 2)))]
946 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
949 (define_insn_and_split "*extendhi<mode>2_dot"
950 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
951 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
953 (clobber (match_scratch:EXTHI 0 "=r,r"))]
958 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
960 (sign_extend:EXTHI (match_dup 1)))
962 (compare:CC (match_dup 0)
965 [(set_attr "type" "exts")
966 (set_attr "dot" "yes")
967 (set_attr "length" "4,8")])
969 (define_insn_and_split "*extendhi<mode>2_dot2"
970 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
971 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
973 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
974 (sign_extend:EXTHI (match_dup 1)))]
979 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
981 (sign_extend:EXTHI (match_dup 1)))
983 (compare:CC (match_dup 0)
986 [(set_attr "type" "exts")
987 (set_attr "dot" "yes")
988 (set_attr "length" "4,8")])
991 (define_insn "extendsi<mode>2"
992 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
993 "=r, r, wl, wu, wj, wK, wH, wr")
995 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
996 "Y, r, Z, Z, r, wK, wH, ?wIwH")))]
1007 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1008 (set_attr "sign_extend" "yes")
1009 (set_attr "length" "4,4,4,4,4,4,8,8")])
1012 [(set (match_operand:EXTSI 0 "int_reg_operand")
1013 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1014 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1018 (sign_extend:DI (match_dup 2)))]
1020 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1024 [(set (match_operand:DI 0 "altivec_register_operand")
1025 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1026 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1029 rtx dest = operands[0];
1030 rtx src = operands[1];
1031 int dest_regno = REGNO (dest);
1032 int src_regno = REGNO (src);
1033 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1034 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1036 if (BYTES_BIG_ENDIAN)
1038 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1039 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1043 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1044 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1049 (define_insn_and_split "*extendsi<mode>2_dot"
1050 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1051 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1053 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1058 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1060 (sign_extend:EXTSI (match_dup 1)))
1062 (compare:CC (match_dup 0)
1065 [(set_attr "type" "exts")
1066 (set_attr "dot" "yes")
1067 (set_attr "length" "4,8")])
1069 (define_insn_and_split "*extendsi<mode>2_dot2"
1070 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1071 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1073 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1074 (sign_extend:EXTSI (match_dup 1)))]
1079 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1081 (sign_extend:EXTSI (match_dup 1)))
1083 (compare:CC (match_dup 0)
1086 [(set_attr "type" "exts")
1087 (set_attr "dot" "yes")
1088 (set_attr "length" "4,8")])
1090 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1092 (define_insn "*macchwc"
1093 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1094 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1095 (match_operand:SI 2 "gpc_reg_operand" "r")
1098 (match_operand:HI 1 "gpc_reg_operand" "r")))
1099 (match_operand:SI 4 "gpc_reg_operand" "0"))
1101 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1102 (plus:SI (mult:SI (ashiftrt:SI
1110 [(set_attr "type" "halfmul")])
1112 (define_insn "*macchw"
1113 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1114 (plus:SI (mult:SI (ashiftrt:SI
1115 (match_operand:SI 2 "gpc_reg_operand" "r")
1118 (match_operand:HI 1 "gpc_reg_operand" "r")))
1119 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1122 [(set_attr "type" "halfmul")])
1124 (define_insn "*macchwuc"
1125 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1126 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1127 (match_operand:SI 2 "gpc_reg_operand" "r")
1130 (match_operand:HI 1 "gpc_reg_operand" "r")))
1131 (match_operand:SI 4 "gpc_reg_operand" "0"))
1133 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1134 (plus:SI (mult:SI (lshiftrt:SI
1142 [(set_attr "type" "halfmul")])
1144 (define_insn "*macchwu"
1145 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1146 (plus:SI (mult:SI (lshiftrt:SI
1147 (match_operand:SI 2 "gpc_reg_operand" "r")
1150 (match_operand:HI 1 "gpc_reg_operand" "r")))
1151 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1154 [(set_attr "type" "halfmul")])
1156 (define_insn "*machhwc"
1157 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1158 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1159 (match_operand:SI 1 "gpc_reg_operand" "%r")
1162 (match_operand:SI 2 "gpc_reg_operand" "r")
1164 (match_operand:SI 4 "gpc_reg_operand" "0"))
1166 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1167 (plus:SI (mult:SI (ashiftrt:SI
1176 [(set_attr "type" "halfmul")])
1178 (define_insn "*machhw"
1179 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1180 (plus:SI (mult:SI (ashiftrt:SI
1181 (match_operand:SI 1 "gpc_reg_operand" "%r")
1184 (match_operand:SI 2 "gpc_reg_operand" "r")
1186 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1189 [(set_attr "type" "halfmul")])
1191 (define_insn "*machhwuc"
1192 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1193 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1194 (match_operand:SI 1 "gpc_reg_operand" "%r")
1197 (match_operand:SI 2 "gpc_reg_operand" "r")
1199 (match_operand:SI 4 "gpc_reg_operand" "0"))
1201 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1202 (plus:SI (mult:SI (lshiftrt:SI
1211 [(set_attr "type" "halfmul")])
1213 (define_insn "*machhwu"
1214 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1215 (plus:SI (mult:SI (lshiftrt:SI
1216 (match_operand:SI 1 "gpc_reg_operand" "%r")
1219 (match_operand:SI 2 "gpc_reg_operand" "r")
1221 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1224 [(set_attr "type" "halfmul")])
1226 (define_insn "*maclhwc"
1227 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1228 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1229 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1231 (match_operand:HI 2 "gpc_reg_operand" "r")))
1232 (match_operand:SI 4 "gpc_reg_operand" "0"))
1234 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235 (plus:SI (mult:SI (sign_extend:SI
1242 [(set_attr "type" "halfmul")])
1244 (define_insn "*maclhw"
1245 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1246 (plus:SI (mult:SI (sign_extend:SI
1247 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1249 (match_operand:HI 2 "gpc_reg_operand" "r")))
1250 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1253 [(set_attr "type" "halfmul")])
1255 (define_insn "*maclhwuc"
1256 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1257 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1258 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1260 (match_operand:HI 2 "gpc_reg_operand" "r")))
1261 (match_operand:SI 4 "gpc_reg_operand" "0"))
1263 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264 (plus:SI (mult:SI (zero_extend:SI
1271 [(set_attr "type" "halfmul")])
1273 (define_insn "*maclhwu"
1274 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1275 (plus:SI (mult:SI (zero_extend:SI
1276 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1278 (match_operand:HI 2 "gpc_reg_operand" "r")))
1279 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1282 [(set_attr "type" "halfmul")])
1284 (define_insn "*nmacchwc"
1285 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1286 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1287 (mult:SI (ashiftrt:SI
1288 (match_operand:SI 2 "gpc_reg_operand" "r")
1291 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1293 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1294 (minus:SI (match_dup 4)
1295 (mult:SI (ashiftrt:SI
1302 [(set_attr "type" "halfmul")])
1304 (define_insn "*nmacchw"
1305 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1306 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1307 (mult:SI (ashiftrt:SI
1308 (match_operand:SI 2 "gpc_reg_operand" "r")
1311 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1314 [(set_attr "type" "halfmul")])
1316 (define_insn "*nmachhwc"
1317 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1318 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1319 (mult:SI (ashiftrt:SI
1320 (match_operand:SI 1 "gpc_reg_operand" "%r")
1323 (match_operand:SI 2 "gpc_reg_operand" "r")
1326 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1327 (minus:SI (match_dup 4)
1328 (mult:SI (ashiftrt:SI
1336 [(set_attr "type" "halfmul")])
1338 (define_insn "*nmachhw"
1339 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1340 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1341 (mult:SI (ashiftrt:SI
1342 (match_operand:SI 1 "gpc_reg_operand" "%r")
1345 (match_operand:SI 2 "gpc_reg_operand" "r")
1349 [(set_attr "type" "halfmul")])
1351 (define_insn "*nmaclhwc"
1352 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1353 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1354 (mult:SI (sign_extend:SI
1355 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1357 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1359 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1360 (minus:SI (match_dup 4)
1361 (mult:SI (sign_extend:SI
1367 [(set_attr "type" "halfmul")])
1369 (define_insn "*nmaclhw"
1370 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1371 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1372 (mult:SI (sign_extend:SI
1373 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1375 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1378 [(set_attr "type" "halfmul")])
1380 (define_insn "*mulchwc"
1381 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1382 (compare:CC (mult:SI (ashiftrt:SI
1383 (match_operand:SI 2 "gpc_reg_operand" "r")
1386 (match_operand:HI 1 "gpc_reg_operand" "r")))
1388 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389 (mult:SI (ashiftrt:SI
1396 [(set_attr "type" "halfmul")])
1398 (define_insn "*mulchw"
1399 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1400 (mult:SI (ashiftrt:SI
1401 (match_operand:SI 2 "gpc_reg_operand" "r")
1404 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1407 [(set_attr "type" "halfmul")])
1409 (define_insn "*mulchwuc"
1410 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1411 (compare:CC (mult:SI (lshiftrt:SI
1412 (match_operand:SI 2 "gpc_reg_operand" "r")
1415 (match_operand:HI 1 "gpc_reg_operand" "r")))
1417 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1418 (mult:SI (lshiftrt:SI
1425 [(set_attr "type" "halfmul")])
1427 (define_insn "*mulchwu"
1428 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1429 (mult:SI (lshiftrt:SI
1430 (match_operand:SI 2 "gpc_reg_operand" "r")
1433 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1436 [(set_attr "type" "halfmul")])
1438 (define_insn "*mulhhwc"
1439 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1440 (compare:CC (mult:SI (ashiftrt:SI
1441 (match_operand:SI 1 "gpc_reg_operand" "%r")
1444 (match_operand:SI 2 "gpc_reg_operand" "r")
1447 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1448 (mult:SI (ashiftrt:SI
1456 [(set_attr "type" "halfmul")])
1458 (define_insn "*mulhhw"
1459 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1460 (mult:SI (ashiftrt:SI
1461 (match_operand:SI 1 "gpc_reg_operand" "%r")
1464 (match_operand:SI 2 "gpc_reg_operand" "r")
1468 [(set_attr "type" "halfmul")])
1470 (define_insn "*mulhhwuc"
1471 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1472 (compare:CC (mult:SI (lshiftrt:SI
1473 (match_operand:SI 1 "gpc_reg_operand" "%r")
1476 (match_operand:SI 2 "gpc_reg_operand" "r")
1479 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1480 (mult:SI (lshiftrt:SI
1488 [(set_attr "type" "halfmul")])
1490 (define_insn "*mulhhwu"
1491 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1492 (mult:SI (lshiftrt:SI
1493 (match_operand:SI 1 "gpc_reg_operand" "%r")
1496 (match_operand:SI 2 "gpc_reg_operand" "r")
1500 [(set_attr "type" "halfmul")])
1502 (define_insn "*mullhwc"
1503 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1504 (compare:CC (mult:SI (sign_extend:SI
1505 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1507 (match_operand:HI 2 "gpc_reg_operand" "r")))
1509 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1510 (mult:SI (sign_extend:SI
1516 [(set_attr "type" "halfmul")])
1518 (define_insn "*mullhw"
1519 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1520 (mult:SI (sign_extend:SI
1521 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1523 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1526 [(set_attr "type" "halfmul")])
1528 (define_insn "*mullhwuc"
1529 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1530 (compare:CC (mult:SI (zero_extend:SI
1531 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1533 (match_operand:HI 2 "gpc_reg_operand" "r")))
1535 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1536 (mult:SI (zero_extend:SI
1542 [(set_attr "type" "halfmul")])
1544 (define_insn "*mullhwu"
1545 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1546 (mult:SI (zero_extend:SI
1547 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1549 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1552 [(set_attr "type" "halfmul")])
1554 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1555 (define_insn "dlmzb"
1556 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1557 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1558 (match_operand:SI 2 "gpc_reg_operand" "r")]
1560 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1561 (unspec:SI [(match_dup 1)
1567 (define_expand "strlensi"
1568 [(set (match_operand:SI 0 "gpc_reg_operand")
1569 (unspec:SI [(match_operand:BLK 1 "general_operand")
1570 (match_operand:QI 2 "const_int_operand")
1571 (match_operand 3 "const_int_operand")]
1572 UNSPEC_DLMZB_STRLEN))
1573 (clobber (match_scratch:CC 4))]
1574 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1576 rtx result = operands[0];
1577 rtx src = operands[1];
1578 rtx search_char = operands[2];
1579 rtx align = operands[3];
1580 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1581 rtx loop_label, end_label, mem, cr0, cond;
1582 if (search_char != const0_rtx
1583 || GET_CODE (align) != CONST_INT
1584 || INTVAL (align) < 8)
1586 word1 = gen_reg_rtx (SImode);
1587 word2 = gen_reg_rtx (SImode);
1588 scratch_dlmzb = gen_reg_rtx (SImode);
1589 scratch_string = gen_reg_rtx (Pmode);
1590 loop_label = gen_label_rtx ();
1591 end_label = gen_label_rtx ();
1592 addr = force_reg (Pmode, XEXP (src, 0));
1593 emit_move_insn (scratch_string, addr);
1594 emit_label (loop_label);
1595 mem = change_address (src, SImode, scratch_string);
1596 emit_move_insn (word1, mem);
1597 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1598 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1599 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1600 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1601 emit_jump_insn (gen_rtx_SET (pc_rtx,
1602 gen_rtx_IF_THEN_ELSE (VOIDmode,
1608 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1609 emit_jump_insn (gen_rtx_SET (pc_rtx,
1610 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1612 emit_label (end_label);
1613 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1614 emit_insn (gen_subsi3 (result, scratch_string, addr));
1615 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1619 ;; Fixed-point arithmetic insns.
1621 (define_expand "add<mode>3"
1622 [(set (match_operand:SDI 0 "gpc_reg_operand")
1623 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1624 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1627 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1629 rtx lo0 = gen_lowpart (SImode, operands[0]);
1630 rtx lo1 = gen_lowpart (SImode, operands[1]);
1631 rtx lo2 = gen_lowpart (SImode, operands[2]);
1632 rtx hi0 = gen_highpart (SImode, operands[0]);
1633 rtx hi1 = gen_highpart (SImode, operands[1]);
1634 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1636 if (!reg_or_short_operand (lo2, SImode))
1637 lo2 = force_reg (SImode, lo2);
1638 if (!adde_operand (hi2, SImode))
1639 hi2 = force_reg (SImode, hi2);
1641 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1642 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1646 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1648 rtx tmp = ((!can_create_pseudo_p ()
1649 || rtx_equal_p (operands[0], operands[1]))
1650 ? operands[0] : gen_reg_rtx (<MODE>mode));
1652 /* Adding a constant to r0 is not a valid insn, so use a different
1653 strategy in that case. */
1654 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1656 if (operands[0] == operands[1])
1658 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1659 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1663 HOST_WIDE_INT val = INTVAL (operands[2]);
1664 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1665 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1667 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1670 /* The ordering here is important for the prolog expander.
1671 When space is allocated from the stack, adding 'low' first may
1672 produce a temporary deallocation (which would be bad). */
1673 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1674 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1679 (define_insn "*add<mode>3"
1680 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1681 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1682 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1688 [(set_attr "type" "add")])
1690 (define_insn "addsi3_high"
1691 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1692 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1693 (high:SI (match_operand 2 "" ""))))]
1694 "TARGET_MACHO && !TARGET_64BIT"
1695 "addis %0,%1,ha16(%2)"
1696 [(set_attr "type" "add")])
1698 (define_insn_and_split "*add<mode>3_dot"
1699 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1700 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1701 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1703 (clobber (match_scratch:GPR 0 "=r,r"))]
1704 "<MODE>mode == Pmode"
1708 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1710 (plus:GPR (match_dup 1)
1713 (compare:CC (match_dup 0)
1716 [(set_attr "type" "add")
1717 (set_attr "dot" "yes")
1718 (set_attr "length" "4,8")])
1720 (define_insn_and_split "*add<mode>3_dot2"
1721 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1722 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1723 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1725 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1726 (plus:GPR (match_dup 1)
1728 "<MODE>mode == Pmode"
1732 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1734 (plus:GPR (match_dup 1)
1737 (compare:CC (match_dup 0)
1740 [(set_attr "type" "add")
1741 (set_attr "dot" "yes")
1742 (set_attr "length" "4,8")])
1744 (define_insn_and_split "*add<mode>3_imm_dot"
1745 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1746 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1747 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1749 (clobber (match_scratch:GPR 0 "=r,r"))
1750 (clobber (reg:GPR CA_REGNO))]
1751 "<MODE>mode == Pmode"
1755 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1757 (plus:GPR (match_dup 1)
1760 (compare:CC (match_dup 0)
1763 [(set_attr "type" "add")
1764 (set_attr "dot" "yes")
1765 (set_attr "length" "4,8")])
1767 (define_insn_and_split "*add<mode>3_imm_dot2"
1768 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1769 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1770 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1772 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1773 (plus:GPR (match_dup 1)
1775 (clobber (reg:GPR CA_REGNO))]
1776 "<MODE>mode == Pmode"
1780 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1782 (plus:GPR (match_dup 1)
1785 (compare:CC (match_dup 0)
1788 [(set_attr "type" "add")
1789 (set_attr "dot" "yes")
1790 (set_attr "length" "4,8")])
1792 ;; Split an add that we can't do in one insn into two insns, each of which
1793 ;; does one 16-bit part. This is used by combine. Note that the low-order
1794 ;; add should be last in case the result gets used in an address.
1797 [(set (match_operand:GPR 0 "gpc_reg_operand")
1798 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1799 (match_operand:GPR 2 "non_add_cint_operand")))]
1801 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1802 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1804 HOST_WIDE_INT val = INTVAL (operands[2]);
1805 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1806 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1808 operands[4] = GEN_INT (low);
1809 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1810 operands[3] = GEN_INT (rest);
1811 else if (can_create_pseudo_p ())
1813 operands[3] = gen_reg_rtx (DImode);
1814 emit_move_insn (operands[3], operands[2]);
1815 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1823 (define_insn "add<mode>3_carry"
1824 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1825 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1826 (match_operand:P 2 "reg_or_short_operand" "rI")))
1827 (set (reg:P CA_REGNO)
1828 (ltu:P (plus:P (match_dup 1)
1833 [(set_attr "type" "add")])
1835 (define_insn "*add<mode>3_imm_carry_pos"
1836 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1837 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1838 (match_operand:P 2 "short_cint_operand" "n")))
1839 (set (reg:P CA_REGNO)
1840 (geu:P (match_dup 1)
1841 (match_operand:P 3 "const_int_operand" "n")))]
1842 "INTVAL (operands[2]) > 0
1843 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1845 [(set_attr "type" "add")])
1847 (define_insn "*add<mode>3_imm_carry_0"
1848 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1849 (match_operand:P 1 "gpc_reg_operand" "r"))
1850 (set (reg:P CA_REGNO)
1854 [(set_attr "type" "add")])
1856 (define_insn "*add<mode>3_imm_carry_m1"
1857 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1858 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1860 (set (reg:P CA_REGNO)
1865 [(set_attr "type" "add")])
1867 (define_insn "*add<mode>3_imm_carry_neg"
1868 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1869 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1870 (match_operand:P 2 "short_cint_operand" "n")))
1871 (set (reg:P CA_REGNO)
1872 (gtu:P (match_dup 1)
1873 (match_operand:P 3 "const_int_operand" "n")))]
1874 "INTVAL (operands[2]) < 0
1875 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1877 [(set_attr "type" "add")])
1880 (define_expand "add<mode>3_carry_in"
1882 (set (match_operand:GPR 0 "gpc_reg_operand")
1883 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1884 (match_operand:GPR 2 "adde_operand"))
1885 (reg:GPR CA_REGNO)))
1886 (clobber (reg:GPR CA_REGNO))])]
1889 if (operands[2] == const0_rtx)
1891 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1894 if (operands[2] == constm1_rtx)
1896 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1901 (define_insn "*add<mode>3_carry_in_internal"
1902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1904 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1905 (reg:GPR CA_REGNO)))
1906 (clobber (reg:GPR CA_REGNO))]
1909 [(set_attr "type" "add")])
1911 (define_insn "*add<mode>3_carry_in_internal2"
1912 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1913 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1915 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1916 (clobber (reg:GPR CA_REGNO))]
1919 [(set_attr "type" "add")])
1921 (define_insn "add<mode>3_carry_in_0"
1922 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1923 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1924 (reg:GPR CA_REGNO)))
1925 (clobber (reg:GPR CA_REGNO))]
1928 [(set_attr "type" "add")])
1930 (define_insn "add<mode>3_carry_in_m1"
1931 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1932 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1935 (clobber (reg:GPR CA_REGNO))]
1938 [(set_attr "type" "add")])
1941 (define_expand "one_cmpl<mode>2"
1942 [(set (match_operand:SDI 0 "gpc_reg_operand")
1943 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1946 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1948 rs6000_split_logical (operands, NOT, false, false, false);
1953 (define_insn "*one_cmpl<mode>2"
1954 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1955 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1959 (define_insn_and_split "*one_cmpl<mode>2_dot"
1960 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1961 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1963 (clobber (match_scratch:GPR 0 "=r,r"))]
1964 "<MODE>mode == Pmode"
1968 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1970 (not:GPR (match_dup 1)))
1972 (compare:CC (match_dup 0)
1975 [(set_attr "type" "logical")
1976 (set_attr "dot" "yes")
1977 (set_attr "length" "4,8")])
1979 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1980 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1981 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1983 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1984 (not:GPR (match_dup 1)))]
1985 "<MODE>mode == Pmode"
1989 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1991 (not:GPR (match_dup 1)))
1993 (compare:CC (match_dup 0)
1996 [(set_attr "type" "logical")
1997 (set_attr "dot" "yes")
1998 (set_attr "length" "4,8")])
2001 (define_expand "sub<mode>3"
2002 [(set (match_operand:SDI 0 "gpc_reg_operand")
2003 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2004 (match_operand:SDI 2 "gpc_reg_operand")))]
2007 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2009 rtx lo0 = gen_lowpart (SImode, operands[0]);
2010 rtx lo1 = gen_lowpart (SImode, operands[1]);
2011 rtx lo2 = gen_lowpart (SImode, operands[2]);
2012 rtx hi0 = gen_highpart (SImode, operands[0]);
2013 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2014 rtx hi2 = gen_highpart (SImode, operands[2]);
2016 if (!reg_or_short_operand (lo1, SImode))
2017 lo1 = force_reg (SImode, lo1);
2018 if (!adde_operand (hi1, SImode))
2019 hi1 = force_reg (SImode, hi1);
2021 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2022 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2026 if (short_cint_operand (operands[1], <MODE>mode))
2028 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2033 (define_insn "*subf<mode>3"
2034 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2035 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2036 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2039 [(set_attr "type" "add")])
2041 (define_insn_and_split "*subf<mode>3_dot"
2042 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2043 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2044 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2046 (clobber (match_scratch:GPR 0 "=r,r"))]
2047 "<MODE>mode == Pmode"
2051 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2053 (minus:GPR (match_dup 2)
2056 (compare:CC (match_dup 0)
2059 [(set_attr "type" "add")
2060 (set_attr "dot" "yes")
2061 (set_attr "length" "4,8")])
2063 (define_insn_and_split "*subf<mode>3_dot2"
2064 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2065 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2066 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2068 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2069 (minus:GPR (match_dup 2)
2071 "<MODE>mode == Pmode"
2075 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2077 (minus:GPR (match_dup 2)
2080 (compare:CC (match_dup 0)
2083 [(set_attr "type" "add")
2084 (set_attr "dot" "yes")
2085 (set_attr "length" "4,8")])
2087 (define_insn "subf<mode>3_imm"
2088 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2089 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2090 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2091 (clobber (reg:GPR CA_REGNO))]
2094 [(set_attr "type" "add")])
2096 (define_insn_and_split "subf<mode>3_carry_dot2"
2097 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2098 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2099 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2101 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2102 (minus:P (match_dup 2)
2104 (set (reg:P CA_REGNO)
2105 (leu:P (match_dup 1)
2107 "<MODE>mode == Pmode"
2111 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2112 [(parallel [(set (match_dup 0)
2113 (minus:P (match_dup 2)
2115 (set (reg:P CA_REGNO)
2116 (leu:P (match_dup 1)
2119 (compare:CC (match_dup 0)
2122 [(set_attr "type" "add")
2123 (set_attr "dot" "yes")
2124 (set_attr "length" "4,8")])
2126 (define_insn "subf<mode>3_carry"
2127 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2128 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2129 (match_operand:P 1 "gpc_reg_operand" "r")))
2130 (set (reg:P CA_REGNO)
2131 (leu:P (match_dup 1)
2135 [(set_attr "type" "add")])
2137 (define_insn "*subf<mode>3_imm_carry_0"
2138 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2139 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2140 (set (reg:P CA_REGNO)
2145 [(set_attr "type" "add")])
2147 (define_insn "*subf<mode>3_imm_carry_m1"
2148 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2149 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2150 (set (reg:P CA_REGNO)
2154 [(set_attr "type" "add")])
2157 (define_expand "subf<mode>3_carry_in"
2159 (set (match_operand:GPR 0 "gpc_reg_operand")
2160 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2162 (match_operand:GPR 2 "adde_operand")))
2163 (clobber (reg:GPR CA_REGNO))])]
2166 if (operands[2] == const0_rtx)
2168 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2171 if (operands[2] == constm1_rtx)
2173 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2178 (define_insn "*subf<mode>3_carry_in_internal"
2179 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2182 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2183 (clobber (reg:GPR CA_REGNO))]
2186 [(set_attr "type" "add")])
2188 (define_insn "subf<mode>3_carry_in_0"
2189 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2190 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2191 (reg:GPR CA_REGNO)))
2192 (clobber (reg:GPR CA_REGNO))]
2195 [(set_attr "type" "add")])
2197 (define_insn "subf<mode>3_carry_in_m1"
2198 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2200 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2202 (clobber (reg:GPR CA_REGNO))]
2205 [(set_attr "type" "add")])
2207 (define_insn "subf<mode>3_carry_in_xx"
2208 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2209 (plus:GPR (reg:GPR CA_REGNO)
2211 (clobber (reg:GPR CA_REGNO))]
2214 [(set_attr "type" "add")])
2217 (define_insn "neg<mode>2"
2218 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2219 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2222 [(set_attr "type" "add")])
2224 (define_insn_and_split "*neg<mode>2_dot"
2225 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2226 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2228 (clobber (match_scratch:GPR 0 "=r,r"))]
2229 "<MODE>mode == Pmode"
2233 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2235 (neg:GPR (match_dup 1)))
2237 (compare:CC (match_dup 0)
2240 [(set_attr "type" "add")
2241 (set_attr "dot" "yes")
2242 (set_attr "length" "4,8")])
2244 (define_insn_and_split "*neg<mode>2_dot2"
2245 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2246 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2248 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2249 (neg:GPR (match_dup 1)))]
2250 "<MODE>mode == Pmode"
2254 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2256 (neg:GPR (match_dup 1)))
2258 (compare:CC (match_dup 0)
2261 [(set_attr "type" "add")
2262 (set_attr "dot" "yes")
2263 (set_attr "length" "4,8")])
2266 (define_insn "clz<mode>2"
2267 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2268 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2271 [(set_attr "type" "cntlz")])
2273 (define_expand "ctz<mode>2"
2274 [(set (match_operand:GPR 0 "gpc_reg_operand")
2275 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2280 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2284 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2285 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2286 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2290 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2291 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2292 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2293 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2297 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2298 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2299 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2300 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2306 (define_insn "ctz<mode>2_hw"
2307 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2308 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2311 [(set_attr "type" "cntlz")])
2313 (define_expand "ffs<mode>2"
2314 [(set (match_operand:GPR 0 "gpc_reg_operand")
2315 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2318 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2319 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2320 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2321 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2322 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2323 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2324 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2329 (define_expand "popcount<mode>2"
2330 [(set (match_operand:GPR 0 "gpc_reg_operand")
2331 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2332 "TARGET_POPCNTB || TARGET_POPCNTD"
2334 rs6000_emit_popcount (operands[0], operands[1]);
2338 (define_insn "popcntb<mode>2"
2339 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2340 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2344 [(set_attr "type" "popcnt")])
2346 (define_insn "popcntd<mode>2"
2347 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2348 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2351 [(set_attr "type" "popcnt")])
2354 (define_expand "parity<mode>2"
2355 [(set (match_operand:GPR 0 "gpc_reg_operand")
2356 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2359 rs6000_emit_parity (operands[0], operands[1]);
2363 (define_insn "parity<mode>2_cmpb"
2364 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2365 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2366 "TARGET_CMPB && TARGET_POPCNTB"
2368 [(set_attr "type" "popcnt")])
2370 (define_insn "cmpb<mode>3"
2371 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2372 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2373 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2376 [(set_attr "type" "cmp")])
2378 ;; Since the hardware zeros the upper part of the register, save generating the
2379 ;; AND immediate if we are converting to unsigned
2380 (define_insn "*bswap<mode>2_extenddi"
2381 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2383 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2386 [(set_attr "length" "4")
2387 (set_attr "type" "load")])
2389 (define_insn "*bswaphi2_extendsi"
2390 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2392 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2395 [(set_attr "length" "4")
2396 (set_attr "type" "load")])
2398 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2399 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2400 ;; load with byte swap, which can be slower than doing it in the registers. It
2401 ;; also prevents certain failures with the RELOAD register allocator.
2403 (define_expand "bswap<mode>2"
2404 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2405 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2408 rtx dest = operands[0];
2409 rtx src = operands[1];
2411 if (!REG_P (dest) && !REG_P (src))
2412 src = force_reg (<MODE>mode, src);
2415 emit_insn (gen_bswap<mode>2_load (dest, src));
2416 else if (MEM_P (dest))
2417 emit_insn (gen_bswap<mode>2_store (dest, src));
2419 emit_insn (gen_bswap<mode>2_reg (dest, src));
2423 (define_insn "bswap<mode>2_load"
2424 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2425 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2428 [(set_attr "type" "load")])
2430 (define_insn "bswap<mode>2_store"
2431 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2432 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2435 [(set_attr "type" "store")])
2437 (define_insn_and_split "bswaphi2_reg"
2438 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2440 (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2441 (clobber (match_scratch:SI 2 "=&r,X"))]
2446 "reload_completed && int_reg_operand (operands[0], HImode)"
2448 (and:SI (lshiftrt:SI (match_dup 4)
2452 (and:SI (ashift:SI (match_dup 4)
2454 (const_int 65280))) ;; 0xff00
2456 (ior:SI (match_dup 3)
2459 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2460 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2462 [(set_attr "length" "12,4")
2463 (set_attr "type" "*,vecperm")])
2465 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2466 ;; zero_extract insns do not change for -mlittle.
2467 (define_insn_and_split "bswapsi2_reg"
2468 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2470 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2475 "reload_completed && int_reg_operand (operands[0], SImode)"
2476 [(set (match_dup 0) ; DABC
2477 (rotate:SI (match_dup 1)
2479 (set (match_dup 0) ; DCBC
2480 (ior:SI (and:SI (ashift:SI (match_dup 1)
2482 (const_int 16711680))
2483 (and:SI (match_dup 0)
2484 (const_int -16711681))))
2485 (set (match_dup 0) ; DCBA
2486 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2489 (and:SI (match_dup 0)
2490 (const_int -256))))]
2492 [(set_attr "length" "12,4")
2493 (set_attr "type" "*,vecperm")])
2495 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2496 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2499 (define_expand "bswapdi2"
2500 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2502 (match_operand:DI 1 "reg_or_mem_operand")))
2503 (clobber (match_scratch:DI 2))
2504 (clobber (match_scratch:DI 3))])]
2507 rtx dest = operands[0];
2508 rtx src = operands[1];
2510 if (!REG_P (dest) && !REG_P (src))
2511 operands[1] = src = force_reg (DImode, src);
2513 if (TARGET_POWERPC64 && TARGET_LDBRX)
2516 emit_insn (gen_bswapdi2_load (dest, src));
2517 else if (MEM_P (dest))
2518 emit_insn (gen_bswapdi2_store (dest, src));
2519 else if (TARGET_P9_VECTOR)
2520 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2522 emit_insn (gen_bswapdi2_reg (dest, src));
2526 if (!TARGET_POWERPC64)
2528 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2529 that uses 64-bit registers needs the same scratch registers as 64-bit
2531 emit_insn (gen_bswapdi2_32bit (dest, src));
2536 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2537 (define_insn "bswapdi2_load"
2538 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2539 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2540 "TARGET_POWERPC64 && TARGET_LDBRX"
2542 [(set_attr "type" "load")])
2544 (define_insn "bswapdi2_store"
2545 [(set (match_operand:DI 0 "memory_operand" "=Z")
2546 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2547 "TARGET_POWERPC64 && TARGET_LDBRX"
2549 [(set_attr "type" "store")])
2551 (define_insn "bswapdi2_xxbrd"
2552 [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2553 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2556 [(set_attr "type" "vecperm")])
2558 (define_insn "bswapdi2_reg"
2559 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2560 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2561 (clobber (match_scratch:DI 2 "=&r"))
2562 (clobber (match_scratch:DI 3 "=&r"))]
2563 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2565 [(set_attr "length" "36")])
2567 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2568 (define_insn "*bswapdi2_64bit"
2569 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2570 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2571 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2572 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2573 "TARGET_POWERPC64 && !TARGET_LDBRX
2574 && (REG_P (operands[0]) || REG_P (operands[1]))
2575 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2576 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2578 [(set_attr "length" "16,12,36")])
2581 [(set (match_operand:DI 0 "gpc_reg_operand")
2582 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2583 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2584 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2585 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2588 rtx dest = operands[0];
2589 rtx src = operands[1];
2590 rtx op2 = operands[2];
2591 rtx op3 = operands[3];
2592 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2593 BYTES_BIG_ENDIAN ? 4 : 0);
2594 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2595 BYTES_BIG_ENDIAN ? 4 : 0);
2601 addr1 = XEXP (src, 0);
2602 if (GET_CODE (addr1) == PLUS)
2604 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2605 if (TARGET_AVOID_XFORM)
2607 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2611 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2613 else if (TARGET_AVOID_XFORM)
2615 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2620 emit_move_insn (op2, GEN_INT (4));
2621 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2624 word1 = change_address (src, SImode, addr1);
2625 word2 = change_address (src, SImode, addr2);
2627 if (BYTES_BIG_ENDIAN)
2629 emit_insn (gen_bswapsi2 (op3_32, word2));
2630 emit_insn (gen_bswapsi2 (dest_32, word1));
2634 emit_insn (gen_bswapsi2 (op3_32, word1));
2635 emit_insn (gen_bswapsi2 (dest_32, word2));
2638 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2639 emit_insn (gen_iordi3 (dest, dest, op3));
2644 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2645 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2646 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2647 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2648 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2651 rtx dest = operands[0];
2652 rtx src = operands[1];
2653 rtx op2 = operands[2];
2654 rtx op3 = operands[3];
2655 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2656 BYTES_BIG_ENDIAN ? 4 : 0);
2657 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2658 BYTES_BIG_ENDIAN ? 4 : 0);
2664 addr1 = XEXP (dest, 0);
2665 if (GET_CODE (addr1) == PLUS)
2667 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2668 if (TARGET_AVOID_XFORM)
2670 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2674 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2676 else if (TARGET_AVOID_XFORM)
2678 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2683 emit_move_insn (op2, GEN_INT (4));
2684 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2687 word1 = change_address (dest, SImode, addr1);
2688 word2 = change_address (dest, SImode, addr2);
2690 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2692 if (BYTES_BIG_ENDIAN)
2694 emit_insn (gen_bswapsi2 (word1, src_si));
2695 emit_insn (gen_bswapsi2 (word2, op3_si));
2699 emit_insn (gen_bswapsi2 (word2, src_si));
2700 emit_insn (gen_bswapsi2 (word1, op3_si));
2706 [(set (match_operand:DI 0 "gpc_reg_operand")
2707 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2708 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2709 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2710 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2713 rtx dest = operands[0];
2714 rtx src = operands[1];
2715 rtx op2 = operands[2];
2716 rtx op3 = operands[3];
2717 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2718 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2719 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2720 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2721 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2723 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2724 emit_insn (gen_bswapsi2 (dest_si, src_si));
2725 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2726 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2727 emit_insn (gen_iordi3 (dest, dest, op3));
2731 (define_insn "bswapdi2_32bit"
2732 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2733 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2734 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2735 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2737 [(set_attr "length" "16,12,36")])
2740 [(set (match_operand:DI 0 "gpc_reg_operand")
2741 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2742 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2743 "!TARGET_POWERPC64 && reload_completed"
2746 rtx dest = operands[0];
2747 rtx src = operands[1];
2748 rtx op2 = operands[2];
2749 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2750 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2756 addr1 = XEXP (src, 0);
2757 if (GET_CODE (addr1) == PLUS)
2759 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2760 if (TARGET_AVOID_XFORM
2761 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2763 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2767 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2769 else if (TARGET_AVOID_XFORM
2770 || REGNO (addr1) == REGNO (dest2))
2772 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2777 emit_move_insn (op2, GEN_INT (4));
2778 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2781 word1 = change_address (src, SImode, addr1);
2782 word2 = change_address (src, SImode, addr2);
2784 emit_insn (gen_bswapsi2 (dest2, word1));
2785 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2786 thus allowing us to omit an early clobber on the output. */
2787 emit_insn (gen_bswapsi2 (dest1, word2));
2792 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2793 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2794 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2795 "!TARGET_POWERPC64 && reload_completed"
2798 rtx dest = operands[0];
2799 rtx src = operands[1];
2800 rtx op2 = operands[2];
2801 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2802 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2808 addr1 = XEXP (dest, 0);
2809 if (GET_CODE (addr1) == PLUS)
2811 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2812 if (TARGET_AVOID_XFORM)
2814 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2818 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2820 else if (TARGET_AVOID_XFORM)
2822 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2827 emit_move_insn (op2, GEN_INT (4));
2828 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2831 word1 = change_address (dest, SImode, addr1);
2832 word2 = change_address (dest, SImode, addr2);
2834 emit_insn (gen_bswapsi2 (word2, src1));
2835 emit_insn (gen_bswapsi2 (word1, src2));
2840 [(set (match_operand:DI 0 "gpc_reg_operand")
2841 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2842 (clobber (match_operand:SI 2 ""))]
2843 "!TARGET_POWERPC64 && reload_completed"
2846 rtx dest = operands[0];
2847 rtx src = operands[1];
2848 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2849 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2850 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2851 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2853 emit_insn (gen_bswapsi2 (dest1, src2));
2854 emit_insn (gen_bswapsi2 (dest2, src1));
2859 (define_insn "mul<mode>3"
2860 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2861 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2862 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2867 [(set_attr "type" "mul")
2869 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2871 (match_operand:GPR 2 "short_cint_operand")
2872 (const_string "16")]
2873 (const_string "<bits>")))])
2875 (define_insn_and_split "*mul<mode>3_dot"
2876 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2877 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2878 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2880 (clobber (match_scratch:GPR 0 "=r,r"))]
2881 "<MODE>mode == Pmode"
2885 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2887 (mult:GPR (match_dup 1)
2890 (compare:CC (match_dup 0)
2893 [(set_attr "type" "mul")
2894 (set_attr "size" "<bits>")
2895 (set_attr "dot" "yes")
2896 (set_attr "length" "4,8")])
2898 (define_insn_and_split "*mul<mode>3_dot2"
2899 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2900 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2901 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2903 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2904 (mult:GPR (match_dup 1)
2906 "<MODE>mode == Pmode"
2910 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2912 (mult:GPR (match_dup 1)
2915 (compare:CC (match_dup 0)
2918 [(set_attr "type" "mul")
2919 (set_attr "size" "<bits>")
2920 (set_attr "dot" "yes")
2921 (set_attr "length" "4,8")])
2924 (define_expand "<su>mul<mode>3_highpart"
2925 [(set (match_operand:GPR 0 "gpc_reg_operand")
2927 (mult:<DMODE> (any_extend:<DMODE>
2928 (match_operand:GPR 1 "gpc_reg_operand"))
2930 (match_operand:GPR 2 "gpc_reg_operand")))
2934 if (<MODE>mode == SImode && TARGET_POWERPC64)
2936 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2941 if (!WORDS_BIG_ENDIAN)
2943 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2949 (define_insn "*<su>mul<mode>3_highpart"
2950 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2952 (mult:<DMODE> (any_extend:<DMODE>
2953 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2955 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2957 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2958 "mulh<wd><u> %0,%1,%2"
2959 [(set_attr "type" "mul")
2960 (set_attr "size" "<bits>")])
2962 (define_insn "<su>mulsi3_highpart_le"
2963 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2965 (mult:DI (any_extend:DI
2966 (match_operand:SI 1 "gpc_reg_operand" "r"))
2968 (match_operand:SI 2 "gpc_reg_operand" "r")))
2970 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2972 [(set_attr "type" "mul")])
2974 (define_insn "<su>muldi3_highpart_le"
2975 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2977 (mult:TI (any_extend:TI
2978 (match_operand:DI 1 "gpc_reg_operand" "r"))
2980 (match_operand:DI 2 "gpc_reg_operand" "r")))
2982 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2984 [(set_attr "type" "mul")
2985 (set_attr "size" "64")])
2987 (define_insn "<su>mulsi3_highpart_64"
2988 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2991 (mult:DI (any_extend:DI
2992 (match_operand:SI 1 "gpc_reg_operand" "r"))
2994 (match_operand:SI 2 "gpc_reg_operand" "r")))
2998 [(set_attr "type" "mul")])
3000 (define_expand "<u>mul<mode><dmode>3"
3001 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3002 (mult:<DMODE> (any_extend:<DMODE>
3003 (match_operand:GPR 1 "gpc_reg_operand"))
3005 (match_operand:GPR 2 "gpc_reg_operand"))))]
3006 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3008 rtx l = gen_reg_rtx (<MODE>mode);
3009 rtx h = gen_reg_rtx (<MODE>mode);
3010 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3011 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3012 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3013 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3017 (define_insn "*maddld4"
3018 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3019 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3020 (match_operand:DI 2 "gpc_reg_operand" "r"))
3021 (match_operand:DI 3 "gpc_reg_operand" "r")))]
3023 "maddld %0,%1,%2,%3"
3024 [(set_attr "type" "mul")])
3026 (define_insn "udiv<mode>3"
3027 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3028 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3029 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3032 [(set_attr "type" "div")
3033 (set_attr "size" "<bits>")])
3036 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3037 ;; modulus. If it isn't a power of two, force operands into register and do
3039 (define_expand "div<mode>3"
3040 [(set (match_operand:GPR 0 "gpc_reg_operand")
3041 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3042 (match_operand:GPR 2 "reg_or_cint_operand")))]
3045 if (CONST_INT_P (operands[2])
3046 && INTVAL (operands[2]) > 0
3047 && exact_log2 (INTVAL (operands[2])) >= 0)
3049 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3053 operands[2] = force_reg (<MODE>mode, operands[2]);
3056 (define_insn "*div<mode>3"
3057 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3058 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3059 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3062 [(set_attr "type" "div")
3063 (set_attr "size" "<bits>")])
3065 (define_insn "div<mode>3_sra"
3066 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3067 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3068 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3069 (clobber (reg:GPR CA_REGNO))]
3071 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3072 [(set_attr "type" "two")
3073 (set_attr "length" "8")])
3075 (define_insn_and_split "*div<mode>3_sra_dot"
3076 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3077 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3078 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3080 (clobber (match_scratch:GPR 0 "=r,r"))
3081 (clobber (reg:GPR CA_REGNO))]
3082 "<MODE>mode == Pmode"
3084 sra<wd>i %0,%1,%p2\;addze. %0,%0
3086 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3087 [(parallel [(set (match_dup 0)
3088 (div:GPR (match_dup 1)
3090 (clobber (reg:GPR CA_REGNO))])
3092 (compare:CC (match_dup 0)
3095 [(set_attr "type" "two")
3096 (set_attr "length" "8,12")
3097 (set_attr "cell_micro" "not")])
3099 (define_insn_and_split "*div<mode>3_sra_dot2"
3100 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3101 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3102 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3104 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3105 (div:GPR (match_dup 1)
3107 (clobber (reg:GPR CA_REGNO))]
3108 "<MODE>mode == Pmode"
3110 sra<wd>i %0,%1,%p2\;addze. %0,%0
3112 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3113 [(parallel [(set (match_dup 0)
3114 (div:GPR (match_dup 1)
3116 (clobber (reg:GPR CA_REGNO))])
3118 (compare:CC (match_dup 0)
3121 [(set_attr "type" "two")
3122 (set_attr "length" "8,12")
3123 (set_attr "cell_micro" "not")])
3125 (define_expand "mod<mode>3"
3126 [(set (match_operand:GPR 0 "gpc_reg_operand")
3127 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3128 (match_operand:GPR 2 "reg_or_cint_operand")))]
3135 if (GET_CODE (operands[2]) != CONST_INT
3136 || INTVAL (operands[2]) <= 0
3137 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3142 operands[2] = force_reg (<MODE>mode, operands[2]);
3146 temp1 = gen_reg_rtx (<MODE>mode);
3147 temp2 = gen_reg_rtx (<MODE>mode);
3149 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3150 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3151 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3156 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3157 ;; mod, prefer putting the result of mod into a different register
3158 (define_insn "*mod<mode>3"
3159 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3160 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3161 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3164 [(set_attr "type" "div")
3165 (set_attr "size" "<bits>")])
3168 (define_insn "umod<mode>3"
3169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3170 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3171 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3174 [(set_attr "type" "div")
3175 (set_attr "size" "<bits>")])
3177 ;; On machines with modulo support, do a combined div/mod the old fashioned
3178 ;; method, since the multiply/subtract is faster than doing the mod instruction
3182 [(set (match_operand:GPR 0 "gpc_reg_operand")
3183 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3184 (match_operand:GPR 2 "gpc_reg_operand")))
3185 (set (match_operand:GPR 3 "gpc_reg_operand")
3186 (mod:GPR (match_dup 1)
3189 && ! reg_mentioned_p (operands[0], operands[1])
3190 && ! reg_mentioned_p (operands[0], operands[2])
3191 && ! reg_mentioned_p (operands[3], operands[1])
3192 && ! reg_mentioned_p (operands[3], operands[2])"
3194 (div:GPR (match_dup 1)
3197 (mult:GPR (match_dup 0)
3200 (minus:GPR (match_dup 1)
3204 [(set (match_operand:GPR 0 "gpc_reg_operand")
3205 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3206 (match_operand:GPR 2 "gpc_reg_operand")))
3207 (set (match_operand:GPR 3 "gpc_reg_operand")
3208 (umod:GPR (match_dup 1)
3211 && ! reg_mentioned_p (operands[0], operands[1])
3212 && ! reg_mentioned_p (operands[0], operands[2])
3213 && ! reg_mentioned_p (operands[3], operands[1])
3214 && ! reg_mentioned_p (operands[3], operands[2])"
3216 (udiv:GPR (match_dup 1)
3219 (mult:GPR (match_dup 0)
3222 (minus:GPR (match_dup 1)
3226 ;; Logical instructions
3227 ;; The logical instructions are mostly combined by using match_operator,
3228 ;; but the plain AND insns are somewhat different because there is no
3229 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3230 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3232 (define_expand "and<mode>3"
3233 [(set (match_operand:SDI 0 "gpc_reg_operand")
3234 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3235 (match_operand:SDI 2 "reg_or_cint_operand")))]
3238 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3240 rs6000_split_logical (operands, AND, false, false, false);
3244 if (CONST_INT_P (operands[2]))
3246 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3248 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3252 if (logical_const_operand (operands[2], <MODE>mode))
3254 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3258 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3260 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3264 operands[2] = force_reg (<MODE>mode, operands[2]);
3269 (define_insn "and<mode>3_imm"
3270 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3271 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3272 (match_operand:GPR 2 "logical_const_operand" "n")))
3273 (clobber (match_scratch:CC 3 "=x"))]
3274 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3275 "andi%e2. %0,%1,%u2"
3276 [(set_attr "type" "logical")
3277 (set_attr "dot" "yes")])
3279 (define_insn_and_split "*and<mode>3_imm_dot"
3280 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3281 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3282 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3284 (clobber (match_scratch:GPR 0 "=r,r"))
3285 (clobber (match_scratch:CC 4 "=X,x"))]
3286 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3287 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3291 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3292 [(parallel [(set (match_dup 0)
3293 (and:GPR (match_dup 1)
3295 (clobber (match_dup 4))])
3297 (compare:CC (match_dup 0)
3300 [(set_attr "type" "logical")
3301 (set_attr "dot" "yes")
3302 (set_attr "length" "4,8")])
3304 (define_insn_and_split "*and<mode>3_imm_dot2"
3305 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3306 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3307 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3309 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3310 (and:GPR (match_dup 1)
3312 (clobber (match_scratch:CC 4 "=X,x"))]
3313 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3314 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3318 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3319 [(parallel [(set (match_dup 0)
3320 (and:GPR (match_dup 1)
3322 (clobber (match_dup 4))])
3324 (compare:CC (match_dup 0)
3327 [(set_attr "type" "logical")
3328 (set_attr "dot" "yes")
3329 (set_attr "length" "4,8")])
3331 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3332 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3333 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3336 (clobber (match_scratch:GPR 0 "=r,r"))]
3337 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3338 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3342 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3344 (and:GPR (match_dup 1)
3347 (compare:CC (match_dup 0)
3350 [(set_attr "type" "logical")
3351 (set_attr "dot" "yes")
3352 (set_attr "length" "4,8")])
3354 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3355 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3356 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3357 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3359 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3360 (and:GPR (match_dup 1)
3362 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3363 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3367 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3369 (and:GPR (match_dup 1)
3372 (compare:CC (match_dup 0)
3375 [(set_attr "type" "logical")
3376 (set_attr "dot" "yes")
3377 (set_attr "length" "4,8")])
3379 (define_insn "*and<mode>3_imm_dot_shifted"
3380 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3383 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3384 (match_operand:SI 4 "const_int_operand" "n"))
3385 (match_operand:GPR 2 "const_int_operand" "n"))
3387 (clobber (match_scratch:GPR 0 "=r"))]
3388 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3389 << INTVAL (operands[4])),
3391 && (<MODE>mode == Pmode
3392 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3394 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3395 return "andi%e2. %0,%1,%u2";
3397 [(set_attr "type" "logical")
3398 (set_attr "dot" "yes")])
3401 (define_insn "and<mode>3_mask"
3402 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3403 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3404 (match_operand:GPR 2 "const_int_operand" "n")))]
3405 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3407 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3409 [(set_attr "type" "shift")])
3411 (define_insn_and_split "*and<mode>3_mask_dot"
3412 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3413 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3414 (match_operand:GPR 2 "const_int_operand" "n,n"))
3416 (clobber (match_scratch:GPR 0 "=r,r"))]
3417 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3418 && !logical_const_operand (operands[2], <MODE>mode)
3419 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3421 if (which_alternative == 0)
3422 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3426 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3428 (and:GPR (match_dup 1)
3431 (compare:CC (match_dup 0)
3434 [(set_attr "type" "shift")
3435 (set_attr "dot" "yes")
3436 (set_attr "length" "4,8")])
3438 (define_insn_and_split "*and<mode>3_mask_dot2"
3439 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3440 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3441 (match_operand:GPR 2 "const_int_operand" "n,n"))
3443 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3444 (and:GPR (match_dup 1)
3446 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3447 && !logical_const_operand (operands[2], <MODE>mode)
3448 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3450 if (which_alternative == 0)
3451 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3455 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3457 (and:GPR (match_dup 1)
3460 (compare:CC (match_dup 0)
3463 [(set_attr "type" "shift")
3464 (set_attr "dot" "yes")
3465 (set_attr "length" "4,8")])
3468 (define_insn_and_split "*and<mode>3_2insn"
3469 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3470 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3471 (match_operand:GPR 2 "const_int_operand" "n")))]
3472 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3473 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3474 || logical_const_operand (operands[2], <MODE>mode))"
3479 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3482 [(set_attr "type" "shift")
3483 (set_attr "length" "8")])
3485 (define_insn_and_split "*and<mode>3_2insn_dot"
3486 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3487 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3488 (match_operand:GPR 2 "const_int_operand" "n,n"))
3490 (clobber (match_scratch:GPR 0 "=r,r"))]
3491 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3492 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3493 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3494 || logical_const_operand (operands[2], <MODE>mode))"
3496 "&& reload_completed"
3499 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3502 [(set_attr "type" "shift")
3503 (set_attr "dot" "yes")
3504 (set_attr "length" "8,12")])
3506 (define_insn_and_split "*and<mode>3_2insn_dot2"
3507 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3508 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3509 (match_operand:GPR 2 "const_int_operand" "n,n"))
3511 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3512 (and:GPR (match_dup 1)
3514 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3515 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3516 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3517 || logical_const_operand (operands[2], <MODE>mode))"
3519 "&& reload_completed"
3522 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3525 [(set_attr "type" "shift")
3526 (set_attr "dot" "yes")
3527 (set_attr "length" "8,12")])
3530 (define_expand "<code><mode>3"
3531 [(set (match_operand:SDI 0 "gpc_reg_operand")
3532 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3533 (match_operand:SDI 2 "reg_or_cint_operand")))]
3536 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3538 rs6000_split_logical (operands, <CODE>, false, false, false);
3542 if (non_logical_cint_operand (operands[2], <MODE>mode))
3544 rtx tmp = ((!can_create_pseudo_p ()
3545 || rtx_equal_p (operands[0], operands[1]))
3546 ? operands[0] : gen_reg_rtx (<MODE>mode));
3548 HOST_WIDE_INT value = INTVAL (operands[2]);
3549 HOST_WIDE_INT lo = value & 0xffff;
3550 HOST_WIDE_INT hi = value - lo;
3552 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3553 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3557 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3558 operands[2] = force_reg (<MODE>mode, operands[2]);
3562 [(set (match_operand:GPR 0 "gpc_reg_operand")
3563 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3564 (match_operand:GPR 2 "non_logical_cint_operand")))]
3567 (iorxor:GPR (match_dup 1)
3570 (iorxor:GPR (match_dup 3)
3573 operands[3] = ((!can_create_pseudo_p ()
3574 || rtx_equal_p (operands[0], operands[1]))
3575 ? operands[0] : gen_reg_rtx (<MODE>mode));
3577 HOST_WIDE_INT value = INTVAL (operands[2]);
3578 HOST_WIDE_INT lo = value & 0xffff;
3579 HOST_WIDE_INT hi = value - lo;
3581 operands[4] = GEN_INT (hi);
3582 operands[5] = GEN_INT (lo);
3585 (define_insn "*bool<mode>3_imm"
3586 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3587 (match_operator:GPR 3 "boolean_or_operator"
3588 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3589 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3592 [(set_attr "type" "logical")])
3594 (define_insn "*bool<mode>3"
3595 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3596 (match_operator:GPR 3 "boolean_operator"
3597 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3598 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3601 [(set_attr "type" "logical")])
3603 (define_insn_and_split "*bool<mode>3_dot"
3604 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3605 (compare:CC (match_operator:GPR 3 "boolean_operator"
3606 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3607 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3609 (clobber (match_scratch:GPR 0 "=r,r"))]
3610 "<MODE>mode == Pmode"
3614 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3618 (compare:CC (match_dup 0)
3621 [(set_attr "type" "logical")
3622 (set_attr "dot" "yes")
3623 (set_attr "length" "4,8")])
3625 (define_insn_and_split "*bool<mode>3_dot2"
3626 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3627 (compare:CC (match_operator:GPR 3 "boolean_operator"
3628 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3629 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3631 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3633 "<MODE>mode == Pmode"
3637 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3641 (compare:CC (match_dup 0)
3644 [(set_attr "type" "logical")
3645 (set_attr "dot" "yes")
3646 (set_attr "length" "4,8")])
3649 (define_insn "*boolc<mode>3"
3650 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3651 (match_operator:GPR 3 "boolean_operator"
3652 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3653 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3656 [(set_attr "type" "logical")])
3658 (define_insn_and_split "*boolc<mode>3_dot"
3659 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3660 (compare:CC (match_operator:GPR 3 "boolean_operator"
3661 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3662 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3664 (clobber (match_scratch:GPR 0 "=r,r"))]
3665 "<MODE>mode == Pmode"
3669 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3673 (compare:CC (match_dup 0)
3676 [(set_attr "type" "logical")
3677 (set_attr "dot" "yes")
3678 (set_attr "length" "4,8")])
3680 (define_insn_and_split "*boolc<mode>3_dot2"
3681 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3682 (compare:CC (match_operator:GPR 3 "boolean_operator"
3683 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3684 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3686 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3688 "<MODE>mode == Pmode"
3692 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3696 (compare:CC (match_dup 0)
3699 [(set_attr "type" "logical")
3700 (set_attr "dot" "yes")
3701 (set_attr "length" "4,8")])
3704 (define_insn "*boolcc<mode>3"
3705 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3706 (match_operator:GPR 3 "boolean_operator"
3707 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3708 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3711 [(set_attr "type" "logical")])
3713 (define_insn_and_split "*boolcc<mode>3_dot"
3714 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3715 (compare:CC (match_operator:GPR 3 "boolean_operator"
3716 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3717 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3719 (clobber (match_scratch:GPR 0 "=r,r"))]
3720 "<MODE>mode == Pmode"
3724 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3728 (compare:CC (match_dup 0)
3731 [(set_attr "type" "logical")
3732 (set_attr "dot" "yes")
3733 (set_attr "length" "4,8")])
3735 (define_insn_and_split "*boolcc<mode>3_dot2"
3736 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3737 (compare:CC (match_operator:GPR 3 "boolean_operator"
3738 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3739 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3741 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3743 "<MODE>mode == Pmode"
3747 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3751 (compare:CC (match_dup 0)
3754 [(set_attr "type" "logical")
3755 (set_attr "dot" "yes")
3756 (set_attr "length" "4,8")])
3759 ;; TODO: Should have dots of this as well.
3760 (define_insn "*eqv<mode>3"
3761 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3762 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3763 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3766 [(set_attr "type" "logical")])
3768 ;; Rotate-and-mask and insert.
3770 (define_insn "*rotl<mode>3_mask"
3771 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3772 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3773 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3774 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3775 (match_operand:GPR 3 "const_int_operand" "n")))]
3776 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3778 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3780 [(set_attr "type" "shift")
3781 (set_attr "maybe_var_shift" "yes")])
3783 (define_insn_and_split "*rotl<mode>3_mask_dot"
3784 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3786 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3787 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3788 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3789 (match_operand:GPR 3 "const_int_operand" "n,n"))
3791 (clobber (match_scratch:GPR 0 "=r,r"))]
3792 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3793 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3795 if (which_alternative == 0)
3796 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3800 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3802 (and:GPR (match_dup 4)
3805 (compare:CC (match_dup 0)
3808 [(set_attr "type" "shift")
3809 (set_attr "maybe_var_shift" "yes")
3810 (set_attr "dot" "yes")
3811 (set_attr "length" "4,8")])
3813 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3814 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3816 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3817 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3818 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3819 (match_operand:GPR 3 "const_int_operand" "n,n"))
3821 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3822 (and:GPR (match_dup 4)
3824 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3825 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3827 if (which_alternative == 0)
3828 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3832 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3834 (and:GPR (match_dup 4)
3837 (compare:CC (match_dup 0)
3840 [(set_attr "type" "shift")
3841 (set_attr "maybe_var_shift" "yes")
3842 (set_attr "dot" "yes")
3843 (set_attr "length" "4,8")])
3845 ; Special case for less-than-0. We can do it with just one machine
3846 ; instruction, but the generic optimizers do not realise it is cheap.
3847 (define_insn "*lt0_<mode>di"
3848 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3849 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3853 [(set_attr "type" "shift")])
3855 (define_insn "*lt0_<mode>si"
3856 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3857 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3860 "rlwinm %0,%1,1,31,31"
3861 [(set_attr "type" "shift")])
3865 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3866 ; both are an AND so are the same precedence).
3867 (define_insn "*rotl<mode>3_insert"
3868 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3869 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3870 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3871 (match_operand:SI 2 "const_int_operand" "n")])
3872 (match_operand:GPR 3 "const_int_operand" "n"))
3873 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3874 (match_operand:GPR 6 "const_int_operand" "n"))))]
3875 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3876 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3878 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3880 [(set_attr "type" "insert")])
3881 ; FIXME: this needs an attr "size", so that the scheduler can see the
3882 ; difference between rlwimi and rldimi. We also might want dot forms,
3883 ; but not for rlwimi on POWER4 and similar processors.
3885 (define_insn "*rotl<mode>3_insert_2"
3886 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3887 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3888 (match_operand:GPR 6 "const_int_operand" "n"))
3889 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3890 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3891 (match_operand:SI 2 "const_int_operand" "n")])
3892 (match_operand:GPR 3 "const_int_operand" "n"))))]
3893 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3894 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3896 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3898 [(set_attr "type" "insert")])
3900 ; There are also some forms without one of the ANDs.
3901 (define_insn "*rotl<mode>3_insert_3"
3902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3903 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3904 (match_operand:GPR 4 "const_int_operand" "n"))
3905 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3906 (match_operand:SI 2 "const_int_operand" "n"))))]
3907 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3909 if (<MODE>mode == SImode)
3910 return "rlwimi %0,%1,%h2,0,31-%h2";
3912 return "rldimi %0,%1,%H2,0";
3914 [(set_attr "type" "insert")])
3916 (define_insn "*rotl<mode>3_insert_4"
3917 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3918 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3919 (match_operand:GPR 4 "const_int_operand" "n"))
3920 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3921 (match_operand:SI 2 "const_int_operand" "n"))))]
3922 "<MODE>mode == SImode &&
3923 GET_MODE_PRECISION (<MODE>mode)
3924 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3926 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3927 - INTVAL (operands[2]));
3928 if (<MODE>mode == SImode)
3929 return "rlwimi %0,%1,%h2,32-%h2,31";
3931 return "rldimi %0,%1,%H2,64-%H2";
3933 [(set_attr "type" "insert")])
3935 (define_insn "*rotlsi3_insert_5"
3936 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3937 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3938 (match_operand:SI 2 "const_int_operand" "n,n"))
3939 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3940 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3941 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3942 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3943 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3947 [(set_attr "type" "insert")])
3949 (define_insn "*rotldi3_insert_6"
3950 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3951 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3952 (match_operand:DI 2 "const_int_operand" "n"))
3953 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3954 (match_operand:DI 4 "const_int_operand" "n"))))]
3955 "exact_log2 (-UINTVAL (operands[2])) > 0
3956 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3958 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3959 return "rldimi %0,%3,0,%5";
3961 [(set_attr "type" "insert")
3962 (set_attr "size" "64")])
3964 (define_insn "*rotldi3_insert_7"
3965 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3966 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3967 (match_operand:DI 4 "const_int_operand" "n"))
3968 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3969 (match_operand:DI 2 "const_int_operand" "n"))))]
3970 "exact_log2 (-UINTVAL (operands[2])) > 0
3971 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3973 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3974 return "rldimi %0,%3,0,%5";
3976 [(set_attr "type" "insert")
3977 (set_attr "size" "64")])
3980 ; This handles the important case of multiple-precision shifts. There is
3981 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3983 [(set (match_operand:GPR 0 "gpc_reg_operand")
3984 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3985 (match_operand:SI 3 "const_int_operand"))
3986 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3987 (match_operand:SI 4 "const_int_operand"))))]
3988 "can_create_pseudo_p ()
3989 && INTVAL (operands[3]) + INTVAL (operands[4])
3990 >= GET_MODE_PRECISION (<MODE>mode)"
3992 (lshiftrt:GPR (match_dup 2)
3995 (ior:GPR (and:GPR (match_dup 5)
3997 (ashift:GPR (match_dup 1)
4000 unsigned HOST_WIDE_INT mask = 1;
4001 mask = (mask << INTVAL (operands[3])) - 1;
4002 operands[5] = gen_reg_rtx (<MODE>mode);
4003 operands[6] = GEN_INT (mask);
4007 [(set (match_operand:GPR 0 "gpc_reg_operand")
4008 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4009 (match_operand:SI 4 "const_int_operand"))
4010 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4011 (match_operand:SI 3 "const_int_operand"))))]
4012 "can_create_pseudo_p ()
4013 && INTVAL (operands[3]) + INTVAL (operands[4])
4014 >= GET_MODE_PRECISION (<MODE>mode)"
4016 (lshiftrt:GPR (match_dup 2)
4019 (ior:GPR (and:GPR (match_dup 5)
4021 (ashift:GPR (match_dup 1)
4024 unsigned HOST_WIDE_INT mask = 1;
4025 mask = (mask << INTVAL (operands[3])) - 1;
4026 operands[5] = gen_reg_rtx (<MODE>mode);
4027 operands[6] = GEN_INT (mask);
4031 ; Another important case is setting some bits to 1; we can do that with
4032 ; an insert instruction, in many cases.
4033 (define_insn_and_split "*ior<mode>_mask"
4034 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4035 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4036 (match_operand:GPR 2 "const_int_operand" "n")))
4037 (clobber (match_scratch:GPR 3 "=r"))]
4038 "!logical_const_operand (operands[2], <MODE>mode)
4039 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4045 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4048 (and:GPR (match_dup 1)
4052 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4053 if (GET_CODE (operands[3]) == SCRATCH)
4054 operands[3] = gen_reg_rtx (<MODE>mode);
4055 operands[4] = GEN_INT (ne);
4056 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4058 [(set_attr "type" "two")
4059 (set_attr "length" "8")])
4062 ;; Now the simple shifts.
4064 (define_insn "rotl<mode>3"
4065 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4066 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4067 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4069 "rotl<wd>%I2 %0,%1,%<hH>2"
4070 [(set_attr "type" "shift")
4071 (set_attr "maybe_var_shift" "yes")])
4073 (define_insn "*rotlsi3_64"
4074 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4076 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4077 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4079 "rotlw%I2 %0,%1,%h2"
4080 [(set_attr "type" "shift")
4081 (set_attr "maybe_var_shift" "yes")])
4083 (define_insn_and_split "*rotl<mode>3_dot"
4084 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4085 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4086 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4088 (clobber (match_scratch:GPR 0 "=r,r"))]
4089 "<MODE>mode == Pmode"
4091 rotl<wd>%I2. %0,%1,%<hH>2
4093 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4095 (rotate:GPR (match_dup 1)
4098 (compare:CC (match_dup 0)
4101 [(set_attr "type" "shift")
4102 (set_attr "maybe_var_shift" "yes")
4103 (set_attr "dot" "yes")
4104 (set_attr "length" "4,8")])
4106 (define_insn_and_split "*rotl<mode>3_dot2"
4107 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4108 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4109 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4111 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4112 (rotate:GPR (match_dup 1)
4114 "<MODE>mode == Pmode"
4116 rotl<wd>%I2. %0,%1,%<hH>2
4118 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4120 (rotate:GPR (match_dup 1)
4123 (compare:CC (match_dup 0)
4126 [(set_attr "type" "shift")
4127 (set_attr "maybe_var_shift" "yes")
4128 (set_attr "dot" "yes")
4129 (set_attr "length" "4,8")])
4132 (define_insn "ashl<mode>3"
4133 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4134 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4135 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4137 "sl<wd>%I2 %0,%1,%<hH>2"
4138 [(set_attr "type" "shift")
4139 (set_attr "maybe_var_shift" "yes")])
4141 (define_insn "*ashlsi3_64"
4142 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4144 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4145 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4148 [(set_attr "type" "shift")
4149 (set_attr "maybe_var_shift" "yes")])
4151 (define_insn_and_split "*ashl<mode>3_dot"
4152 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4153 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4154 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4156 (clobber (match_scratch:GPR 0 "=r,r"))]
4157 "<MODE>mode == Pmode"
4159 sl<wd>%I2. %0,%1,%<hH>2
4161 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4163 (ashift:GPR (match_dup 1)
4166 (compare:CC (match_dup 0)
4169 [(set_attr "type" "shift")
4170 (set_attr "maybe_var_shift" "yes")
4171 (set_attr "dot" "yes")
4172 (set_attr "length" "4,8")])
4174 (define_insn_and_split "*ashl<mode>3_dot2"
4175 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4176 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4177 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4179 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4180 (ashift:GPR (match_dup 1)
4182 "<MODE>mode == Pmode"
4184 sl<wd>%I2. %0,%1,%<hH>2
4186 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4188 (ashift:GPR (match_dup 1)
4191 (compare:CC (match_dup 0)
4194 [(set_attr "type" "shift")
4195 (set_attr "maybe_var_shift" "yes")
4196 (set_attr "dot" "yes")
4197 (set_attr "length" "4,8")])
4199 ;; Pretend we have a memory form of extswsli until register allocation is done
4200 ;; so that we use LWZ to load the value from memory, instead of LWA.
4201 (define_insn_and_split "ashdi3_extswsli"
4202 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4204 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4205 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4210 "&& reload_completed && MEM_P (operands[1])"
4214 (ashift:DI (sign_extend:DI (match_dup 3))
4217 operands[3] = gen_lowpart (SImode, operands[0]);
4219 [(set_attr "type" "shift")
4220 (set_attr "maybe_var_shift" "no")])
4223 (define_insn_and_split "ashdi3_extswsli_dot"
4224 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4227 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4228 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4230 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4237 "&& reload_completed
4238 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4239 || memory_operand (operands[1], SImode))"
4242 rtx dest = operands[0];
4243 rtx src = operands[1];
4244 rtx shift = operands[2];
4245 rtx cr = operands[3];
4252 src2 = gen_lowpart (SImode, dest);
4253 emit_move_insn (src2, src);
4256 if (REGNO (cr) == CR0_REGNO)
4258 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4262 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4263 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4266 [(set_attr "type" "shift")
4267 (set_attr "maybe_var_shift" "no")
4268 (set_attr "dot" "yes")
4269 (set_attr "length" "4,8,8,12")])
4271 (define_insn_and_split "ashdi3_extswsli_dot2"
4272 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4275 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4276 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4278 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4279 (ashift:DI (sign_extend:DI (match_dup 1))
4287 "&& reload_completed
4288 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4289 || memory_operand (operands[1], SImode))"
4292 rtx dest = operands[0];
4293 rtx src = operands[1];
4294 rtx shift = operands[2];
4295 rtx cr = operands[3];
4302 src2 = gen_lowpart (SImode, dest);
4303 emit_move_insn (src2, src);
4306 if (REGNO (cr) == CR0_REGNO)
4308 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4312 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4313 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4316 [(set_attr "type" "shift")
4317 (set_attr "maybe_var_shift" "no")
4318 (set_attr "dot" "yes")
4319 (set_attr "length" "4,8,8,12")])
4321 (define_insn "lshr<mode>3"
4322 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4323 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4324 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4326 "sr<wd>%I2 %0,%1,%<hH>2"
4327 [(set_attr "type" "shift")
4328 (set_attr "maybe_var_shift" "yes")])
4330 (define_insn "*lshrsi3_64"
4331 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4333 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4334 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4337 [(set_attr "type" "shift")
4338 (set_attr "maybe_var_shift" "yes")])
4340 (define_insn_and_split "*lshr<mode>3_dot"
4341 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4342 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4343 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4345 (clobber (match_scratch:GPR 0 "=r,r"))]
4346 "<MODE>mode == Pmode"
4348 sr<wd>%I2. %0,%1,%<hH>2
4350 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4352 (lshiftrt:GPR (match_dup 1)
4355 (compare:CC (match_dup 0)
4358 [(set_attr "type" "shift")
4359 (set_attr "maybe_var_shift" "yes")
4360 (set_attr "dot" "yes")
4361 (set_attr "length" "4,8")])
4363 (define_insn_and_split "*lshr<mode>3_dot2"
4364 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4365 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4366 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4368 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4369 (lshiftrt:GPR (match_dup 1)
4371 "<MODE>mode == Pmode"
4373 sr<wd>%I2. %0,%1,%<hH>2
4375 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4377 (lshiftrt:GPR (match_dup 1)
4380 (compare:CC (match_dup 0)
4383 [(set_attr "type" "shift")
4384 (set_attr "maybe_var_shift" "yes")
4385 (set_attr "dot" "yes")
4386 (set_attr "length" "4,8")])
4389 (define_insn "ashr<mode>3"
4390 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4391 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4392 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4393 (clobber (reg:GPR CA_REGNO))]
4395 "sra<wd>%I2 %0,%1,%<hH>2"
4396 [(set_attr "type" "shift")
4397 (set_attr "maybe_var_shift" "yes")])
4399 (define_insn "*ashrsi3_64"
4400 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4402 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4403 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4404 (clobber (reg:SI CA_REGNO))]
4407 [(set_attr "type" "shift")
4408 (set_attr "maybe_var_shift" "yes")])
4410 (define_insn_and_split "*ashr<mode>3_dot"
4411 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4412 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4413 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4415 (clobber (match_scratch:GPR 0 "=r,r"))
4416 (clobber (reg:GPR CA_REGNO))]
4417 "<MODE>mode == Pmode"
4419 sra<wd>%I2. %0,%1,%<hH>2
4421 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4422 [(parallel [(set (match_dup 0)
4423 (ashiftrt:GPR (match_dup 1)
4425 (clobber (reg:GPR CA_REGNO))])
4427 (compare:CC (match_dup 0)
4430 [(set_attr "type" "shift")
4431 (set_attr "maybe_var_shift" "yes")
4432 (set_attr "dot" "yes")
4433 (set_attr "length" "4,8")])
4435 (define_insn_and_split "*ashr<mode>3_dot2"
4436 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4437 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4438 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4440 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4441 (ashiftrt:GPR (match_dup 1)
4443 (clobber (reg:GPR CA_REGNO))]
4444 "<MODE>mode == Pmode"
4446 sra<wd>%I2. %0,%1,%<hH>2
4448 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4449 [(parallel [(set (match_dup 0)
4450 (ashiftrt:GPR (match_dup 1)
4452 (clobber (reg:GPR CA_REGNO))])
4454 (compare:CC (match_dup 0)
4457 [(set_attr "type" "shift")
4458 (set_attr "maybe_var_shift" "yes")
4459 (set_attr "dot" "yes")
4460 (set_attr "length" "4,8")])
4462 ;; Builtins to replace a division to generate FRE reciprocal estimate
4463 ;; instructions and the necessary fixup instructions
4464 (define_expand "recip<mode>3"
4465 [(match_operand:RECIPF 0 "gpc_reg_operand")
4466 (match_operand:RECIPF 1 "gpc_reg_operand")
4467 (match_operand:RECIPF 2 "gpc_reg_operand")]
4468 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4470 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4474 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4475 ;; hardware division. This is only done before register allocation and with
4476 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4477 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4478 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4480 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4481 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4482 (match_operand 2 "gpc_reg_operand")))]
4483 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4484 && can_create_pseudo_p () && flag_finite_math_only
4485 && !flag_trapping_math && flag_reciprocal_math"
4488 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4492 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4493 ;; appropriate fixup.
4494 (define_expand "rsqrt<mode>2"
4495 [(match_operand:RECIPF 0 "gpc_reg_operand")
4496 (match_operand:RECIPF 1 "gpc_reg_operand")]
4497 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4499 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4503 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4504 ;; modes here, and also add in conditional vsx/power8-vector support to access
4505 ;; values in the traditional Altivec registers if the appropriate
4506 ;; -mupper-regs-{df,sf} option is enabled.
4508 (define_expand "abs<mode>2"
4509 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4510 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4514 (define_insn "*abs<mode>2_fpr"
4515 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4516 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4521 [(set_attr "type" "fpsimple")])
4523 (define_insn "*nabs<mode>2_fpr"
4524 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4527 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4532 [(set_attr "type" "fpsimple")])
4534 (define_expand "neg<mode>2"
4535 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4536 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4540 (define_insn "*neg<mode>2_fpr"
4541 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4542 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4547 [(set_attr "type" "fpsimple")])
4549 (define_expand "add<mode>3"
4550 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4551 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4552 (match_operand:SFDF 2 "gpc_reg_operand")))]
4556 (define_insn "*add<mode>3_fpr"
4557 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4558 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4559 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4562 fadd<Ftrad> %0,%1,%2
4563 xsadd<Fvsx> %x0,%x1,%x2"
4564 [(set_attr "type" "fp")])
4566 (define_expand "sub<mode>3"
4567 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4568 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4569 (match_operand:SFDF 2 "gpc_reg_operand")))]
4573 (define_insn "*sub<mode>3_fpr"
4574 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4575 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4576 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4579 fsub<Ftrad> %0,%1,%2
4580 xssub<Fvsx> %x0,%x1,%x2"
4581 [(set_attr "type" "fp")])
4583 (define_expand "mul<mode>3"
4584 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4585 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4586 (match_operand:SFDF 2 "gpc_reg_operand")))]
4590 (define_insn "*mul<mode>3_fpr"
4591 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4592 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4593 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4596 fmul<Ftrad> %0,%1,%2
4597 xsmul<Fvsx> %x0,%x1,%x2"
4598 [(set_attr "type" "dmul")])
4600 (define_expand "div<mode>3"
4601 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4602 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4603 (match_operand:SFDF 2 "gpc_reg_operand")))]
4606 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4607 && can_create_pseudo_p () && flag_finite_math_only
4608 && !flag_trapping_math && flag_reciprocal_math)
4610 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4615 (define_insn "*div<mode>3_fpr"
4616 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4617 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4618 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4621 fdiv<Ftrad> %0,%1,%2
4622 xsdiv<Fvsx> %x0,%x1,%x2"
4623 [(set_attr "type" "<Fs>div")])
4625 (define_insn "*sqrt<mode>2_internal"
4626 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4627 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4628 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4631 xssqrt<Fvsx> %x0,%x1"
4632 [(set_attr "type" "<Fs>sqrt")])
4634 (define_expand "sqrt<mode>2"
4635 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4636 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4637 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4639 if (<MODE>mode == SFmode
4640 && TARGET_RECIP_PRECISION
4641 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4642 && !optimize_function_for_size_p (cfun)
4643 && flag_finite_math_only && !flag_trapping_math
4644 && flag_unsafe_math_optimizations)
4646 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4651 ;; Floating point reciprocal approximation
4652 (define_insn "fre<Fs>"
4653 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4654 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4660 [(set_attr "type" "fp")])
4662 (define_insn "*rsqrt<mode>2"
4663 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4664 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4666 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4668 frsqrte<Ftrad> %0,%1
4669 xsrsqrte<Fvsx> %x0,%x1"
4670 [(set_attr "type" "fp")])
4672 ;; Floating point comparisons
4673 (define_insn "*cmp<mode>_fpr"
4674 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4675 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4676 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4680 xscmpudp %0,%x1,%x2"
4681 [(set_attr "type" "fpcompare")])
4683 ;; Floating point conversions
4684 (define_expand "extendsfdf2"
4685 [(set (match_operand:DF 0 "gpc_reg_operand")
4686 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4689 if (HONOR_SNANS (SFmode))
4690 operands[1] = force_reg (SFmode, operands[1]);
4693 (define_insn_and_split "*extendsfdf2_fpr"
4694 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4695 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4696 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4702 xscpsgndp %x0,%x1,%x1
4705 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4708 emit_note (NOTE_INSN_DELETED);
4711 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4713 (define_insn "*extendsfdf2_snan"
4714 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4715 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4716 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4720 [(set_attr "type" "fp")])
4722 (define_expand "truncdfsf2"
4723 [(set (match_operand:SF 0 "gpc_reg_operand")
4724 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4728 (define_insn "*truncdfsf2_fpr"
4729 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4730 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4735 [(set_attr "type" "fp")])
4737 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4738 ;; builtins.c and optabs.c that are not correct for IBM long double
4739 ;; when little-endian.
4740 (define_expand "signbit<mode>2"
4742 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4744 (subreg:DI (match_dup 2) 0))
4747 (set (match_operand:SI 0 "gpc_reg_operand")
4750 && (!FLOAT128_IEEE_P (<MODE>mode)
4751 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4753 if (FLOAT128_IEEE_P (<MODE>mode))
4755 rtx dest = operands[0];
4756 rtx src = operands[1];
4757 rtx tmp = gen_reg_rtx (DImode);
4758 rtx dest_di = gen_lowpart (DImode, dest);
4760 if (<MODE>mode == KFmode)
4761 emit_insn (gen_signbitkf2_dm (tmp, src));
4762 else if (<MODE>mode == TFmode)
4763 emit_insn (gen_signbittf2_dm (tmp, src));
4767 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4770 operands[2] = gen_reg_rtx (DFmode);
4771 operands[3] = gen_reg_rtx (DImode);
4772 if (TARGET_POWERPC64)
4774 operands[4] = gen_reg_rtx (DImode);
4775 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4776 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4777 WORDS_BIG_ENDIAN ? 4 : 0);
4781 operands[4] = gen_reg_rtx (SImode);
4782 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4783 WORDS_BIG_ENDIAN ? 0 : 4);
4784 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4788 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4789 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4790 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4791 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4793 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4794 ;; split allows the post reload phases to eliminate the move, and do the shift
4795 ;; directly with the register that contains the signbit.
4796 (define_insn_and_split "signbit<mode>2_dm"
4797 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4798 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4800 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4804 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4808 operands[2] = gen_highpart (DImode, operands[1]);
4810 [(set_attr "type" "mftgpr,*")])
4812 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4813 ;; register and then doing a direct move if the value comes from memory. On
4814 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4815 (define_insn_and_split "*signbit<mode>2_dm_mem"
4816 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4817 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4819 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4825 rtx dest = operands[0];
4826 rtx src = operands[1];
4827 rtx addr = XEXP (src, 0);
4829 if (WORDS_BIG_ENDIAN)
4830 operands[2] = adjust_address (src, DImode, 0);
4832 else if (REG_P (addr) || SUBREG_P (addr))
4833 operands[2] = adjust_address (src, DImode, 8);
4835 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4836 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4837 operands[2] = adjust_address (src, DImode, 8);
4841 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4842 emit_insn (gen_rtx_SET (tmp, addr));
4843 operands[2] = change_address (src, DImode,
4844 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4848 (define_expand "copysign<mode>3"
4850 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4852 (neg:SFDF (abs:SFDF (match_dup 1))))
4853 (set (match_operand:SFDF 0 "gpc_reg_operand")
4854 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4859 && ((TARGET_PPC_GFXOPT
4860 && !HONOR_NANS (<MODE>mode)
4861 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4863 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4865 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4867 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4872 operands[3] = gen_reg_rtx (<MODE>mode);
4873 operands[4] = gen_reg_rtx (<MODE>mode);
4874 operands[5] = CONST0_RTX (<MODE>mode);
4877 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4878 ;; compiler from optimizing -0.0
4879 (define_insn "copysign<mode>3_fcpsgn"
4880 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4881 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4882 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4884 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4887 xscpsgndp %x0,%x2,%x1"
4888 [(set_attr "type" "fpsimple")])
4890 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4891 ;; fsel instruction and some auxiliary computations. Then we just have a
4892 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4894 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4895 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4896 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4897 ;; define_splits to make them if made by combine. On VSX machines we have the
4898 ;; min/max instructions.
4900 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4901 ;; to allow either DF/SF to use only traditional registers.
4903 (define_expand "s<minmax><mode>3"
4904 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4905 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4906 (match_operand:SFDF 2 "gpc_reg_operand")))]
4909 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4913 (define_insn "*s<minmax><mode>3_vsx"
4914 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4915 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4916 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4917 "TARGET_VSX && TARGET_HARD_FLOAT"
4919 return (TARGET_P9_MINMAX
4920 ? "xs<minmax>cdp %x0,%x1,%x2"
4921 : "xs<minmax>dp %x0,%x1,%x2");
4923 [(set_attr "type" "fp")])
4925 ;; The conditional move instructions allow us to perform max and min operations
4926 ;; even when we don't have the appropriate max/min instruction using the FSEL
4929 (define_insn_and_split "*s<minmax><mode>3_fpr"
4930 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4931 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4932 (match_operand:SFDF 2 "gpc_reg_operand")))]
4933 "!TARGET_VSX && TARGET_MINMAX"
4938 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4942 (define_expand "mov<mode>cc"
4943 [(set (match_operand:GPR 0 "gpc_reg_operand")
4944 (if_then_else:GPR (match_operand 1 "comparison_operator")
4945 (match_operand:GPR 2 "gpc_reg_operand")
4946 (match_operand:GPR 3 "gpc_reg_operand")))]
4949 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4955 ;; We use the BASE_REGS for the isel input operands because, if rA is
4956 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4957 ;; because we may switch the operands and rB may end up being rA.
4959 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4960 ;; leave out the mode in operand 4 and use one pattern, but reload can
4961 ;; change the mode underneath our feet and then gets confused trying
4962 ;; to reload the value.
4963 (define_insn "isel_signed_<mode>"
4964 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4966 (match_operator 1 "scc_comparison_operator"
4967 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4969 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4970 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4973 [(set_attr "type" "isel")])
4975 (define_insn "isel_unsigned_<mode>"
4976 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4978 (match_operator 1 "scc_comparison_operator"
4979 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4981 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4982 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4985 [(set_attr "type" "isel")])
4987 ;; These patterns can be useful for combine; they let combine know that
4988 ;; isel can handle reversed comparisons so long as the operands are
4991 (define_insn "*isel_reversed_signed_<mode>"
4992 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4994 (match_operator 1 "scc_rev_comparison_operator"
4995 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4997 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
4998 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5001 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5002 return "isel %0,%3,%2,%j1";
5004 [(set_attr "type" "isel")])
5006 (define_insn "*isel_reversed_unsigned_<mode>"
5007 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5009 (match_operator 1 "scc_rev_comparison_operator"
5010 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5012 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5013 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5016 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5017 return "isel %0,%3,%2,%j1";
5019 [(set_attr "type" "isel")])
5021 ;; Floating point conditional move
5022 (define_expand "mov<mode>cc"
5023 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5024 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5025 (match_operand:SFDF 2 "gpc_reg_operand")
5026 (match_operand:SFDF 3 "gpc_reg_operand")))]
5027 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5029 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5035 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5036 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5038 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5039 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5040 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5041 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5042 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5044 [(set_attr "type" "fp")])
5046 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5047 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5049 (match_operator:CCFP 1 "fpmask_comparison_operator"
5050 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5051 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5052 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5053 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5054 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5059 (if_then_else:V2DI (match_dup 1)
5063 (if_then_else:SFDF (ne (match_dup 6)
5068 if (GET_CODE (operands[6]) == SCRATCH)
5069 operands[6] = gen_reg_rtx (V2DImode);
5071 operands[7] = CONSTM1_RTX (V2DImode);
5072 operands[8] = CONST0_RTX (V2DImode);
5074 [(set_attr "length" "8")
5075 (set_attr "type" "vecperm")])
5077 ;; Handle inverting the fpmask comparisons.
5078 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5079 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5081 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5082 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5083 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5084 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5085 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5086 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5091 (if_then_else:V2DI (match_dup 9)
5095 (if_then_else:SFDF (ne (match_dup 6)
5100 rtx op1 = operands[1];
5101 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5103 if (GET_CODE (operands[6]) == SCRATCH)
5104 operands[6] = gen_reg_rtx (V2DImode);
5106 operands[7] = CONSTM1_RTX (V2DImode);
5107 operands[8] = CONST0_RTX (V2DImode);
5109 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5111 [(set_attr "length" "8")
5112 (set_attr "type" "vecperm")])
5114 (define_insn "*fpmask<mode>"
5115 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5117 (match_operator:CCFP 1 "fpmask_comparison_operator"
5118 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5119 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5120 (match_operand:V2DI 4 "all_ones_constant" "")
5121 (match_operand:V2DI 5 "zero_constant" "")))]
5123 "xscmp%V1dp %x0,%x2,%x3"
5124 [(set_attr "type" "fpcompare")])
5126 (define_insn "*xxsel<mode>"
5127 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5128 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5129 (match_operand:V2DI 2 "zero_constant" ""))
5130 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5131 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5133 "xxsel %x0,%x4,%x3,%x1"
5134 [(set_attr "type" "vecmove")])
5137 ;; Conversions to and from floating-point.
5139 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5140 ; don't want to support putting SImode in FPR registers.
5141 (define_insn "lfiwax"
5142 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5143 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5145 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5151 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5153 ; This split must be run before register allocation because it allocates the
5154 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5155 ; it earlier to allow for the combiner to merge insns together where it might
5156 ; not be needed and also in case the insns are deleted as dead code.
5158 (define_insn_and_split "floatsi<mode>2_lfiwax"
5159 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5160 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5161 (clobber (match_scratch:DI 2 "=wi"))]
5162 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5163 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5168 rtx dest = operands[0];
5169 rtx src = operands[1];
5172 if (!MEM_P (src) && TARGET_POWERPC64
5173 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5174 tmp = convert_to_mode (DImode, src, false);
5178 if (GET_CODE (tmp) == SCRATCH)
5179 tmp = gen_reg_rtx (DImode);
5182 src = rs6000_address_for_fpconvert (src);
5183 emit_insn (gen_lfiwax (tmp, src));
5187 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5188 emit_move_insn (stack, src);
5189 emit_insn (gen_lfiwax (tmp, stack));
5192 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5195 [(set_attr "length" "12")
5196 (set_attr "type" "fpload")])
5198 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5199 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5202 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5203 (clobber (match_scratch:DI 2 "=wi"))]
5204 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5209 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5210 if (GET_CODE (operands[2]) == SCRATCH)
5211 operands[2] = gen_reg_rtx (DImode);
5212 if (TARGET_P8_VECTOR)
5213 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5215 emit_insn (gen_lfiwax (operands[2], operands[1]));
5216 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5219 [(set_attr "length" "8")
5220 (set_attr "type" "fpload")])
5222 (define_insn "lfiwzx"
5223 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5224 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5226 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5231 xxextractuw %x0,%x1,4"
5232 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5234 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5235 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5236 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5237 (clobber (match_scratch:DI 2 "=wi"))]
5238 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5243 rtx dest = operands[0];
5244 rtx src = operands[1];
5247 if (!MEM_P (src) && TARGET_POWERPC64
5248 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5249 tmp = convert_to_mode (DImode, src, true);
5253 if (GET_CODE (tmp) == SCRATCH)
5254 tmp = gen_reg_rtx (DImode);
5257 src = rs6000_address_for_fpconvert (src);
5258 emit_insn (gen_lfiwzx (tmp, src));
5262 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5263 emit_move_insn (stack, src);
5264 emit_insn (gen_lfiwzx (tmp, stack));
5267 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5270 [(set_attr "length" "12")
5271 (set_attr "type" "fpload")])
5273 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5274 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5275 (unsigned_float:SFDF
5277 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5278 (clobber (match_scratch:DI 2 "=wi"))]
5279 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5284 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5285 if (GET_CODE (operands[2]) == SCRATCH)
5286 operands[2] = gen_reg_rtx (DImode);
5287 if (TARGET_P8_VECTOR)
5288 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5290 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5291 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5294 [(set_attr "length" "8")
5295 (set_attr "type" "fpload")])
5297 ; For each of these conversions, there is a define_expand, a define_insn
5298 ; with a '#' template, and a define_split (with C code). The idea is
5299 ; to allow constant folding with the template of the define_insn,
5300 ; then to have the insns split later (between sched1 and final).
5302 (define_expand "floatsidf2"
5303 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5304 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5307 (clobber (match_dup 4))
5308 (clobber (match_dup 5))
5309 (clobber (match_dup 6))])]
5312 if (TARGET_LFIWAX && TARGET_FCFID)
5314 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5317 else if (TARGET_FCFID)
5319 rtx dreg = operands[1];
5321 dreg = force_reg (SImode, dreg);
5322 dreg = convert_to_mode (DImode, dreg, false);
5323 emit_insn (gen_floatdidf2 (operands[0], dreg));
5327 if (!REG_P (operands[1]))
5328 operands[1] = force_reg (SImode, operands[1]);
5329 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5330 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5331 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5332 operands[5] = gen_reg_rtx (DFmode);
5333 operands[6] = gen_reg_rtx (SImode);
5336 (define_insn_and_split "*floatsidf2_internal"
5337 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5338 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5339 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5340 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5341 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5342 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5343 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5344 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5349 rtx lowword, highword;
5350 gcc_assert (MEM_P (operands[4]));
5351 highword = adjust_address (operands[4], SImode, 0);
5352 lowword = adjust_address (operands[4], SImode, 4);
5353 if (! WORDS_BIG_ENDIAN)
5354 std::swap (lowword, highword);
5356 emit_insn (gen_xorsi3 (operands[6], operands[1],
5357 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5358 emit_move_insn (lowword, operands[6]);
5359 emit_move_insn (highword, operands[2]);
5360 emit_move_insn (operands[5], operands[4]);
5361 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5364 [(set_attr "length" "24")
5365 (set_attr "type" "fp")])
5367 ;; If we don't have a direct conversion to single precision, don't enable this
5368 ;; conversion for 32-bit without fast math, because we don't have the insn to
5369 ;; generate the fixup swizzle to avoid double rounding problems.
5370 (define_expand "floatunssisf2"
5371 [(set (match_operand:SF 0 "gpc_reg_operand")
5372 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5374 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5376 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5378 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5380 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5385 rtx dreg = operands[1];
5387 dreg = force_reg (SImode, dreg);
5388 dreg = convert_to_mode (DImode, dreg, true);
5389 emit_insn (gen_floatdisf2 (operands[0], dreg));
5394 (define_expand "floatunssidf2"
5395 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5396 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5399 (clobber (match_dup 4))
5400 (clobber (match_dup 5))])]
5403 if (TARGET_LFIWZX && TARGET_FCFID)
5405 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5408 else if (TARGET_FCFID)
5410 rtx dreg = operands[1];
5412 dreg = force_reg (SImode, dreg);
5413 dreg = convert_to_mode (DImode, dreg, true);
5414 emit_insn (gen_floatdidf2 (operands[0], dreg));
5418 if (!REG_P (operands[1]))
5419 operands[1] = force_reg (SImode, operands[1]);
5420 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5421 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5422 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5423 operands[5] = gen_reg_rtx (DFmode);
5426 (define_insn_and_split "*floatunssidf2_internal"
5427 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5428 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5429 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5430 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5431 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5432 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5433 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5434 && !(TARGET_FCFID && TARGET_POWERPC64)"
5439 rtx lowword, highword;
5440 gcc_assert (MEM_P (operands[4]));
5441 highword = adjust_address (operands[4], SImode, 0);
5442 lowword = adjust_address (operands[4], SImode, 4);
5443 if (! WORDS_BIG_ENDIAN)
5444 std::swap (lowword, highword);
5446 emit_move_insn (lowword, operands[1]);
5447 emit_move_insn (highword, operands[2]);
5448 emit_move_insn (operands[5], operands[4]);
5449 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5452 [(set_attr "length" "20")
5453 (set_attr "type" "fp")])
5455 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5456 ;; vector registers. These insns favor doing the sign/zero extension in
5457 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5458 ;; extension and then a direct move.
5460 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5461 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5463 (match_operand:QHI 1 "input_operand")))
5464 (clobber (match_scratch:DI 2))
5465 (clobber (match_scratch:DI 3))
5466 (clobber (match_scratch:<QHI:MODE> 4))])]
5467 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5469 if (MEM_P (operands[1]))
5470 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5473 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5474 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5476 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5477 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5478 (clobber (match_scratch:DI 3 "=X,r,X"))
5479 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5480 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5482 "&& reload_completed"
5485 rtx result = operands[0];
5486 rtx input = operands[1];
5487 rtx di = operands[2];
5491 rtx tmp = operands[3];
5492 if (altivec_register_operand (input, <QHI:MODE>mode))
5493 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5494 else if (GET_CODE (tmp) == SCRATCH)
5495 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5498 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5499 emit_move_insn (di, tmp);
5504 rtx tmp = operands[4];
5505 emit_move_insn (tmp, input);
5506 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5509 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5513 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5514 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5515 (unsigned_float:FP_ISA3
5516 (match_operand:QHI 1 "input_operand")))
5517 (clobber (match_scratch:DI 2))
5518 (clobber (match_scratch:DI 3))])]
5519 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5521 if (MEM_P (operands[1]))
5522 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5525 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5526 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5527 (unsigned_float:FP_ISA3
5528 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5529 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5530 (clobber (match_scratch:DI 3 "=X,r,X"))]
5531 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5533 "&& reload_completed"
5536 rtx result = operands[0];
5537 rtx input = operands[1];
5538 rtx di = operands[2];
5540 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5541 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5544 rtx tmp = operands[3];
5545 if (GET_CODE (tmp) == SCRATCH)
5546 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5549 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5550 emit_move_insn (di, tmp);
5554 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5558 (define_expand "fix_trunc<mode>si2"
5559 [(set (match_operand:SI 0 "gpc_reg_operand")
5560 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5563 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5565 rtx src = force_reg (<MODE>mode, operands[1]);
5568 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5571 rtx tmp = gen_reg_rtx (DImode);
5572 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5573 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5580 ; Like the convert to float patterns, this insn must be split before
5581 ; register allocation so that it can allocate the memory slot if it
5583 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5584 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5585 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5586 (clobber (match_scratch:DI 2 "=d"))]
5587 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5588 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5593 rtx dest = operands[0];
5594 rtx src = operands[1];
5595 rtx tmp = operands[2];
5597 if (GET_CODE (tmp) == SCRATCH)
5598 tmp = gen_reg_rtx (DImode);
5600 emit_insn (gen_fctiwz_<mode> (tmp, src));
5603 dest = rs6000_address_for_fpconvert (dest);
5604 emit_insn (gen_stfiwx (dest, tmp));
5607 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5609 dest = gen_lowpart (DImode, dest);
5610 emit_move_insn (dest, tmp);
5615 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5616 emit_insn (gen_stfiwx (stack, tmp));
5617 emit_move_insn (dest, stack);
5621 [(set_attr "length" "12")
5622 (set_attr "type" "fp")])
5624 (define_insn_and_split "fix_trunc<mode>si2_internal"
5625 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5626 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5627 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5628 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5630 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5636 gcc_assert (MEM_P (operands[3]));
5637 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5639 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5640 emit_move_insn (operands[3], operands[2]);
5641 emit_move_insn (operands[0], lowword);
5644 [(set_attr "length" "16")
5645 (set_attr "type" "fp")])
5647 (define_expand "fix_trunc<mode>di2"
5648 [(set (match_operand:DI 0 "gpc_reg_operand")
5649 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5650 "TARGET_HARD_FLOAT && TARGET_FCFID"
5653 (define_insn "*fix_trunc<mode>di2_fctidz"
5654 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5655 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5656 "TARGET_HARD_FLOAT && TARGET_FCFID"
5660 [(set_attr "type" "fp")])
5662 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5663 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5664 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5665 ;; values can go in VSX registers. Keeping the direct move part through
5666 ;; register allocation prevents the register allocator from doing a direct move
5667 ;; of the SImode value to a GPR, and then a store/load.
5668 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5669 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5670 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5671 (clobber (match_scratch:SI 2 "=X,X,wi"))]
5672 "TARGET_DIRECT_MOVE"
5675 xscvdp<su>xws %x0,%x1
5677 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5679 (any_fix:SI (match_dup 1)))
5683 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5685 [(set_attr "length" "4,4,8")
5686 (set_attr "type" "fp")])
5688 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5689 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5690 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5691 "TARGET_DIRECT_MOVE"
5694 xscvdp<su>xws %x0,%x1"
5695 [(set_attr "type" "fp")])
5697 ;; Keep the convert and store together through register allocation to prevent
5698 ;; the register allocator from getting clever and doing a direct move to a GPR
5699 ;; and then store for reg+offset stores.
5700 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5701 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5702 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5703 (clobber (match_scratch:SI 2 "=wa"))]
5704 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5706 "&& reload_completed"
5708 (any_fix:SI (match_dup 1)))
5712 operands[3] = (<QHSI:MODE>mode == SImode
5714 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5717 (define_expand "fixuns_trunc<mode>si2"
5718 [(set (match_operand:SI 0 "gpc_reg_operand")
5719 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5720 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5722 if (!TARGET_P8_VECTOR)
5724 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5729 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5730 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5731 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5732 (clobber (match_scratch:DI 2 "=d"))]
5733 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5734 && TARGET_STFIWX && can_create_pseudo_p ()
5735 && !TARGET_P8_VECTOR"
5740 rtx dest = operands[0];
5741 rtx src = operands[1];
5742 rtx tmp = operands[2];
5744 if (GET_CODE (tmp) == SCRATCH)
5745 tmp = gen_reg_rtx (DImode);
5747 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5750 dest = rs6000_address_for_fpconvert (dest);
5751 emit_insn (gen_stfiwx (dest, tmp));
5754 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5756 dest = gen_lowpart (DImode, dest);
5757 emit_move_insn (dest, tmp);
5762 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5763 emit_insn (gen_stfiwx (stack, tmp));
5764 emit_move_insn (dest, stack);
5768 [(set_attr "length" "12")
5769 (set_attr "type" "fp")])
5771 (define_insn "fixuns_trunc<mode>di2"
5772 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5773 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5774 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5778 [(set_attr "type" "fp")])
5780 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5781 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5782 ;; because the first makes it clear that operand 0 is not live
5783 ;; before the instruction.
5784 (define_insn "fctiwz_<mode>"
5785 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5787 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5793 [(set_attr "type" "fp")])
5795 (define_insn "fctiwuz_<mode>"
5796 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5797 (unspec:DI [(unsigned_fix:SI
5798 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5800 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5804 [(set_attr "type" "fp")])
5806 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5807 ;; since the friz instruction does not truncate the value if the floating
5808 ;; point value is < LONG_MIN or > LONG_MAX.
5809 (define_insn "*friz"
5810 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5811 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5812 "TARGET_HARD_FLOAT && TARGET_FPRND
5813 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5817 [(set_attr "type" "fp")])
5819 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5820 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5821 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5822 ;; extend it, store it back on the stack from the GPR, load it back into the
5823 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5824 ;; disable using store and load to sign/zero extend the value.
5825 (define_insn_and_split "*round32<mode>2_fprs"
5826 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5828 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5829 (clobber (match_scratch:DI 2 "=d"))
5830 (clobber (match_scratch:DI 3 "=d"))]
5832 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5833 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5838 rtx dest = operands[0];
5839 rtx src = operands[1];
5840 rtx tmp1 = operands[2];
5841 rtx tmp2 = operands[3];
5842 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5844 if (GET_CODE (tmp1) == SCRATCH)
5845 tmp1 = gen_reg_rtx (DImode);
5846 if (GET_CODE (tmp2) == SCRATCH)
5847 tmp2 = gen_reg_rtx (DImode);
5849 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5850 emit_insn (gen_stfiwx (stack, tmp1));
5851 emit_insn (gen_lfiwax (tmp2, stack));
5852 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5855 [(set_attr "type" "fpload")
5856 (set_attr "length" "16")])
5858 (define_insn_and_split "*roundu32<mode>2_fprs"
5859 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5860 (unsigned_float:SFDF
5861 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5862 (clobber (match_scratch:DI 2 "=d"))
5863 (clobber (match_scratch:DI 3 "=d"))]
5865 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5866 && can_create_pseudo_p ()"
5871 rtx dest = operands[0];
5872 rtx src = operands[1];
5873 rtx tmp1 = operands[2];
5874 rtx tmp2 = operands[3];
5875 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5877 if (GET_CODE (tmp1) == SCRATCH)
5878 tmp1 = gen_reg_rtx (DImode);
5879 if (GET_CODE (tmp2) == SCRATCH)
5880 tmp2 = gen_reg_rtx (DImode);
5882 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5883 emit_insn (gen_stfiwx (stack, tmp1));
5884 emit_insn (gen_lfiwzx (tmp2, stack));
5885 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5888 [(set_attr "type" "fpload")
5889 (set_attr "length" "16")])
5891 ;; No VSX equivalent to fctid
5892 (define_insn "lrint<mode>di2"
5893 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5894 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5896 "TARGET_HARD_FLOAT && TARGET_FPRND"
5898 [(set_attr "type" "fp")])
5900 (define_insn "btrunc<mode>2"
5901 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5902 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5904 "TARGET_HARD_FLOAT && TARGET_FPRND"
5908 [(set_attr "type" "fp")])
5910 (define_insn "ceil<mode>2"
5911 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5912 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5914 "TARGET_HARD_FLOAT && TARGET_FPRND"
5918 [(set_attr "type" "fp")])
5920 (define_insn "floor<mode>2"
5921 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5922 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5924 "TARGET_HARD_FLOAT && TARGET_FPRND"
5928 [(set_attr "type" "fp")])
5930 ;; No VSX equivalent to frin
5931 (define_insn "round<mode>2"
5932 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5933 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5935 "TARGET_HARD_FLOAT && TARGET_FPRND"
5937 [(set_attr "type" "fp")])
5939 (define_insn "*xsrdpi<mode>2"
5940 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5941 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5943 "TARGET_HARD_FLOAT && TARGET_VSX"
5945 [(set_attr "type" "fp")])
5947 (define_expand "lround<mode>di2"
5949 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
5951 (set (match_operand:DI 0 "gpc_reg_operand")
5952 (unspec:DI [(match_dup 2)]
5954 "TARGET_HARD_FLOAT && TARGET_VSX"
5956 operands[2] = gen_reg_rtx (<MODE>mode);
5959 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5960 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5961 ; is only generated for Power8 or later.
5962 (define_insn "stfiwx"
5963 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5964 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5970 [(set_attr "type" "fpstore")])
5972 ;; If we don't have a direct conversion to single precision, don't enable this
5973 ;; conversion for 32-bit without fast math, because we don't have the insn to
5974 ;; generate the fixup swizzle to avoid double rounding problems.
5975 (define_expand "floatsisf2"
5976 [(set (match_operand:SF 0 "gpc_reg_operand")
5977 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5979 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5981 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5983 if (TARGET_FCFIDS && TARGET_LFIWAX)
5985 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5988 else if (TARGET_FCFID && TARGET_LFIWAX)
5990 rtx dfreg = gen_reg_rtx (DFmode);
5991 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5992 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5997 rtx dreg = operands[1];
5999 dreg = force_reg (SImode, dreg);
6000 dreg = convert_to_mode (DImode, dreg, false);
6001 emit_insn (gen_floatdisf2 (operands[0], dreg));
6006 (define_insn "floatdidf2"
6007 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6008 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6009 "TARGET_FCFID && TARGET_HARD_FLOAT"
6013 [(set_attr "type" "fp")])
6015 ; Allow the combiner to merge source memory operands to the conversion so that
6016 ; the optimizer/register allocator doesn't try to load the value too early in a
6017 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6018 ; hit. We will split after reload to avoid the trip through the GPRs
6020 (define_insn_and_split "*floatdidf2_mem"
6021 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6022 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6023 (clobber (match_scratch:DI 2 "=d,wi"))]
6024 "TARGET_HARD_FLOAT && TARGET_FCFID"
6026 "&& reload_completed"
6027 [(set (match_dup 2) (match_dup 1))
6028 (set (match_dup 0) (float:DF (match_dup 2)))]
6030 [(set_attr "length" "8")
6031 (set_attr "type" "fpload")])
6033 (define_expand "floatunsdidf2"
6034 [(set (match_operand:DF 0 "gpc_reg_operand")
6036 (match_operand:DI 1 "gpc_reg_operand")))]
6037 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6040 (define_insn "*floatunsdidf2_fcfidu"
6041 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6042 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6043 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6047 [(set_attr "type" "fp")
6048 (set_attr "length" "4")])
6050 (define_insn_and_split "*floatunsdidf2_mem"
6051 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6052 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6053 (clobber (match_scratch:DI 2 "=d,wi"))]
6054 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6056 "&& reload_completed"
6057 [(set (match_dup 2) (match_dup 1))
6058 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6060 [(set_attr "length" "8")
6061 (set_attr "type" "fpload")])
6063 (define_expand "floatdisf2"
6064 [(set (match_operand:SF 0 "gpc_reg_operand")
6065 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6066 "TARGET_FCFID && TARGET_HARD_FLOAT
6067 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6071 rtx val = operands[1];
6072 if (!flag_unsafe_math_optimizations)
6074 rtx label = gen_label_rtx ();
6075 val = gen_reg_rtx (DImode);
6076 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6079 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6084 (define_insn "floatdisf2_fcfids"
6085 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6086 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6087 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6091 [(set_attr "type" "fp")])
6093 (define_insn_and_split "*floatdisf2_mem"
6094 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6095 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6096 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6097 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6099 "&& reload_completed"
6102 emit_move_insn (operands[2], operands[1]);
6103 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6106 [(set_attr "length" "8")])
6108 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6109 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6110 ;; from double rounding.
6111 ;; Instead of creating a new cpu type for two FP operations, just use fp
6112 (define_insn_and_split "floatdisf2_internal1"
6113 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6114 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6115 (clobber (match_scratch:DF 2 "=d"))]
6116 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6118 "&& reload_completed"
6120 (float:DF (match_dup 1)))
6122 (float_truncate:SF (match_dup 2)))]
6124 [(set_attr "length" "8")
6125 (set_attr "type" "fp")])
6127 ;; Twiddles bits to avoid double rounding.
6128 ;; Bits that might be truncated when converting to DFmode are replaced
6129 ;; by a bit that won't be lost at that stage, but is below the SFmode
6130 ;; rounding position.
6131 (define_expand "floatdisf2_internal2"
6132 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6134 (clobber (reg:DI CA_REGNO))])
6135 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6137 (set (match_dup 3) (plus:DI (match_dup 3)
6139 (set (match_dup 0) (plus:DI (match_dup 0)
6141 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6143 (set (match_dup 0) (ior:DI (match_dup 0)
6145 (set (match_dup 0) (and:DI (match_dup 0)
6147 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6148 (label_ref (match_operand:DI 2 ""))
6150 (set (match_dup 0) (match_dup 1))]
6151 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6153 operands[3] = gen_reg_rtx (DImode);
6154 operands[4] = gen_reg_rtx (CCUNSmode);
6157 (define_expand "floatunsdisf2"
6158 [(set (match_operand:SF 0 "gpc_reg_operand")
6159 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6160 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6163 (define_insn "floatunsdisf2_fcfidus"
6164 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6165 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6166 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6170 [(set_attr "type" "fp")])
6172 (define_insn_and_split "*floatunsdisf2_mem"
6173 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6174 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6175 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6176 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6178 "&& reload_completed"
6181 emit_move_insn (operands[2], operands[1]);
6182 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6185 [(set_attr "length" "8")
6186 (set_attr "type" "fpload")])
6188 ;; Define the TImode operations that can be done in a small number
6189 ;; of instructions. The & constraints are to prevent the register
6190 ;; allocator from allocating registers that overlap with the inputs
6191 ;; (for example, having an input in 7,8 and an output in 6,7). We
6192 ;; also allow for the output being the same as one of the inputs.
6194 (define_expand "addti3"
6195 [(set (match_operand:TI 0 "gpc_reg_operand")
6196 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6197 (match_operand:TI 2 "reg_or_short_operand")))]
6200 rtx lo0 = gen_lowpart (DImode, operands[0]);
6201 rtx lo1 = gen_lowpart (DImode, operands[1]);
6202 rtx lo2 = gen_lowpart (DImode, operands[2]);
6203 rtx hi0 = gen_highpart (DImode, operands[0]);
6204 rtx hi1 = gen_highpart (DImode, operands[1]);
6205 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6207 if (!reg_or_short_operand (lo2, DImode))
6208 lo2 = force_reg (DImode, lo2);
6209 if (!adde_operand (hi2, DImode))
6210 hi2 = force_reg (DImode, hi2);
6212 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6213 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6217 (define_expand "subti3"
6218 [(set (match_operand:TI 0 "gpc_reg_operand")
6219 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6220 (match_operand:TI 2 "gpc_reg_operand")))]
6223 rtx lo0 = gen_lowpart (DImode, operands[0]);
6224 rtx lo1 = gen_lowpart (DImode, operands[1]);
6225 rtx lo2 = gen_lowpart (DImode, operands[2]);
6226 rtx hi0 = gen_highpart (DImode, operands[0]);
6227 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6228 rtx hi2 = gen_highpart (DImode, operands[2]);
6230 if (!reg_or_short_operand (lo1, DImode))
6231 lo1 = force_reg (DImode, lo1);
6232 if (!adde_operand (hi1, DImode))
6233 hi1 = force_reg (DImode, hi1);
6235 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6236 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6240 ;; 128-bit logical operations expanders
6242 (define_expand "and<mode>3"
6243 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6244 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6245 (match_operand:BOOL_128 2 "vlogical_operand")))]
6249 (define_expand "ior<mode>3"
6250 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6251 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6252 (match_operand:BOOL_128 2 "vlogical_operand")))]
6256 (define_expand "xor<mode>3"
6257 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6258 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6259 (match_operand:BOOL_128 2 "vlogical_operand")))]
6263 (define_expand "one_cmpl<mode>2"
6264 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6265 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6269 (define_expand "nor<mode>3"
6270 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6272 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6273 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6277 (define_expand "andc<mode>3"
6278 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6280 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6281 (match_operand:BOOL_128 1 "vlogical_operand")))]
6285 ;; Power8 vector logical instructions.
6286 (define_expand "eqv<mode>3"
6287 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6289 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6290 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6291 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6294 ;; Rewrite nand into canonical form
6295 (define_expand "nand<mode>3"
6296 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6298 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6299 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6300 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6303 ;; The canonical form is to have the negated element first, so we need to
6304 ;; reverse arguments.
6305 (define_expand "orc<mode>3"
6306 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6308 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6309 (match_operand:BOOL_128 1 "vlogical_operand")))]
6310 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6313 ;; 128-bit logical operations insns and split operations
6314 (define_insn_and_split "*and<mode>3_internal"
6315 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6317 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6318 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6321 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6322 return "xxland %x0,%x1,%x2";
6324 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6325 return "vand %0,%1,%2";
6329 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6332 rs6000_split_logical (operands, AND, false, false, false);
6337 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6338 (const_string "veclogical")
6339 (const_string "integer")))
6340 (set (attr "length")
6342 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6345 (match_test "TARGET_POWERPC64")
6347 (const_string "16"))))])
6350 (define_insn_and_split "*bool<mode>3_internal"
6351 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6352 (match_operator:BOOL_128 3 "boolean_or_operator"
6353 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6354 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6357 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6358 return "xxl%q3 %x0,%x1,%x2";
6360 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6361 return "v%q3 %0,%1,%2";
6365 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6368 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6373 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6374 (const_string "veclogical")
6375 (const_string "integer")))
6376 (set (attr "length")
6378 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6381 (match_test "TARGET_POWERPC64")
6383 (const_string "16"))))])
6386 (define_insn_and_split "*boolc<mode>3_internal1"
6387 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6388 (match_operator:BOOL_128 3 "boolean_operator"
6390 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6391 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6392 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6394 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6395 return "xxl%q3 %x0,%x1,%x2";
6397 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6398 return "v%q3 %0,%1,%2";
6402 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6403 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6406 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6411 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6412 (const_string "veclogical")
6413 (const_string "integer")))
6414 (set (attr "length")
6416 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6419 (match_test "TARGET_POWERPC64")
6421 (const_string "16"))))])
6423 (define_insn_and_split "*boolc<mode>3_internal2"
6424 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6425 (match_operator:TI2 3 "boolean_operator"
6427 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6428 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6429 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6431 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6434 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6437 [(set_attr "type" "integer")
6438 (set (attr "length")
6440 (match_test "TARGET_POWERPC64")
6442 (const_string "16")))])
6445 (define_insn_and_split "*boolcc<mode>3_internal1"
6446 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6447 (match_operator:BOOL_128 3 "boolean_operator"
6449 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6451 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6452 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6454 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6455 return "xxl%q3 %x0,%x1,%x2";
6457 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6458 return "v%q3 %0,%1,%2";
6462 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6463 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6466 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6471 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6472 (const_string "veclogical")
6473 (const_string "integer")))
6474 (set (attr "length")
6476 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6479 (match_test "TARGET_POWERPC64")
6481 (const_string "16"))))])
6483 (define_insn_and_split "*boolcc<mode>3_internal2"
6484 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6485 (match_operator:TI2 3 "boolean_operator"
6487 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6489 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6490 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6492 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6495 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6498 [(set_attr "type" "integer")
6499 (set (attr "length")
6501 (match_test "TARGET_POWERPC64")
6503 (const_string "16")))])
6507 (define_insn_and_split "*eqv<mode>3_internal1"
6508 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6511 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6512 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6515 if (vsx_register_operand (operands[0], <MODE>mode))
6516 return "xxleqv %x0,%x1,%x2";
6520 "TARGET_P8_VECTOR && reload_completed
6521 && int_reg_operand (operands[0], <MODE>mode)"
6524 rs6000_split_logical (operands, XOR, true, false, false);
6529 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6530 (const_string "veclogical")
6531 (const_string "integer")))
6532 (set (attr "length")
6534 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6537 (match_test "TARGET_POWERPC64")
6539 (const_string "16"))))])
6541 (define_insn_and_split "*eqv<mode>3_internal2"
6542 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6545 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6546 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6549 "reload_completed && !TARGET_P8_VECTOR"
6552 rs6000_split_logical (operands, XOR, true, false, false);
6555 [(set_attr "type" "integer")
6556 (set (attr "length")
6558 (match_test "TARGET_POWERPC64")
6560 (const_string "16")))])
6562 ;; 128-bit one's complement
6563 (define_insn_and_split "*one_cmpl<mode>3_internal"
6564 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6566 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6569 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6570 return "xxlnor %x0,%x1,%x1";
6572 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6573 return "vnor %0,%1,%1";
6577 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6580 rs6000_split_logical (operands, NOT, false, false, false);
6585 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6586 (const_string "veclogical")
6587 (const_string "integer")))
6588 (set (attr "length")
6590 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6593 (match_test "TARGET_POWERPC64")
6595 (const_string "16"))))])
6598 ;; Now define ways of moving data around.
6600 ;; Set up a register with a value from the GOT table
6602 (define_expand "movsi_got"
6603 [(set (match_operand:SI 0 "gpc_reg_operand")
6604 (unspec:SI [(match_operand:SI 1 "got_operand")
6605 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6606 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6608 if (GET_CODE (operands[1]) == CONST)
6610 rtx offset = const0_rtx;
6611 HOST_WIDE_INT value;
6613 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6614 value = INTVAL (offset);
6617 rtx tmp = (!can_create_pseudo_p ()
6619 : gen_reg_rtx (Pmode));
6620 emit_insn (gen_movsi_got (tmp, operands[1]));
6621 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6626 operands[2] = rs6000_got_register (operands[1]);
6629 (define_insn "*movsi_got_internal"
6630 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6631 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6632 (match_operand:SI 2 "gpc_reg_operand" "b")]
6634 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6635 "lwz %0,%a1@got(%2)"
6636 [(set_attr "type" "load")])
6638 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6639 ;; didn't get allocated to a hard register.
6641 [(set (match_operand:SI 0 "gpc_reg_operand")
6642 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6643 (match_operand:SI 2 "memory_operand")]
6645 "DEFAULT_ABI == ABI_V4
6647 && reload_completed"
6648 [(set (match_dup 0) (match_dup 2))
6649 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6653 ;; For SI, we special-case integers that can't be loaded in one insn. We
6654 ;; do the load 16-bits at a time. We could do this by loading from memory,
6655 ;; and this is even supposed to be faster, but it is simpler not to get
6656 ;; integers in the TOC.
6657 (define_insn "movsi_low"
6658 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6659 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6660 (match_operand 2 "" ""))))]
6661 "TARGET_MACHO && ! TARGET_64BIT"
6662 "lwz %0,lo16(%2)(%1)"
6663 [(set_attr "type" "load")
6664 (set_attr "length" "4")])
6666 ;; MR LA LWZ LFIWZX LXSIWZX
6667 ;; STW STFIWX STXSIWX LI LIS
6668 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6669 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6670 ;; MF%1 MT%0 MT%0 NOP
6671 (define_insn "*movsi_internal1"
6672 [(set (match_operand:SI 0 "nonimmediate_operand"
6673 "=r, r, r, ?*wI, ?*wH,
6675 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6676 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6679 (match_operand:SI 1 "input_operand"
6686 "gpc_reg_operand (operands[0], SImode)
6687 || gpc_reg_operand (operands[1], SImode)"
6714 "*, *, load, fpload, fpload,
6715 store, fpstore, fpstore, *, *,
6716 *, veclogical, vecsimple, vecsimple, vecsimple,
6717 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6727 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6728 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6730 ;; Because SF values are actually stored as DF values within the vector
6731 ;; registers, we need to convert the value to the vector SF format when
6732 ;; we need to use the bits in a union or similar cases. We only need
6733 ;; to do this transformation when the value is a vector register. Loads,
6734 ;; stores, and transfers within GPRs are assumed to be safe.
6736 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6737 ;; no alternatives, because the call is created as part of secondary_reload,
6738 ;; and operand #2's register class is used to allocate the temporary register.
6739 ;; This function is called before reload, and it creates the temporary as
6742 ;; MR LWZ LFIWZX LXSIWZX STW
6743 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6746 (define_insn_and_split "movsi_from_sf"
6747 [(set (match_operand:SI 0 "nonimmediate_operand"
6748 "=r, r, ?*wI, ?*wH, m,
6749 m, wY, Z, r, ?*wIwH,
6752 (unspec:SI [(match_operand:SF 1 "input_operand"
6754 f, wb, wu, wIwH, wIwH,
6758 (clobber (match_scratch:V4SF 2
6763 "TARGET_NO_SF_SUBREG
6764 && (register_operand (operands[0], SImode)
6765 || register_operand (operands[1], SFmode))"
6778 "&& reload_completed
6779 && int_reg_operand (operands[0], SImode)
6780 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6783 rtx op0 = operands[0];
6784 rtx op1 = operands[1];
6785 rtx op2 = operands[2];
6786 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6787 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6789 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6790 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6794 "*, load, fpload, fpload, store,
6795 fpstore, fpstore, fpstore, mftgpr, fp,
6803 ;; movsi_from_sf with zero extension
6805 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6808 (define_insn_and_split "*movdi_from_sf_zero_ext"
6809 [(set (match_operand:DI 0 "gpc_reg_operand"
6810 "=r, r, ?*wI, ?*wH, r,
6814 (unspec:SI [(match_operand:SF 1 "input_operand"
6817 UNSPEC_SI_FROM_SF)))
6819 (clobber (match_scratch:V4SF 2
6823 "TARGET_DIRECT_MOVE_64BIT
6824 && (register_operand (operands[0], DImode)
6825 || register_operand (operands[1], SImode))"
6834 "&& reload_completed
6835 && register_operand (operands[0], DImode)
6836 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6839 rtx op0 = operands[0];
6840 rtx op1 = operands[1];
6841 rtx op2 = operands[2];
6842 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6844 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6845 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6849 "*, load, fpload, fpload, two,
6856 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6857 ;; moving it to SImode. We can do a SFmode store without having to do the
6858 ;; conversion explicitly. If we are doing a register->register conversion, use
6859 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6860 ;; input will not fit in a SFmode, and the later assumes the value has already
6862 (define_insn "*movsi_from_df"
6863 [(set (match_operand:SI 0 "nonimmediate_operand" "=wa,m,wY,Z")
6864 (unspec:SI [(float_truncate:SF
6865 (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6866 UNSPEC_SI_FROM_SF))]
6868 "TARGET_NO_SF_SUBREG"
6874 [(set_attr "type" "fp,fpstore,fpstore,fpstore")])
6876 ;; Split a load of a large constant into the appropriate two-insn
6880 [(set (match_operand:SI 0 "gpc_reg_operand")
6881 (match_operand:SI 1 "const_int_operand"))]
6882 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6883 && (INTVAL (operands[1]) & 0xffff) != 0"
6887 (ior:SI (match_dup 0)
6890 if (rs6000_emit_set_const (operands[0], operands[1]))
6896 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6898 [(set (match_operand:DI 0 "altivec_register_operand")
6899 (match_operand:DI 1 "xxspltib_constant_split"))]
6900 "TARGET_P9_VECTOR && reload_completed"
6903 rtx op0 = operands[0];
6904 rtx op1 = operands[1];
6905 int r = REGNO (op0);
6906 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6908 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6909 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6913 (define_insn "*mov<mode>_internal2"
6914 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6915 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6917 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6923 [(set_attr "type" "cmp,logical,cmp")
6924 (set_attr "dot" "yes")
6925 (set_attr "length" "4,4,8")])
6928 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
6929 (compare:CC (match_operand:P 1 "gpc_reg_operand")
6931 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
6933 [(set (match_dup 0) (match_dup 1))
6935 (compare:CC (match_dup 0)
6939 (define_expand "mov<mode>"
6940 [(set (match_operand:INT 0 "general_operand")
6941 (match_operand:INT 1 "any_operand"))]
6944 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
6948 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
6949 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
6950 ;; MTVSRWZ MF%1 MT%1 NOP
6951 (define_insn "*mov<mode>_internal"
6952 [(set (match_operand:QHI 0 "nonimmediate_operand"
6953 "=r, r, ?*wJwK, m, Z, r,
6954 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
6955 ?*wJwK, r, *c*l, *h")
6957 (match_operand:QHI 1 "input_operand"
6958 "r, m, Z, r, wJwK, i,
6959 wJwK, O, wM, wB, wS, ?*wJwK,
6962 "gpc_reg_operand (operands[0], <MODE>mode)
6963 || gpc_reg_operand (operands[1], <MODE>mode)"
6982 "*, load, fpload, store, fpstore, *,
6983 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
6984 mffgpr, mfjmpr, mtjmpr, *")
6992 ;; Here is how to move condition codes around. When we store CC data in
6993 ;; an integer register or memory, we store just the high-order 4 bits.
6994 ;; This lets us not shift in the most common case of CR0.
6995 (define_expand "movcc"
6996 [(set (match_operand:CC 0 "nonimmediate_operand")
6997 (match_operand:CC 1 "nonimmediate_operand"))]
7001 (define_insn "*movcc_internal1"
7002 [(set (match_operand:CC 0 "nonimmediate_operand"
7003 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7004 (match_operand:CC 1 "general_operand"
7005 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7006 "register_operand (operands[0], CCmode)
7007 || register_operand (operands[1], CCmode)"
7011 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7014 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7022 (cond [(eq_attr "alternative" "0,3")
7023 (const_string "cr_logical")
7024 (eq_attr "alternative" "1,2")
7025 (const_string "mtcr")
7026 (eq_attr "alternative" "6,7")
7027 (const_string "integer")
7028 (eq_attr "alternative" "8")
7029 (const_string "mfjmpr")
7030 (eq_attr "alternative" "9")
7031 (const_string "mtjmpr")
7032 (eq_attr "alternative" "10")
7033 (const_string "load")
7034 (eq_attr "alternative" "11")
7035 (const_string "store")
7036 (match_test "TARGET_MFCRF")
7037 (const_string "mfcrf")
7039 (const_string "mfcr")))
7040 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7042 ;; For floating-point, we normally deal with the floating-point registers
7043 ;; unless -msoft-float is used. The sole exception is that parameter passing
7044 ;; can produce floating-point values in fixed-point registers. Unless the
7045 ;; value is a simple constant or already in memory, we deal with this by
7046 ;; allocating memory and copying the value explicitly via that memory location.
7048 ;; Move 32-bit binary/decimal floating point
7049 (define_expand "mov<mode>"
7050 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7051 (match_operand:FMOVE32 1 "any_operand"))]
7054 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7059 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7060 (match_operand:FMOVE32 1 "const_double_operand"))]
7062 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7063 || (GET_CODE (operands[0]) == SUBREG
7064 && GET_CODE (SUBREG_REG (operands[0])) == REG
7065 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7066 [(set (match_dup 2) (match_dup 3))]
7070 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7072 if (! TARGET_POWERPC64)
7073 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7075 operands[2] = gen_lowpart (SImode, operands[0]);
7077 operands[3] = gen_int_mode (l, SImode);
7080 ;; Originally, we tried to keep movsf and movsd common, but the differences
7081 ;; addressing was making it rather difficult to hide with mode attributes. In
7082 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7083 ;; before the VSX stores meant that the register allocator would tend to do a
7084 ;; direct move to the GPR (which involves conversion from scalar to
7085 ;; vector/memory formats) to save values in the traditional Altivec registers,
7086 ;; while SDmode had problems on power6 if the GPR store was not first due to
7087 ;; the power6 not having an integer store operation.
7089 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7090 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7091 ;; MR MT<x> MF<x> NOP
7093 (define_insn "movsf_hardfloat"
7094 [(set (match_operand:SF 0 "nonimmediate_operand"
7095 "=!r, f, wb, wu, m, wY,
7096 Z, m, ww, !r, f, ww,
7098 (match_operand:SF 1 "input_operand"
7099 "m, m, wY, Z, f, wb,
7102 "(register_operand (operands[0], SFmode)
7103 || register_operand (operands[1], SFmode))
7104 && TARGET_HARD_FLOAT
7105 && (TARGET_ALLOW_SF_SUBREG
7106 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7119 xscpsgndp %x0,%x1,%x1
7125 "load, fpload, fpload, fpload, fpstore, fpstore,
7126 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7127 *, mtjmpr, mfjmpr, *")])
7129 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7130 ;; FMR MR MT%0 MF%1 NOP
7131 (define_insn "movsd_hardfloat"
7132 [(set (match_operand:SD 0 "nonimmediate_operand"
7133 "=!r, wz, m, Z, ?wh, ?r,
7134 f, !r, *c*l, !r, *h")
7135 (match_operand:SD 1 "input_operand"
7136 "m, Z, r, wx, r, wh,
7138 "(register_operand (operands[0], SDmode)
7139 || register_operand (operands[1], SDmode))
7140 && TARGET_HARD_FLOAT"
7154 "load, fpload, store, fpstore, mffgpr, mftgpr,
7155 fpsimple, *, mtjmpr, mfjmpr, *")])
7157 ;; MR MT%0 MF%0 LWZ STW LI
7158 ;; LIS G-const. F/n-const NOP
7159 (define_insn "*mov<mode>_softfloat"
7160 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7161 "=r, cl, r, r, m, r,
7164 (match_operand:FMOVE32 1 "input_operand"
7168 "(gpc_reg_operand (operands[0], <MODE>mode)
7169 || gpc_reg_operand (operands[1], <MODE>mode))
7170 && TARGET_SOFT_FLOAT"
7183 "*, mtjmpr, mfjmpr, load, store, *,
7190 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7191 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7193 ;; Because SF values are actually stored as DF values within the vector
7194 ;; registers, we need to convert the value to the vector SF format when
7195 ;; we need to use the bits in a union or similar cases. We only need
7196 ;; to do this transformation when the value is a vector register. Loads,
7197 ;; stores, and transfers within GPRs are assumed to be safe.
7199 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7200 ;; no alternatives, because the call is created as part of secondary_reload,
7201 ;; and operand #2's register class is used to allocate the temporary register.
7202 ;; This function is called before reload, and it creates the temporary as
7205 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7206 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7207 (define_insn_and_split "movsf_from_si"
7208 [(set (match_operand:SF 0 "nonimmediate_operand"
7209 "=!r, f, wb, wu, m, Z,
7212 (unspec:SF [(match_operand:SI 1 "input_operand"
7217 (clobber (match_scratch:DI 2
7221 "TARGET_NO_SF_SUBREG
7222 && (register_operand (operands[0], SFmode)
7223 || register_operand (operands[1], SImode))"
7236 "&& reload_completed
7237 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7238 && int_reg_operand_not_pseudo (operands[1], SImode)"
7241 rtx op0 = operands[0];
7242 rtx op1 = operands[1];
7243 rtx op2 = operands[2];
7244 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7246 /* Move SF value to upper 32-bits for xscvspdpn. */
7247 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7248 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7249 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7256 "load, fpload, fpload, fpload, store, fpstore,
7257 fpstore, vecfloat, mffgpr, *")])
7260 ;; Move 64-bit binary/decimal floating point
7261 (define_expand "mov<mode>"
7262 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7263 (match_operand:FMOVE64 1 "any_operand"))]
7266 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7271 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7272 (match_operand:FMOVE64 1 "const_int_operand"))]
7273 "! TARGET_POWERPC64 && reload_completed
7274 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7275 || (GET_CODE (operands[0]) == SUBREG
7276 && GET_CODE (SUBREG_REG (operands[0])) == REG
7277 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7278 [(set (match_dup 2) (match_dup 4))
7279 (set (match_dup 3) (match_dup 1))]
7281 int endian = (WORDS_BIG_ENDIAN == 0);
7282 HOST_WIDE_INT value = INTVAL (operands[1]);
7284 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7285 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7286 operands[4] = GEN_INT (value >> 32);
7287 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7291 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7292 (match_operand:FMOVE64 1 "const_double_operand"))]
7293 "! TARGET_POWERPC64 && reload_completed
7294 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7295 || (GET_CODE (operands[0]) == SUBREG
7296 && GET_CODE (SUBREG_REG (operands[0])) == REG
7297 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7298 [(set (match_dup 2) (match_dup 4))
7299 (set (match_dup 3) (match_dup 5))]
7301 int endian = (WORDS_BIG_ENDIAN == 0);
7304 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7306 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7307 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7308 operands[4] = gen_int_mode (l[endian], SImode);
7309 operands[5] = gen_int_mode (l[1 - endian], SImode);
7313 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7314 (match_operand:FMOVE64 1 "const_double_operand"))]
7315 "TARGET_POWERPC64 && reload_completed
7316 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7317 || (GET_CODE (operands[0]) == SUBREG
7318 && GET_CODE (SUBREG_REG (operands[0])) == REG
7319 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7320 [(set (match_dup 2) (match_dup 3))]
7322 int endian = (WORDS_BIG_ENDIAN == 0);
7326 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7328 operands[2] = gen_lowpart (DImode, operands[0]);
7329 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7330 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7331 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7333 operands[3] = gen_int_mode (val, DImode);
7336 ;; Don't have reload use general registers to load a constant. It is
7337 ;; less efficient than loading the constant into an FP register, since
7338 ;; it will probably be used there.
7340 ;; The move constraints are ordered to prefer floating point registers before
7341 ;; general purpose registers to avoid doing a store and a load to get the value
7342 ;; into a floating point register when it is needed for a floating point
7343 ;; operation. Prefer traditional floating point registers over VSX registers,
7344 ;; since the D-form version of the memory instructions does not need a GPR for
7345 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7348 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7349 ;; except for 0.0 which can be created on VSX with an xor instruction.
7351 ;; STFD LFD FMR LXSD STXSD
7352 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7356 (define_insn "*mov<mode>_hardfloat32"
7357 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7358 "=m, d, d, <f64_p9>, wY,
7359 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7362 (match_operand:FMOVE64 1 "input_operand"
7363 "d, m, d, wY, <f64_p9>,
7364 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7367 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7368 && (gpc_reg_operand (operands[0], <MODE>mode)
7369 || gpc_reg_operand (operands[1], <MODE>mode))"
7385 "fpstore, fpload, fpsimple, fpload, fpstore,
7386 fpload, fpstore, veclogical, veclogical, two,
7389 (set_attr "size" "64")
7395 ;; STW LWZ MR G-const H-const F-const
7397 (define_insn "*mov<mode>_softfloat32"
7398 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7399 "=Y, r, r, r, r, r")
7401 (match_operand:FMOVE64 1 "input_operand"
7402 "r, Y, r, G, H, F"))]
7405 && (gpc_reg_operand (operands[0], <MODE>mode)
7406 || gpc_reg_operand (operands[1], <MODE>mode))"
7409 "store, load, two, *, *, *")
7412 "8, 8, 8, 8, 12, 16")])
7414 ; ld/std require word-aligned displacements -> 'Y' constraint.
7415 ; List Y->r and r->Y before r->r for reload.
7417 ;; STFD LFD FMR LXSD STXSD
7418 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7419 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7420 ;; NOP MFTGPR MFFGPR MFVSRD MTVSRD
7422 (define_insn "*mov<mode>_hardfloat64"
7423 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7424 "=m, d, d, <f64_p9>, wY,
7425 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7427 *h, r, wg, r, <f64_dm>")
7429 (match_operand:FMOVE64 1 "input_operand"
7430 "d, m, d, wY, <f64_p9>,
7431 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7433 0, wg, r, <f64_dm>, r"))]
7435 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7436 && (gpc_reg_operand (operands[0], <MODE>mode)
7437 || gpc_reg_operand (operands[1], <MODE>mode))"
7460 "fpstore, fpload, fpsimple, fpload, fpstore,
7461 fpload, fpstore, veclogical, veclogical, integer,
7462 store, load, *, mtjmpr, mfjmpr,
7463 *, mftgpr, mffgpr, mftgpr, mffgpr")
7465 (set_attr "size" "64")
7466 (set_attr "length" "4")])
7468 ;; STD LD MR MT<SPR> MF<SPR> G-const
7469 ;; H-const F-const Special
7471 (define_insn "*mov<mode>_softfloat64"
7472 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7473 "=Y, r, r, cl, r, r,
7476 (match_operand:FMOVE64 1 "input_operand"
7480 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7481 && (gpc_reg_operand (operands[0], <MODE>mode)
7482 || gpc_reg_operand (operands[1], <MODE>mode))"
7494 "store, load, *, mtjmpr, mfjmpr, *,
7501 (define_expand "mov<mode>"
7502 [(set (match_operand:FMOVE128 0 "general_operand")
7503 (match_operand:FMOVE128 1 "any_operand"))]
7506 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7510 ;; It's important to list Y->r and r->Y before r->r because otherwise
7511 ;; reload, given m->r, will try to pick r->r and reload it, which
7512 ;; doesn't make progress.
7514 ;; We can't split little endian direct moves of TDmode, because the words are
7515 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7516 ;; problematical. Don't allow direct move for this case.
7518 (define_insn_and_split "*mov<mode>_64bit_dm"
7519 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7520 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7521 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7522 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7523 && (gpc_reg_operand (operands[0], <MODE>mode)
7524 || gpc_reg_operand (operands[1], <MODE>mode))"
7526 "&& reload_completed"
7528 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7529 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7531 (define_insn_and_split "*movtd_64bit_nodm"
7532 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7533 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7534 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7535 && (gpc_reg_operand (operands[0], TDmode)
7536 || gpc_reg_operand (operands[1], TDmode))"
7538 "&& reload_completed"
7540 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7541 [(set_attr "length" "8,8,8,12,12,8")])
7543 (define_insn_and_split "*mov<mode>_32bit"
7544 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7545 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7546 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7547 && (FLOAT128_2REG_P (<MODE>mode)
7548 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7549 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7550 && (gpc_reg_operand (operands[0], <MODE>mode)
7551 || gpc_reg_operand (operands[1], <MODE>mode))"
7553 "&& reload_completed"
7555 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7556 [(set_attr "length" "8,8,8,8,20,20,16")])
7558 (define_insn_and_split "*mov<mode>_softfloat"
7559 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7560 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7562 && (gpc_reg_operand (operands[0], <MODE>mode)
7563 || gpc_reg_operand (operands[1], <MODE>mode))"
7565 "&& reload_completed"
7567 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7568 [(set_attr "length" "20,20,16")])
7570 (define_expand "extenddf<mode>2"
7571 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7572 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7573 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7575 if (FLOAT128_IEEE_P (<MODE>mode))
7576 rs6000_expand_float128_convert (operands[0], operands[1], false);
7577 else if (TARGET_VSX)
7579 if (<MODE>mode == TFmode)
7580 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7581 else if (<MODE>mode == IFmode)
7582 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7588 rtx zero = gen_reg_rtx (DFmode);
7589 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7591 if (<MODE>mode == TFmode)
7592 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7593 else if (<MODE>mode == IFmode)
7594 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7601 ;; Allow memory operands for the source to be created by the combiner.
7602 (define_insn_and_split "extenddf<mode>2_fprs"
7603 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7604 (float_extend:IBM128
7605 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7606 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7607 "!TARGET_VSX && TARGET_HARD_FLOAT
7608 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7610 "&& reload_completed"
7611 [(set (match_dup 3) (match_dup 1))
7612 (set (match_dup 4) (match_dup 2))]
7614 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7615 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7617 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7618 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7621 (define_insn_and_split "extenddf<mode>2_vsx"
7622 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7623 (float_extend:IBM128
7624 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7625 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7627 "&& reload_completed"
7628 [(set (match_dup 2) (match_dup 1))
7629 (set (match_dup 3) (match_dup 4))]
7631 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7632 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7634 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7635 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7636 operands[4] = CONST0_RTX (DFmode);
7639 (define_expand "extendsf<mode>2"
7640 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7641 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7642 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7644 if (FLOAT128_IEEE_P (<MODE>mode))
7645 rs6000_expand_float128_convert (operands[0], operands[1], false);
7648 rtx tmp = gen_reg_rtx (DFmode);
7649 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7650 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7655 (define_expand "trunc<mode>df2"
7656 [(set (match_operand:DF 0 "gpc_reg_operand")
7657 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7658 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7660 if (FLOAT128_IEEE_P (<MODE>mode))
7662 rs6000_expand_float128_convert (operands[0], operands[1], false);
7667 (define_insn_and_split "trunc<mode>df2_internal1"
7668 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7670 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7671 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7672 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7676 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7679 emit_note (NOTE_INSN_DELETED);
7682 [(set_attr "type" "fpsimple")])
7684 (define_insn "trunc<mode>df2_internal2"
7685 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7686 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7687 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7688 && TARGET_LONG_DOUBLE_128"
7690 [(set_attr "type" "fp")])
7692 (define_expand "trunc<mode>sf2"
7693 [(set (match_operand:SF 0 "gpc_reg_operand")
7694 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7695 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7697 if (FLOAT128_IEEE_P (<MODE>mode))
7698 rs6000_expand_float128_convert (operands[0], operands[1], false);
7699 else if (<MODE>mode == TFmode)
7700 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7701 else if (<MODE>mode == IFmode)
7702 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7708 (define_insn_and_split "trunc<mode>sf2_fprs"
7709 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7710 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7711 (clobber (match_scratch:DF 2 "=d"))]
7712 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7714 "&& reload_completed"
7716 (float_truncate:DF (match_dup 1)))
7718 (float_truncate:SF (match_dup 2)))]
7721 (define_expand "floatsi<mode>2"
7722 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7723 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7724 (clobber (match_scratch:DI 2))])]
7725 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7727 rtx op0 = operands[0];
7728 rtx op1 = operands[1];
7730 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7732 else if (FLOAT128_IEEE_P (<MODE>mode))
7734 rs6000_expand_float128_convert (op0, op1, false);
7739 rtx tmp = gen_reg_rtx (DFmode);
7740 expand_float (tmp, op1, false);
7741 if (<MODE>mode == TFmode)
7742 emit_insn (gen_extenddftf2 (op0, tmp));
7743 else if (<MODE>mode == IFmode)
7744 emit_insn (gen_extenddfif2 (op0, tmp));
7751 ; fadd, but rounding towards zero.
7752 ; This is probably not the optimal code sequence.
7753 (define_insn "fix_trunc_helper<mode>"
7754 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7755 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7756 UNSPEC_FIX_TRUNC_TF))
7757 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7758 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7759 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7760 [(set_attr "type" "fp")
7761 (set_attr "length" "20")])
7763 (define_expand "fix_trunc<mode>si2"
7764 [(set (match_operand:SI 0 "gpc_reg_operand")
7765 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7766 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7768 rtx op0 = operands[0];
7769 rtx op1 = operands[1];
7771 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7775 if (FLOAT128_IEEE_P (<MODE>mode))
7776 rs6000_expand_float128_convert (op0, op1, false);
7777 else if (<MODE>mode == TFmode)
7778 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7779 else if (<MODE>mode == IFmode)
7780 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7787 (define_expand "fix_trunc<mode>si2_fprs"
7788 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7789 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7790 (clobber (match_dup 2))
7791 (clobber (match_dup 3))
7792 (clobber (match_dup 4))
7793 (clobber (match_dup 5))])]
7794 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7796 operands[2] = gen_reg_rtx (DFmode);
7797 operands[3] = gen_reg_rtx (DFmode);
7798 operands[4] = gen_reg_rtx (DImode);
7799 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7802 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7803 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7804 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7805 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7806 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7807 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7808 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7809 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7815 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7818 gcc_assert (MEM_P (operands[5]));
7819 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7821 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7822 emit_move_insn (operands[5], operands[4]);
7823 emit_move_insn (operands[0], lowword);
7827 (define_expand "fix_trunc<mode>di2"
7828 [(set (match_operand:DI 0 "gpc_reg_operand")
7829 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7830 "TARGET_FLOAT128_TYPE"
7832 if (!TARGET_FLOAT128_HW)
7834 rs6000_expand_float128_convert (operands[0], operands[1], false);
7839 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7840 [(set (match_operand:SDI 0 "gpc_reg_operand")
7841 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7842 "TARGET_FLOAT128_TYPE"
7844 rs6000_expand_float128_convert (operands[0], operands[1], true);
7848 (define_expand "floatdi<mode>2"
7849 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7850 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7851 "TARGET_FLOAT128_TYPE"
7853 if (!TARGET_FLOAT128_HW)
7855 rs6000_expand_float128_convert (operands[0], operands[1], false);
7860 (define_expand "floatunsdi<IEEE128:mode>2"
7861 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7862 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7863 "TARGET_FLOAT128_TYPE"
7865 if (!TARGET_FLOAT128_HW)
7867 rs6000_expand_float128_convert (operands[0], operands[1], true);
7872 (define_expand "floatuns<IEEE128:mode>2"
7873 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7874 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
7875 "TARGET_FLOAT128_TYPE"
7877 rtx op0 = operands[0];
7878 rtx op1 = operands[1];
7880 if (TARGET_FLOAT128_HW)
7881 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7883 rs6000_expand_float128_convert (op0, op1, true);
7887 (define_expand "neg<mode>2"
7888 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7889 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7890 "FLOAT128_IEEE_P (<MODE>mode)
7891 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7893 if (FLOAT128_IEEE_P (<MODE>mode))
7895 if (TARGET_FLOAT128_HW)
7897 if (<MODE>mode == TFmode)
7898 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7899 else if (<MODE>mode == KFmode)
7900 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7904 else if (TARGET_FLOAT128_TYPE)
7906 if (<MODE>mode == TFmode)
7907 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7908 else if (<MODE>mode == KFmode)
7909 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7915 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7916 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7918 operands[1], <MODE>mode);
7920 if (target && !rtx_equal_p (target, operands[0]))
7921 emit_move_insn (operands[0], target);
7927 (define_insn "neg<mode>2_internal"
7928 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7929 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7930 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7932 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7933 return "fneg %L0,%L1\;fneg %0,%1";
7935 return "fneg %0,%1\;fneg %L0,%L1";
7937 [(set_attr "type" "fpsimple")
7938 (set_attr "length" "8")])
7940 (define_expand "abs<mode>2"
7941 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7942 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7943 "FLOAT128_IEEE_P (<MODE>mode)
7944 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7948 if (FLOAT128_IEEE_P (<MODE>mode))
7950 if (TARGET_FLOAT128_HW)
7952 if (<MODE>mode == TFmode)
7953 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7954 else if (<MODE>mode == KFmode)
7955 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7960 else if (TARGET_FLOAT128_TYPE)
7962 if (<MODE>mode == TFmode)
7963 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7964 else if (<MODE>mode == KFmode)
7965 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7974 label = gen_label_rtx ();
7975 if (<MODE>mode == TFmode)
7976 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7977 else if (<MODE>mode == TFmode)
7978 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7985 (define_expand "abs<mode>2_internal"
7986 [(set (match_operand:IBM128 0 "gpc_reg_operand")
7987 (match_operand:IBM128 1 "gpc_reg_operand"))
7988 (set (match_dup 3) (match_dup 5))
7989 (set (match_dup 5) (abs:DF (match_dup 5)))
7990 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7991 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7992 (label_ref (match_operand 2 ""))
7994 (set (match_dup 6) (neg:DF (match_dup 6)))]
7995 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7997 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7998 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7999 operands[3] = gen_reg_rtx (DFmode);
8000 operands[4] = gen_reg_rtx (CCFPmode);
8001 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8002 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8006 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8009 (define_expand "ieee_128bit_negative_zero"
8010 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8011 "TARGET_FLOAT128_TYPE"
8013 rtvec v = rtvec_alloc (16);
8016 for (i = 0; i < 16; i++)
8017 RTVEC_ELT (v, i) = const0_rtx;
8019 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8020 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8022 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8026 ;; IEEE 128-bit negate
8028 ;; We have 2 insns here for negate and absolute value. The first uses
8029 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8030 ;; insns, and second insn after the first split pass loads up the bit to
8031 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8032 ;; neg/abs to create the constant just once.
8034 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8035 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8036 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8037 (clobber (match_scratch:V16QI 2 "=v"))]
8038 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8041 [(parallel [(set (match_dup 0)
8042 (neg:IEEE128 (match_dup 1)))
8043 (use (match_dup 2))])]
8045 if (GET_CODE (operands[2]) == SCRATCH)
8046 operands[2] = gen_reg_rtx (V16QImode);
8048 operands[3] = gen_reg_rtx (V16QImode);
8049 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8051 [(set_attr "length" "8")
8052 (set_attr "type" "vecsimple")])
8054 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8055 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8056 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8057 (use (match_operand:V16QI 2 "register_operand" "v"))]
8058 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8059 "xxlxor %x0,%x1,%x2"
8060 [(set_attr "type" "veclogical")])
8062 ;; IEEE 128-bit absolute value
8063 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8064 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8065 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8066 (clobber (match_scratch:V16QI 2 "=v"))]
8067 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8070 [(parallel [(set (match_dup 0)
8071 (abs:IEEE128 (match_dup 1)))
8072 (use (match_dup 2))])]
8074 if (GET_CODE (operands[2]) == SCRATCH)
8075 operands[2] = gen_reg_rtx (V16QImode);
8077 operands[3] = gen_reg_rtx (V16QImode);
8078 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8080 [(set_attr "length" "8")
8081 (set_attr "type" "vecsimple")])
8083 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8084 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8085 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8086 (use (match_operand:V16QI 2 "register_operand" "v"))]
8087 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8088 "xxlandc %x0,%x1,%x2"
8089 [(set_attr "type" "veclogical")])
8091 ;; IEEE 128-bit negative absolute value
8092 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8093 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8096 (match_operand:IEEE128 1 "register_operand" "wa"))))
8097 (clobber (match_scratch:V16QI 2 "=v"))]
8098 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8099 && FLOAT128_IEEE_P (<MODE>mode)"
8102 [(parallel [(set (match_dup 0)
8103 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8104 (use (match_dup 2))])]
8106 if (GET_CODE (operands[2]) == SCRATCH)
8107 operands[2] = gen_reg_rtx (V16QImode);
8109 operands[3] = gen_reg_rtx (V16QImode);
8110 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8112 [(set_attr "length" "8")
8113 (set_attr "type" "vecsimple")])
8115 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8116 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8119 (match_operand:IEEE128 1 "register_operand" "wa"))))
8120 (use (match_operand:V16QI 2 "register_operand" "v"))]
8121 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8123 [(set_attr "type" "veclogical")])
8125 ;; Float128 conversion functions. These expand to library function calls.
8126 ;; We use expand to convert from IBM double double to IEEE 128-bit
8127 ;; and trunc for the opposite.
8128 (define_expand "extendiftf2"
8129 [(set (match_operand:TF 0 "gpc_reg_operand")
8130 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8131 "TARGET_FLOAT128_TYPE"
8133 rs6000_expand_float128_convert (operands[0], operands[1], false);
8137 (define_expand "extendifkf2"
8138 [(set (match_operand:KF 0 "gpc_reg_operand")
8139 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8140 "TARGET_FLOAT128_TYPE"
8142 rs6000_expand_float128_convert (operands[0], operands[1], false);
8146 (define_expand "extendtfkf2"
8147 [(set (match_operand:KF 0 "gpc_reg_operand")
8148 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8149 "TARGET_FLOAT128_TYPE"
8151 rs6000_expand_float128_convert (operands[0], operands[1], false);
8155 (define_expand "trunciftf2"
8156 [(set (match_operand:IF 0 "gpc_reg_operand")
8157 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8158 "TARGET_FLOAT128_TYPE"
8160 rs6000_expand_float128_convert (operands[0], operands[1], false);
8164 (define_expand "truncifkf2"
8165 [(set (match_operand:IF 0 "gpc_reg_operand")
8166 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand")))]
8167 "TARGET_FLOAT128_TYPE"
8169 rs6000_expand_float128_convert (operands[0], operands[1], false);
8173 (define_expand "trunckftf2"
8174 [(set (match_operand:TF 0 "gpc_reg_operand")
8175 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8176 "TARGET_FLOAT128_TYPE"
8178 rs6000_expand_float128_convert (operands[0], operands[1], false);
8182 (define_expand "trunctfif2"
8183 [(set (match_operand:IF 0 "gpc_reg_operand")
8184 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8185 "TARGET_FLOAT128_TYPE"
8187 rs6000_expand_float128_convert (operands[0], operands[1], false);
8192 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8193 ;; must have 3 arguments, and scratch register constraint must be a single
8196 ;; Reload patterns to support gpr load/store with misaligned mem.
8197 ;; and multiple gpr load/store at offset >= 0xfffc
8198 (define_expand "reload_<mode>_store"
8199 [(parallel [(match_operand 0 "memory_operand" "=m")
8200 (match_operand 1 "gpc_reg_operand" "r")
8201 (match_operand:GPR 2 "register_operand" "=&b")])]
8204 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8208 (define_expand "reload_<mode>_load"
8209 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8210 (match_operand 1 "memory_operand" "m")
8211 (match_operand:GPR 2 "register_operand" "=b")])]
8214 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8219 ;; Reload patterns for various types using the vector registers. We may need
8220 ;; an additional base register to convert the reg+offset addressing to reg+reg
8221 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8222 ;; index register for gpr registers.
8223 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8224 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8225 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8226 (match_operand:P 2 "register_operand" "=b")])]
8229 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8233 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8234 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8235 (match_operand:RELOAD 1 "memory_operand" "m")
8236 (match_operand:P 2 "register_operand" "=b")])]
8239 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8244 ;; Reload sometimes tries to move the address to a GPR, and can generate
8245 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8246 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8248 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8249 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8250 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8251 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8253 "TARGET_ALTIVEC && reload_completed"
8255 "&& reload_completed"
8257 (plus:P (match_dup 1)
8260 (and:P (match_dup 0)
8263 ;; Power8 merge instructions to allow direct move to/from floating point
8264 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8265 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8266 ;; value, since it is allocated in reload and not all of the flow information
8267 ;; is setup for it. We have two patterns to do the two moves between gprs and
8268 ;; fprs. There isn't a dependancy between the two, but we could potentially
8269 ;; schedule other instructions between the two instructions.
8271 (define_insn "p8_fmrgow_<mode>"
8272 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8274 (match_operand:DF 1 "register_operand" "d")
8275 (match_operand:DF 2 "register_operand" "d")]
8276 UNSPEC_P8V_FMRGOW))]
8277 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8279 [(set_attr "type" "fpsimple")])
8281 (define_insn "p8_mtvsrwz"
8282 [(set (match_operand:DF 0 "register_operand" "=d")
8283 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8284 UNSPEC_P8V_MTVSRWZ))]
8285 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8287 [(set_attr "type" "mftgpr")])
8289 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8290 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8291 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8292 UNSPEC_P8V_RELOAD_FROM_GPR))
8293 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8294 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8296 "&& reload_completed"
8299 rtx dest = operands[0];
8300 rtx src = operands[1];
8301 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8302 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8303 rtx gpr_hi_reg = gen_highpart (SImode, src);
8304 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8306 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8307 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8308 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8311 [(set_attr "length" "12")
8312 (set_attr "type" "three")])
8314 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8315 (define_insn "p8_mtvsrd_df"
8316 [(set (match_operand:DF 0 "register_operand" "=wa")
8317 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8318 UNSPEC_P8V_MTVSRD))]
8319 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8321 [(set_attr "type" "mftgpr")])
8323 (define_insn "p8_xxpermdi_<mode>"
8324 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8325 (unspec:FMOVE128_GPR [
8326 (match_operand:DF 1 "register_operand" "wa")
8327 (match_operand:DF 2 "register_operand" "wa")]
8328 UNSPEC_P8V_XXPERMDI))]
8329 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8330 "xxpermdi %x0,%x1,%x2,0"
8331 [(set_attr "type" "vecperm")])
8333 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8334 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8335 (unspec:FMOVE128_GPR
8336 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8337 UNSPEC_P8V_RELOAD_FROM_GPR))
8338 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8339 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8341 "&& reload_completed"
8344 rtx dest = operands[0];
8345 rtx src = operands[1];
8346 /* You might think that we could use op0 as one temp and a DF clobber
8347 as op2, but you'd be wrong. Secondary reload move patterns don't
8348 check for overlap of the clobber and the destination. */
8349 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8350 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8351 rtx gpr_hi_reg = gen_highpart (DImode, src);
8352 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8354 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8355 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8356 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8359 [(set_attr "length" "12")
8360 (set_attr "type" "three")])
8363 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8364 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8366 && (int_reg_operand (operands[0], <MODE>mode)
8367 || int_reg_operand (operands[1], <MODE>mode))
8368 && (!TARGET_DIRECT_MOVE_128
8369 || (!vsx_register_operand (operands[0], <MODE>mode)
8370 && !vsx_register_operand (operands[1], <MODE>mode)))"
8372 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8374 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8375 ;; type is stored internally as double precision in the VSX registers, we have
8376 ;; to convert it from the vector format.
8377 (define_insn "p8_mtvsrd_sf"
8378 [(set (match_operand:SF 0 "register_operand" "=wa")
8379 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8380 UNSPEC_P8V_MTVSRD))]
8381 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8383 [(set_attr "type" "mftgpr")])
8385 (define_insn_and_split "reload_vsx_from_gprsf"
8386 [(set (match_operand:SF 0 "register_operand" "=wa")
8387 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8388 UNSPEC_P8V_RELOAD_FROM_GPR))
8389 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8390 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8392 "&& reload_completed"
8395 rtx op0 = operands[0];
8396 rtx op1 = operands[1];
8397 rtx op2 = operands[2];
8398 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8400 /* Move SF value to upper 32-bits for xscvspdpn. */
8401 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8402 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8403 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8406 [(set_attr "length" "8")
8407 (set_attr "type" "two")])
8409 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8410 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8411 ;; and then doing a move of that.
8412 (define_insn "p8_mfvsrd_3_<mode>"
8413 [(set (match_operand:DF 0 "register_operand" "=r")
8414 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8415 UNSPEC_P8V_RELOAD_FROM_VSX))]
8416 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8418 [(set_attr "type" "mftgpr")])
8420 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8421 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8422 (unspec:FMOVE128_GPR
8423 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8424 UNSPEC_P8V_RELOAD_FROM_VSX))
8425 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8426 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8428 "&& reload_completed"
8431 rtx dest = operands[0];
8432 rtx src = operands[1];
8433 rtx tmp = operands[2];
8434 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8435 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8437 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8438 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8439 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8442 [(set_attr "length" "12")
8443 (set_attr "type" "three")])
8445 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8446 ;; type is stored internally as double precision, we have to convert it to the
8449 (define_insn_and_split "reload_gpr_from_vsxsf"
8450 [(set (match_operand:SF 0 "register_operand" "=r")
8451 (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8452 UNSPEC_P8V_RELOAD_FROM_VSX))
8453 (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8454 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8456 "&& reload_completed"
8459 rtx op0 = operands[0];
8460 rtx op1 = operands[1];
8461 rtx op2 = operands[2];
8462 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8463 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8465 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8466 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8469 [(set_attr "length" "8")
8470 (set_attr "type" "two")])
8473 ;; Next come the multi-word integer load and store and the load and store
8476 ;; List r->r after r->Y, otherwise reload will try to reload a
8477 ;; non-offsettable address by using r->r which won't make progress.
8478 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8479 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8481 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8482 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8483 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8486 (define_insn "*movdi_internal32"
8487 [(set (match_operand:DI 0 "nonimmediate_operand"
8488 "=Y, r, r, ^m, ^d, ^d,
8489 r, ^wY, $Z, ^wb, $wv, ^wi,
8490 *wo, *wo, *wv, *wi, *wi, *wv,
8493 (match_operand:DI 1 "input_operand"
8495 IJKnGHF, wb, wv, wY, Z, wi,
8496 Oj, wM, OjwM, Oj, wM, wS,
8500 && (gpc_reg_operand (operands[0], DImode)
8501 || gpc_reg_operand (operands[1], DImode))"
8523 "store, load, *, fpstore, fpload, fpsimple,
8524 *, fpstore, fpstore, fpload, fpload, veclogical,
8525 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8527 (set_attr "size" "64")])
8530 [(set (match_operand:DI 0 "gpc_reg_operand")
8531 (match_operand:DI 1 "const_int_operand"))]
8532 "! TARGET_POWERPC64 && reload_completed
8533 && gpr_or_gpr_p (operands[0], operands[1])
8534 && !direct_move_p (operands[0], operands[1])"
8535 [(set (match_dup 2) (match_dup 4))
8536 (set (match_dup 3) (match_dup 1))]
8538 HOST_WIDE_INT value = INTVAL (operands[1]);
8539 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8541 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8543 operands[4] = GEN_INT (value >> 32);
8544 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8548 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8549 (match_operand:DIFD 1 "input_operand"))]
8550 "reload_completed && !TARGET_POWERPC64
8551 && gpr_or_gpr_p (operands[0], operands[1])
8552 && !direct_move_p (operands[0], operands[1])"
8554 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8556 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8557 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8558 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8559 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8560 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8561 (define_insn "*movdi_internal64"
8562 [(set (match_operand:DI 0 "nonimmediate_operand"
8563 "=YZ, r, r, r, r, r,
8564 ^m, ^d, ^d, ^wY, $Z, $wb,
8565 $wv, ^wi, *wo, *wo, *wv, *wi,
8566 *wi, *wv, *wv, r, *h, *h,
8567 ?*r, ?*wg, ?*r, ?*wj")
8569 (match_operand:DI 1 "input_operand"
8570 "r, YZ, r, I, L, nF,
8571 d, m, d, wb, wv, wY,
8572 Z, wi, Oj, wM, OjwM, Oj,
8573 wM, wS, wB, *h, r, 0,
8577 && (gpc_reg_operand (operands[0], DImode)
8578 || gpc_reg_operand (operands[1], DImode))"
8609 "store, load, *, *, *, *,
8610 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8611 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8612 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8613 mftgpr, mffgpr, mftgpr, mffgpr")
8615 (set_attr "size" "64")
8623 ; Some DImode loads are best done as a load of -1 followed by a mask
8626 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8627 (match_operand:DI 1 "const_int_operand"))]
8629 && num_insns_constant (operands[1], DImode) > 1
8630 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8631 && rs6000_is_valid_and_mask (operands[1], DImode)"
8635 (and:DI (match_dup 0)
8639 ;; Split a load of a large constant into the appropriate five-instruction
8640 ;; sequence. Handle anything in a constant number of insns.
8641 ;; When non-easy constants can go in the TOC, this should use
8642 ;; easy_fp_constant predicate.
8644 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8645 (match_operand:DI 1 "const_int_operand"))]
8646 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8647 [(set (match_dup 0) (match_dup 2))
8648 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8650 if (rs6000_emit_set_const (operands[0], operands[1]))
8657 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8658 (match_operand:DI 1 "const_scalar_int_operand"))]
8659 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8660 [(set (match_dup 0) (match_dup 2))
8661 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8663 if (rs6000_emit_set_const (operands[0], operands[1]))
8670 [(set (match_operand:DI 0 "altivec_register_operand")
8671 (match_operand:DI 1 "s5bit_cint_operand"))]
8672 "TARGET_VSX && reload_completed"
8675 rtx op0 = operands[0];
8676 rtx op1 = operands[1];
8677 int r = REGNO (op0);
8678 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8680 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8681 if (op1 != const0_rtx && op1 != constm1_rtx)
8683 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8684 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8689 ;; Split integer constants that can be loaded with XXSPLTIB and a
8690 ;; sign extend operation.
8692 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8693 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8694 "TARGET_P9_VECTOR && reload_completed"
8697 rtx op0 = operands[0];
8698 rtx op1 = operands[1];
8699 int r = REGNO (op0);
8700 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8702 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8703 if (<MODE>mode == DImode)
8704 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8705 else if (<MODE>mode == SImode)
8706 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8707 else if (<MODE>mode == HImode)
8709 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8710 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8716 ;; TImode/PTImode is similar, except that we usually want to compute the
8717 ;; address into a register and use lsi/stsi (the exception is during reload).
8719 (define_insn "*mov<mode>_string"
8720 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8721 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8723 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8724 && (gpc_reg_operand (operands[0], <MODE>mode)
8725 || gpc_reg_operand (operands[1], <MODE>mode))"
8727 [(set_attr "type" "store,store,load,load,*,*")
8728 (set_attr "update" "yes")
8729 (set_attr "indexed" "yes")
8730 (set_attr "cell_micro" "conditional")])
8732 (define_insn "*mov<mode>_ppc64"
8733 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8734 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8735 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8736 && (gpc_reg_operand (operands[0], <MODE>mode)
8737 || gpc_reg_operand (operands[1], <MODE>mode)))"
8739 return rs6000_output_move_128bit (operands);
8741 [(set_attr "type" "store,store,load,load,*,*")
8742 (set_attr "length" "8")])
8745 [(set (match_operand:TI2 0 "int_reg_operand")
8746 (match_operand:TI2 1 "const_scalar_int_operand"))]
8748 && (VECTOR_MEM_NONE_P (<MODE>mode)
8749 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8750 [(set (match_dup 2) (match_dup 4))
8751 (set (match_dup 3) (match_dup 5))]
8753 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8755 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8757 if (CONST_WIDE_INT_P (operands[1]))
8759 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8760 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8762 else if (CONST_INT_P (operands[1]))
8764 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8765 operands[5] = operands[1];
8772 [(set (match_operand:TI2 0 "nonimmediate_operand")
8773 (match_operand:TI2 1 "input_operand"))]
8775 && gpr_or_gpr_p (operands[0], operands[1])
8776 && !direct_move_p (operands[0], operands[1])
8777 && !quad_load_store_p (operands[0], operands[1])"
8779 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8781 (define_expand "setmemsi"
8782 [(parallel [(set (match_operand:BLK 0 "")
8783 (match_operand 2 "const_int_operand"))
8784 (use (match_operand:SI 1 ""))
8785 (use (match_operand:SI 3 ""))])]
8788 /* If value to set is not zero, use the library routine. */
8789 if (operands[2] != const0_rtx)
8792 if (expand_block_clear (operands))
8798 ;; String compare N insn.
8799 ;; Argument 0 is the target (result)
8800 ;; Argument 1 is the destination
8801 ;; Argument 2 is the source
8802 ;; Argument 3 is the length
8803 ;; Argument 4 is the alignment
8805 (define_expand "cmpstrnsi"
8806 [(parallel [(set (match_operand:SI 0)
8807 (compare:SI (match_operand:BLK 1)
8808 (match_operand:BLK 2)))
8809 (use (match_operand:SI 3))
8810 (use (match_operand:SI 4))])]
8811 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8813 if (optimize_insn_for_size_p ())
8816 if (expand_strn_compare (operands, 0))
8822 ;; String compare insn.
8823 ;; Argument 0 is the target (result)
8824 ;; Argument 1 is the destination
8825 ;; Argument 2 is the source
8826 ;; Argument 3 is the alignment
8828 (define_expand "cmpstrsi"
8829 [(parallel [(set (match_operand:SI 0)
8830 (compare:SI (match_operand:BLK 1)
8831 (match_operand:BLK 2)))
8832 (use (match_operand:SI 3))])]
8833 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8835 if (optimize_insn_for_size_p ())
8838 if (expand_strn_compare (operands, 1))
8844 ;; Block compare insn.
8845 ;; Argument 0 is the target (result)
8846 ;; Argument 1 is the destination
8847 ;; Argument 2 is the source
8848 ;; Argument 3 is the length
8849 ;; Argument 4 is the alignment
8851 (define_expand "cmpmemsi"
8852 [(parallel [(set (match_operand:SI 0)
8853 (compare:SI (match_operand:BLK 1)
8854 (match_operand:BLK 2)))
8855 (use (match_operand:SI 3))
8856 (use (match_operand:SI 4))])]
8859 if (expand_block_compare (operands))
8865 ;; String/block move insn.
8866 ;; Argument 0 is the destination
8867 ;; Argument 1 is the source
8868 ;; Argument 2 is the length
8869 ;; Argument 3 is the alignment
8871 (define_expand "movmemsi"
8872 [(parallel [(set (match_operand:BLK 0 "")
8873 (match_operand:BLK 1 ""))
8874 (use (match_operand:SI 2 ""))
8875 (use (match_operand:SI 3 ""))])]
8878 if (expand_block_move (operands))
8884 ;; Define insns that do load or store with update. Some of these we can
8885 ;; get by using pre-decrement or pre-increment, but the hardware can also
8886 ;; do cases where the increment is not the size of the object.
8888 ;; In all these cases, we use operands 0 and 1 for the register being
8889 ;; incremented because those are the operands that local-alloc will
8890 ;; tie and these are the pair most likely to be tieable (and the ones
8891 ;; that will benefit the most).
8893 (define_insn "*movdi_update1"
8894 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8895 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8896 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8897 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8898 (plus:DI (match_dup 1) (match_dup 2)))]
8899 "TARGET_POWERPC64 && TARGET_UPDATE
8900 && (!avoiding_indexed_address_p (DImode)
8901 || !gpc_reg_operand (operands[2], DImode))"
8905 [(set_attr "type" "load")
8906 (set_attr "update" "yes")
8907 (set_attr "indexed" "yes,no")])
8909 (define_insn "movdi_<mode>_update"
8910 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8911 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8912 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8913 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8914 (plus:P (match_dup 1) (match_dup 2)))]
8915 "TARGET_POWERPC64 && TARGET_UPDATE
8916 && (!avoiding_indexed_address_p (Pmode)
8917 || !gpc_reg_operand (operands[2], Pmode)
8918 || (REG_P (operands[0])
8919 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8923 [(set_attr "type" "store")
8924 (set_attr "update" "yes")
8925 (set_attr "indexed" "yes,no")])
8927 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8928 ;; needed for stack allocation, even if the user passes -mno-update.
8929 (define_insn "movdi_<mode>_update_stack"
8930 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8931 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8932 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8933 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8934 (plus:P (match_dup 1) (match_dup 2)))]
8939 [(set_attr "type" "store")
8940 (set_attr "update" "yes")
8941 (set_attr "indexed" "yes,no")])
8943 (define_insn "*movsi_update1"
8944 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8945 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8946 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8947 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8948 (plus:SI (match_dup 1) (match_dup 2)))]
8950 && (!avoiding_indexed_address_p (SImode)
8951 || !gpc_reg_operand (operands[2], SImode))"
8955 [(set_attr "type" "load")
8956 (set_attr "update" "yes")
8957 (set_attr "indexed" "yes,no")])
8959 (define_insn "*movsi_update2"
8960 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8962 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8963 (match_operand:DI 2 "gpc_reg_operand" "r")))))
8964 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8965 (plus:DI (match_dup 1) (match_dup 2)))]
8966 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
8968 [(set_attr "type" "load")
8969 (set_attr "sign_extend" "yes")
8970 (set_attr "update" "yes")
8971 (set_attr "indexed" "yes")])
8973 (define_insn "movsi_update"
8974 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8975 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8976 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8977 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8978 (plus:SI (match_dup 1) (match_dup 2)))]
8980 && (!avoiding_indexed_address_p (SImode)
8981 || !gpc_reg_operand (operands[2], SImode)
8982 || (REG_P (operands[0])
8983 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8987 [(set_attr "type" "store")
8988 (set_attr "update" "yes")
8989 (set_attr "indexed" "yes,no")])
8991 ;; This is an unconditional pattern; needed for stack allocation, even
8992 ;; if the user passes -mno-update.
8993 (define_insn "movsi_update_stack"
8994 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8995 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8996 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8997 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8998 (plus:SI (match_dup 1) (match_dup 2)))]
9003 [(set_attr "type" "store")
9004 (set_attr "update" "yes")
9005 (set_attr "indexed" "yes,no")])
9007 (define_insn "*movhi_update1"
9008 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9009 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9010 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9011 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9012 (plus:SI (match_dup 1) (match_dup 2)))]
9014 && (!avoiding_indexed_address_p (SImode)
9015 || !gpc_reg_operand (operands[2], SImode))"
9019 [(set_attr "type" "load")
9020 (set_attr "update" "yes")
9021 (set_attr "indexed" "yes,no")])
9023 (define_insn "*movhi_update2"
9024 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9026 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9027 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9028 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9029 (plus:SI (match_dup 1) (match_dup 2)))]
9031 && (!avoiding_indexed_address_p (SImode)
9032 || !gpc_reg_operand (operands[2], SImode))"
9036 [(set_attr "type" "load")
9037 (set_attr "update" "yes")
9038 (set_attr "indexed" "yes,no")])
9040 (define_insn "*movhi_update3"
9041 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9043 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9044 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9045 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9046 (plus:SI (match_dup 1) (match_dup 2)))]
9048 && !(avoiding_indexed_address_p (SImode)
9049 && gpc_reg_operand (operands[2], SImode))"
9053 [(set_attr "type" "load")
9054 (set_attr "sign_extend" "yes")
9055 (set_attr "update" "yes")
9056 (set_attr "indexed" "yes,no")])
9058 (define_insn "*movhi_update4"
9059 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9060 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9061 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9062 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9063 (plus:SI (match_dup 1) (match_dup 2)))]
9065 && (!avoiding_indexed_address_p (SImode)
9066 || !gpc_reg_operand (operands[2], SImode))"
9070 [(set_attr "type" "store")
9071 (set_attr "update" "yes")
9072 (set_attr "indexed" "yes,no")])
9074 (define_insn "*movqi_update1"
9075 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9076 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9077 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9078 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9079 (plus:SI (match_dup 1) (match_dup 2)))]
9081 && (!avoiding_indexed_address_p (SImode)
9082 || !gpc_reg_operand (operands[2], SImode))"
9086 [(set_attr "type" "load")
9087 (set_attr "update" "yes")
9088 (set_attr "indexed" "yes,no")])
9090 (define_insn "*movqi_update2"
9091 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9093 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9094 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9095 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9096 (plus:SI (match_dup 1) (match_dup 2)))]
9098 && (!avoiding_indexed_address_p (SImode)
9099 || !gpc_reg_operand (operands[2], SImode))"
9103 [(set_attr "type" "load")
9104 (set_attr "update" "yes")
9105 (set_attr "indexed" "yes,no")])
9107 (define_insn "*movqi_update3"
9108 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9109 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9110 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9111 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9112 (plus:SI (match_dup 1) (match_dup 2)))]
9114 && (!avoiding_indexed_address_p (SImode)
9115 || !gpc_reg_operand (operands[2], SImode))"
9119 [(set_attr "type" "store")
9120 (set_attr "update" "yes")
9121 (set_attr "indexed" "yes,no")])
9123 (define_insn "*movsf_update1"
9124 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9125 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9126 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9127 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9128 (plus:SI (match_dup 1) (match_dup 2)))]
9129 "TARGET_HARD_FLOAT && TARGET_UPDATE
9130 && (!avoiding_indexed_address_p (SImode)
9131 || !gpc_reg_operand (operands[2], SImode))"
9135 [(set_attr "type" "fpload")
9136 (set_attr "update" "yes")
9137 (set_attr "indexed" "yes,no")])
9139 (define_insn "*movsf_update2"
9140 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9141 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9142 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9143 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9144 (plus:SI (match_dup 1) (match_dup 2)))]
9145 "TARGET_HARD_FLOAT && TARGET_UPDATE
9146 && (!avoiding_indexed_address_p (SImode)
9147 || !gpc_reg_operand (operands[2], SImode))"
9151 [(set_attr "type" "fpstore")
9152 (set_attr "update" "yes")
9153 (set_attr "indexed" "yes,no")])
9155 (define_insn "*movsf_update3"
9156 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9157 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9158 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9159 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9160 (plus:SI (match_dup 1) (match_dup 2)))]
9161 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9162 && (!avoiding_indexed_address_p (SImode)
9163 || !gpc_reg_operand (operands[2], SImode))"
9167 [(set_attr "type" "load")
9168 (set_attr "update" "yes")
9169 (set_attr "indexed" "yes,no")])
9171 (define_insn "*movsf_update4"
9172 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9173 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9174 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9175 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9176 (plus:SI (match_dup 1) (match_dup 2)))]
9177 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9178 && (!avoiding_indexed_address_p (SImode)
9179 || !gpc_reg_operand (operands[2], SImode))"
9183 [(set_attr "type" "store")
9184 (set_attr "update" "yes")
9185 (set_attr "indexed" "yes,no")])
9187 (define_insn "*movdf_update1"
9188 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9189 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9190 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
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_UPDATE
9194 && (!avoiding_indexed_address_p (SImode)
9195 || !gpc_reg_operand (operands[2], SImode))"
9199 [(set_attr "type" "fpload")
9200 (set_attr "update" "yes")
9201 (set_attr "indexed" "yes,no")
9202 (set_attr "size" "64")])
9204 (define_insn "*movdf_update2"
9205 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9206 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9207 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9208 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9209 (plus:SI (match_dup 1) (match_dup 2)))]
9210 "TARGET_HARD_FLOAT && TARGET_UPDATE
9211 && (!avoiding_indexed_address_p (SImode)
9212 || !gpc_reg_operand (operands[2], SImode))"
9216 [(set_attr "type" "fpstore")
9217 (set_attr "update" "yes")
9218 (set_attr "indexed" "yes,no")])
9221 ;; After inserting conditional returns we can sometimes have
9222 ;; unnecessary register moves. Unfortunately we cannot have a
9223 ;; modeless peephole here, because some single SImode sets have early
9224 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9225 ;; sequences, using get_attr_length here will smash the operands
9226 ;; array. Neither is there an early_cobbler_p predicate.
9227 ;; Also this optimization interferes with scalars going into
9228 ;; altivec registers (the code does reloading through the FPRs).
9230 [(set (match_operand:DF 0 "gpc_reg_operand")
9231 (match_operand:DF 1 "any_operand"))
9232 (set (match_operand:DF 2 "gpc_reg_operand")
9235 && peep2_reg_dead_p (2, operands[0])"
9236 [(set (match_dup 2) (match_dup 1))])
9239 [(set (match_operand:SF 0 "gpc_reg_operand")
9240 (match_operand:SF 1 "any_operand"))
9241 (set (match_operand:SF 2 "gpc_reg_operand")
9244 && peep2_reg_dead_p (2, operands[0])"
9245 [(set (match_dup 2) (match_dup 1))])
9250 ;; Mode attributes for different ABIs.
9251 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9252 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9253 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9254 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9256 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9257 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9258 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9259 (match_operand 4 "" "g")))
9260 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9261 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9263 (clobber (reg:SI LR_REGNO))]
9264 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9266 if (TARGET_CMODEL != CMODEL_SMALL)
9267 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9270 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9272 "&& TARGET_TLS_MARKERS"
9274 (unspec:TLSmode [(match_dup 1)
9277 (parallel [(set (match_dup 0)
9278 (call (mem:TLSmode (match_dup 3))
9280 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9281 (clobber (reg:SI LR_REGNO))])]
9283 [(set_attr "type" "two")
9284 (set (attr "length")
9285 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9289 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9290 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9291 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9292 (match_operand 4 "" "g")))
9293 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9294 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9296 (clobber (reg:SI LR_REGNO))]
9297 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9301 if (TARGET_SECURE_PLT && flag_pic == 2)
9302 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9304 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9307 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9309 "&& TARGET_TLS_MARKERS"
9311 (unspec:TLSmode [(match_dup 1)
9314 (parallel [(set (match_dup 0)
9315 (call (mem:TLSmode (match_dup 3))
9317 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9318 (clobber (reg:SI LR_REGNO))])]
9320 [(set_attr "type" "two")
9321 (set_attr "length" "8")])
9323 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9324 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9325 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9326 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9328 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9329 "addi %0,%1,%2@got@tlsgd"
9330 "&& TARGET_CMODEL != CMODEL_SMALL"
9333 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9335 (lo_sum:TLSmode (match_dup 3)
9336 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9338 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9340 [(set (attr "length")
9341 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9345 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9346 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9348 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9349 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9351 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9352 "addis %0,%1,%2@got@tlsgd@ha"
9353 [(set_attr "length" "4")])
9355 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9356 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9357 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9358 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9359 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9361 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9362 "addi %0,%1,%2@got@tlsgd@l"
9363 [(set_attr "length" "4")])
9365 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9366 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9367 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9368 (match_operand 2 "" "g")))
9369 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9371 (clobber (reg:SI LR_REGNO))]
9372 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9373 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9374 "bl %z1(%3@tlsgd)\;nop"
9375 [(set_attr "type" "branch")
9376 (set_attr "length" "8")])
9378 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9379 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9380 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9381 (match_operand 2 "" "g")))
9382 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9384 (clobber (reg:SI LR_REGNO))]
9385 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9389 if (TARGET_SECURE_PLT && flag_pic == 2)
9390 return "bl %z1+32768(%3@tlsgd)@plt";
9391 return "bl %z1(%3@tlsgd)@plt";
9393 return "bl %z1(%3@tlsgd)";
9395 [(set_attr "type" "branch")
9396 (set_attr "length" "4")])
9398 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9399 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9400 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9401 (match_operand 3 "" "g")))
9402 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9404 (clobber (reg:SI LR_REGNO))]
9405 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9407 if (TARGET_CMODEL != CMODEL_SMALL)
9408 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9411 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9413 "&& TARGET_TLS_MARKERS"
9415 (unspec:TLSmode [(match_dup 1)]
9417 (parallel [(set (match_dup 0)
9418 (call (mem:TLSmode (match_dup 2))
9420 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9421 (clobber (reg:SI LR_REGNO))])]
9423 [(set_attr "type" "two")
9424 (set (attr "length")
9425 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9429 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9430 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9431 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9432 (match_operand 3 "" "g")))
9433 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9435 (clobber (reg:SI LR_REGNO))]
9436 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9440 if (TARGET_SECURE_PLT && flag_pic == 2)
9441 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9443 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9446 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9448 "&& TARGET_TLS_MARKERS"
9450 (unspec:TLSmode [(match_dup 1)]
9452 (parallel [(set (match_dup 0)
9453 (call (mem:TLSmode (match_dup 2))
9455 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9456 (clobber (reg:SI LR_REGNO))])]
9458 [(set_attr "length" "8")])
9460 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9461 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9462 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9464 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9465 "addi %0,%1,%&@got@tlsld"
9466 "&& TARGET_CMODEL != CMODEL_SMALL"
9469 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9471 (lo_sum:TLSmode (match_dup 2)
9472 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9474 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9476 [(set (attr "length")
9477 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9481 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9482 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9484 (unspec:TLSmode [(const_int 0)
9485 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9487 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9488 "addis %0,%1,%&@got@tlsld@ha"
9489 [(set_attr "length" "4")])
9491 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9492 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9493 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9494 (unspec:TLSmode [(const_int 0)
9495 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9497 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9498 "addi %0,%1,%&@got@tlsld@l"
9499 [(set_attr "length" "4")])
9501 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9502 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9503 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9504 (match_operand 2 "" "g")))
9505 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9506 (clobber (reg:SI LR_REGNO))]
9507 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9508 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9509 "bl %z1(%&@tlsld)\;nop"
9510 [(set_attr "type" "branch")
9511 (set_attr "length" "8")])
9513 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9514 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9515 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9516 (match_operand 2 "" "g")))
9517 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9518 (clobber (reg:SI LR_REGNO))]
9519 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9523 if (TARGET_SECURE_PLT && flag_pic == 2)
9524 return "bl %z1+32768(%&@tlsld)@plt";
9525 return "bl %z1(%&@tlsld)@plt";
9527 return "bl %z1(%&@tlsld)";
9529 [(set_attr "type" "branch")
9530 (set_attr "length" "4")])
9532 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9533 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9534 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9535 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9538 "addi %0,%1,%2@dtprel")
9540 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9541 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9542 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9543 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9544 UNSPEC_TLSDTPRELHA))]
9546 "addis %0,%1,%2@dtprel@ha")
9548 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9549 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9550 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9551 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9552 UNSPEC_TLSDTPRELLO))]
9554 "addi %0,%1,%2@dtprel@l")
9556 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9557 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9558 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9559 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9560 UNSPEC_TLSGOTDTPREL))]
9562 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9563 "&& TARGET_CMODEL != CMODEL_SMALL"
9566 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9568 (lo_sum:TLSmode (match_dup 3)
9569 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9571 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9573 [(set (attr "length")
9574 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9578 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9579 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9581 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9582 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9583 UNSPEC_TLSGOTDTPREL)))]
9584 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9585 "addis %0,%1,%2@got@dtprel@ha"
9586 [(set_attr "length" "4")])
9588 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9589 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9590 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9591 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9592 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9593 UNSPEC_TLSGOTDTPREL)))]
9594 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9595 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9596 [(set_attr "length" "4")])
9598 (define_insn "tls_tprel_<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" "")]
9604 "addi %0,%1,%2@tprel")
9606 (define_insn "tls_tprel_ha_<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_TLSTPRELHA))]
9612 "addis %0,%1,%2@tprel@ha")
9614 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9615 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9616 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9617 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9618 UNSPEC_TLSTPRELLO))]
9620 "addi %0,%1,%2@tprel@l")
9622 ;; "b" output constraint here and on tls_tls input to support linker tls
9623 ;; optimization. The linker may edit the instructions emitted by a
9624 ;; tls_got_tprel/tls_tls pair to addis,addi.
9625 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9626 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9627 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9628 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9629 UNSPEC_TLSGOTTPREL))]
9631 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9632 "&& TARGET_CMODEL != CMODEL_SMALL"
9635 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9637 (lo_sum:TLSmode (match_dup 3)
9638 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9640 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9642 [(set (attr "length")
9643 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9647 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9648 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9650 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9651 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9652 UNSPEC_TLSGOTTPREL)))]
9653 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9654 "addis %0,%1,%2@got@tprel@ha"
9655 [(set_attr "length" "4")])
9657 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9658 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9659 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9660 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9661 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9662 UNSPEC_TLSGOTTPREL)))]
9663 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9664 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9665 [(set_attr "length" "4")])
9667 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9668 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9669 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9670 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9672 "TARGET_ELF && HAVE_AS_TLS"
9675 (define_expand "tls_get_tpointer"
9676 [(set (match_operand:SI 0 "gpc_reg_operand")
9677 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9678 "TARGET_XCOFF && HAVE_AS_TLS"
9680 emit_insn (gen_tls_get_tpointer_internal ());
9681 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9685 (define_insn "tls_get_tpointer_internal"
9687 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9688 (clobber (reg:SI LR_REGNO))]
9689 "TARGET_XCOFF && HAVE_AS_TLS"
9690 "bla __get_tpointer")
9692 (define_expand "tls_get_addr<mode>"
9693 [(set (match_operand:P 0 "gpc_reg_operand")
9694 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9695 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9696 "TARGET_XCOFF && HAVE_AS_TLS"
9698 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9699 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9700 emit_insn (gen_tls_get_addr_internal<mode> ());
9701 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9705 (define_insn "tls_get_addr_internal<mode>"
9707 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9711 (clobber (reg:P 11))
9712 (clobber (reg:CC CR0_REGNO))
9713 (clobber (reg:P LR_REGNO))]
9714 "TARGET_XCOFF && HAVE_AS_TLS"
9715 "bla __tls_get_addr")
9717 ;; Next come insns related to the calling sequence.
9719 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9720 ;; We move the back-chain and decrement the stack pointer.
9722 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9723 ;; constant alloca, using that predicate will force the generic code to put
9724 ;; the constant size into a register before calling the expander.
9726 ;; As a result the expander would not have the constant size information
9727 ;; in those cases and would have to generate less efficient code.
9729 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9730 ;; the constant size. The value is forced into a register if necessary.
9732 (define_expand "allocate_stack"
9733 [(set (match_operand 0 "gpc_reg_operand")
9734 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9736 (minus (reg 1) (match_dup 1)))]
9739 rtx chain = gen_reg_rtx (Pmode);
9740 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9742 rtx insn, par, set, mem;
9744 /* By allowing reg_or_cint_operand as the predicate we can get
9745 better code for stack-clash-protection because we do not lose
9746 size information. But the rest of the code expects the operand
9747 to be reg_or_short_operand. If it isn't, then force it into
9749 rtx orig_op1 = operands[1];
9750 if (!reg_or_short_operand (operands[1], Pmode))
9751 operands[1] = force_reg (Pmode, operands[1]);
9753 emit_move_insn (chain, stack_bot);
9755 /* Check stack bounds if necessary. */
9756 if (crtl->limit_stack)
9759 available = expand_binop (Pmode, sub_optab,
9760 stack_pointer_rtx, stack_limit_rtx,
9761 NULL_RTX, 1, OPTAB_WIDEN);
9762 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9765 /* Allocate and probe if requested.
9766 This may look similar to the loop we use for prologue allocations,
9767 but it is critically different. For the former we know the loop
9768 will iterate, but do not know that generally here. The former
9769 uses that knowledge to rotate the loop. Combining them would be
9770 possible with some performance cost. */
9771 if (flag_stack_clash_protection)
9773 rtx rounded_size, last_addr, residual;
9774 HOST_WIDE_INT probe_interval;
9775 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9776 &residual, &probe_interval,
9779 /* We do occasionally get in here with constant sizes, we might
9780 as well do a reasonable job when we obviously can. */
9781 if (rounded_size != const0_rtx)
9783 rtx loop_lab, end_loop;
9784 bool rotated = CONST_INT_P (rounded_size);
9785 rtx update = GEN_INT (-probe_interval);
9786 if (probe_interval > 32768)
9787 update = force_reg (Pmode, update);
9789 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9790 last_addr, rotated);
9792 if (Pmode == SImode)
9793 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9797 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9800 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9801 last_addr, rotated);
9804 /* Now handle residuals. We just have to set operands[1] correctly
9805 and let the rest of the expander run. */
9806 operands[1] = residual;
9809 if (!(CONST_INT_P (operands[1])
9810 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9812 operands[1] = force_reg (Pmode, operands[1]);
9813 neg_op0 = gen_reg_rtx (Pmode);
9815 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9817 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9820 neg_op0 = GEN_INT (-INTVAL (operands[1]));
9822 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9823 : gen_movdi_di_update_stack))
9824 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9826 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9827 it now and set the alias set/attributes. The above gen_*_update
9828 calls will generate a PARALLEL with the MEM set being the first
9830 par = PATTERN (insn);
9831 gcc_assert (GET_CODE (par) == PARALLEL);
9832 set = XVECEXP (par, 0, 0);
9833 gcc_assert (GET_CODE (set) == SET);
9834 mem = SET_DEST (set);
9835 gcc_assert (MEM_P (mem));
9836 MEM_NOTRAP_P (mem) = 1;
9837 set_mem_alias_set (mem, get_frame_alias_set ());
9839 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9843 ;; These patterns say how to save and restore the stack pointer. We need not
9844 ;; save the stack pointer at function level since we are careful to
9845 ;; preserve the backchain. At block level, we have to restore the backchain
9846 ;; when we restore the stack pointer.
9848 ;; For nonlocal gotos, we must save both the stack pointer and its
9849 ;; backchain and restore both. Note that in the nonlocal case, the
9850 ;; save area is a memory location.
9852 (define_expand "save_stack_function"
9853 [(match_operand 0 "any_operand")
9854 (match_operand 1 "any_operand")]
9858 (define_expand "restore_stack_function"
9859 [(match_operand 0 "any_operand")
9860 (match_operand 1 "any_operand")]
9864 ;; Adjust stack pointer (op0) to a new value (op1).
9865 ;; First copy old stack backchain to new location, and ensure that the
9866 ;; scheduler won't reorder the sp assignment before the backchain write.
9867 (define_expand "restore_stack_block"
9868 [(set (match_dup 2) (match_dup 3))
9869 (set (match_dup 4) (match_dup 2))
9871 (set (match_operand 0 "register_operand")
9872 (match_operand 1 "register_operand"))]
9877 operands[1] = force_reg (Pmode, operands[1]);
9878 operands[2] = gen_reg_rtx (Pmode);
9879 operands[3] = gen_frame_mem (Pmode, operands[0]);
9880 operands[4] = gen_frame_mem (Pmode, operands[1]);
9881 p = rtvec_alloc (1);
9882 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9884 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9887 (define_expand "save_stack_nonlocal"
9888 [(set (match_dup 3) (match_dup 4))
9889 (set (match_operand 0 "memory_operand") (match_dup 3))
9890 (set (match_dup 2) (match_operand 1 "register_operand"))]
9893 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9895 /* Copy the backchain to the first word, sp to the second. */
9896 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9897 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9898 operands[3] = gen_reg_rtx (Pmode);
9899 operands[4] = gen_frame_mem (Pmode, operands[1]);
9902 (define_expand "restore_stack_nonlocal"
9903 [(set (match_dup 2) (match_operand 1 "memory_operand"))
9904 (set (match_dup 3) (match_dup 4))
9905 (set (match_dup 5) (match_dup 2))
9907 (set (match_operand 0 "register_operand") (match_dup 3))]
9910 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9913 /* Restore the backchain from the first word, sp from the second. */
9914 operands[2] = gen_reg_rtx (Pmode);
9915 operands[3] = gen_reg_rtx (Pmode);
9916 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9917 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9918 operands[5] = gen_frame_mem (Pmode, operands[3]);
9919 p = rtvec_alloc (1);
9920 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9922 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9925 ;; TOC register handling.
9927 ;; Code to initialize the TOC register...
9929 (define_insn "load_toc_aix_si"
9930 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9931 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9933 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9936 extern int need_toc_init;
9938 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9939 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9940 operands[2] = gen_rtx_REG (Pmode, 2);
9941 return "lwz %0,%1(%2)";
9943 [(set_attr "type" "load")
9944 (set_attr "update" "no")
9945 (set_attr "indexed" "no")])
9947 (define_insn "load_toc_aix_di"
9948 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9949 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9951 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9954 extern int need_toc_init;
9956 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9957 !TARGET_ELF || !TARGET_MINIMAL_TOC);
9959 strcat (buf, "@toc");
9960 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9961 operands[2] = gen_rtx_REG (Pmode, 2);
9962 return "ld %0,%1(%2)";
9964 [(set_attr "type" "load")
9965 (set_attr "update" "no")
9966 (set_attr "indexed" "no")])
9968 (define_insn "load_toc_v4_pic_si"
9969 [(set (reg:SI LR_REGNO)
9970 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9971 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9972 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9973 [(set_attr "type" "branch")
9974 (set_attr "length" "4")])
9976 (define_expand "load_toc_v4_PIC_1"
9977 [(parallel [(set (reg:SI LR_REGNO)
9978 (match_operand:SI 0 "immediate_operand" "s"))
9979 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9980 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9981 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9984 (define_insn "load_toc_v4_PIC_1_normal"
9985 [(set (reg:SI LR_REGNO)
9986 (match_operand:SI 0 "immediate_operand" "s"))
9987 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9988 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9989 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9991 [(set_attr "type" "branch")
9992 (set_attr "length" "4")
9993 (set_attr "cannot_copy" "yes")])
9995 (define_insn "load_toc_v4_PIC_1_476"
9996 [(set (reg:SI LR_REGNO)
9997 (match_operand:SI 0 "immediate_operand" "s"))
9998 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9999 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10000 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10003 static char templ[32];
10005 get_ppc476_thunk_name (name);
10006 sprintf (templ, "bl %s\n%%0:", name);
10009 [(set_attr "type" "branch")
10010 (set_attr "length" "4")
10011 (set_attr "cannot_copy" "yes")])
10013 (define_expand "load_toc_v4_PIC_1b"
10014 [(parallel [(set (reg:SI LR_REGNO)
10015 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10016 (label_ref (match_operand 1 ""))]
10019 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10022 (define_insn "load_toc_v4_PIC_1b_normal"
10023 [(set (reg:SI LR_REGNO)
10024 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10025 (label_ref (match_operand 1 "" ""))]
10028 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10029 "bcl 20,31,$+8\;.long %0-$"
10030 [(set_attr "type" "branch")
10031 (set_attr "length" "8")])
10033 (define_insn "load_toc_v4_PIC_1b_476"
10034 [(set (reg:SI LR_REGNO)
10035 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10036 (label_ref (match_operand 1 "" ""))]
10039 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10042 static char templ[32];
10044 get_ppc476_thunk_name (name);
10045 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10048 [(set_attr "type" "branch")
10049 (set_attr "length" "16")])
10051 (define_insn "load_toc_v4_PIC_2"
10052 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10054 (match_operand:SI 1 "gpc_reg_operand" "b")
10056 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10057 (match_operand:SI 3 "immediate_operand" "s"))))))]
10058 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10060 [(set_attr "type" "load")])
10062 (define_insn "load_toc_v4_PIC_3b"
10063 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10065 (match_operand:SI 1 "gpc_reg_operand" "b")
10068 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10069 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10070 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10071 "addis %0,%1,%2-%3@ha")
10073 (define_insn "load_toc_v4_PIC_3c"
10074 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10076 (match_operand:SI 1 "gpc_reg_operand" "b")
10078 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10079 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10080 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10081 "addi %0,%1,%2-%3@l")
10083 ;; If the TOC is shared over a translation unit, as happens with all
10084 ;; the kinds of PIC that we support, we need to restore the TOC
10085 ;; pointer only when jumping over units of translation.
10086 ;; On Darwin, we need to reload the picbase.
10088 (define_expand "builtin_setjmp_receiver"
10089 [(use (label_ref (match_operand 0 "")))]
10090 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10091 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10092 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10095 if (DEFAULT_ABI == ABI_DARWIN)
10097 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10098 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10102 crtl->uses_pic_offset_table = 1;
10103 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10104 CODE_LABEL_NUMBER (operands[0]));
10105 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10107 emit_insn (gen_load_macho_picbase (tmplabrtx));
10108 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10109 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10113 rs6000_emit_load_toc_table (FALSE);
10117 ;; Largetoc support
10118 (define_insn "*largetoc_high"
10119 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10121 (unspec [(match_operand:DI 1 "" "")
10122 (match_operand:DI 2 "gpc_reg_operand" "b")]
10124 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10125 "addis %0,%2,%1@toc@ha")
10127 (define_insn "*largetoc_high_aix<mode>"
10128 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10130 (unspec [(match_operand:P 1 "" "")
10131 (match_operand:P 2 "gpc_reg_operand" "b")]
10133 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10134 "addis %0,%1@u(%2)")
10136 (define_insn "*largetoc_high_plus"
10137 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10140 (unspec [(match_operand:DI 1 "" "")
10141 (match_operand:DI 2 "gpc_reg_operand" "b")]
10143 (match_operand:DI 3 "add_cint_operand" "n"))))]
10144 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10145 "addis %0,%2,%1+%3@toc@ha")
10147 (define_insn "*largetoc_high_plus_aix<mode>"
10148 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10151 (unspec [(match_operand:P 1 "" "")
10152 (match_operand:P 2 "gpc_reg_operand" "b")]
10154 (match_operand:P 3 "add_cint_operand" "n"))))]
10155 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10156 "addis %0,%1+%3@u(%2)")
10158 (define_insn "*largetoc_low"
10159 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10160 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10161 (match_operand:DI 2 "" "")))]
10162 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10165 (define_insn "*largetoc_low_aix<mode>"
10166 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10167 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10168 (match_operand:P 2 "" "")))]
10169 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10172 (define_insn_and_split "*tocref<mode>"
10173 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10174 (match_operand:P 1 "small_toc_ref" "R"))]
10177 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10178 [(set (match_dup 0) (high:P (match_dup 1)))
10179 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10181 ;; Elf specific ways of loading addresses for non-PIC code.
10182 ;; The output of this could be r0, but we make a very strong
10183 ;; preference for a base register because it will usually
10184 ;; be needed there.
10185 (define_insn "elf_high"
10186 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10187 (high:SI (match_operand 1 "" "")))]
10188 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10191 (define_insn "elf_low"
10192 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10193 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10194 (match_operand 2 "" "")))]
10195 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10198 ;; Call and call_value insns
10199 (define_expand "call"
10200 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10201 (match_operand 1 ""))
10202 (use (match_operand 2 ""))
10203 (clobber (reg:SI LR_REGNO))])]
10207 if (MACHOPIC_INDIRECT)
10208 operands[0] = machopic_indirect_call_target (operands[0]);
10211 gcc_assert (GET_CODE (operands[0]) == MEM);
10212 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10214 operands[0] = XEXP (operands[0], 0);
10216 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10218 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10222 if (GET_CODE (operands[0]) != SYMBOL_REF
10223 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10225 if (INTVAL (operands[2]) & CALL_LONG)
10226 operands[0] = rs6000_longcall_ref (operands[0]);
10228 switch (DEFAULT_ABI)
10232 operands[0] = force_reg (Pmode, operands[0]);
10236 gcc_unreachable ();
10241 (define_expand "call_value"
10242 [(parallel [(set (match_operand 0 "")
10243 (call (mem:SI (match_operand 1 "address_operand"))
10244 (match_operand 2 "")))
10245 (use (match_operand 3 ""))
10246 (clobber (reg:SI LR_REGNO))])]
10250 if (MACHOPIC_INDIRECT)
10251 operands[1] = machopic_indirect_call_target (operands[1]);
10254 gcc_assert (GET_CODE (operands[1]) == MEM);
10255 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10257 operands[1] = XEXP (operands[1], 0);
10259 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10261 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10265 if (GET_CODE (operands[1]) != SYMBOL_REF
10266 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10268 if (INTVAL (operands[3]) & CALL_LONG)
10269 operands[1] = rs6000_longcall_ref (operands[1]);
10271 switch (DEFAULT_ABI)
10275 operands[1] = force_reg (Pmode, operands[1]);
10279 gcc_unreachable ();
10284 ;; Call to function in current module. No TOC pointer reload needed.
10285 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10286 ;; either the function was not prototyped, or it was prototyped as a
10287 ;; variable argument function. It is > 0 if FP registers were passed
10288 ;; and < 0 if they were not.
10290 (define_insn "*call_local32"
10291 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10292 (match_operand 1 "" "g,g"))
10293 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10294 (clobber (reg:SI LR_REGNO))]
10295 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10297 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10298 output_asm_insn ("crxor 6,6,6", operands);
10300 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10301 output_asm_insn ("creqv 6,6,6", operands);
10303 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10305 [(set_attr "type" "branch")
10306 (set_attr "length" "4,8")])
10308 (define_insn "*call_local64"
10309 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10310 (match_operand 1 "" "g,g"))
10311 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10312 (clobber (reg:SI LR_REGNO))]
10313 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10315 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10316 output_asm_insn ("crxor 6,6,6", operands);
10318 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10319 output_asm_insn ("creqv 6,6,6", operands);
10321 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10323 [(set_attr "type" "branch")
10324 (set_attr "length" "4,8")])
10326 (define_insn "*call_value_local32"
10327 [(set (match_operand 0 "" "")
10328 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10329 (match_operand 2 "" "g,g")))
10330 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10331 (clobber (reg:SI LR_REGNO))]
10332 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10334 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10335 output_asm_insn ("crxor 6,6,6", operands);
10337 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10338 output_asm_insn ("creqv 6,6,6", operands);
10340 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10342 [(set_attr "type" "branch")
10343 (set_attr "length" "4,8")])
10346 (define_insn "*call_value_local64"
10347 [(set (match_operand 0 "" "")
10348 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10349 (match_operand 2 "" "g,g")))
10350 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10351 (clobber (reg:SI LR_REGNO))]
10352 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10354 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10355 output_asm_insn ("crxor 6,6,6", operands);
10357 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10358 output_asm_insn ("creqv 6,6,6", operands);
10360 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10362 [(set_attr "type" "branch")
10363 (set_attr "length" "4,8")])
10366 ;; A function pointer under System V is just a normal pointer
10367 ;; operands[0] is the function pointer
10368 ;; operands[1] is the stack size to clean up
10369 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10370 ;; which indicates how to set cr1
10372 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10373 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10374 (match_operand 1 "" "g,g,g,g"))
10375 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10376 (clobber (reg:SI LR_REGNO))]
10377 "DEFAULT_ABI == ABI_V4
10378 || DEFAULT_ABI == ABI_DARWIN"
10380 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10381 output_asm_insn ("crxor 6,6,6", operands);
10383 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10384 output_asm_insn ("creqv 6,6,6", operands);
10386 if (rs6000_speculate_indirect_jumps
10387 || which_alternative == 1 || which_alternative == 3)
10390 return "crset 2\;beq%T0l-";
10392 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10393 (set (attr "length")
10394 (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10395 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10398 (and (eq (symbol_ref "which_alternative") (const_int 2))
10399 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10402 (and (eq (symbol_ref "which_alternative") (const_int 2))
10403 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10405 (const_string "12")
10406 (eq (symbol_ref "which_alternative") (const_int 3))
10407 (const_string "8")]
10408 (const_string "4")))])
10410 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10411 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10412 (match_operand 1 "" "g,g"))
10413 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10414 (clobber (reg:SI LR_REGNO))]
10415 "(DEFAULT_ABI == ABI_DARWIN
10416 || (DEFAULT_ABI == ABI_V4
10417 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10419 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10420 output_asm_insn ("crxor 6,6,6", operands);
10422 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10423 output_asm_insn ("creqv 6,6,6", operands);
10426 return output_call(insn, operands, 0, 2);
10428 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10430 gcc_assert (!TARGET_SECURE_PLT);
10431 return "bl %z0@plt";
10437 "DEFAULT_ABI == ABI_V4
10438 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10439 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10440 [(parallel [(call (mem:SI (match_dup 0))
10442 (use (match_dup 2))
10443 (use (match_dup 3))
10444 (clobber (reg:SI LR_REGNO))])]
10446 operands[3] = pic_offset_table_rtx;
10448 [(set_attr "type" "branch,branch")
10449 (set_attr "length" "4,8")])
10451 (define_insn "*call_nonlocal_sysv_secure<mode>"
10452 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10453 (match_operand 1 "" "g,g"))
10454 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10455 (use (match_operand:SI 3 "register_operand" "r,r"))
10456 (clobber (reg:SI LR_REGNO))]
10457 "(DEFAULT_ABI == ABI_V4
10458 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10459 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10461 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10462 output_asm_insn ("crxor 6,6,6", operands);
10464 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10465 output_asm_insn ("creqv 6,6,6", operands);
10468 /* The magic 32768 offset here and in the other sysv call insns
10469 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10470 See sysv4.h:toc_section. */
10471 return "bl %z0+32768@plt";
10473 return "bl %z0@plt";
10475 [(set_attr "type" "branch,branch")
10476 (set_attr "length" "4,8")])
10478 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10479 [(set (match_operand 0 "" "")
10480 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10481 (match_operand 2 "" "g,g,g,g")))
10482 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10483 (clobber (reg:SI LR_REGNO))]
10484 "DEFAULT_ABI == ABI_V4
10485 || DEFAULT_ABI == ABI_DARWIN"
10487 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10488 output_asm_insn ("crxor 6,6,6", operands);
10490 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10491 output_asm_insn ("creqv 6,6,6", operands);
10493 if (rs6000_speculate_indirect_jumps
10494 || which_alternative == 1 || which_alternative == 3)
10497 return "crset 2\;beq%T1l-";
10499 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10500 (set (attr "length")
10501 (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10502 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10505 (and (eq (symbol_ref "which_alternative") (const_int 2))
10506 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10509 (and (eq (symbol_ref "which_alternative") (const_int 2))
10510 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10512 (const_string "12")
10513 (eq (symbol_ref "which_alternative") (const_int 3))
10514 (const_string "8")]
10515 (const_string "4")))])
10517 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10518 [(set (match_operand 0 "" "")
10519 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10520 (match_operand 2 "" "g,g")))
10521 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10522 (clobber (reg:SI LR_REGNO))]
10523 "(DEFAULT_ABI == ABI_DARWIN
10524 || (DEFAULT_ABI == ABI_V4
10525 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10527 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10528 output_asm_insn ("crxor 6,6,6", operands);
10530 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10531 output_asm_insn ("creqv 6,6,6", operands);
10534 return output_call(insn, operands, 1, 3);
10536 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10538 gcc_assert (!TARGET_SECURE_PLT);
10539 return "bl %z1@plt";
10545 "DEFAULT_ABI == ABI_V4
10546 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10547 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10548 [(parallel [(set (match_dup 0)
10549 (call (mem:SI (match_dup 1))
10551 (use (match_dup 3))
10552 (use (match_dup 4))
10553 (clobber (reg:SI LR_REGNO))])]
10555 operands[4] = pic_offset_table_rtx;
10557 [(set_attr "type" "branch,branch")
10558 (set_attr "length" "4,8")])
10560 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10561 [(set (match_operand 0 "" "")
10562 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10563 (match_operand 2 "" "g,g")))
10564 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10565 (use (match_operand:SI 4 "register_operand" "r,r"))
10566 (clobber (reg:SI LR_REGNO))]
10567 "(DEFAULT_ABI == ABI_V4
10568 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10569 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10571 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10572 output_asm_insn ("crxor 6,6,6", operands);
10574 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10575 output_asm_insn ("creqv 6,6,6", operands);
10578 return "bl %z1+32768@plt";
10580 return "bl %z1@plt";
10582 [(set_attr "type" "branch,branch")
10583 (set_attr "length" "4,8")])
10586 ;; Call to AIX abi function in the same module.
10588 (define_insn "*call_local_aix<mode>"
10589 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10590 (match_operand 1 "" "g"))
10591 (clobber (reg:P LR_REGNO))]
10592 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10594 [(set_attr "type" "branch")
10595 (set_attr "length" "4")])
10597 (define_insn "*call_value_local_aix<mode>"
10598 [(set (match_operand 0 "" "")
10599 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10600 (match_operand 2 "" "g")))
10601 (clobber (reg:P LR_REGNO))]
10602 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10604 [(set_attr "type" "branch")
10605 (set_attr "length" "4")])
10607 ;; Call to AIX abi function which may be in another module.
10608 ;; Restore the TOC pointer (r2) after the call.
10610 (define_insn "*call_nonlocal_aix<mode>"
10611 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10612 (match_operand 1 "" "g"))
10613 (clobber (reg:P LR_REGNO))]
10614 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10616 [(set_attr "type" "branch")
10617 (set_attr "length" "8")])
10619 (define_insn "*call_value_nonlocal_aix<mode>"
10620 [(set (match_operand 0 "" "")
10621 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10622 (match_operand 2 "" "g")))
10623 (clobber (reg:P LR_REGNO))]
10624 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10626 [(set_attr "type" "branch")
10627 (set_attr "length" "8")])
10629 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10630 ;; Operand0 is the addresss of the function to call
10631 ;; Operand2 is the location in the function descriptor to load r2 from
10632 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10634 (define_insn "*call_indirect_aix<mode>"
10635 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10636 (match_operand 1 "" "g,g"))
10637 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10638 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10639 (clobber (reg:P LR_REGNO))]
10640 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10641 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10642 [(set_attr "type" "jmpreg")
10643 (set_attr "length" "12")])
10645 (define_insn "*call_indirect_aix<mode>_nospec"
10646 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10647 (match_operand 1 "" "g,g"))
10648 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10649 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10650 (clobber (reg:P LR_REGNO))]
10651 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10652 "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10653 [(set_attr "type" "jmpreg")
10654 (set_attr "length" "16")])
10656 (define_insn "*call_value_indirect_aix<mode>"
10657 [(set (match_operand 0 "" "")
10658 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10659 (match_operand 2 "" "g,g")))
10660 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10661 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10662 (clobber (reg:P LR_REGNO))]
10663 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10664 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10665 [(set_attr "type" "jmpreg")
10666 (set_attr "length" "12")])
10668 (define_insn "*call_value_indirect_aix<mode>_nospec"
10669 [(set (match_operand 0 "" "")
10670 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10671 (match_operand 2 "" "g,g")))
10672 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10673 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10674 (clobber (reg:P LR_REGNO))]
10675 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10676 "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10677 [(set_attr "type" "jmpreg")
10678 (set_attr "length" "16")])
10680 ;; Call to indirect functions with the ELFv2 ABI.
10681 ;; Operand0 is the addresss of the function to call
10682 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10684 (define_insn "*call_indirect_elfv2<mode>"
10685 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10686 (match_operand 1 "" "g,g"))
10687 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10688 (clobber (reg:P LR_REGNO))]
10689 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10690 "b%T0l\;<ptrload> 2,%2(1)"
10691 [(set_attr "type" "jmpreg")
10692 (set_attr "length" "8")])
10694 ;; Variant with deliberate misprediction.
10695 (define_insn "*call_indirect_elfv2<mode>_nospec"
10696 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10697 (match_operand 1 "" "g,g"))
10698 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10699 (clobber (reg:P LR_REGNO))]
10700 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10701 "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10702 [(set_attr "type" "jmpreg")
10703 (set_attr "length" "12")])
10705 (define_insn "*call_value_indirect_elfv2<mode>"
10706 [(set (match_operand 0 "" "")
10707 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10708 (match_operand 2 "" "g,g")))
10709 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10710 (clobber (reg:P LR_REGNO))]
10711 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10712 "b%T1l\;<ptrload> 2,%3(1)"
10713 [(set_attr "type" "jmpreg")
10714 (set_attr "length" "8")])
10716 ; Variant with deliberate misprediction.
10717 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10718 [(set (match_operand 0 "" "")
10719 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10720 (match_operand 2 "" "g,g")))
10721 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10722 (clobber (reg:P LR_REGNO))]
10723 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10724 "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10725 [(set_attr "type" "jmpreg")
10726 (set_attr "length" "12")])
10728 ;; Call subroutine returning any type.
10729 (define_expand "untyped_call"
10730 [(parallel [(call (match_operand 0 "")
10732 (match_operand 1 "")
10733 (match_operand 2 "")])]
10738 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10740 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10742 rtx set = XVECEXP (operands[2], 0, i);
10743 emit_move_insn (SET_DEST (set), SET_SRC (set));
10746 /* The optimizer does not know that the call sets the function value
10747 registers we stored in the result block. We avoid problems by
10748 claiming that all hard registers are used and clobbered at this
10750 emit_insn (gen_blockage ());
10755 ;; sibling call patterns
10756 (define_expand "sibcall"
10757 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10758 (match_operand 1 ""))
10759 (use (match_operand 2 ""))
10764 if (MACHOPIC_INDIRECT)
10765 operands[0] = machopic_indirect_call_target (operands[0]);
10768 gcc_assert (GET_CODE (operands[0]) == MEM);
10769 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10771 operands[0] = XEXP (operands[0], 0);
10773 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10775 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10780 (define_expand "sibcall_value"
10781 [(parallel [(set (match_operand 0 "register_operand")
10782 (call (mem:SI (match_operand 1 "address_operand"))
10783 (match_operand 2 "")))
10784 (use (match_operand 3 ""))
10789 if (MACHOPIC_INDIRECT)
10790 operands[1] = machopic_indirect_call_target (operands[1]);
10793 gcc_assert (GET_CODE (operands[1]) == MEM);
10794 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10796 operands[1] = XEXP (operands[1], 0);
10798 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10800 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10805 (define_insn "*sibcall_local32"
10806 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10807 (match_operand 1 "" "g,g"))
10808 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10810 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10812 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10813 output_asm_insn ("crxor 6,6,6", operands);
10815 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10816 output_asm_insn ("creqv 6,6,6", operands);
10818 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10820 [(set_attr "type" "branch")
10821 (set_attr "length" "4,8")])
10823 (define_insn "*sibcall_local64"
10824 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10825 (match_operand 1 "" "g,g"))
10826 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10828 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10830 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10831 output_asm_insn ("crxor 6,6,6", operands);
10833 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10834 output_asm_insn ("creqv 6,6,6", operands);
10836 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10838 [(set_attr "type" "branch")
10839 (set_attr "length" "4,8")])
10841 (define_insn "*sibcall_value_local32"
10842 [(set (match_operand 0 "" "")
10843 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10844 (match_operand 2 "" "g,g")))
10845 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10847 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10849 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10850 output_asm_insn ("crxor 6,6,6", operands);
10852 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10853 output_asm_insn ("creqv 6,6,6", operands);
10855 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10857 [(set_attr "type" "branch")
10858 (set_attr "length" "4,8")])
10860 (define_insn "*sibcall_value_local64"
10861 [(set (match_operand 0 "" "")
10862 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10863 (match_operand 2 "" "g,g")))
10864 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10866 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10868 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10869 output_asm_insn ("crxor 6,6,6", operands);
10871 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10872 output_asm_insn ("creqv 6,6,6", operands);
10874 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10876 [(set_attr "type" "branch")
10877 (set_attr "length" "4,8")])
10879 (define_insn "*sibcall_nonlocal_sysv<mode>"
10880 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10881 (match_operand 1 "" ""))
10882 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10884 "(DEFAULT_ABI == ABI_DARWIN
10885 || DEFAULT_ABI == ABI_V4)
10886 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10888 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10889 output_asm_insn ("crxor 6,6,6", operands);
10891 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10892 output_asm_insn ("creqv 6,6,6", operands);
10894 if (which_alternative >= 2)
10896 if (rs6000_speculate_indirect_jumps)
10899 /* Can use CR0 since it is volatile across sibcalls. */
10900 return "crset 2\;beq%T0-\;b $";
10902 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10904 gcc_assert (!TARGET_SECURE_PLT);
10905 return "b %z0@plt";
10910 [(set_attr "type" "branch")
10911 (set (attr "length")
10912 (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10914 (and (eq (symbol_ref "which_alternative") (const_int 2))
10915 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10917 (const_string "12")
10918 (and (eq (symbol_ref "which_alternative") (const_int 3))
10919 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10922 (and (eq (symbol_ref "which_alternative") (const_int 3))
10923 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10925 (const_string "16")]
10926 (const_string "4")))])
10928 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10929 [(set (match_operand 0 "" "")
10930 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10931 (match_operand 2 "" "")))
10932 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10934 "(DEFAULT_ABI == ABI_DARWIN
10935 || DEFAULT_ABI == ABI_V4)
10936 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10938 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10939 output_asm_insn ("crxor 6,6,6", operands);
10941 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10942 output_asm_insn ("creqv 6,6,6", operands);
10944 if (which_alternative >= 2)
10946 if (rs6000_speculate_indirect_jumps)
10949 /* Can use CR0 since it is volatile across sibcalls. */
10950 return "crset 2\;beq%T1-\;b $";
10952 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10954 gcc_assert (!TARGET_SECURE_PLT);
10955 return "b %z1@plt";
10960 [(set_attr "type" "branch")
10961 (set (attr "length")
10962 (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10964 (and (eq (symbol_ref "which_alternative") (const_int 2))
10965 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10967 (const_string "12")
10968 (and (eq (symbol_ref "which_alternative") (const_int 3))
10969 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10972 (and (eq (symbol_ref "which_alternative") (const_int 3))
10973 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10975 (const_string "16")]
10976 (const_string "4")))])
10978 ;; AIX ABI sibling call patterns.
10980 (define_insn "*sibcall_aix<mode>"
10981 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10982 (match_operand 1 "" "g,g"))
10984 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10988 [(set_attr "type" "branch")
10989 (set_attr "length" "4")])
10991 (define_insn "*sibcall_value_aix<mode>"
10992 [(set (match_operand 0 "" "")
10993 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10994 (match_operand 2 "" "g,g")))
10996 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11000 [(set_attr "type" "branch")
11001 (set_attr "length" "4")])
11003 (define_expand "sibcall_epilogue"
11004 [(use (const_int 0))]
11007 if (!TARGET_SCHED_PROLOG)
11008 emit_insn (gen_blockage ());
11009 rs6000_emit_epilogue (TRUE);
11013 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11014 ;; all of memory. This blocks insns from being moved across this point.
11016 (define_insn "blockage"
11017 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11020 [(set_attr "length" "0")])
11022 (define_expand "probe_stack_address"
11023 [(use (match_operand 0 "address_operand"))]
11026 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11027 MEM_VOLATILE_P (operands[0]) = 1;
11030 emit_insn (gen_probe_stack_di (operands[0]));
11032 emit_insn (gen_probe_stack_si (operands[0]));
11036 (define_insn "probe_stack_<mode>"
11037 [(set (match_operand:P 0 "memory_operand" "=m")
11038 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11041 operands[1] = gen_rtx_REG (Pmode, 0);
11042 return "st<wd>%U0%X0 %1,%0";
11044 [(set_attr "type" "store")
11045 (set (attr "update")
11046 (if_then_else (match_operand 0 "update_address_mem")
11047 (const_string "yes")
11048 (const_string "no")))
11049 (set (attr "indexed")
11050 (if_then_else (match_operand 0 "indexed_address_mem")
11051 (const_string "yes")
11052 (const_string "no")))
11053 (set_attr "length" "4")])
11055 (define_insn "probe_stack_range<P:mode>"
11056 [(set (match_operand:P 0 "register_operand" "=&r")
11057 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11058 (match_operand:P 2 "register_operand" "r")
11059 (match_operand:P 3 "register_operand" "r")]
11060 UNSPECV_PROBE_STACK_RANGE))]
11062 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11063 [(set_attr "type" "three")])
11065 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11066 ;; signed & unsigned, and one type of branch.
11068 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11069 ;; insns, and branches.
11071 (define_expand "cbranch<mode>4"
11072 [(use (match_operator 0 "comparison_operator"
11073 [(match_operand:GPR 1 "gpc_reg_operand")
11074 (match_operand:GPR 2 "reg_or_short_operand")]))
11075 (use (match_operand 3))]
11078 /* Take care of the possibility that operands[2] might be negative but
11079 this might be a logical operation. That insn doesn't exist. */
11080 if (GET_CODE (operands[2]) == CONST_INT
11081 && INTVAL (operands[2]) < 0)
11083 operands[2] = force_reg (<MODE>mode, operands[2]);
11084 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11085 GET_MODE (operands[0]),
11086 operands[1], operands[2]);
11089 rs6000_emit_cbranch (<MODE>mode, operands);
11093 (define_expand "cbranch<mode>4"
11094 [(use (match_operator 0 "comparison_operator"
11095 [(match_operand:FP 1 "gpc_reg_operand")
11096 (match_operand:FP 2 "gpc_reg_operand")]))
11097 (use (match_operand 3))]
11100 rs6000_emit_cbranch (<MODE>mode, operands);
11104 (define_expand "cstore<mode>4_signed"
11105 [(use (match_operator 1 "signed_comparison_operator"
11106 [(match_operand:P 2 "gpc_reg_operand")
11107 (match_operand:P 3 "gpc_reg_operand")]))
11108 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11111 enum rtx_code cond_code = GET_CODE (operands[1]);
11113 rtx op0 = operands[0];
11114 rtx op1 = operands[2];
11115 rtx op2 = operands[3];
11117 if (cond_code == GE || cond_code == LT)
11119 cond_code = swap_condition (cond_code);
11120 std::swap (op1, op2);
11123 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11124 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11125 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11127 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11128 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11129 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11131 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11133 if (cond_code == LE)
11134 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11137 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11138 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11139 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11145 (define_expand "cstore<mode>4_unsigned"
11146 [(use (match_operator 1 "unsigned_comparison_operator"
11147 [(match_operand:P 2 "gpc_reg_operand")
11148 (match_operand:P 3 "reg_or_short_operand")]))
11149 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11152 enum rtx_code cond_code = GET_CODE (operands[1]);
11154 rtx op0 = operands[0];
11155 rtx op1 = operands[2];
11156 rtx op2 = operands[3];
11158 if (cond_code == GEU || cond_code == LTU)
11160 cond_code = swap_condition (cond_code);
11161 std::swap (op1, op2);
11164 if (!gpc_reg_operand (op1, <MODE>mode))
11165 op1 = force_reg (<MODE>mode, op1);
11166 if (!reg_or_short_operand (op2, <MODE>mode))
11167 op2 = force_reg (<MODE>mode, op2);
11169 rtx tmp = gen_reg_rtx (<MODE>mode);
11170 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11172 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11173 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11175 if (cond_code == LEU)
11176 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11178 emit_insn (gen_neg<mode>2 (op0, tmp2));
11183 (define_expand "cstore_si_as_di"
11184 [(use (match_operator 1 "unsigned_comparison_operator"
11185 [(match_operand:SI 2 "gpc_reg_operand")
11186 (match_operand:SI 3 "reg_or_short_operand")]))
11187 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11190 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11191 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11193 operands[2] = force_reg (SImode, operands[2]);
11194 operands[3] = force_reg (SImode, operands[3]);
11195 rtx op1 = gen_reg_rtx (DImode);
11196 rtx op2 = gen_reg_rtx (DImode);
11197 convert_move (op1, operands[2], uns_flag);
11198 convert_move (op2, operands[3], uns_flag);
11200 if (cond_code == GT || cond_code == LE)
11202 cond_code = swap_condition (cond_code);
11203 std::swap (op1, op2);
11206 rtx tmp = gen_reg_rtx (DImode);
11207 rtx tmp2 = gen_reg_rtx (DImode);
11208 emit_insn (gen_subdi3 (tmp, op1, op2));
11209 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11215 gcc_unreachable ();
11220 tmp3 = gen_reg_rtx (DImode);
11221 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11225 convert_move (operands[0], tmp3, 1);
11230 (define_expand "cstore<mode>4_signed_imm"
11231 [(use (match_operator 1 "signed_comparison_operator"
11232 [(match_operand:GPR 2 "gpc_reg_operand")
11233 (match_operand:GPR 3 "immediate_operand")]))
11234 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11237 bool invert = false;
11239 enum rtx_code cond_code = GET_CODE (operands[1]);
11241 rtx op0 = operands[0];
11242 rtx op1 = operands[2];
11243 HOST_WIDE_INT val = INTVAL (operands[3]);
11245 if (cond_code == GE || cond_code == GT)
11247 cond_code = reverse_condition (cond_code);
11251 if (cond_code == LE)
11254 rtx tmp = gen_reg_rtx (<MODE>mode);
11255 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11256 rtx x = gen_reg_rtx (<MODE>mode);
11258 emit_insn (gen_and<mode>3 (x, op1, tmp));
11260 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11264 rtx tmp = gen_reg_rtx (<MODE>mode);
11265 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11269 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11270 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11275 (define_expand "cstore<mode>4_unsigned_imm"
11276 [(use (match_operator 1 "unsigned_comparison_operator"
11277 [(match_operand:GPR 2 "gpc_reg_operand")
11278 (match_operand:GPR 3 "immediate_operand")]))
11279 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11282 bool invert = false;
11284 enum rtx_code cond_code = GET_CODE (operands[1]);
11286 rtx op0 = operands[0];
11287 rtx op1 = operands[2];
11288 HOST_WIDE_INT val = INTVAL (operands[3]);
11290 if (cond_code == GEU || cond_code == GTU)
11292 cond_code = reverse_condition (cond_code);
11296 if (cond_code == LEU)
11299 rtx tmp = gen_reg_rtx (<MODE>mode);
11300 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11301 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11302 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11303 rtx x = gen_reg_rtx (<MODE>mode);
11305 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11307 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11311 rtx tmp = gen_reg_rtx (<MODE>mode);
11312 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11316 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11317 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11322 (define_expand "cstore<mode>4"
11323 [(use (match_operator 1 "comparison_operator"
11324 [(match_operand:GPR 2 "gpc_reg_operand")
11325 (match_operand:GPR 3 "reg_or_short_operand")]))
11326 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11329 /* Expanding EQ and NE directly to some machine instructions does not help
11330 but does hurt combine. So don't. */
11331 if (GET_CODE (operands[1]) == EQ)
11332 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11333 else if (<MODE>mode == Pmode
11334 && GET_CODE (operands[1]) == NE)
11335 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11336 else if (GET_CODE (operands[1]) == NE)
11338 rtx tmp = gen_reg_rtx (<MODE>mode);
11339 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11340 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11343 /* If ISEL is fast, expand to it. */
11344 else if (TARGET_ISEL)
11345 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11347 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11348 etc. combinations magically work out just right. */
11349 else if (<MODE>mode == Pmode
11350 && unsigned_comparison_operator (operands[1], VOIDmode))
11351 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11352 operands[2], operands[3]));
11354 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11355 else if (<MODE>mode == SImode && Pmode == DImode)
11356 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11357 operands[2], operands[3]));
11359 /* For signed comparisons against a constant, we can do some simple
11361 else if (signed_comparison_operator (operands[1], VOIDmode)
11362 && CONST_INT_P (operands[3]))
11363 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11364 operands[2], operands[3]));
11366 /* And similarly for unsigned comparisons. */
11367 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11368 && CONST_INT_P (operands[3]))
11369 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11370 operands[2], operands[3]));
11372 /* We also do not want to use mfcr for signed comparisons. */
11373 else if (<MODE>mode == Pmode
11374 && signed_comparison_operator (operands[1], VOIDmode))
11375 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11376 operands[2], operands[3]));
11378 /* Everything else, use the mfcr brute force. */
11380 rs6000_emit_sCOND (<MODE>mode, operands);
11385 (define_expand "cstore<mode>4"
11386 [(use (match_operator 1 "comparison_operator"
11387 [(match_operand:FP 2 "gpc_reg_operand")
11388 (match_operand:FP 3 "gpc_reg_operand")]))
11389 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11392 rs6000_emit_sCOND (<MODE>mode, operands);
11397 (define_expand "stack_protect_set"
11398 [(match_operand 0 "memory_operand")
11399 (match_operand 1 "memory_operand")]
11402 if (rs6000_stack_protector_guard == SSP_TLS)
11404 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11405 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11406 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11407 operands[1] = gen_rtx_MEM (Pmode, addr);
11411 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11413 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11418 (define_insn "stack_protect_setsi"
11419 [(set (match_operand:SI 0 "memory_operand" "=m")
11420 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11421 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11423 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11424 [(set_attr "type" "three")
11425 (set_attr "length" "12")])
11427 (define_insn "stack_protect_setdi"
11428 [(set (match_operand:DI 0 "memory_operand" "=Y")
11429 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11430 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11432 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11433 [(set_attr "type" "three")
11434 (set_attr "length" "12")])
11436 (define_expand "stack_protect_test"
11437 [(match_operand 0 "memory_operand")
11438 (match_operand 1 "memory_operand")
11439 (match_operand 2 "")]
11442 rtx guard = operands[1];
11444 if (rs6000_stack_protector_guard == SSP_TLS)
11446 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11447 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11448 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11449 guard = gen_rtx_MEM (Pmode, addr);
11452 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11453 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11454 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11455 emit_jump_insn (jump);
11460 (define_insn "stack_protect_testsi"
11461 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11462 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11463 (match_operand:SI 2 "memory_operand" "m,m")]
11465 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11466 (clobber (match_scratch:SI 3 "=&r,&r"))]
11469 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11470 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11471 [(set_attr "length" "16,20")])
11473 (define_insn "stack_protect_testdi"
11474 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11475 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11476 (match_operand:DI 2 "memory_operand" "Y,Y")]
11478 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11479 (clobber (match_scratch:DI 3 "=&r,&r"))]
11482 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11483 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11484 [(set_attr "length" "16,20")])
11487 ;; Here are the actual compare insns.
11488 (define_insn "*cmp<mode>_signed"
11489 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11490 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11491 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11493 "cmp<wd>%I2 %0,%1,%2"
11494 [(set_attr "type" "cmp")])
11496 (define_insn "*cmp<mode>_unsigned"
11497 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11498 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11499 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11501 "cmpl<wd>%I2 %0,%1,%2"
11502 [(set_attr "type" "cmp")])
11504 ;; If we are comparing a register for equality with a large constant,
11505 ;; we can do this with an XOR followed by a compare. But this is profitable
11506 ;; only if the large constant is only used for the comparison (and in this
11507 ;; case we already have a register to reuse as scratch).
11509 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11510 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11513 [(set (match_operand:SI 0 "register_operand")
11514 (match_operand:SI 1 "logical_const_operand"))
11515 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11517 (match_operand:SI 2 "logical_const_operand")]))
11518 (set (match_operand:CC 4 "cc_reg_operand")
11519 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11522 (if_then_else (match_operator 6 "equality_operator"
11523 [(match_dup 4) (const_int 0)])
11524 (match_operand 7 "")
11525 (match_operand 8 "")))]
11526 "peep2_reg_dead_p (3, operands[0])
11527 && peep2_reg_dead_p (4, operands[4])
11528 && REGNO (operands[0]) != REGNO (operands[5])"
11529 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11530 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11531 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11534 /* Get the constant we are comparing against, and see what it looks like
11535 when sign-extended from 16 to 32 bits. Then see what constant we could
11536 XOR with SEXTC to get the sign-extended value. */
11537 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11539 operands[1], operands[2]);
11540 HOST_WIDE_INT c = INTVAL (cnst);
11541 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11542 HOST_WIDE_INT xorv = c ^ sextc;
11544 operands[9] = GEN_INT (xorv);
11545 operands[10] = GEN_INT (sextc);
11548 ;; The following two insns don't exist as single insns, but if we provide
11549 ;; them, we can swap an add and compare, which will enable us to overlap more
11550 ;; of the required delay between a compare and branch. We generate code for
11551 ;; them by splitting.
11554 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11555 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11556 (match_operand:SI 2 "short_cint_operand" "i")))
11557 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11558 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11561 [(set_attr "length" "8")])
11564 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11565 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11566 (match_operand:SI 2 "u_short_cint_operand" "i")))
11567 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11568 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11571 [(set_attr "length" "8")])
11574 [(set (match_operand:CC 3 "cc_reg_operand")
11575 (compare:CC (match_operand:SI 1 "gpc_reg_operand")
11576 (match_operand:SI 2 "short_cint_operand")))
11577 (set (match_operand:SI 0 "gpc_reg_operand")
11578 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11580 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11581 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11584 [(set (match_operand:CCUNS 3 "cc_reg_operand")
11585 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand")
11586 (match_operand:SI 2 "u_short_cint_operand")))
11587 (set (match_operand:SI 0 "gpc_reg_operand")
11588 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11590 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11591 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11593 ;; Only need to compare second words if first words equal
11594 (define_insn "*cmp<mode>_internal1"
11595 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11596 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11597 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11598 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11599 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11600 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11601 [(set_attr "type" "fpcompare")
11602 (set_attr "length" "12")])
11604 (define_insn_and_split "*cmp<mode>_internal2"
11605 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11606 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11607 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11608 (clobber (match_scratch:DF 3 "=d"))
11609 (clobber (match_scratch:DF 4 "=d"))
11610 (clobber (match_scratch:DF 5 "=d"))
11611 (clobber (match_scratch:DF 6 "=d"))
11612 (clobber (match_scratch:DF 7 "=d"))
11613 (clobber (match_scratch:DF 8 "=d"))
11614 (clobber (match_scratch:DF 9 "=d"))
11615 (clobber (match_scratch:DF 10 "=d"))
11616 (clobber (match_scratch:GPR 11 "=b"))]
11617 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11618 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11620 "&& reload_completed"
11621 [(set (match_dup 3) (match_dup 14))
11622 (set (match_dup 4) (match_dup 15))
11623 (set (match_dup 9) (abs:DF (match_dup 5)))
11624 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11625 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11626 (label_ref (match_dup 12))
11628 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11629 (set (pc) (label_ref (match_dup 13)))
11631 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11632 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11633 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11634 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11637 REAL_VALUE_TYPE rv;
11638 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11639 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11641 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11642 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11643 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11644 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11645 operands[12] = gen_label_rtx ();
11646 operands[13] = gen_label_rtx ();
11648 operands[14] = force_const_mem (DFmode,
11649 const_double_from_real_value (rv, DFmode));
11650 operands[15] = force_const_mem (DFmode,
11651 const_double_from_real_value (dconst0,
11656 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11657 operands[14] = gen_const_mem (DFmode, tocref);
11658 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11659 operands[15] = gen_const_mem (DFmode, tocref);
11660 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11661 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11665 ;; Now we have the scc insns. We can do some combinations because of the
11666 ;; way the machine works.
11668 ;; Note that this is probably faster if we can put an insn between the
11669 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11670 ;; cases the insns below which don't use an intermediate CR field will
11671 ;; be used instead.
11673 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11674 (match_operator:SI 1 "scc_comparison_operator"
11675 [(match_operand 2 "cc_reg_operand" "y")
11678 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11679 [(set (attr "type")
11680 (cond [(match_test "TARGET_MFCRF")
11681 (const_string "mfcrf")
11683 (const_string "mfcr")))
11684 (set_attr "length" "8")])
11687 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11688 (match_operator:DI 1 "scc_comparison_operator"
11689 [(match_operand 2 "cc_reg_operand" "y")
11692 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11693 [(set (attr "type")
11694 (cond [(match_test "TARGET_MFCRF")
11695 (const_string "mfcrf")
11697 (const_string "mfcr")))
11698 (set_attr "length" "8")])
11701 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11702 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11703 [(match_operand 2 "cc_reg_operand" "y,y")
11706 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11707 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11710 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11712 [(set_attr "type" "shift")
11713 (set_attr "dot" "yes")
11714 (set_attr "length" "8,16")])
11717 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11718 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11719 [(match_operand 2 "cc_reg_operand")
11722 (set (match_operand:SI 3 "gpc_reg_operand")
11723 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11724 "TARGET_32BIT && reload_completed"
11725 [(set (match_dup 3)
11726 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11728 (compare:CC (match_dup 3)
11733 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11734 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11735 [(match_operand 2 "cc_reg_operand" "y")
11737 (match_operand:SI 3 "const_int_operand" "n")))]
11740 int is_bit = ccr_bit (operands[1], 1);
11741 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11744 if (is_bit >= put_bit)
11745 count = is_bit - put_bit;
11747 count = 32 - (put_bit - is_bit);
11749 operands[4] = GEN_INT (count);
11750 operands[5] = GEN_INT (put_bit);
11752 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11754 [(set (attr "type")
11755 (cond [(match_test "TARGET_MFCRF")
11756 (const_string "mfcrf")
11758 (const_string "mfcr")))
11759 (set_attr "length" "8")])
11762 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11764 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11765 [(match_operand 2 "cc_reg_operand" "y,y")
11767 (match_operand:SI 3 "const_int_operand" "n,n"))
11769 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11770 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11774 int is_bit = ccr_bit (operands[1], 1);
11775 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11778 /* Force split for non-cc0 compare. */
11779 if (which_alternative == 1)
11782 if (is_bit >= put_bit)
11783 count = is_bit - put_bit;
11785 count = 32 - (put_bit - is_bit);
11787 operands[5] = GEN_INT (count);
11788 operands[6] = GEN_INT (put_bit);
11790 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11792 [(set_attr "type" "shift")
11793 (set_attr "dot" "yes")
11794 (set_attr "length" "8,16")])
11797 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11799 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11800 [(match_operand 2 "cc_reg_operand")
11802 (match_operand:SI 3 "const_int_operand"))
11804 (set (match_operand:SI 4 "gpc_reg_operand")
11805 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11808 [(set (match_dup 4)
11809 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11812 (compare:CC (match_dup 4)
11817 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11818 (define_code_attr UNS [(eq "CC")
11820 (lt "CC") (ltu "CCUNS")
11821 (gt "CC") (gtu "CCUNS")
11822 (le "CC") (leu "CCUNS")
11823 (ge "CC") (geu "CCUNS")])
11824 (define_code_attr UNSu_ [(eq "")
11829 (ge "") (geu "u_")])
11830 (define_code_attr UNSIK [(eq "I")
11835 (ge "I") (geu "K")])
11837 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11838 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11839 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11840 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11841 (clobber (match_scratch:GPR 3 "=r"))
11842 (clobber (match_scratch:GPR 4 "=r"))
11843 (clobber (match_scratch:<UNS> 5 "=y"))]
11845 && !(<CODE> == EQ && operands[2] == const0_rtx)
11846 && !(<CODE> == NE && operands[2] == const0_rtx
11847 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11852 rtx_code code = <CODE>;
11853 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11855 HOST_WIDE_INT val = INTVAL (operands[2]);
11856 if (code == LT && val != -0x8000)
11861 if (code == GT && val != 0x7fff)
11866 if (code == LTU && val != 0)
11871 if (code == GTU && val != 0xffff)
11876 operands[2] = GEN_INT (val);
11879 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11880 operands[3] = const0_rtx;
11883 if (GET_CODE (operands[3]) == SCRATCH)
11884 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11885 emit_move_insn (operands[3], const0_rtx);
11888 if (GET_CODE (operands[4]) == SCRATCH)
11889 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11890 emit_move_insn (operands[4], const1_rtx);
11892 if (GET_CODE (operands[5]) == SCRATCH)
11893 operands[5] = gen_reg_rtx (<UNS>mode);
11895 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11896 emit_insn (gen_rtx_SET (operands[5], c1));
11898 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11899 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11900 emit_move_insn (operands[0], x);
11904 [(set (attr "cost")
11905 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11907 || <CODE> == LE || <CODE> == GE
11908 || <CODE> == LEU || <CODE> == GEU")
11910 (const_string "10")))])
11912 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11915 (define_expand "eq<mode>3"
11917 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11918 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11919 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11920 (clobber (match_scratch:GPR 3 "=r"))
11921 (clobber (match_scratch:GPR 4 "=r"))])]
11924 if (TARGET_ISEL && operands[2] != const0_rtx)
11926 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11932 (define_insn_and_split "*eq<mode>3"
11933 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11934 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11935 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11936 (clobber (match_scratch:GPR 3 "=r"))
11937 (clobber (match_scratch:GPR 4 "=r"))]
11938 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11941 [(set (match_dup 4)
11942 (clz:GPR (match_dup 3)))
11944 (lshiftrt:GPR (match_dup 4)
11947 operands[3] = rs6000_emit_eqne (<MODE>mode,
11948 operands[1], operands[2], operands[3]);
11950 if (GET_CODE (operands[4]) == SCRATCH)
11951 operands[4] = gen_reg_rtx (<MODE>mode);
11953 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11955 [(set (attr "length")
11956 (if_then_else (match_test "operands[2] == const0_rtx")
11958 (const_string "12")))])
11960 (define_expand "ne<mode>3"
11962 (set (match_operand:P 0 "gpc_reg_operand" "=r")
11963 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11964 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11965 (clobber (match_scratch:P 3 "=r"))
11966 (clobber (match_scratch:P 4 "=r"))
11967 (clobber (reg:P CA_REGNO))])]
11970 if (TARGET_ISEL && operands[2] != const0_rtx)
11972 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11978 (define_insn_and_split "*ne<mode>3"
11979 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11980 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11981 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11982 (clobber (match_scratch:P 3 "=r"))
11983 (clobber (match_scratch:P 4 "=r"))
11984 (clobber (reg:P CA_REGNO))]
11985 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11988 [(parallel [(set (match_dup 4)
11989 (plus:P (match_dup 3)
11991 (set (reg:P CA_REGNO)
11992 (ne:P (match_dup 3)
11994 (parallel [(set (match_dup 0)
11995 (plus:P (plus:P (not:P (match_dup 4))
11998 (clobber (reg:P CA_REGNO))])]
12000 operands[3] = rs6000_emit_eqne (<MODE>mode,
12001 operands[1], operands[2], operands[3]);
12003 if (GET_CODE (operands[4]) == SCRATCH)
12004 operands[4] = gen_reg_rtx (<MODE>mode);
12006 [(set (attr "length")
12007 (if_then_else (match_test "operands[2] == const0_rtx")
12009 (const_string "12")))])
12011 (define_insn_and_split "*neg_eq_<mode>"
12012 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12013 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12014 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12015 (clobber (match_scratch:P 3 "=r"))
12016 (clobber (match_scratch:P 4 "=r"))
12017 (clobber (reg:P CA_REGNO))]
12021 [(parallel [(set (match_dup 4)
12022 (plus:P (match_dup 3)
12024 (set (reg:P CA_REGNO)
12025 (ne:P (match_dup 3)
12027 (parallel [(set (match_dup 0)
12028 (plus:P (reg:P CA_REGNO)
12030 (clobber (reg:P CA_REGNO))])]
12032 operands[3] = rs6000_emit_eqne (<MODE>mode,
12033 operands[1], operands[2], operands[3]);
12035 if (GET_CODE (operands[4]) == SCRATCH)
12036 operands[4] = gen_reg_rtx (<MODE>mode);
12038 [(set (attr "length")
12039 (if_then_else (match_test "operands[2] == const0_rtx")
12041 (const_string "12")))])
12043 (define_insn_and_split "*neg_ne_<mode>"
12044 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12045 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12046 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12047 (clobber (match_scratch:P 3 "=r"))
12048 (clobber (match_scratch:P 4 "=r"))
12049 (clobber (reg:P CA_REGNO))]
12053 [(parallel [(set (match_dup 4)
12054 (neg:P (match_dup 3)))
12055 (set (reg:P CA_REGNO)
12056 (eq:P (match_dup 3)
12058 (parallel [(set (match_dup 0)
12059 (plus:P (reg:P CA_REGNO)
12061 (clobber (reg:P CA_REGNO))])]
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 [(set (attr "length")
12070 (if_then_else (match_test "operands[2] == const0_rtx")
12072 (const_string "12")))])
12074 (define_insn_and_split "*plus_eq_<mode>"
12075 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12076 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12077 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12078 (match_operand:P 3 "gpc_reg_operand" "r")))
12079 (clobber (match_scratch:P 4 "=r"))
12080 (clobber (match_scratch:P 5 "=r"))
12081 (clobber (reg:P CA_REGNO))]
12085 [(parallel [(set (match_dup 5)
12086 (neg:P (match_dup 4)))
12087 (set (reg:P CA_REGNO)
12088 (eq:P (match_dup 4)
12090 (parallel [(set (match_dup 0)
12091 (plus:P (match_dup 3)
12093 (clobber (reg:P CA_REGNO))])]
12095 operands[4] = rs6000_emit_eqne (<MODE>mode,
12096 operands[1], operands[2], operands[4]);
12098 if (GET_CODE (operands[5]) == SCRATCH)
12099 operands[5] = gen_reg_rtx (<MODE>mode);
12101 [(set (attr "length")
12102 (if_then_else (match_test "operands[2] == const0_rtx")
12104 (const_string "12")))])
12106 (define_insn_and_split "*plus_ne_<mode>"
12107 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12108 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12109 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12110 (match_operand:P 3 "gpc_reg_operand" "r")))
12111 (clobber (match_scratch:P 4 "=r"))
12112 (clobber (match_scratch:P 5 "=r"))
12113 (clobber (reg:P CA_REGNO))]
12117 [(parallel [(set (match_dup 5)
12118 (plus:P (match_dup 4)
12120 (set (reg:P CA_REGNO)
12121 (ne:P (match_dup 4)
12123 (parallel [(set (match_dup 0)
12124 (plus:P (match_dup 3)
12126 (clobber (reg:P CA_REGNO))])]
12128 operands[4] = rs6000_emit_eqne (<MODE>mode,
12129 operands[1], operands[2], operands[4]);
12131 if (GET_CODE (operands[5]) == SCRATCH)
12132 operands[5] = gen_reg_rtx (<MODE>mode);
12134 [(set (attr "length")
12135 (if_then_else (match_test "operands[2] == const0_rtx")
12137 (const_string "12")))])
12139 (define_insn_and_split "*minus_eq_<mode>"
12140 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12141 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12142 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12143 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12144 (clobber (match_scratch:P 4 "=r"))
12145 (clobber (match_scratch:P 5 "=r"))
12146 (clobber (reg:P CA_REGNO))]
12150 [(parallel [(set (match_dup 5)
12151 (plus:P (match_dup 4)
12153 (set (reg:P CA_REGNO)
12154 (ne:P (match_dup 4)
12156 (parallel [(set (match_dup 0)
12157 (plus:P (plus:P (match_dup 3)
12160 (clobber (reg:P CA_REGNO))])]
12162 operands[4] = rs6000_emit_eqne (<MODE>mode,
12163 operands[1], operands[2], operands[4]);
12165 if (GET_CODE (operands[5]) == SCRATCH)
12166 operands[5] = gen_reg_rtx (<MODE>mode);
12168 [(set (attr "length")
12169 (if_then_else (match_test "operands[2] == const0_rtx")
12171 (const_string "12")))])
12173 (define_insn_and_split "*minus_ne_<mode>"
12174 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12175 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12176 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12177 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12178 (clobber (match_scratch:P 4 "=r"))
12179 (clobber (match_scratch:P 5 "=r"))
12180 (clobber (reg:P CA_REGNO))]
12184 [(parallel [(set (match_dup 5)
12185 (neg:P (match_dup 4)))
12186 (set (reg:P CA_REGNO)
12187 (eq:P (match_dup 4)
12189 (parallel [(set (match_dup 0)
12190 (plus:P (plus:P (match_dup 3)
12193 (clobber (reg:P CA_REGNO))])]
12195 operands[4] = rs6000_emit_eqne (<MODE>mode,
12196 operands[1], operands[2], operands[4]);
12198 if (GET_CODE (operands[5]) == SCRATCH)
12199 operands[5] = gen_reg_rtx (<MODE>mode);
12201 [(set (attr "length")
12202 (if_then_else (match_test "operands[2] == const0_rtx")
12204 (const_string "12")))])
12206 (define_insn_and_split "*eqsi3_ext<mode>"
12207 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12208 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12209 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12210 (clobber (match_scratch:SI 3 "=r"))
12211 (clobber (match_scratch:SI 4 "=r"))]
12215 [(set (match_dup 4)
12216 (clz:SI (match_dup 3)))
12219 (lshiftrt:SI (match_dup 4)
12222 operands[3] = rs6000_emit_eqne (SImode,
12223 operands[1], operands[2], operands[3]);
12225 if (GET_CODE (operands[4]) == SCRATCH)
12226 operands[4] = gen_reg_rtx (SImode);
12228 [(set (attr "length")
12229 (if_then_else (match_test "operands[2] == const0_rtx")
12231 (const_string "12")))])
12233 (define_insn_and_split "*nesi3_ext<mode>"
12234 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12235 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12236 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12237 (clobber (match_scratch:SI 3 "=r"))
12238 (clobber (match_scratch:SI 4 "=r"))
12239 (clobber (match_scratch:EXTSI 5 "=r"))]
12243 [(set (match_dup 4)
12244 (clz:SI (match_dup 3)))
12247 (lshiftrt:SI (match_dup 4)
12250 (xor:EXTSI (match_dup 5)
12253 operands[3] = rs6000_emit_eqne (SImode,
12254 operands[1], operands[2], operands[3]);
12256 if (GET_CODE (operands[4]) == SCRATCH)
12257 operands[4] = gen_reg_rtx (SImode);
12258 if (GET_CODE (operands[5]) == SCRATCH)
12259 operands[5] = gen_reg_rtx (<MODE>mode);
12261 [(set (attr "length")
12262 (if_then_else (match_test "operands[2] == const0_rtx")
12263 (const_string "12")
12264 (const_string "16")))])
12266 ;; Define both directions of branch and return. If we need a reload
12267 ;; register, we'd rather use CR0 since it is much easier to copy a
12268 ;; register CC value to there.
12272 (if_then_else (match_operator 1 "branch_comparison_operator"
12273 [(match_operand 2 "cc_reg_operand" "y")
12275 (label_ref (match_operand 0))
12279 return output_cbranch (operands[1], "%l0", 0, insn);
12281 [(set_attr "type" "branch")])
12285 (if_then_else (match_operator 0 "branch_comparison_operator"
12286 [(match_operand 1 "cc_reg_operand" "y")
12292 return output_cbranch (operands[0], NULL, 0, insn);
12294 [(set_attr "type" "jmpreg")
12295 (set_attr "length" "4")])
12297 ;; Logic on condition register values.
12299 ; This pattern matches things like
12300 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12301 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12303 ; which are generated by the branch logic.
12304 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12306 (define_insn "cceq_ior_compare"
12307 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12308 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12309 [(match_operator:SI 2
12310 "branch_positive_comparison_operator"
12312 "cc_reg_operand" "y,y")
12314 (match_operator:SI 4
12315 "branch_positive_comparison_operator"
12317 "cc_reg_operand" "0,y")
12321 "cr%q1 %E0,%j2,%j4"
12322 [(set_attr "type" "cr_logical")
12323 (set_attr "cr_logical_3op" "no,yes")])
12325 ; Why is the constant -1 here, but 1 in the previous pattern?
12326 ; Because ~1 has all but the low bit set.
12327 (define_insn "cceq_ior_compare_complement"
12328 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12329 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12330 [(not:SI (match_operator:SI 2
12331 "branch_positive_comparison_operator"
12333 "cc_reg_operand" "y,y")
12335 (match_operator:SI 4
12336 "branch_positive_comparison_operator"
12338 "cc_reg_operand" "0,y")
12342 "cr%q1 %E0,%j2,%j4"
12343 [(set_attr "type" "cr_logical")
12344 (set_attr "cr_logical_3op" "no,yes")])
12346 (define_insn "*cceq_rev_compare"
12347 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12348 (compare:CCEQ (match_operator:SI 1
12349 "branch_positive_comparison_operator"
12351 "cc_reg_operand" "0,y")
12356 [(set_attr "type" "cr_logical")
12357 (set_attr "cr_logical_3op" "no,yes")])
12359 ;; If we are comparing the result of two comparisons, this can be done
12360 ;; using creqv or crxor.
12362 (define_insn_and_split ""
12363 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12364 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12365 [(match_operand 2 "cc_reg_operand" "y")
12367 (match_operator 3 "branch_comparison_operator"
12368 [(match_operand 4 "cc_reg_operand" "y")
12373 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12376 int positive_1, positive_2;
12378 positive_1 = branch_positive_comparison_operator (operands[1],
12379 GET_MODE (operands[1]));
12380 positive_2 = branch_positive_comparison_operator (operands[3],
12381 GET_MODE (operands[3]));
12384 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12385 GET_CODE (operands[1])),
12387 operands[2], const0_rtx);
12388 else if (GET_MODE (operands[1]) != SImode)
12389 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12390 operands[2], const0_rtx);
12393 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12394 GET_CODE (operands[3])),
12396 operands[4], const0_rtx);
12397 else if (GET_MODE (operands[3]) != SImode)
12398 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12399 operands[4], const0_rtx);
12401 if (positive_1 == positive_2)
12403 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12404 operands[5] = constm1_rtx;
12408 operands[5] = const1_rtx;
12412 ;; Unconditional branch and return.
12414 (define_insn "jump"
12416 (label_ref (match_operand 0)))]
12419 [(set_attr "type" "branch")])
12421 (define_insn "<return_str>return"
12425 [(set_attr "type" "jmpreg")])
12427 (define_expand "indirect_jump"
12428 [(set (pc) (match_operand 0 "register_operand"))]
12431 if (!rs6000_speculate_indirect_jumps) {
12432 rtx ccreg = gen_reg_rtx (CCmode);
12433 if (Pmode == DImode)
12434 emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12436 emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12441 (define_insn "*indirect_jump<mode>"
12443 (match_operand:P 0 "register_operand" "c,*l"))]
12444 "rs6000_speculate_indirect_jumps"
12446 [(set_attr "type" "jmpreg")])
12448 (define_insn "indirect_jump<mode>_nospec"
12449 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12450 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12451 "!rs6000_speculate_indirect_jumps"
12452 "crset %E1\;beq%T0- %1\;b $"
12453 [(set_attr "type" "jmpreg")
12454 (set_attr "length" "12")])
12456 ;; Table jump for switch statements:
12457 (define_expand "tablejump"
12458 [(use (match_operand 0))
12459 (use (label_ref (match_operand 1)))]
12462 if (rs6000_speculate_indirect_jumps)
12465 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12467 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12471 rtx ccreg = gen_reg_rtx (CCmode);
12474 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12476 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12477 emit_jump_insn (jump);
12482 (define_expand "tablejumpsi"
12483 [(set (match_dup 3)
12484 (plus:SI (match_operand:SI 0)
12486 (parallel [(set (pc)
12488 (use (label_ref (match_operand 1)))])]
12489 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12491 operands[0] = force_reg (SImode, operands[0]);
12492 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12493 operands[3] = gen_reg_rtx (SImode);
12496 (define_expand "tablejumpsi_nospec"
12497 [(set (match_dup 4)
12498 (plus:SI (match_operand:SI 0)
12500 (parallel [(set (pc)
12502 (use (label_ref (match_operand 1)))
12503 (clobber (match_operand 2))])]
12504 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12506 operands[0] = force_reg (SImode, operands[0]);
12507 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12508 operands[4] = gen_reg_rtx (SImode);
12511 (define_expand "tablejumpdi"
12512 [(set (match_dup 4)
12513 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12515 (plus:DI (match_dup 4)
12517 (parallel [(set (pc)
12519 (use (label_ref (match_operand 1)))])]
12520 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12522 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12523 operands[3] = gen_reg_rtx (DImode);
12524 operands[4] = gen_reg_rtx (DImode);
12527 (define_expand "tablejumpdi_nospec"
12528 [(set (match_dup 5)
12529 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12531 (plus:DI (match_dup 5)
12533 (parallel [(set (pc)
12535 (use (label_ref (match_operand 1)))
12536 (clobber (match_operand 2))])]
12537 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12539 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12540 operands[4] = gen_reg_rtx (DImode);
12541 operands[5] = gen_reg_rtx (DImode);
12544 (define_insn "*tablejump<mode>_internal1"
12546 (match_operand:P 0 "register_operand" "c,*l"))
12547 (use (label_ref (match_operand 1)))]
12548 "rs6000_speculate_indirect_jumps"
12550 [(set_attr "type" "jmpreg")])
12552 (define_insn "*tablejump<mode>_internal1_nospec"
12554 (match_operand:P 0 "register_operand" "c,*l"))
12555 (use (label_ref (match_operand 1)))
12556 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12557 "!rs6000_speculate_indirect_jumps"
12558 "crset %E2\;beq%T0- %2\;b $"
12559 [(set_attr "type" "jmpreg")
12560 (set_attr "length" "12")])
12563 [(unspec [(const_int 0)] UNSPEC_NOP)]
12567 (define_insn "group_ending_nop"
12568 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12571 if (rs6000_tune == PROCESSOR_POWER6)
12572 return "ori 1,1,0";
12573 return "ori 2,2,0";
12576 (define_insn "rs6000_speculation_barrier"
12577 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12581 ;; Define the subtract-one-and-jump insns, starting with the template
12582 ;; so loop.c knows what to generate.
12584 (define_expand "doloop_end"
12585 [(use (match_operand 0)) ; loop pseudo
12586 (use (match_operand 1))] ; label
12591 if (GET_MODE (operands[0]) != DImode)
12593 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12597 if (GET_MODE (operands[0]) != SImode)
12599 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12604 (define_expand "ctr<mode>"
12605 [(parallel [(set (pc)
12606 (if_then_else (ne (match_operand:P 0 "register_operand")
12608 (label_ref (match_operand 1))
12611 (plus:P (match_dup 0)
12613 (clobber (match_scratch:CC 2))
12614 (clobber (match_scratch:P 3))])]
12618 ;; We need to be able to do this for any operand, including MEM, or we
12619 ;; will cause reload to blow up since we don't allow output reloads on
12621 ;; For the length attribute to be calculated correctly, the
12622 ;; label MUST be operand 0.
12623 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12624 ;; the ctr<mode> insns.
12626 (define_code_iterator eqne [eq ne])
12627 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12628 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12630 (define_insn "<bd>_<mode>"
12632 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12634 (label_ref (match_operand 0))
12636 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12637 (plus:P (match_dup 1)
12639 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12640 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12643 if (which_alternative != 0)
12645 else if (get_attr_length (insn) == 4)
12648 return "<bd_neg> $+8\;b %l0";
12650 [(set_attr "type" "branch")
12651 (set_attr "length" "*,16,20,20")])
12653 ;; Now the splitter if we could not allocate the CTR register
12656 (if_then_else (match_operator 2 "comparison_operator"
12657 [(match_operand:P 1 "gpc_reg_operand")
12660 (match_operand 6)))
12661 (set (match_operand:P 0 "nonimmediate_operand")
12662 (plus:P (match_dup 1)
12664 (clobber (match_scratch:CC 3))
12665 (clobber (match_scratch:P 4))]
12668 (if_then_else (match_dup 7)
12672 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12674 emit_insn (gen_rtx_SET (operands[3],
12675 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12676 if (gpc_reg_operand (operands[0], <MODE>mode))
12677 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12680 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12681 emit_move_insn (operands[0], operands[4]);
12683 /* No DONE so branch comes from the pattern. */
12686 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12687 ;; Note that in the case of long branches we have to decompose this into
12688 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12689 ;; and the CR bit, which means there is no way to conveniently invert the
12690 ;; comparison as is done with plain bdnz/bdz.
12692 (define_insn "<bd>tf_<mode>"
12696 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12698 (match_operator 3 "branch_comparison_operator"
12699 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12701 (label_ref (match_operand 0))
12703 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12704 (plus:P (match_dup 1)
12706 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12707 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12708 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12711 if (which_alternative != 0)
12713 else if (get_attr_length (insn) == 4)
12715 if (branch_positive_comparison_operator (operands[3],
12716 GET_MODE (operands[3])))
12717 return "<bd>t %j3,%l0";
12719 return "<bd>f %j3,%l0";
12723 static char seq[96];
12724 char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12725 sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12729 [(set_attr "type" "branch")
12730 (set_attr "length" "*,16,20,20")])
12732 ;; Now the splitter if we could not allocate the CTR register
12737 (match_operator 1 "comparison_operator"
12738 [(match_operand:P 0 "gpc_reg_operand")
12740 (match_operator 3 "branch_comparison_operator"
12741 [(match_operand 2 "cc_reg_operand")
12744 (match_operand 5)))
12745 (set (match_operand:P 6 "int_reg_operand")
12746 (plus:P (match_dup 0)
12748 (clobber (match_scratch:P 7))
12749 (clobber (match_scratch:CC 8))
12750 (clobber (match_scratch:CCEQ 9))]
12754 rtx ctr = operands[0];
12755 rtx ctrcmp = operands[1];
12756 rtx ccin = operands[2];
12757 rtx cccmp = operands[3];
12758 rtx dst1 = operands[4];
12759 rtx dst2 = operands[5];
12760 rtx ctrout = operands[6];
12761 rtx ctrtmp = operands[7];
12762 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12763 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12765 cmpcode = reverse_condition (cmpcode);
12766 /* Generate crand/crandc here. */
12767 emit_insn (gen_rtx_SET (operands[8],
12768 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12769 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12771 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12773 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12774 operands[8], cccmp, ccin));
12776 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12777 operands[8], cccmp, ccin));
12778 if (gpc_reg_operand (operands[0], <MODE>mode))
12779 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12782 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12783 emit_move_insn (ctrout, ctrtmp);
12785 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12786 emit_jump_insn (gen_rtx_SET (pc_rtx,
12787 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12793 (define_insn "trap"
12794 [(trap_if (const_int 1) (const_int 0))]
12797 [(set_attr "type" "trap")])
12799 (define_expand "ctrap<mode>4"
12800 [(trap_if (match_operator 0 "ordered_comparison_operator"
12801 [(match_operand:GPR 1 "register_operand")
12802 (match_operand:GPR 2 "reg_or_short_operand")])
12803 (match_operand 3 "zero_constant" ""))]
12808 [(trap_if (match_operator 0 "ordered_comparison_operator"
12809 [(match_operand:GPR 1 "register_operand" "r")
12810 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12813 "t<wd>%V0%I2 %1,%2"
12814 [(set_attr "type" "trap")])
12816 ;; Insns related to generating the function prologue and epilogue.
12818 (define_expand "prologue"
12819 [(use (const_int 0))]
12822 rs6000_emit_prologue ();
12823 if (!TARGET_SCHED_PROLOG)
12824 emit_insn (gen_blockage ());
12828 (define_insn "*movesi_from_cr_one"
12829 [(match_parallel 0 "mfcr_operation"
12830 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12831 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12832 (match_operand 3 "immediate_operand" "n")]
12833 UNSPEC_MOVESI_FROM_CR))])]
12838 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12840 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12841 operands[4] = GEN_INT (mask);
12842 output_asm_insn ("mfcr %1,%4", operands);
12846 [(set_attr "type" "mfcrf")])
12848 ;; Don't include the volatile CRs since their values are not used wrt CR save
12849 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12850 ;; prologue past an insn (early exit test) that defines a register used in the
12852 (define_insn "prologue_movesi_from_cr"
12853 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12854 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12855 (reg:CC CR4_REGNO)]
12856 UNSPEC_MOVESI_FROM_CR))]
12859 [(set_attr "type" "mfcr")])
12861 (define_insn "*crsave"
12862 [(match_parallel 0 "crsave_operation"
12863 [(set (match_operand:SI 1 "memory_operand" "=m")
12864 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12867 [(set_attr "type" "store")])
12869 (define_insn "*stmw"
12870 [(match_parallel 0 "stmw_operation"
12871 [(set (match_operand:SI 1 "memory_operand" "=m")
12872 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12875 [(set_attr "type" "store")
12876 (set_attr "update" "yes")
12877 (set_attr "indexed" "yes")])
12879 ; The following comment applies to:
12883 ; return_and_restore_gpregs*
12884 ; return_and_restore_fpregs*
12885 ; return_and_restore_fpregs_aix*
12887 ; The out-of-line save / restore functions expects one input argument.
12888 ; Since those are not standard call_insn's, we must avoid using
12889 ; MATCH_OPERAND for that argument. That way the register rename
12890 ; optimization will not try to rename this register.
12891 ; Each pattern is repeated for each possible register number used in
12892 ; various ABIs (r11, r1, and for some functions r12)
12894 (define_insn "*save_gpregs_<mode>_r11"
12895 [(match_parallel 0 "any_parallel_operand"
12896 [(clobber (reg:P LR_REGNO))
12897 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12899 (set (match_operand:P 2 "memory_operand" "=m")
12900 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12903 [(set_attr "type" "branch")
12904 (set_attr "length" "4")])
12906 (define_insn "*save_gpregs_<mode>_r12"
12907 [(match_parallel 0 "any_parallel_operand"
12908 [(clobber (reg:P LR_REGNO))
12909 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12911 (set (match_operand:P 2 "memory_operand" "=m")
12912 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12915 [(set_attr "type" "branch")
12916 (set_attr "length" "4")])
12918 (define_insn "*save_gpregs_<mode>_r1"
12919 [(match_parallel 0 "any_parallel_operand"
12920 [(clobber (reg:P LR_REGNO))
12921 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12923 (set (match_operand:P 2 "memory_operand" "=m")
12924 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12927 [(set_attr "type" "branch")
12928 (set_attr "length" "4")])
12930 (define_insn "*save_fpregs_<mode>_r11"
12931 [(match_parallel 0 "any_parallel_operand"
12932 [(clobber (reg:P LR_REGNO))
12933 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12935 (set (match_operand:DF 2 "memory_operand" "=m")
12936 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12939 [(set_attr "type" "branch")
12940 (set_attr "length" "4")])
12942 (define_insn "*save_fpregs_<mode>_r12"
12943 [(match_parallel 0 "any_parallel_operand"
12944 [(clobber (reg:P LR_REGNO))
12945 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12947 (set (match_operand:DF 2 "memory_operand" "=m")
12948 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12951 [(set_attr "type" "branch")
12952 (set_attr "length" "4")])
12954 (define_insn "*save_fpregs_<mode>_r1"
12955 [(match_parallel 0 "any_parallel_operand"
12956 [(clobber (reg:P LR_REGNO))
12957 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12959 (set (match_operand:DF 2 "memory_operand" "=m")
12960 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12963 [(set_attr "type" "branch")
12964 (set_attr "length" "4")])
12966 ; This is to explain that changes to the stack pointer should
12967 ; not be moved over loads from or stores to stack memory.
12968 (define_insn "stack_tie"
12969 [(match_parallel 0 "tie_operand"
12970 [(set (mem:BLK (reg 1)) (const_int 0))])]
12973 [(set_attr "length" "0")])
12975 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12976 ; stay behind all restores from the stack, it cannot be reordered to before
12977 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
12978 (define_insn "stack_restore_tie"
12979 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12980 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12981 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12982 (set (mem:BLK (scratch)) (const_int 0))]
12987 [(set_attr "type" "*,add")])
12989 (define_expand "epilogue"
12990 [(use (const_int 0))]
12993 if (!TARGET_SCHED_PROLOG)
12994 emit_insn (gen_blockage ());
12995 rs6000_emit_epilogue (FALSE);
12999 ; On some processors, doing the mtcrf one CC register at a time is
13000 ; faster (like on the 604e). On others, doing them all at once is
13001 ; faster; for instance, on the 601 and 750.
13003 (define_expand "movsi_to_cr_one"
13004 [(set (match_operand:CC 0 "cc_reg_operand")
13005 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13006 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13008 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13010 (define_insn "*movsi_to_cr"
13011 [(match_parallel 0 "mtcrf_operation"
13012 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13013 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13014 (match_operand 3 "immediate_operand" "n")]
13015 UNSPEC_MOVESI_TO_CR))])]
13020 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13021 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13022 operands[4] = GEN_INT (mask);
13023 return "mtcrf %4,%2";
13025 [(set_attr "type" "mtcr")])
13027 (define_insn "*mtcrfsi"
13028 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13029 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13030 (match_operand 2 "immediate_operand" "n")]
13031 UNSPEC_MOVESI_TO_CR))]
13032 "GET_CODE (operands[0]) == REG
13033 && CR_REGNO_P (REGNO (operands[0]))
13034 && GET_CODE (operands[2]) == CONST_INT
13035 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13037 [(set_attr "type" "mtcr")])
13039 ; The load-multiple instructions have similar properties.
13040 ; Note that "load_multiple" is a name known to the machine-independent
13041 ; code that actually corresponds to the PowerPC load-string.
13043 (define_insn "*lmw"
13044 [(match_parallel 0 "lmw_operation"
13045 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13046 (match_operand:SI 2 "memory_operand" "m"))])]
13049 [(set_attr "type" "load")
13050 (set_attr "update" "yes")
13051 (set_attr "indexed" "yes")
13052 (set_attr "cell_micro" "always")])
13054 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13055 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13057 ; The following comment applies to:
13061 ; return_and_restore_gpregs*
13062 ; return_and_restore_fpregs*
13063 ; return_and_restore_fpregs_aix*
13065 ; The out-of-line save / restore functions expects one input argument.
13066 ; Since those are not standard call_insn's, we must avoid using
13067 ; MATCH_OPERAND for that argument. That way the register rename
13068 ; optimization will not try to rename this register.
13069 ; Each pattern is repeated for each possible register number used in
13070 ; various ABIs (r11, r1, and for some functions r12)
13072 (define_insn "*restore_gpregs_<mode>_r11"
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:P 2 "gpc_reg_operand" "=r")
13078 (match_operand:P 3 "memory_operand" "m"))])]
13081 [(set_attr "type" "branch")
13082 (set_attr "length" "4")])
13084 (define_insn "*restore_gpregs_<mode>_r12"
13085 [(match_parallel 0 "any_parallel_operand"
13086 [(clobber (reg:P LR_REGNO))
13087 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13089 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13090 (match_operand:P 3 "memory_operand" "m"))])]
13093 [(set_attr "type" "branch")
13094 (set_attr "length" "4")])
13096 (define_insn "*restore_gpregs_<mode>_r1"
13097 [(match_parallel 0 "any_parallel_operand"
13098 [(clobber (reg:P LR_REGNO))
13099 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13101 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13102 (match_operand:P 3 "memory_operand" "m"))])]
13105 [(set_attr "type" "branch")
13106 (set_attr "length" "4")])
13108 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13109 [(match_parallel 0 "any_parallel_operand"
13111 (clobber (reg:P LR_REGNO))
13112 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13114 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13115 (match_operand:P 3 "memory_operand" "m"))])]
13118 [(set_attr "type" "branch")
13119 (set_attr "length" "4")])
13121 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13122 [(match_parallel 0 "any_parallel_operand"
13124 (clobber (reg:P LR_REGNO))
13125 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13127 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13128 (match_operand:P 3 "memory_operand" "m"))])]
13131 [(set_attr "type" "branch")
13132 (set_attr "length" "4")])
13134 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13135 [(match_parallel 0 "any_parallel_operand"
13137 (clobber (reg:P LR_REGNO))
13138 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13140 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13141 (match_operand:P 3 "memory_operand" "m"))])]
13144 [(set_attr "type" "branch")
13145 (set_attr "length" "4")])
13147 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13148 [(match_parallel 0 "any_parallel_operand"
13150 (clobber (reg:P LR_REGNO))
13151 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13153 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13154 (match_operand:DF 3 "memory_operand" "m"))])]
13157 [(set_attr "type" "branch")
13158 (set_attr "length" "4")])
13160 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13161 [(match_parallel 0 "any_parallel_operand"
13163 (clobber (reg:P LR_REGNO))
13164 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13166 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13167 (match_operand:DF 3 "memory_operand" "m"))])]
13170 [(set_attr "type" "branch")
13171 (set_attr "length" "4")])
13173 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13174 [(match_parallel 0 "any_parallel_operand"
13176 (clobber (reg:P LR_REGNO))
13177 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13179 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13180 (match_operand:DF 3 "memory_operand" "m"))])]
13183 [(set_attr "type" "branch")
13184 (set_attr "length" "4")])
13186 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13187 [(match_parallel 0 "any_parallel_operand"
13189 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13191 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13192 (match_operand:DF 3 "memory_operand" "m"))])]
13195 [(set_attr "type" "branch")
13196 (set_attr "length" "4")])
13198 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13199 [(match_parallel 0 "any_parallel_operand"
13201 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13203 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13204 (match_operand:DF 3 "memory_operand" "m"))])]
13207 [(set_attr "type" "branch")
13208 (set_attr "length" "4")])
13210 ; This is used in compiling the unwind routines.
13211 (define_expand "eh_return"
13212 [(use (match_operand 0 "general_operand"))]
13216 emit_insn (gen_eh_set_lr_si (operands[0]));
13218 emit_insn (gen_eh_set_lr_di (operands[0]));
13222 ; We can't expand this before we know where the link register is stored.
13223 (define_insn "eh_set_lr_<mode>"
13224 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13226 (clobber (match_scratch:P 1 "=&b"))]
13231 [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13232 (clobber (match_scratch 1))]
13236 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13240 (define_insn "prefetch"
13241 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13242 (match_operand:SI 1 "const_int_operand" "n")
13243 (match_operand:SI 2 "const_int_operand" "n"))]
13246 /* dcbtstt, dcbtt and TM=0b10000 support starts with ISA 2.06. */
13247 int inst_select = INTVAL (operands[2]) || !TARGET_POPCNTD;
13249 if (REG_P (operands[0]))
13251 if (INTVAL (operands[1]) == 0)
13252 return inst_select ? "dcbt 0,%0" : "dcbtt 0,%0";
13254 return inst_select ? "dcbtst 0,%0" : "dcbtstt 0,%0";
13258 if (INTVAL (operands[1]) == 0)
13259 return inst_select ? "dcbt %a0" : "dcbtt %a0";
13261 return inst_select ? "dcbtst %a0" : "dcbtstt %a0";
13264 [(set_attr "type" "load")])
13266 ;; Handle -fsplit-stack.
13268 (define_expand "split_stack_prologue"
13272 rs6000_expand_split_stack_prologue ();
13276 (define_expand "load_split_stack_limit"
13277 [(set (match_operand 0)
13278 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13281 emit_insn (gen_rtx_SET (operands[0],
13282 gen_rtx_UNSPEC (Pmode,
13283 gen_rtvec (1, const0_rtx),
13284 UNSPEC_STACK_CHECK)));
13288 (define_insn "load_split_stack_limit_di"
13289 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13290 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13292 "ld %0,-0x7040(13)"
13293 [(set_attr "type" "load")
13294 (set_attr "update" "no")
13295 (set_attr "indexed" "no")])
13297 (define_insn "load_split_stack_limit_si"
13298 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13299 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13301 "lwz %0,-0x7020(2)"
13302 [(set_attr "type" "load")
13303 (set_attr "update" "no")
13304 (set_attr "indexed" "no")])
13306 ;; A return instruction which the middle-end doesn't see.
13307 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13308 ;; after the call to __morestack.
13309 (define_insn "split_stack_return"
13310 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13313 [(set_attr "type" "jmpreg")])
13315 ;; If there are operand 0 bytes available on the stack, jump to
13317 (define_expand "split_stack_space_check"
13318 [(set (match_dup 2)
13319 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13321 (minus (reg STACK_POINTER_REGNUM)
13322 (match_operand 0)))
13323 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13324 (set (pc) (if_then_else
13325 (geu (match_dup 4) (const_int 0))
13326 (label_ref (match_operand 1))
13330 rs6000_split_stack_space_check (operands[0], operands[1]);
13334 (define_insn "bpermd_<mode>"
13335 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13336 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13337 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13340 [(set_attr "type" "popcnt")])
13343 ;; Builtin fma support. Handle
13344 ;; Note that the conditions for expansion are in the FMA_F iterator.
13346 (define_expand "fma<mode>4"
13347 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13349 (match_operand:FMA_F 1 "gpc_reg_operand")
13350 (match_operand:FMA_F 2 "gpc_reg_operand")
13351 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13355 (define_insn "*fma<mode>4_fpr"
13356 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13358 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13359 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13360 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13361 "TARGET_HARD_FLOAT"
13363 fmadd<Ftrad> %0,%1,%2,%3
13364 xsmadda<Fvsx> %x0,%x1,%x2
13365 xsmaddm<Fvsx> %x0,%x1,%x3"
13366 [(set_attr "type" "fp")])
13368 ; Altivec only has fma and nfms.
13369 (define_expand "fms<mode>4"
13370 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13372 (match_operand:FMA_F 1 "gpc_reg_operand")
13373 (match_operand:FMA_F 2 "gpc_reg_operand")
13374 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13375 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13378 (define_insn "*fms<mode>4_fpr"
13379 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13381 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13382 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13383 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13384 "TARGET_HARD_FLOAT"
13386 fmsub<Ftrad> %0,%1,%2,%3
13387 xsmsuba<Fvsx> %x0,%x1,%x2
13388 xsmsubm<Fvsx> %x0,%x1,%x3"
13389 [(set_attr "type" "fp")])
13391 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13392 (define_expand "fnma<mode>4"
13393 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13396 (match_operand:FMA_F 1 "gpc_reg_operand")
13397 (match_operand:FMA_F 2 "gpc_reg_operand")
13398 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13399 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13402 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13403 (define_expand "fnms<mode>4"
13404 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13407 (match_operand:FMA_F 1 "gpc_reg_operand")
13408 (match_operand:FMA_F 2 "gpc_reg_operand")
13409 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13410 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13413 ; Not an official optab name, but used from builtins.
13414 (define_expand "nfma<mode>4"
13415 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13418 (match_operand:FMA_F 1 "gpc_reg_operand")
13419 (match_operand:FMA_F 2 "gpc_reg_operand")
13420 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13421 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13424 (define_insn "*nfma<mode>4_fpr"
13425 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13428 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13429 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13430 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13431 "TARGET_HARD_FLOAT"
13433 fnmadd<Ftrad> %0,%1,%2,%3
13434 xsnmadda<Fvsx> %x0,%x1,%x2
13435 xsnmaddm<Fvsx> %x0,%x1,%x3"
13436 [(set_attr "type" "fp")])
13438 ; Not an official optab name, but used from builtins.
13439 (define_expand "nfms<mode>4"
13440 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13443 (match_operand:FMA_F 1 "gpc_reg_operand")
13444 (match_operand:FMA_F 2 "gpc_reg_operand")
13445 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13449 (define_insn "*nfmssf4_fpr"
13450 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13453 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13454 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13456 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13457 "TARGET_HARD_FLOAT"
13459 fnmsub<Ftrad> %0,%1,%2,%3
13460 xsnmsuba<Fvsx> %x0,%x1,%x2
13461 xsnmsubm<Fvsx> %x0,%x1,%x3"
13462 [(set_attr "type" "fp")])
13465 (define_expand "rs6000_get_timebase"
13466 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13469 if (TARGET_POWERPC64)
13470 emit_insn (gen_rs6000_mftb_di (operands[0]));
13472 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13476 (define_insn "rs6000_get_timebase_ppc32"
13477 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13478 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13479 (clobber (match_scratch:SI 1 "=r"))
13480 (clobber (match_scratch:CC 2 "=y"))]
13481 "!TARGET_POWERPC64"
13483 if (WORDS_BIG_ENDIAN)
13486 return "mfspr %0,269\;"
13494 return "mftbu %0\;"
13503 return "mfspr %L0,269\;"
13511 return "mftbu %L0\;"
13518 [(set_attr "length" "20")])
13520 (define_insn "rs6000_mftb_<mode>"
13521 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13522 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13526 return "mfspr %0,268";
13532 (define_insn "rs6000_mffs"
13533 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13534 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13535 "TARGET_HARD_FLOAT"
13538 (define_insn "rs6000_mtfsf"
13539 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13540 (match_operand:DF 1 "gpc_reg_operand" "d")]
13542 "TARGET_HARD_FLOAT"
13546 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13547 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13548 ;; register that is being loaded. The fused ops must be physically adjacent.
13550 ;; There are two parts to addis fusion. The support for fused TOCs occur
13551 ;; before register allocation, and is meant to reduce the lifetime for the
13552 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13553 ;; to use the register that is being load. The peephole2 then gathers any
13554 ;; other fused possibilities that it can find after register allocation. If
13555 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13557 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13558 ;; before register allocation, so that we can avoid allocating a temporary base
13559 ;; register that won't be used, and that we try to load into base registers,
13560 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13561 ;; (addis followed by load) even on power8.
13564 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand")
13565 (match_operand:INT1 1 "toc_fusion_mem_raw"))]
13566 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13567 [(parallel [(set (match_dup 0) (match_dup 2))
13568 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13569 (use (match_dup 3))
13570 (clobber (scratch:DI))])]
13572 operands[2] = fusion_wrap_memory_address (operands[1]);
13573 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13576 (define_insn "*toc_fusionload_<mode>"
13577 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13578 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13579 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13580 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13581 (clobber (match_scratch:DI 3 "=X,&b"))]
13582 "TARGET_TOC_FUSION_INT"
13584 if (base_reg_operand (operands[0], <MODE>mode))
13585 return emit_fusion_gpr_load (operands[0], operands[1]);
13587 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13589 [(set_attr "type" "load")
13590 (set_attr "length" "8")])
13592 (define_insn "*toc_fusionload_di"
13593 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13594 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13595 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13596 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13597 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13598 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13599 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13601 if (base_reg_operand (operands[0], DImode))
13602 return emit_fusion_gpr_load (operands[0], operands[1]);
13604 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13606 [(set_attr "type" "load")
13607 (set_attr "length" "8")])
13610 ;; Find cases where the addis that feeds into a load instruction is either used
13611 ;; once or is the same as the target register, and replace it with the fusion
13615 [(set (match_operand:P 0 "base_reg_operand")
13616 (match_operand:P 1 "fusion_gpr_addis"))
13617 (set (match_operand:INT1 2 "base_reg_operand")
13618 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13620 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13624 expand_fusion_gpr_load (operands);
13628 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13631 (define_insn "fusion_gpr_load_<mode>"
13632 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13633 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13634 UNSPEC_FUSION_GPR))]
13637 return emit_fusion_gpr_load (operands[0], operands[1]);
13639 [(set_attr "type" "load")
13640 (set_attr "length" "8")])
13643 ;; ISA 3.0 (power9) fusion support
13644 ;; Merge addis with floating load/store to FPRs (or GPRs).
13646 [(set (match_operand:P 0 "base_reg_operand")
13647 (match_operand:P 1 "fusion_gpr_addis"))
13648 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand")
13649 (match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
13650 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13651 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13654 expand_fusion_p9_load (operands);
13659 [(set (match_operand:P 0 "base_reg_operand")
13660 (match_operand:P 1 "fusion_gpr_addis"))
13661 (set (match_operand:SFDF 2 "offsettable_mem_operand")
13662 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand"))]
13663 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13664 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13665 && !rtx_equal_p (operands[0], operands[3])"
13668 expand_fusion_p9_store (operands);
13673 [(set (match_operand:SDI 0 "int_reg_operand")
13674 (match_operand:SDI 1 "upper16_cint_operand"))
13676 (ior:SDI (match_dup 0)
13677 (match_operand:SDI 2 "u_short_cint_operand")))]
13679 [(set (match_dup 0)
13680 (unspec:SDI [(match_dup 1)
13681 (match_dup 2)] UNSPEC_FUSION_P9))])
13684 [(set (match_operand:SDI 0 "int_reg_operand")
13685 (match_operand:SDI 1 "upper16_cint_operand"))
13686 (set (match_operand:SDI 2 "int_reg_operand")
13687 (ior:SDI (match_dup 0)
13688 (match_operand:SDI 3 "u_short_cint_operand")))]
13690 && !rtx_equal_p (operands[0], operands[2])
13691 && peep2_reg_dead_p (2, operands[0])"
13692 [(set (match_dup 2)
13693 (unspec:SDI [(match_dup 1)
13694 (match_dup 3)] UNSPEC_FUSION_P9))])
13696 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13697 ;; reload). Because we want to eventually have secondary_reload generate
13698 ;; these, they have to have a single alternative that gives the register
13699 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13700 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13701 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13703 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13705 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13708 /* This insn is a secondary reload insn, which cannot have alternatives.
13709 If we are not loading up register 0, use the power8 fusion instead. */
13710 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13711 return emit_fusion_gpr_load (operands[0], operands[1]);
13713 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13715 [(set_attr "type" "load")
13716 (set_attr "length" "8")])
13718 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13719 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13721 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13723 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13726 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13728 [(set_attr "type" "store")
13729 (set_attr "length" "8")])
13731 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13732 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13734 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13736 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13739 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13741 [(set_attr "type" "fpload")
13742 (set_attr "length" "8")])
13744 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13745 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13747 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13749 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13752 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13754 [(set_attr "type" "fpstore")
13755 (set_attr "length" "8")])
13757 (define_insn "*fusion_p9_<mode>_constant"
13758 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13759 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13760 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13761 UNSPEC_FUSION_P9))]
13764 emit_fusion_addis (operands[0], operands[1]);
13765 return "ori %0,%0,%2";
13767 [(set_attr "type" "two")
13768 (set_attr "length" "8")])
13771 ;; Optimize cases where we want to do a D-form load (register+offset) on
13772 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13777 ;; and we change this to:
13782 [(match_scratch:P 0 "b")
13783 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13784 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13785 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13787 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13788 [(set (match_dup 0)
13793 rtx tmp_reg = operands[0];
13794 rtx mem = operands[2];
13795 rtx addr = XEXP (mem, 0);
13796 rtx add_op0, add_op1, new_addr;
13798 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13799 add_op0 = XEXP (addr, 0);
13800 add_op1 = XEXP (addr, 1);
13801 gcc_assert (REG_P (add_op0));
13802 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13804 operands[4] = add_op1;
13805 operands[5] = change_address (mem, <MODE>mode, new_addr);
13808 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13809 ;; Altivec register, and the register allocator has generated:
13813 ;; and we change this to:
13818 [(match_scratch:P 0 "b")
13819 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13820 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13821 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13823 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13824 [(set (match_dup 0)
13829 rtx tmp_reg = operands[0];
13830 rtx mem = operands[3];
13831 rtx addr = XEXP (mem, 0);
13832 rtx add_op0, add_op1, new_addr;
13834 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13835 add_op0 = XEXP (addr, 0);
13836 add_op1 = XEXP (addr, 1);
13837 gcc_assert (REG_P (add_op0));
13838 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13840 operands[4] = add_op1;
13841 operands[5] = change_address (mem, <MODE>mode, new_addr);
13845 ;; Miscellaneous ISA 2.06 (power7) instructions
13846 (define_insn "addg6s"
13847 [(set (match_operand:SI 0 "register_operand" "=r")
13848 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13849 (match_operand:SI 2 "register_operand" "r")]
13853 [(set_attr "type" "integer")
13854 (set_attr "length" "4")])
13856 (define_insn "cdtbcd"
13857 [(set (match_operand:SI 0 "register_operand" "=r")
13858 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13862 [(set_attr "type" "integer")
13863 (set_attr "length" "4")])
13865 (define_insn "cbcdtd"
13866 [(set (match_operand:SI 0 "register_operand" "=r")
13867 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13871 [(set_attr "type" "integer")
13872 (set_attr "length" "4")])
13874 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13877 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13878 (UNSPEC_DIVEU "eu")])
13880 (define_insn "div<div_extend>_<mode>"
13881 [(set (match_operand:GPR 0 "register_operand" "=r")
13882 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13883 (match_operand:GPR 2 "register_operand" "r")]
13884 UNSPEC_DIV_EXTEND))]
13886 "div<wd><div_extend> %0,%1,%2"
13887 [(set_attr "type" "div")
13888 (set_attr "size" "<bits>")])
13891 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13893 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13894 (define_mode_attr FP128_64 [(TF "DF")
13899 (define_expand "unpack<mode>"
13900 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13902 [(match_operand:FMOVE128 1 "register_operand")
13903 (match_operand:QI 2 "const_0_to_1_operand")]
13904 UNSPEC_UNPACK_128BIT))]
13905 "FLOAT128_2REG_P (<MODE>mode)"
13908 (define_insn_and_split "unpack<mode>_dm"
13909 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13911 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13912 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13913 UNSPEC_UNPACK_128BIT))]
13914 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13916 "&& reload_completed"
13917 [(set (match_dup 0) (match_dup 3))]
13919 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13921 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13923 emit_note (NOTE_INSN_DELETED);
13927 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13929 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13930 (set_attr "length" "4")])
13932 (define_insn_and_split "unpack<mode>_nodm"
13933 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13935 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13936 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13937 UNSPEC_UNPACK_128BIT))]
13938 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13940 "&& reload_completed"
13941 [(set (match_dup 0) (match_dup 3))]
13943 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13945 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13947 emit_note (NOTE_INSN_DELETED);
13951 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13953 [(set_attr "type" "fp,fpstore")
13954 (set_attr "length" "4")])
13956 (define_insn_and_split "pack<mode>"
13957 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13959 [(match_operand:<FP128_64> 1 "register_operand" "d")
13960 (match_operand:<FP128_64> 2 "register_operand" "d")]
13961 UNSPEC_PACK_128BIT))]
13962 "FLOAT128_2REG_P (<MODE>mode)"
13964 "&& reload_completed"
13965 [(set (match_dup 3) (match_dup 1))
13966 (set (match_dup 4) (match_dup 2))]
13968 unsigned dest_hi = REGNO (operands[0]);
13969 unsigned dest_lo = dest_hi + 1;
13971 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13972 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13974 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13975 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13977 [(set_attr "type" "fp")
13978 (set_attr "length" "8")])
13980 (define_insn "unpack<mode>"
13981 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13982 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13983 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13984 UNSPEC_UNPACK_128BIT))]
13985 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13987 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13988 return ASM_COMMENT_START " xxpermdi to same register";
13990 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13991 return "xxpermdi %x0,%x1,%x1,%3";
13993 [(set_attr "type" "vecperm")])
13995 (define_insn "pack<mode>"
13996 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13997 (unspec:FMOVE128_VSX
13998 [(match_operand:DI 1 "register_operand" "wa")
13999 (match_operand:DI 2 "register_operand" "wa")]
14000 UNSPEC_PACK_128BIT))]
14002 "xxpermdi %x0,%x1,%x2,0"
14003 [(set_attr "type" "vecperm")])
14007 ;; ISA 2.08 IEEE 128-bit floating point support.
14009 (define_insn "add<mode>3"
14010 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14012 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14013 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14014 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14016 [(set_attr "type" "vecfloat")
14017 (set_attr "size" "128")])
14019 (define_insn "sub<mode>3"
14020 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14022 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14023 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14024 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14026 [(set_attr "type" "vecfloat")
14027 (set_attr "size" "128")])
14029 (define_insn "mul<mode>3"
14030 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14032 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14033 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14034 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14036 [(set_attr "type" "qmul")
14037 (set_attr "size" "128")])
14039 (define_insn "div<mode>3"
14040 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14042 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14043 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14044 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14046 [(set_attr "type" "vecdiv")
14047 (set_attr "size" "128")])
14049 (define_insn "sqrt<mode>2"
14050 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14052 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14053 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14055 [(set_attr "type" "vecdiv")
14056 (set_attr "size" "128")])
14058 (define_expand "copysign<mode>3"
14059 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14060 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14061 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14062 "FLOAT128_IEEE_P (<MODE>mode)"
14064 if (TARGET_FLOAT128_HW)
14065 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14069 rtx tmp = gen_reg_rtx (<MODE>mode);
14070 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14071 operands[2], tmp));
14076 (define_insn "copysign<mode>3_hard"
14077 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14079 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14080 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14082 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14083 "xscpsgnqp %0,%2,%1"
14084 [(set_attr "type" "vecmove")
14085 (set_attr "size" "128")])
14087 (define_insn "copysign<mode>3_soft"
14088 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14090 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14091 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14092 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14094 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14095 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14096 [(set_attr "type" "veccomplex")
14097 (set_attr "length" "8")])
14099 (define_insn "neg<mode>2_hw"
14100 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14102 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14103 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14105 [(set_attr "type" "vecmove")
14106 (set_attr "size" "128")])
14109 (define_insn "abs<mode>2_hw"
14110 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14112 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14113 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14115 [(set_attr "type" "vecmove")
14116 (set_attr "size" "128")])
14119 (define_insn "*nabs<mode>2_hw"
14120 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14123 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14124 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14126 [(set_attr "type" "vecmove")
14127 (set_attr "size" "128")])
14129 ;; Initially don't worry about doing fusion
14130 (define_insn "fma<mode>4_hw"
14131 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14133 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14134 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14135 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14136 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14137 "xsmaddqp %0,%1,%2"
14138 [(set_attr "type" "qmul")
14139 (set_attr "size" "128")])
14141 (define_insn "*fms<mode>4_hw"
14142 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14144 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14145 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14147 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14148 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14149 "xsmsubqp %0,%1,%2"
14150 [(set_attr "type" "qmul")
14151 (set_attr "size" "128")])
14153 (define_insn "*nfma<mode>4_hw"
14154 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14157 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14158 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14159 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14160 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14161 "xsnmaddqp %0,%1,%2"
14162 [(set_attr "type" "qmul")
14163 (set_attr "size" "128")])
14165 (define_insn "*nfms<mode>4_hw"
14166 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14169 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14170 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14172 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14173 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14174 "xsnmsubqp %0,%1,%2"
14175 [(set_attr "type" "qmul")
14176 (set_attr "size" "128")])
14178 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14179 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14180 (float_extend:IEEE128
14181 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14182 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14184 [(set_attr "type" "vecfloat")
14185 (set_attr "size" "128")])
14187 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14188 ;; point is a simple copy.
14189 (define_insn_and_split "extendkftf2"
14190 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14191 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14192 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14196 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14199 emit_note (NOTE_INSN_DELETED);
14202 [(set_attr "type" "*,veclogical")
14203 (set_attr "length" "0,4")])
14205 (define_insn_and_split "trunctfkf2"
14206 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14207 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14208 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14212 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14215 emit_note (NOTE_INSN_DELETED);
14218 [(set_attr "type" "*,veclogical")
14219 (set_attr "length" "0,4")])
14221 (define_insn "trunc<mode>df2_hw"
14222 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14224 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14225 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14227 [(set_attr "type" "vecfloat")
14228 (set_attr "size" "128")])
14230 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14231 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14233 (define_insn_and_split "trunc<mode>sf2_hw"
14234 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14236 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14237 (clobber (match_scratch:DF 2 "=v"))]
14238 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14241 [(set (match_dup 2)
14242 (unspec:DF [(match_dup 1)]
14243 UNSPEC_TRUNC_ROUND_TO_ODD))
14245 (float_truncate:SF (match_dup 2)))]
14247 if (GET_CODE (operands[2]) == SCRATCH)
14248 operands[2] = gen_reg_rtx (DFmode);
14250 [(set_attr "type" "vecfloat")
14251 (set_attr "length" "8")])
14253 ;; Conversion between IEEE 128-bit and integer types
14255 ;; The fix function for DImode and SImode was declared earlier as a
14256 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14257 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14258 ;; unless we have the IEEE 128-bit hardware.
14260 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14261 ;; to provide a GPR target that used direct move and a conversion in the GPR
14262 ;; which works around QImode/HImode not being allowed in vector registers in
14263 ;; ISA 2.07 (power8).
14264 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14265 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14266 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14267 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14268 "xscvqp<su><wd>z %0,%1"
14269 [(set_attr "type" "vecfloat")
14270 (set_attr "size" "128")])
14272 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14273 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14275 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14276 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14277 "xscvqp<su>wz %0,%1"
14278 [(set_attr "type" "vecfloat")
14279 (set_attr "size" "128")])
14281 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14282 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14283 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14284 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14286 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14287 (clobber (match_scratch:QHSI 2 "=v"))]
14288 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14290 "&& reload_completed"
14291 [(set (match_dup 2)
14292 (any_fix:QHSI (match_dup 1)))
14296 (define_insn "float_<mode>di2_hw"
14297 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14298 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14299 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14301 [(set_attr "type" "vecfloat")
14302 (set_attr "size" "128")])
14304 (define_insn_and_split "float_<mode>si2_hw"
14305 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14306 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14307 (clobber (match_scratch:DI 2 "=v"))]
14308 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14311 [(set (match_dup 2)
14312 (sign_extend:DI (match_dup 1)))
14314 (float:IEEE128 (match_dup 2)))]
14316 if (GET_CODE (operands[2]) == SCRATCH)
14317 operands[2] = gen_reg_rtx (DImode);
14319 if (MEM_P (operands[1]))
14320 operands[1] = rs6000_address_for_fpconvert (operands[1]);
14323 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14324 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14325 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14326 (clobber (match_scratch:DI 2 "=X,r,X"))]
14327 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14329 "&& reload_completed"
14332 rtx dest = operands[0];
14333 rtx src = operands[1];
14334 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14336 if (altivec_register_operand (src, <QHI:MODE>mode))
14337 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14338 else if (int_reg_operand (src, <QHI:MODE>mode))
14340 rtx ext_di = operands[2];
14341 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14342 emit_move_insn (dest_di, ext_di);
14344 else if (MEM_P (src))
14346 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14347 emit_move_insn (dest_qhi, src);
14348 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14351 gcc_unreachable ();
14353 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14356 [(set_attr "length" "8,12,12")
14357 (set_attr "type" "vecfloat")
14358 (set_attr "size" "128")])
14360 (define_insn "floatuns_<mode>di2_hw"
14361 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14362 (unsigned_float:IEEE128
14363 (match_operand:DI 1 "altivec_register_operand" "v")))]
14364 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14366 [(set_attr "type" "vecfloat")
14367 (set_attr "size" "128")])
14369 (define_insn_and_split "floatuns_<mode>si2_hw"
14370 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14371 (unsigned_float:IEEE128
14372 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14373 (clobber (match_scratch:DI 2 "=v"))]
14374 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14377 [(set (match_dup 2)
14378 (zero_extend:DI (match_dup 1)))
14380 (float:IEEE128 (match_dup 2)))]
14382 if (GET_CODE (operands[2]) == SCRATCH)
14383 operands[2] = gen_reg_rtx (DImode);
14385 if (MEM_P (operands[1]))
14386 operands[1] = rs6000_address_for_fpconvert (operands[1]);
14389 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14390 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14391 (unsigned_float:IEEE128
14392 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14393 (clobber (match_scratch:DI 2 "=X,r,X"))]
14394 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14396 "&& reload_completed"
14399 rtx dest = operands[0];
14400 rtx src = operands[1];
14401 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14403 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14404 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14405 else if (int_reg_operand (src, <QHI:MODE>mode))
14407 rtx ext_di = operands[2];
14408 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14409 emit_move_insn (dest_di, ext_di);
14412 gcc_unreachable ();
14414 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14417 [(set_attr "length" "8,12,8")
14418 (set_attr "type" "vecfloat")
14419 (set_attr "size" "128")])
14421 ;; IEEE 128-bit round to integer built-in functions
14422 (define_insn "floor<mode>2"
14423 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14425 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14427 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14429 [(set_attr "type" "vecfloat")
14430 (set_attr "size" "128")])
14432 (define_insn "ceil<mode>2"
14433 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14435 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14437 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14439 [(set_attr "type" "vecfloat")
14440 (set_attr "size" "128")])
14442 (define_insn "btrunc<mode>2"
14443 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14445 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14447 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14449 [(set_attr "type" "vecfloat")
14450 (set_attr "size" "128")])
14452 (define_insn "round<mode>2"
14453 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14455 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14457 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14459 [(set_attr "type" "vecfloat")
14460 (set_attr "size" "128")])
14462 ;; IEEE 128-bit instructions with round to odd semantics
14463 (define_insn "add<mode>3_odd"
14464 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14466 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14467 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14468 UNSPEC_ADD_ROUND_TO_ODD))]
14469 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14470 "xsaddqpo %0,%1,%2"
14471 [(set_attr "type" "vecfloat")
14472 (set_attr "size" "128")])
14474 (define_insn "sub<mode>3_odd"
14475 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14477 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14478 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14479 UNSPEC_SUB_ROUND_TO_ODD))]
14480 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14481 "xssubqpo %0,%1,%2"
14482 [(set_attr "type" "vecfloat")
14483 (set_attr "size" "128")])
14485 (define_insn "mul<mode>3_odd"
14486 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14488 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14489 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14490 UNSPEC_MUL_ROUND_TO_ODD))]
14491 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14492 "xsmulqpo %0,%1,%2"
14493 [(set_attr "type" "qmul")
14494 (set_attr "size" "128")])
14496 (define_insn "div<mode>3_odd"
14497 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14499 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14500 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14501 UNSPEC_DIV_ROUND_TO_ODD))]
14502 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14503 "xsdivqpo %0,%1,%2"
14504 [(set_attr "type" "vecdiv")
14505 (set_attr "size" "128")])
14507 (define_insn "sqrt<mode>2_odd"
14508 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14510 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14511 UNSPEC_SQRT_ROUND_TO_ODD))]
14512 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14514 [(set_attr "type" "vecdiv")
14515 (set_attr "size" "128")])
14517 (define_insn "fma<mode>4_odd"
14518 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14520 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14521 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14522 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14523 UNSPEC_FMA_ROUND_TO_ODD))]
14524 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14525 "xsmaddqpo %0,%1,%2"
14526 [(set_attr "type" "qmul")
14527 (set_attr "size" "128")])
14529 (define_insn "*fms<mode>4_odd"
14530 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14532 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14533 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14535 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14536 UNSPEC_FMA_ROUND_TO_ODD))]
14537 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14538 "xsmsubqpo %0,%1,%2"
14539 [(set_attr "type" "qmul")
14540 (set_attr "size" "128")])
14542 (define_insn "*nfma<mode>4_odd"
14543 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14546 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14547 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14548 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14549 UNSPEC_FMA_ROUND_TO_ODD)))]
14550 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14551 "xsnmaddqpo %0,%1,%2"
14552 [(set_attr "type" "qmul")
14553 (set_attr "size" "128")])
14555 (define_insn "*nfms<mode>4_odd"
14556 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14559 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14560 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14562 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14563 UNSPEC_FMA_ROUND_TO_ODD)))]
14564 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14565 "xsnmsubqpo %0,%1,%2"
14566 [(set_attr "type" "qmul")
14567 (set_attr "size" "128")])
14569 (define_insn "trunc<mode>df2_odd"
14570 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14571 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14572 UNSPEC_TRUNC_ROUND_TO_ODD))]
14573 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14575 [(set_attr "type" "vecfloat")
14576 (set_attr "size" "128")])
14578 ;; IEEE 128-bit comparisons
14579 (define_insn "*cmp<mode>_hw"
14580 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14581 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14582 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14583 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14584 "xscmpuqp %0,%1,%2"
14585 [(set_attr "type" "veccmp")
14586 (set_attr "size" "128")])
14590 (include "sync.md")
14591 (include "vector.md")
14593 (include "altivec.md")
14595 (include "crypto.md")