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 ; Iterators for converting to/from TFmode
426 (define_mode_iterator IFKF [IF KF])
428 ; Constraints for moving IF/KFmode.
429 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
431 ; Whether a floating point move is ok, don't allow SD without hardware FP
432 (define_mode_attr fmove_ok [(SF "")
434 (SD "TARGET_HARD_FLOAT")
437 ; Convert REAL_VALUE to the appropriate bits
438 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
439 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
440 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
441 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
443 ; Whether 0.0 has an all-zero bit pattern
444 (define_mode_attr zero_fp [(SF "j")
453 ; Definitions for 64-bit VSX
454 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
456 ; Definitions for 64-bit direct move
457 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
459 ; Definitions for 64-bit use of altivec registers
460 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
462 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
463 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
465 ; These modes do not fit in integer registers in 32-bit mode.
466 (define_mode_iterator DIFD [DI DF DD])
468 ; Iterator for reciprocal estimate instructions
469 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
471 ; Iterator for just SF/DF
472 (define_mode_iterator SFDF [SF DF])
474 ; Like SFDF, but a different name to match conditional move where the
475 ; comparison operands may be a different mode than the input operands.
476 (define_mode_iterator SFDF2 [SF DF])
478 ; Iterator for 128-bit floating point that uses the IBM double-double format
479 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
480 (TF "FLOAT128_IBM_P (TFmode)")])
482 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
483 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
484 (TF "FLOAT128_IEEE_P (TFmode)")])
486 ; Iterator for 128-bit floating point
487 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
488 (IF "TARGET_FLOAT128_TYPE")
489 (TF "TARGET_LONG_DOUBLE_128")])
491 ; Iterator for signbit on 64-bit machines with direct move
492 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
493 (TF "FLOAT128_VECTOR_P (TFmode)")])
495 ; Iterator for ISA 3.0 supported floating point types
496 (define_mode_iterator FP_ISA3 [SF DF])
498 ; SF/DF suffix for traditional floating instructions
499 (define_mode_attr Ftrad [(SF "s") (DF "")])
501 ; SF/DF suffix for VSX instructions
502 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
504 ; SF/DF constraint for arithmetic on traditional floating point registers
505 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
507 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
508 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
509 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
511 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
513 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
514 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
515 ; instructions added in ISA 2.07 (power8)
516 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
518 ; SF/DF constraint for arithmetic on altivec registers
519 (define_mode_attr Fa [(SF "wu") (DF "wv")])
521 ; s/d suffix for things like sdiv/ddiv
522 (define_mode_attr Fs [(SF "s") (DF "d")])
525 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
526 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
528 ; Conditional returns.
529 (define_code_iterator any_return [return simple_return])
530 (define_code_attr return_pred [(return "direct_return ()")
531 (simple_return "1")])
532 (define_code_attr return_str [(return "") (simple_return "simple_")])
535 (define_code_iterator iorxor [ior xor])
536 (define_code_iterator and_ior_xor [and ior xor])
538 ; Signed/unsigned variants of ops.
539 (define_code_iterator any_extend [sign_extend zero_extend])
540 (define_code_iterator any_fix [fix unsigned_fix])
541 (define_code_iterator any_float [float unsigned_float])
543 (define_code_attr u [(sign_extend "")
548 (define_code_attr su [(sign_extend "s")
553 (unsigned_float "u")])
555 (define_code_attr az [(sign_extend "a")
560 (unsigned_float "z")])
562 (define_code_attr uns [(fix "")
565 (unsigned_float "uns")])
567 ; Various instructions that come in SI and DI forms.
568 ; A generic w/d attribute, for things like cmpw/cmpd.
569 (define_mode_attr wd [(QI "b")
580 ;; How many bits in this mode?
581 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
584 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
586 ;; Bitmask for shift instructions
587 (define_mode_attr hH [(SI "h") (DI "H")])
589 ;; A mode twice the size of the given mode
590 (define_mode_attr dmode [(SI "di") (DI "ti")])
591 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
593 ;; Suffix for reload patterns
594 (define_mode_attr ptrsize [(SI "32bit")
597 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
598 (DI "TARGET_64BIT")])
600 (define_mode_attr mptrsize [(SI "si")
603 (define_mode_attr ptrload [(SI "lwz")
606 (define_mode_attr ptrm [(SI "m")
609 (define_mode_attr rreg [(SF "f")
616 (define_mode_attr rreg2 [(SF "f")
619 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
620 (DF "TARGET_FCFID")])
622 ;; Mode iterator for logical operations on 128-bit types
623 (define_mode_iterator BOOL_128 [TI
625 (V16QI "TARGET_ALTIVEC")
626 (V8HI "TARGET_ALTIVEC")
627 (V4SI "TARGET_ALTIVEC")
628 (V4SF "TARGET_ALTIVEC")
629 (V2DI "TARGET_ALTIVEC")
630 (V2DF "TARGET_ALTIVEC")
631 (V1TI "TARGET_ALTIVEC")])
633 ;; For the GPRs we use 3 constraints for register outputs, two that are the
634 ;; same as the output register, and a third where the output register is an
635 ;; early clobber, so we don't have to deal with register overlaps. For the
636 ;; vector types, we prefer to use the vector registers. For TI mode, allow
639 ;; Mode attribute for boolean operation register constraints for output
640 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
642 (V16QI "wa,v,&?r,?r,?r")
643 (V8HI "wa,v,&?r,?r,?r")
644 (V4SI "wa,v,&?r,?r,?r")
645 (V4SF "wa,v,&?r,?r,?r")
646 (V2DI "wa,v,&?r,?r,?r")
647 (V2DF "wa,v,&?r,?r,?r")
648 (V1TI "wa,v,&?r,?r,?r")])
650 ;; Mode attribute for boolean operation register constraints for operand1
651 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
659 (V1TI "wa,v,r,0,r")])
661 ;; Mode attribute for boolean operation register constraints for operand2
662 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
670 (V1TI "wa,v,r,r,0")])
672 ;; Mode attribute for boolean operation register constraints for operand1
673 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
674 ;; is used for operand1 or operand2
675 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
683 (V1TI "wa,v,r,0,0")])
685 ;; Reload iterator for creating the function to allocate a base register to
686 ;; supplement addressing modes.
687 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
688 SF SD SI DF DD DI TI PTI KF IF TF])
690 ;; Iterate over smin, smax
691 (define_code_iterator fp_minmax [smin smax])
693 (define_code_attr minmax [(smin "min")
696 (define_code_attr SMINMAX [(smin "SMIN")
699 ;; Iterator to optimize the following cases:
700 ;; D-form load to FPR register & move to Altivec register
701 ;; Move Altivec register to FPR register and store
702 (define_mode_iterator ALTIVEC_DFORM [DF
703 (SF "TARGET_P8_VECTOR")
704 (DI "TARGET_POWERPC64")])
707 ;; Start with fixed-point load and store insns. Here we put only the more
708 ;; complex forms. Basic data transfer is done later.
710 (define_insn "zero_extendqi<mode>2"
711 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
712 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
719 [(set_attr "type" "load,shift,fpload,vecperm")])
721 (define_insn_and_split "*zero_extendqi<mode>2_dot"
722 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
723 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
725 (clobber (match_scratch:EXTQI 0 "=r,r"))]
730 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
732 (zero_extend:EXTQI (match_dup 1)))
734 (compare:CC (match_dup 0)
737 [(set_attr "type" "logical")
738 (set_attr "dot" "yes")
739 (set_attr "length" "4,8")])
741 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
742 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
743 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
745 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
746 (zero_extend:EXTQI (match_dup 1)))]
751 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
753 (zero_extend:EXTQI (match_dup 1)))
755 (compare:CC (match_dup 0)
758 [(set_attr "type" "logical")
759 (set_attr "dot" "yes")
760 (set_attr "length" "4,8")])
763 (define_insn "zero_extendhi<mode>2"
764 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
765 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
769 rlwinm %0,%1,0,0xffff
772 [(set_attr "type" "load,shift,fpload,vecperm")])
774 (define_insn_and_split "*zero_extendhi<mode>2_dot"
775 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
776 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
778 (clobber (match_scratch:EXTHI 0 "=r,r"))]
783 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
785 (zero_extend:EXTHI (match_dup 1)))
787 (compare:CC (match_dup 0)
790 [(set_attr "type" "logical")
791 (set_attr "dot" "yes")
792 (set_attr "length" "4,8")])
794 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
795 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
796 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
798 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
799 (zero_extend:EXTHI (match_dup 1)))]
804 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
806 (zero_extend:EXTHI (match_dup 1)))
808 (compare:CC (match_dup 0)
811 [(set_attr "type" "logical")
812 (set_attr "dot" "yes")
813 (set_attr "length" "4,8")])
816 (define_insn "zero_extendsi<mode>2"
817 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
818 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
827 xxextractuw %x0,%x1,4"
828 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
830 (define_insn_and_split "*zero_extendsi<mode>2_dot"
831 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
832 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
834 (clobber (match_scratch:EXTSI 0 "=r,r"))]
839 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
841 (zero_extend:DI (match_dup 1)))
843 (compare:CC (match_dup 0)
846 [(set_attr "type" "shift")
847 (set_attr "dot" "yes")
848 (set_attr "length" "4,8")])
850 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
851 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
852 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
854 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
855 (zero_extend:EXTSI (match_dup 1)))]
860 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
862 (zero_extend:EXTSI (match_dup 1)))
864 (compare:CC (match_dup 0)
867 [(set_attr "type" "shift")
868 (set_attr "dot" "yes")
869 (set_attr "length" "4,8")])
872 (define_insn "extendqi<mode>2"
873 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
874 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
879 [(set_attr "type" "exts,vecperm")])
881 (define_insn_and_split "*extendqi<mode>2_dot"
882 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
883 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
885 (clobber (match_scratch:EXTQI 0 "=r,r"))]
890 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
892 (sign_extend:EXTQI (match_dup 1)))
894 (compare:CC (match_dup 0)
897 [(set_attr "type" "exts")
898 (set_attr "dot" "yes")
899 (set_attr "length" "4,8")])
901 (define_insn_and_split "*extendqi<mode>2_dot2"
902 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
903 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
905 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
906 (sign_extend:EXTQI (match_dup 1)))]
911 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
913 (sign_extend:EXTQI (match_dup 1)))
915 (compare:CC (match_dup 0)
918 [(set_attr "type" "exts")
919 (set_attr "dot" "yes")
920 (set_attr "length" "4,8")])
923 (define_expand "extendhi<mode>2"
924 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
925 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
929 (define_insn "*extendhi<mode>2"
930 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
931 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
938 [(set_attr "type" "load,exts,fpload,vecperm")
939 (set_attr "sign_extend" "yes")
940 (set_attr "length" "4,4,8,4")])
943 [(set (match_operand:EXTHI 0 "altivec_register_operand")
945 (match_operand:HI 1 "indexed_or_indirect_operand")))]
946 "TARGET_P9_VECTOR && reload_completed"
950 (sign_extend:EXTHI (match_dup 2)))]
952 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
955 (define_insn_and_split "*extendhi<mode>2_dot"
956 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
957 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
959 (clobber (match_scratch:EXTHI 0 "=r,r"))]
964 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
966 (sign_extend:EXTHI (match_dup 1)))
968 (compare:CC (match_dup 0)
971 [(set_attr "type" "exts")
972 (set_attr "dot" "yes")
973 (set_attr "length" "4,8")])
975 (define_insn_and_split "*extendhi<mode>2_dot2"
976 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
977 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
979 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
980 (sign_extend:EXTHI (match_dup 1)))]
985 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
987 (sign_extend:EXTHI (match_dup 1)))
989 (compare:CC (match_dup 0)
992 [(set_attr "type" "exts")
993 (set_attr "dot" "yes")
994 (set_attr "length" "4,8")])
997 (define_insn "extendsi<mode>2"
998 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
999 "=r, r, wl, wu, wj, wK, wH, wr")
1001 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1002 "Y, r, Z, Z, r, wK, wH, ?wIwH")))]
1013 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1014 (set_attr "sign_extend" "yes")
1015 (set_attr "length" "4,4,4,4,4,4,8,8")])
1018 [(set (match_operand:EXTSI 0 "int_reg_operand")
1019 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1020 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1024 (sign_extend:DI (match_dup 2)))]
1026 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1030 [(set (match_operand:DI 0 "altivec_register_operand")
1031 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1032 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1035 rtx dest = operands[0];
1036 rtx src = operands[1];
1037 int dest_regno = REGNO (dest);
1038 int src_regno = REGNO (src);
1039 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1040 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1042 if (BYTES_BIG_ENDIAN)
1044 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1045 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1049 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1050 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1055 (define_insn_and_split "*extendsi<mode>2_dot"
1056 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1057 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1059 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1064 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1066 (sign_extend:EXTSI (match_dup 1)))
1068 (compare:CC (match_dup 0)
1071 [(set_attr "type" "exts")
1072 (set_attr "dot" "yes")
1073 (set_attr "length" "4,8")])
1075 (define_insn_and_split "*extendsi<mode>2_dot2"
1076 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1077 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1079 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1080 (sign_extend:EXTSI (match_dup 1)))]
1085 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1087 (sign_extend:EXTSI (match_dup 1)))
1089 (compare:CC (match_dup 0)
1092 [(set_attr "type" "exts")
1093 (set_attr "dot" "yes")
1094 (set_attr "length" "4,8")])
1096 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1098 (define_insn "*macchwc"
1099 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1100 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1101 (match_operand:SI 2 "gpc_reg_operand" "r")
1104 (match_operand:HI 1 "gpc_reg_operand" "r")))
1105 (match_operand:SI 4 "gpc_reg_operand" "0"))
1107 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1108 (plus:SI (mult:SI (ashiftrt:SI
1116 [(set_attr "type" "halfmul")])
1118 (define_insn "*macchw"
1119 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1120 (plus:SI (mult:SI (ashiftrt:SI
1121 (match_operand:SI 2 "gpc_reg_operand" "r")
1124 (match_operand:HI 1 "gpc_reg_operand" "r")))
1125 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1128 [(set_attr "type" "halfmul")])
1130 (define_insn "*macchwuc"
1131 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1132 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1133 (match_operand:SI 2 "gpc_reg_operand" "r")
1136 (match_operand:HI 1 "gpc_reg_operand" "r")))
1137 (match_operand:SI 4 "gpc_reg_operand" "0"))
1139 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1140 (plus:SI (mult:SI (lshiftrt:SI
1148 [(set_attr "type" "halfmul")])
1150 (define_insn "*macchwu"
1151 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1152 (plus:SI (mult:SI (lshiftrt:SI
1153 (match_operand:SI 2 "gpc_reg_operand" "r")
1156 (match_operand:HI 1 "gpc_reg_operand" "r")))
1157 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1160 [(set_attr "type" "halfmul")])
1162 (define_insn "*machhwc"
1163 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1164 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1165 (match_operand:SI 1 "gpc_reg_operand" "%r")
1168 (match_operand:SI 2 "gpc_reg_operand" "r")
1170 (match_operand:SI 4 "gpc_reg_operand" "0"))
1172 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1173 (plus:SI (mult:SI (ashiftrt:SI
1182 [(set_attr "type" "halfmul")])
1184 (define_insn "*machhw"
1185 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186 (plus:SI (mult:SI (ashiftrt:SI
1187 (match_operand:SI 1 "gpc_reg_operand" "%r")
1190 (match_operand:SI 2 "gpc_reg_operand" "r")
1192 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1195 [(set_attr "type" "halfmul")])
1197 (define_insn "*machhwuc"
1198 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1199 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1200 (match_operand:SI 1 "gpc_reg_operand" "%r")
1203 (match_operand:SI 2 "gpc_reg_operand" "r")
1205 (match_operand:SI 4 "gpc_reg_operand" "0"))
1207 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1208 (plus:SI (mult:SI (lshiftrt:SI
1217 [(set_attr "type" "halfmul")])
1219 (define_insn "*machhwu"
1220 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1221 (plus:SI (mult:SI (lshiftrt:SI
1222 (match_operand:SI 1 "gpc_reg_operand" "%r")
1225 (match_operand:SI 2 "gpc_reg_operand" "r")
1227 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1230 [(set_attr "type" "halfmul")])
1232 (define_insn "*maclhwc"
1233 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1234 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1235 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1237 (match_operand:HI 2 "gpc_reg_operand" "r")))
1238 (match_operand:SI 4 "gpc_reg_operand" "0"))
1240 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1241 (plus:SI (mult:SI (sign_extend:SI
1248 [(set_attr "type" "halfmul")])
1250 (define_insn "*maclhw"
1251 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1252 (plus:SI (mult:SI (sign_extend:SI
1253 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1255 (match_operand:HI 2 "gpc_reg_operand" "r")))
1256 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1259 [(set_attr "type" "halfmul")])
1261 (define_insn "*maclhwuc"
1262 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1263 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1264 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1266 (match_operand:HI 2 "gpc_reg_operand" "r")))
1267 (match_operand:SI 4 "gpc_reg_operand" "0"))
1269 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1270 (plus:SI (mult:SI (zero_extend:SI
1277 [(set_attr "type" "halfmul")])
1279 (define_insn "*maclhwu"
1280 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1281 (plus:SI (mult:SI (zero_extend:SI
1282 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1284 (match_operand:HI 2 "gpc_reg_operand" "r")))
1285 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1288 [(set_attr "type" "halfmul")])
1290 (define_insn "*nmacchwc"
1291 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1292 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1293 (mult:SI (ashiftrt:SI
1294 (match_operand:SI 2 "gpc_reg_operand" "r")
1297 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1299 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1300 (minus:SI (match_dup 4)
1301 (mult:SI (ashiftrt:SI
1308 [(set_attr "type" "halfmul")])
1310 (define_insn "*nmacchw"
1311 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1312 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1313 (mult:SI (ashiftrt:SI
1314 (match_operand:SI 2 "gpc_reg_operand" "r")
1317 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1320 [(set_attr "type" "halfmul")])
1322 (define_insn "*nmachhwc"
1323 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1324 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1325 (mult:SI (ashiftrt:SI
1326 (match_operand:SI 1 "gpc_reg_operand" "%r")
1329 (match_operand:SI 2 "gpc_reg_operand" "r")
1332 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1333 (minus:SI (match_dup 4)
1334 (mult:SI (ashiftrt:SI
1342 [(set_attr "type" "halfmul")])
1344 (define_insn "*nmachhw"
1345 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1346 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1347 (mult:SI (ashiftrt:SI
1348 (match_operand:SI 1 "gpc_reg_operand" "%r")
1351 (match_operand:SI 2 "gpc_reg_operand" "r")
1355 [(set_attr "type" "halfmul")])
1357 (define_insn "*nmaclhwc"
1358 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1359 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1360 (mult:SI (sign_extend:SI
1361 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1363 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1365 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1366 (minus:SI (match_dup 4)
1367 (mult:SI (sign_extend:SI
1373 [(set_attr "type" "halfmul")])
1375 (define_insn "*nmaclhw"
1376 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1377 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1378 (mult:SI (sign_extend:SI
1379 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1381 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1384 [(set_attr "type" "halfmul")])
1386 (define_insn "*mulchwc"
1387 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1388 (compare:CC (mult:SI (ashiftrt:SI
1389 (match_operand:SI 2 "gpc_reg_operand" "r")
1392 (match_operand:HI 1 "gpc_reg_operand" "r")))
1394 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1395 (mult:SI (ashiftrt:SI
1402 [(set_attr "type" "halfmul")])
1404 (define_insn "*mulchw"
1405 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1406 (mult:SI (ashiftrt:SI
1407 (match_operand:SI 2 "gpc_reg_operand" "r")
1410 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1413 [(set_attr "type" "halfmul")])
1415 (define_insn "*mulchwuc"
1416 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1417 (compare:CC (mult:SI (lshiftrt:SI
1418 (match_operand:SI 2 "gpc_reg_operand" "r")
1421 (match_operand:HI 1 "gpc_reg_operand" "r")))
1423 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1424 (mult:SI (lshiftrt:SI
1431 [(set_attr "type" "halfmul")])
1433 (define_insn "*mulchwu"
1434 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1435 (mult:SI (lshiftrt:SI
1436 (match_operand:SI 2 "gpc_reg_operand" "r")
1439 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1442 [(set_attr "type" "halfmul")])
1444 (define_insn "*mulhhwc"
1445 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1446 (compare:CC (mult:SI (ashiftrt:SI
1447 (match_operand:SI 1 "gpc_reg_operand" "%r")
1450 (match_operand:SI 2 "gpc_reg_operand" "r")
1453 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1454 (mult:SI (ashiftrt:SI
1462 [(set_attr "type" "halfmul")])
1464 (define_insn "*mulhhw"
1465 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1466 (mult:SI (ashiftrt:SI
1467 (match_operand:SI 1 "gpc_reg_operand" "%r")
1470 (match_operand:SI 2 "gpc_reg_operand" "r")
1474 [(set_attr "type" "halfmul")])
1476 (define_insn "*mulhhwuc"
1477 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1478 (compare:CC (mult:SI (lshiftrt:SI
1479 (match_operand:SI 1 "gpc_reg_operand" "%r")
1482 (match_operand:SI 2 "gpc_reg_operand" "r")
1485 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1486 (mult:SI (lshiftrt:SI
1494 [(set_attr "type" "halfmul")])
1496 (define_insn "*mulhhwu"
1497 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1498 (mult:SI (lshiftrt:SI
1499 (match_operand:SI 1 "gpc_reg_operand" "%r")
1502 (match_operand:SI 2 "gpc_reg_operand" "r")
1506 [(set_attr "type" "halfmul")])
1508 (define_insn "*mullhwc"
1509 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1510 (compare:CC (mult:SI (sign_extend:SI
1511 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1513 (match_operand:HI 2 "gpc_reg_operand" "r")))
1515 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1516 (mult:SI (sign_extend:SI
1522 [(set_attr "type" "halfmul")])
1524 (define_insn "*mullhw"
1525 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1526 (mult:SI (sign_extend:SI
1527 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1529 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1532 [(set_attr "type" "halfmul")])
1534 (define_insn "*mullhwuc"
1535 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1536 (compare:CC (mult:SI (zero_extend:SI
1537 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1539 (match_operand:HI 2 "gpc_reg_operand" "r")))
1541 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1542 (mult:SI (zero_extend:SI
1548 [(set_attr "type" "halfmul")])
1550 (define_insn "*mullhwu"
1551 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1552 (mult:SI (zero_extend:SI
1553 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1555 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1558 [(set_attr "type" "halfmul")])
1560 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1561 (define_insn "dlmzb"
1562 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1563 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1564 (match_operand:SI 2 "gpc_reg_operand" "r")]
1566 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1567 (unspec:SI [(match_dup 1)
1573 (define_expand "strlensi"
1574 [(set (match_operand:SI 0 "gpc_reg_operand")
1575 (unspec:SI [(match_operand:BLK 1 "general_operand")
1576 (match_operand:QI 2 "const_int_operand")
1577 (match_operand 3 "const_int_operand")]
1578 UNSPEC_DLMZB_STRLEN))
1579 (clobber (match_scratch:CC 4))]
1580 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1582 rtx result = operands[0];
1583 rtx src = operands[1];
1584 rtx search_char = operands[2];
1585 rtx align = operands[3];
1586 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1587 rtx loop_label, end_label, mem, cr0, cond;
1588 if (search_char != const0_rtx
1589 || GET_CODE (align) != CONST_INT
1590 || INTVAL (align) < 8)
1592 word1 = gen_reg_rtx (SImode);
1593 word2 = gen_reg_rtx (SImode);
1594 scratch_dlmzb = gen_reg_rtx (SImode);
1595 scratch_string = gen_reg_rtx (Pmode);
1596 loop_label = gen_label_rtx ();
1597 end_label = gen_label_rtx ();
1598 addr = force_reg (Pmode, XEXP (src, 0));
1599 emit_move_insn (scratch_string, addr);
1600 emit_label (loop_label);
1601 mem = change_address (src, SImode, scratch_string);
1602 emit_move_insn (word1, mem);
1603 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1604 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1605 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1606 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1607 emit_jump_insn (gen_rtx_SET (pc_rtx,
1608 gen_rtx_IF_THEN_ELSE (VOIDmode,
1614 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1615 emit_jump_insn (gen_rtx_SET (pc_rtx,
1616 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1618 emit_label (end_label);
1619 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1620 emit_insn (gen_subsi3 (result, scratch_string, addr));
1621 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1625 ;; Fixed-point arithmetic insns.
1627 (define_expand "add<mode>3"
1628 [(set (match_operand:SDI 0 "gpc_reg_operand")
1629 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1630 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1633 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1635 rtx lo0 = gen_lowpart (SImode, operands[0]);
1636 rtx lo1 = gen_lowpart (SImode, operands[1]);
1637 rtx lo2 = gen_lowpart (SImode, operands[2]);
1638 rtx hi0 = gen_highpart (SImode, operands[0]);
1639 rtx hi1 = gen_highpart (SImode, operands[1]);
1640 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1642 if (!reg_or_short_operand (lo2, SImode))
1643 lo2 = force_reg (SImode, lo2);
1644 if (!adde_operand (hi2, SImode))
1645 hi2 = force_reg (SImode, hi2);
1647 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1648 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1652 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1654 rtx tmp = ((!can_create_pseudo_p ()
1655 || rtx_equal_p (operands[0], operands[1]))
1656 ? operands[0] : gen_reg_rtx (<MODE>mode));
1658 /* Adding a constant to r0 is not a valid insn, so use a different
1659 strategy in that case. */
1660 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1662 if (operands[0] == operands[1])
1664 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1665 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1669 HOST_WIDE_INT val = INTVAL (operands[2]);
1670 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1671 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1673 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1676 /* The ordering here is important for the prolog expander.
1677 When space is allocated from the stack, adding 'low' first may
1678 produce a temporary deallocation (which would be bad). */
1679 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1680 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1685 (define_insn "*add<mode>3"
1686 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1687 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1688 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1694 [(set_attr "type" "add")])
1696 (define_insn "addsi3_high"
1697 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1698 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1699 (high:SI (match_operand 2 "" ""))))]
1700 "TARGET_MACHO && !TARGET_64BIT"
1701 "addis %0,%1,ha16(%2)"
1702 [(set_attr "type" "add")])
1704 (define_insn_and_split "*add<mode>3_dot"
1705 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1706 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1707 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1709 (clobber (match_scratch:GPR 0 "=r,r"))]
1710 "<MODE>mode == Pmode"
1714 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1716 (plus:GPR (match_dup 1)
1719 (compare:CC (match_dup 0)
1722 [(set_attr "type" "add")
1723 (set_attr "dot" "yes")
1724 (set_attr "length" "4,8")])
1726 (define_insn_and_split "*add<mode>3_dot2"
1727 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1728 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1729 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1731 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1732 (plus:GPR (match_dup 1)
1734 "<MODE>mode == Pmode"
1738 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1740 (plus:GPR (match_dup 1)
1743 (compare:CC (match_dup 0)
1746 [(set_attr "type" "add")
1747 (set_attr "dot" "yes")
1748 (set_attr "length" "4,8")])
1750 (define_insn_and_split "*add<mode>3_imm_dot"
1751 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1752 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1753 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1755 (clobber (match_scratch:GPR 0 "=r,r"))
1756 (clobber (reg:GPR CA_REGNO))]
1757 "<MODE>mode == Pmode"
1761 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1763 (plus:GPR (match_dup 1)
1766 (compare:CC (match_dup 0)
1769 [(set_attr "type" "add")
1770 (set_attr "dot" "yes")
1771 (set_attr "length" "4,8")])
1773 (define_insn_and_split "*add<mode>3_imm_dot2"
1774 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1775 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1776 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1778 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1779 (plus:GPR (match_dup 1)
1781 (clobber (reg:GPR CA_REGNO))]
1782 "<MODE>mode == Pmode"
1786 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1788 (plus:GPR (match_dup 1)
1791 (compare:CC (match_dup 0)
1794 [(set_attr "type" "add")
1795 (set_attr "dot" "yes")
1796 (set_attr "length" "4,8")])
1798 ;; Split an add that we can't do in one insn into two insns, each of which
1799 ;; does one 16-bit part. This is used by combine. Note that the low-order
1800 ;; add should be last in case the result gets used in an address.
1803 [(set (match_operand:GPR 0 "gpc_reg_operand")
1804 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1805 (match_operand:GPR 2 "non_add_cint_operand")))]
1807 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1808 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1810 HOST_WIDE_INT val = INTVAL (operands[2]);
1811 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1812 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1814 operands[4] = GEN_INT (low);
1815 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1816 operands[3] = GEN_INT (rest);
1817 else if (can_create_pseudo_p ())
1819 operands[3] = gen_reg_rtx (DImode);
1820 emit_move_insn (operands[3], operands[2]);
1821 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1829 (define_insn "add<mode>3_carry"
1830 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1831 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1832 (match_operand:P 2 "reg_or_short_operand" "rI")))
1833 (set (reg:P CA_REGNO)
1834 (ltu:P (plus:P (match_dup 1)
1839 [(set_attr "type" "add")])
1841 (define_insn "*add<mode>3_imm_carry_pos"
1842 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1843 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1844 (match_operand:P 2 "short_cint_operand" "n")))
1845 (set (reg:P CA_REGNO)
1846 (geu:P (match_dup 1)
1847 (match_operand:P 3 "const_int_operand" "n")))]
1848 "INTVAL (operands[2]) > 0
1849 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1851 [(set_attr "type" "add")])
1853 (define_insn "*add<mode>3_imm_carry_0"
1854 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1855 (match_operand:P 1 "gpc_reg_operand" "r"))
1856 (set (reg:P CA_REGNO)
1860 [(set_attr "type" "add")])
1862 (define_insn "*add<mode>3_imm_carry_m1"
1863 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1864 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1866 (set (reg:P CA_REGNO)
1871 [(set_attr "type" "add")])
1873 (define_insn "*add<mode>3_imm_carry_neg"
1874 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1875 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1876 (match_operand:P 2 "short_cint_operand" "n")))
1877 (set (reg:P CA_REGNO)
1878 (gtu:P (match_dup 1)
1879 (match_operand:P 3 "const_int_operand" "n")))]
1880 "INTVAL (operands[2]) < 0
1881 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1883 [(set_attr "type" "add")])
1886 (define_expand "add<mode>3_carry_in"
1888 (set (match_operand:GPR 0 "gpc_reg_operand")
1889 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1890 (match_operand:GPR 2 "adde_operand"))
1891 (reg:GPR CA_REGNO)))
1892 (clobber (reg:GPR CA_REGNO))])]
1895 if (operands[2] == const0_rtx)
1897 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1900 if (operands[2] == constm1_rtx)
1902 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1907 (define_insn "*add<mode>3_carry_in_internal"
1908 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1909 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1910 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1911 (reg:GPR CA_REGNO)))
1912 (clobber (reg:GPR CA_REGNO))]
1915 [(set_attr "type" "add")])
1917 (define_insn "*add<mode>3_carry_in_internal2"
1918 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1919 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1921 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1922 (clobber (reg:GPR CA_REGNO))]
1925 [(set_attr "type" "add")])
1927 (define_insn "add<mode>3_carry_in_0"
1928 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1929 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1930 (reg:GPR CA_REGNO)))
1931 (clobber (reg:GPR CA_REGNO))]
1934 [(set_attr "type" "add")])
1936 (define_insn "add<mode>3_carry_in_m1"
1937 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1938 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1941 (clobber (reg:GPR CA_REGNO))]
1944 [(set_attr "type" "add")])
1947 (define_expand "one_cmpl<mode>2"
1948 [(set (match_operand:SDI 0 "gpc_reg_operand")
1949 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1952 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1954 rs6000_split_logical (operands, NOT, false, false, false);
1959 (define_insn "*one_cmpl<mode>2"
1960 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1961 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1965 (define_insn_and_split "*one_cmpl<mode>2_dot"
1966 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1967 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1969 (clobber (match_scratch:GPR 0 "=r,r"))]
1970 "<MODE>mode == Pmode"
1974 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1976 (not:GPR (match_dup 1)))
1978 (compare:CC (match_dup 0)
1981 [(set_attr "type" "logical")
1982 (set_attr "dot" "yes")
1983 (set_attr "length" "4,8")])
1985 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1986 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1987 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1989 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1990 (not:GPR (match_dup 1)))]
1991 "<MODE>mode == Pmode"
1995 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1997 (not:GPR (match_dup 1)))
1999 (compare:CC (match_dup 0)
2002 [(set_attr "type" "logical")
2003 (set_attr "dot" "yes")
2004 (set_attr "length" "4,8")])
2007 (define_expand "sub<mode>3"
2008 [(set (match_operand:SDI 0 "gpc_reg_operand")
2009 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2010 (match_operand:SDI 2 "gpc_reg_operand")))]
2013 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2015 rtx lo0 = gen_lowpart (SImode, operands[0]);
2016 rtx lo1 = gen_lowpart (SImode, operands[1]);
2017 rtx lo2 = gen_lowpart (SImode, operands[2]);
2018 rtx hi0 = gen_highpart (SImode, operands[0]);
2019 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2020 rtx hi2 = gen_highpart (SImode, operands[2]);
2022 if (!reg_or_short_operand (lo1, SImode))
2023 lo1 = force_reg (SImode, lo1);
2024 if (!adde_operand (hi1, SImode))
2025 hi1 = force_reg (SImode, hi1);
2027 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2028 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2032 if (short_cint_operand (operands[1], <MODE>mode))
2034 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2039 (define_insn "*subf<mode>3"
2040 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2041 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2042 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2045 [(set_attr "type" "add")])
2047 (define_insn_and_split "*subf<mode>3_dot"
2048 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2049 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2050 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2052 (clobber (match_scratch:GPR 0 "=r,r"))]
2053 "<MODE>mode == Pmode"
2057 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2059 (minus:GPR (match_dup 2)
2062 (compare:CC (match_dup 0)
2065 [(set_attr "type" "add")
2066 (set_attr "dot" "yes")
2067 (set_attr "length" "4,8")])
2069 (define_insn_and_split "*subf<mode>3_dot2"
2070 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2071 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2072 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2074 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2075 (minus:GPR (match_dup 2)
2077 "<MODE>mode == Pmode"
2081 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2083 (minus:GPR (match_dup 2)
2086 (compare:CC (match_dup 0)
2089 [(set_attr "type" "add")
2090 (set_attr "dot" "yes")
2091 (set_attr "length" "4,8")])
2093 (define_insn "subf<mode>3_imm"
2094 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2095 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2096 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2097 (clobber (reg:GPR CA_REGNO))]
2100 [(set_attr "type" "add")])
2102 (define_insn_and_split "subf<mode>3_carry_dot2"
2103 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2104 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2105 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2107 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2108 (minus:P (match_dup 2)
2110 (set (reg:P CA_REGNO)
2111 (leu:P (match_dup 1)
2113 "<MODE>mode == Pmode"
2117 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2118 [(parallel [(set (match_dup 0)
2119 (minus:P (match_dup 2)
2121 (set (reg:P CA_REGNO)
2122 (leu:P (match_dup 1)
2125 (compare:CC (match_dup 0)
2128 [(set_attr "type" "add")
2129 (set_attr "dot" "yes")
2130 (set_attr "length" "4,8")])
2132 (define_insn "subf<mode>3_carry"
2133 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2134 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2135 (match_operand:P 1 "gpc_reg_operand" "r")))
2136 (set (reg:P CA_REGNO)
2137 (leu:P (match_dup 1)
2141 [(set_attr "type" "add")])
2143 (define_insn "*subf<mode>3_imm_carry_0"
2144 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2145 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2146 (set (reg:P CA_REGNO)
2151 [(set_attr "type" "add")])
2153 (define_insn "*subf<mode>3_imm_carry_m1"
2154 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2155 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2156 (set (reg:P CA_REGNO)
2160 [(set_attr "type" "add")])
2163 (define_expand "subf<mode>3_carry_in"
2165 (set (match_operand:GPR 0 "gpc_reg_operand")
2166 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2168 (match_operand:GPR 2 "adde_operand")))
2169 (clobber (reg:GPR CA_REGNO))])]
2172 if (operands[2] == const0_rtx)
2174 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2177 if (operands[2] == constm1_rtx)
2179 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2184 (define_insn "*subf<mode>3_carry_in_internal"
2185 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2186 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2188 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2189 (clobber (reg:GPR CA_REGNO))]
2192 [(set_attr "type" "add")])
2194 (define_insn "subf<mode>3_carry_in_0"
2195 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2196 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2197 (reg:GPR CA_REGNO)))
2198 (clobber (reg:GPR CA_REGNO))]
2201 [(set_attr "type" "add")])
2203 (define_insn "subf<mode>3_carry_in_m1"
2204 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2205 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2206 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2208 (clobber (reg:GPR CA_REGNO))]
2211 [(set_attr "type" "add")])
2213 (define_insn "subf<mode>3_carry_in_xx"
2214 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2215 (plus:GPR (reg:GPR CA_REGNO)
2217 (clobber (reg:GPR CA_REGNO))]
2220 [(set_attr "type" "add")])
2223 (define_insn "neg<mode>2"
2224 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2225 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2228 [(set_attr "type" "add")])
2230 (define_insn_and_split "*neg<mode>2_dot"
2231 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2232 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2234 (clobber (match_scratch:GPR 0 "=r,r"))]
2235 "<MODE>mode == Pmode"
2239 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2241 (neg:GPR (match_dup 1)))
2243 (compare:CC (match_dup 0)
2246 [(set_attr "type" "add")
2247 (set_attr "dot" "yes")
2248 (set_attr "length" "4,8")])
2250 (define_insn_and_split "*neg<mode>2_dot2"
2251 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2252 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2254 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2255 (neg:GPR (match_dup 1)))]
2256 "<MODE>mode == Pmode"
2260 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2262 (neg:GPR (match_dup 1)))
2264 (compare:CC (match_dup 0)
2267 [(set_attr "type" "add")
2268 (set_attr "dot" "yes")
2269 (set_attr "length" "4,8")])
2272 (define_insn "clz<mode>2"
2273 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2274 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2277 [(set_attr "type" "cntlz")])
2279 (define_expand "ctz<mode>2"
2280 [(set (match_operand:GPR 0 "gpc_reg_operand")
2281 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2286 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2290 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2291 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2292 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2296 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2297 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2298 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2299 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2303 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2304 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2305 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2306 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2312 (define_insn "ctz<mode>2_hw"
2313 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2314 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2317 [(set_attr "type" "cntlz")])
2319 (define_expand "ffs<mode>2"
2320 [(set (match_operand:GPR 0 "gpc_reg_operand")
2321 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2324 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2325 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2326 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2327 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2328 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2329 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2330 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2335 (define_expand "popcount<mode>2"
2336 [(set (match_operand:GPR 0 "gpc_reg_operand")
2337 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2338 "TARGET_POPCNTB || TARGET_POPCNTD"
2340 rs6000_emit_popcount (operands[0], operands[1]);
2344 (define_insn "popcntb<mode>2"
2345 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2346 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2350 [(set_attr "type" "popcnt")])
2352 (define_insn "popcntd<mode>2"
2353 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2354 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2357 [(set_attr "type" "popcnt")])
2360 (define_expand "parity<mode>2"
2361 [(set (match_operand:GPR 0 "gpc_reg_operand")
2362 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2365 rs6000_emit_parity (operands[0], operands[1]);
2369 (define_insn "parity<mode>2_cmpb"
2370 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2371 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2372 "TARGET_CMPB && TARGET_POPCNTB"
2374 [(set_attr "type" "popcnt")])
2376 (define_insn "cmpb<mode>3"
2377 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2378 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2379 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2382 [(set_attr "type" "cmp")])
2384 ;; Since the hardware zeros the upper part of the register, save generating the
2385 ;; AND immediate if we are converting to unsigned
2386 (define_insn "*bswap<mode>2_extenddi"
2387 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2389 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2392 [(set_attr "length" "4")
2393 (set_attr "type" "load")])
2395 (define_insn "*bswaphi2_extendsi"
2396 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2398 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2401 [(set_attr "length" "4")
2402 (set_attr "type" "load")])
2404 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2405 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2406 ;; load with byte swap, which can be slower than doing it in the registers. It
2407 ;; also prevents certain failures with the RELOAD register allocator.
2409 (define_expand "bswap<mode>2"
2410 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2411 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2414 rtx dest = operands[0];
2415 rtx src = operands[1];
2417 if (!REG_P (dest) && !REG_P (src))
2418 src = force_reg (<MODE>mode, src);
2421 emit_insn (gen_bswap<mode>2_load (dest, src));
2422 else if (MEM_P (dest))
2423 emit_insn (gen_bswap<mode>2_store (dest, src));
2425 emit_insn (gen_bswap<mode>2_reg (dest, src));
2429 (define_insn "bswap<mode>2_load"
2430 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2431 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2434 [(set_attr "type" "load")])
2436 (define_insn "bswap<mode>2_store"
2437 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2438 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2441 [(set_attr "type" "store")])
2443 (define_insn_and_split "bswaphi2_reg"
2444 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2446 (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2447 (clobber (match_scratch:SI 2 "=&r,X"))]
2452 "reload_completed && int_reg_operand (operands[0], HImode)"
2454 (and:SI (lshiftrt:SI (match_dup 4)
2458 (and:SI (ashift:SI (match_dup 4)
2460 (const_int 65280))) ;; 0xff00
2462 (ior:SI (match_dup 3)
2465 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2466 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2468 [(set_attr "length" "12,4")
2469 (set_attr "type" "*,vecperm")])
2471 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2472 ;; zero_extract insns do not change for -mlittle.
2473 (define_insn_and_split "bswapsi2_reg"
2474 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2476 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2481 "reload_completed && int_reg_operand (operands[0], SImode)"
2482 [(set (match_dup 0) ; DABC
2483 (rotate:SI (match_dup 1)
2485 (set (match_dup 0) ; DCBC
2486 (ior:SI (and:SI (ashift:SI (match_dup 1)
2488 (const_int 16711680))
2489 (and:SI (match_dup 0)
2490 (const_int -16711681))))
2491 (set (match_dup 0) ; DCBA
2492 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2495 (and:SI (match_dup 0)
2496 (const_int -256))))]
2498 [(set_attr "length" "12,4")
2499 (set_attr "type" "*,vecperm")])
2501 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2502 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2505 (define_expand "bswapdi2"
2506 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2508 (match_operand:DI 1 "reg_or_mem_operand")))
2509 (clobber (match_scratch:DI 2))
2510 (clobber (match_scratch:DI 3))])]
2513 rtx dest = operands[0];
2514 rtx src = operands[1];
2516 if (!REG_P (dest) && !REG_P (src))
2517 operands[1] = src = force_reg (DImode, src);
2519 if (TARGET_POWERPC64 && TARGET_LDBRX)
2522 emit_insn (gen_bswapdi2_load (dest, src));
2523 else if (MEM_P (dest))
2524 emit_insn (gen_bswapdi2_store (dest, src));
2525 else if (TARGET_P9_VECTOR)
2526 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2528 emit_insn (gen_bswapdi2_reg (dest, src));
2532 if (!TARGET_POWERPC64)
2534 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2535 that uses 64-bit registers needs the same scratch registers as 64-bit
2537 emit_insn (gen_bswapdi2_32bit (dest, src));
2542 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2543 (define_insn "bswapdi2_load"
2544 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2545 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2546 "TARGET_POWERPC64 && TARGET_LDBRX"
2548 [(set_attr "type" "load")])
2550 (define_insn "bswapdi2_store"
2551 [(set (match_operand:DI 0 "memory_operand" "=Z")
2552 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2553 "TARGET_POWERPC64 && TARGET_LDBRX"
2555 [(set_attr "type" "store")])
2557 (define_insn "bswapdi2_xxbrd"
2558 [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2559 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2562 [(set_attr "type" "vecperm")])
2564 (define_insn "bswapdi2_reg"
2565 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2566 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2567 (clobber (match_scratch:DI 2 "=&r"))
2568 (clobber (match_scratch:DI 3 "=&r"))]
2569 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2571 [(set_attr "length" "36")])
2573 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2574 (define_insn "*bswapdi2_64bit"
2575 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2576 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2577 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2578 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2579 "TARGET_POWERPC64 && !TARGET_LDBRX
2580 && (REG_P (operands[0]) || REG_P (operands[1]))
2581 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2582 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2584 [(set_attr "length" "16,12,36")])
2587 [(set (match_operand:DI 0 "gpc_reg_operand")
2588 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2589 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2590 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2591 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2594 rtx dest = operands[0];
2595 rtx src = operands[1];
2596 rtx op2 = operands[2];
2597 rtx op3 = operands[3];
2598 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2599 BYTES_BIG_ENDIAN ? 4 : 0);
2600 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2601 BYTES_BIG_ENDIAN ? 4 : 0);
2607 addr1 = XEXP (src, 0);
2608 if (GET_CODE (addr1) == PLUS)
2610 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2611 if (TARGET_AVOID_XFORM)
2613 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2617 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2619 else if (TARGET_AVOID_XFORM)
2621 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2626 emit_move_insn (op2, GEN_INT (4));
2627 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2630 word1 = change_address (src, SImode, addr1);
2631 word2 = change_address (src, SImode, addr2);
2633 if (BYTES_BIG_ENDIAN)
2635 emit_insn (gen_bswapsi2 (op3_32, word2));
2636 emit_insn (gen_bswapsi2 (dest_32, word1));
2640 emit_insn (gen_bswapsi2 (op3_32, word1));
2641 emit_insn (gen_bswapsi2 (dest_32, word2));
2644 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2645 emit_insn (gen_iordi3 (dest, dest, op3));
2650 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2651 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2652 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2653 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2654 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2657 rtx dest = operands[0];
2658 rtx src = operands[1];
2659 rtx op2 = operands[2];
2660 rtx op3 = operands[3];
2661 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2662 BYTES_BIG_ENDIAN ? 4 : 0);
2663 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2664 BYTES_BIG_ENDIAN ? 4 : 0);
2670 addr1 = XEXP (dest, 0);
2671 if (GET_CODE (addr1) == PLUS)
2673 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2674 if (TARGET_AVOID_XFORM)
2676 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2680 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2682 else if (TARGET_AVOID_XFORM)
2684 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2689 emit_move_insn (op2, GEN_INT (4));
2690 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2693 word1 = change_address (dest, SImode, addr1);
2694 word2 = change_address (dest, SImode, addr2);
2696 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2698 if (BYTES_BIG_ENDIAN)
2700 emit_insn (gen_bswapsi2 (word1, src_si));
2701 emit_insn (gen_bswapsi2 (word2, op3_si));
2705 emit_insn (gen_bswapsi2 (word2, src_si));
2706 emit_insn (gen_bswapsi2 (word1, op3_si));
2712 [(set (match_operand:DI 0 "gpc_reg_operand")
2713 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2714 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2715 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2716 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2719 rtx dest = operands[0];
2720 rtx src = operands[1];
2721 rtx op2 = operands[2];
2722 rtx op3 = operands[3];
2723 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2724 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2725 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2726 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2727 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2729 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2730 emit_insn (gen_bswapsi2 (dest_si, src_si));
2731 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2732 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2733 emit_insn (gen_iordi3 (dest, dest, op3));
2737 (define_insn "bswapdi2_32bit"
2738 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2739 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2740 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2741 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2743 [(set_attr "length" "16,12,36")])
2746 [(set (match_operand:DI 0 "gpc_reg_operand")
2747 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2748 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2749 "!TARGET_POWERPC64 && reload_completed"
2752 rtx dest = operands[0];
2753 rtx src = operands[1];
2754 rtx op2 = operands[2];
2755 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2756 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2762 addr1 = XEXP (src, 0);
2763 if (GET_CODE (addr1) == PLUS)
2765 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2766 if (TARGET_AVOID_XFORM
2767 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2769 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2773 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2775 else if (TARGET_AVOID_XFORM
2776 || REGNO (addr1) == REGNO (dest2))
2778 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2783 emit_move_insn (op2, GEN_INT (4));
2784 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2787 word1 = change_address (src, SImode, addr1);
2788 word2 = change_address (src, SImode, addr2);
2790 emit_insn (gen_bswapsi2 (dest2, word1));
2791 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2792 thus allowing us to omit an early clobber on the output. */
2793 emit_insn (gen_bswapsi2 (dest1, word2));
2798 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2799 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2800 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2801 "!TARGET_POWERPC64 && reload_completed"
2804 rtx dest = operands[0];
2805 rtx src = operands[1];
2806 rtx op2 = operands[2];
2807 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2808 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2814 addr1 = XEXP (dest, 0);
2815 if (GET_CODE (addr1) == PLUS)
2817 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2818 if (TARGET_AVOID_XFORM)
2820 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2824 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2826 else if (TARGET_AVOID_XFORM)
2828 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2833 emit_move_insn (op2, GEN_INT (4));
2834 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2837 word1 = change_address (dest, SImode, addr1);
2838 word2 = change_address (dest, SImode, addr2);
2840 emit_insn (gen_bswapsi2 (word2, src1));
2841 emit_insn (gen_bswapsi2 (word1, src2));
2846 [(set (match_operand:DI 0 "gpc_reg_operand")
2847 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2848 (clobber (match_operand:SI 2 ""))]
2849 "!TARGET_POWERPC64 && reload_completed"
2852 rtx dest = operands[0];
2853 rtx src = operands[1];
2854 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2855 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2856 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2857 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2859 emit_insn (gen_bswapsi2 (dest1, src2));
2860 emit_insn (gen_bswapsi2 (dest2, src1));
2865 (define_insn "mul<mode>3"
2866 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2867 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2868 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2873 [(set_attr "type" "mul")
2875 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2877 (match_operand:GPR 2 "short_cint_operand")
2878 (const_string "16")]
2879 (const_string "<bits>")))])
2881 (define_insn_and_split "*mul<mode>3_dot"
2882 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2883 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2884 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2886 (clobber (match_scratch:GPR 0 "=r,r"))]
2887 "<MODE>mode == Pmode"
2891 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2893 (mult:GPR (match_dup 1)
2896 (compare:CC (match_dup 0)
2899 [(set_attr "type" "mul")
2900 (set_attr "size" "<bits>")
2901 (set_attr "dot" "yes")
2902 (set_attr "length" "4,8")])
2904 (define_insn_and_split "*mul<mode>3_dot2"
2905 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2906 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2907 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2909 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2910 (mult:GPR (match_dup 1)
2912 "<MODE>mode == Pmode"
2916 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2918 (mult:GPR (match_dup 1)
2921 (compare:CC (match_dup 0)
2924 [(set_attr "type" "mul")
2925 (set_attr "size" "<bits>")
2926 (set_attr "dot" "yes")
2927 (set_attr "length" "4,8")])
2930 (define_expand "<su>mul<mode>3_highpart"
2931 [(set (match_operand:GPR 0 "gpc_reg_operand")
2933 (mult:<DMODE> (any_extend:<DMODE>
2934 (match_operand:GPR 1 "gpc_reg_operand"))
2936 (match_operand:GPR 2 "gpc_reg_operand")))
2940 if (<MODE>mode == SImode && TARGET_POWERPC64)
2942 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2947 if (!WORDS_BIG_ENDIAN)
2949 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2955 (define_insn "*<su>mul<mode>3_highpart"
2956 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2958 (mult:<DMODE> (any_extend:<DMODE>
2959 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2961 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2963 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2964 "mulh<wd><u> %0,%1,%2"
2965 [(set_attr "type" "mul")
2966 (set_attr "size" "<bits>")])
2968 (define_insn "<su>mulsi3_highpart_le"
2969 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2971 (mult:DI (any_extend:DI
2972 (match_operand:SI 1 "gpc_reg_operand" "r"))
2974 (match_operand:SI 2 "gpc_reg_operand" "r")))
2976 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2978 [(set_attr "type" "mul")])
2980 (define_insn "<su>muldi3_highpart_le"
2981 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2983 (mult:TI (any_extend:TI
2984 (match_operand:DI 1 "gpc_reg_operand" "r"))
2986 (match_operand:DI 2 "gpc_reg_operand" "r")))
2988 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2990 [(set_attr "type" "mul")
2991 (set_attr "size" "64")])
2993 (define_insn "<su>mulsi3_highpart_64"
2994 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2997 (mult:DI (any_extend:DI
2998 (match_operand:SI 1 "gpc_reg_operand" "r"))
3000 (match_operand:SI 2 "gpc_reg_operand" "r")))
3004 [(set_attr "type" "mul")])
3006 (define_expand "<u>mul<mode><dmode>3"
3007 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3008 (mult:<DMODE> (any_extend:<DMODE>
3009 (match_operand:GPR 1 "gpc_reg_operand"))
3011 (match_operand:GPR 2 "gpc_reg_operand"))))]
3012 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3014 rtx l = gen_reg_rtx (<MODE>mode);
3015 rtx h = gen_reg_rtx (<MODE>mode);
3016 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3017 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3018 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3019 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3023 (define_insn "*maddld4"
3024 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3025 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3026 (match_operand:DI 2 "gpc_reg_operand" "r"))
3027 (match_operand:DI 3 "gpc_reg_operand" "r")))]
3029 "maddld %0,%1,%2,%3"
3030 [(set_attr "type" "mul")])
3032 (define_insn "udiv<mode>3"
3033 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3034 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3035 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3038 [(set_attr "type" "div")
3039 (set_attr "size" "<bits>")])
3042 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3043 ;; modulus. If it isn't a power of two, force operands into register and do
3045 (define_expand "div<mode>3"
3046 [(set (match_operand:GPR 0 "gpc_reg_operand")
3047 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3048 (match_operand:GPR 2 "reg_or_cint_operand")))]
3051 if (CONST_INT_P (operands[2])
3052 && INTVAL (operands[2]) > 0
3053 && exact_log2 (INTVAL (operands[2])) >= 0)
3055 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3059 operands[2] = force_reg (<MODE>mode, operands[2]);
3062 (define_insn "*div<mode>3"
3063 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3064 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3065 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3068 [(set_attr "type" "div")
3069 (set_attr "size" "<bits>")])
3071 (define_insn "div<mode>3_sra"
3072 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3073 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3074 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3075 (clobber (reg:GPR CA_REGNO))]
3077 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3078 [(set_attr "type" "two")
3079 (set_attr "length" "8")])
3081 (define_insn_and_split "*div<mode>3_sra_dot"
3082 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3083 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3084 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3086 (clobber (match_scratch:GPR 0 "=r,r"))
3087 (clobber (reg:GPR CA_REGNO))]
3088 "<MODE>mode == Pmode"
3090 sra<wd>i %0,%1,%p2\;addze. %0,%0
3092 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3093 [(parallel [(set (match_dup 0)
3094 (div:GPR (match_dup 1)
3096 (clobber (reg:GPR CA_REGNO))])
3098 (compare:CC (match_dup 0)
3101 [(set_attr "type" "two")
3102 (set_attr "length" "8,12")
3103 (set_attr "cell_micro" "not")])
3105 (define_insn_and_split "*div<mode>3_sra_dot2"
3106 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3107 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3108 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3110 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3111 (div:GPR (match_dup 1)
3113 (clobber (reg:GPR CA_REGNO))]
3114 "<MODE>mode == Pmode"
3116 sra<wd>i %0,%1,%p2\;addze. %0,%0
3118 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3119 [(parallel [(set (match_dup 0)
3120 (div:GPR (match_dup 1)
3122 (clobber (reg:GPR CA_REGNO))])
3124 (compare:CC (match_dup 0)
3127 [(set_attr "type" "two")
3128 (set_attr "length" "8,12")
3129 (set_attr "cell_micro" "not")])
3131 (define_expand "mod<mode>3"
3132 [(set (match_operand:GPR 0 "gpc_reg_operand")
3133 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3134 (match_operand:GPR 2 "reg_or_cint_operand")))]
3141 if (GET_CODE (operands[2]) != CONST_INT
3142 || INTVAL (operands[2]) <= 0
3143 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3148 operands[2] = force_reg (<MODE>mode, operands[2]);
3152 temp1 = gen_reg_rtx (<MODE>mode);
3153 temp2 = gen_reg_rtx (<MODE>mode);
3155 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3156 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3157 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3162 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3163 ;; mod, prefer putting the result of mod into a different register
3164 (define_insn "*mod<mode>3"
3165 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3166 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3167 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3170 [(set_attr "type" "div")
3171 (set_attr "size" "<bits>")])
3174 (define_insn "umod<mode>3"
3175 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3176 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3177 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3180 [(set_attr "type" "div")
3181 (set_attr "size" "<bits>")])
3183 ;; On machines with modulo support, do a combined div/mod the old fashioned
3184 ;; method, since the multiply/subtract is faster than doing the mod instruction
3188 [(set (match_operand:GPR 0 "gpc_reg_operand")
3189 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3190 (match_operand:GPR 2 "gpc_reg_operand")))
3191 (set (match_operand:GPR 3 "gpc_reg_operand")
3192 (mod:GPR (match_dup 1)
3195 && ! reg_mentioned_p (operands[0], operands[1])
3196 && ! reg_mentioned_p (operands[0], operands[2])
3197 && ! reg_mentioned_p (operands[3], operands[1])
3198 && ! reg_mentioned_p (operands[3], operands[2])"
3200 (div:GPR (match_dup 1)
3203 (mult:GPR (match_dup 0)
3206 (minus:GPR (match_dup 1)
3210 [(set (match_operand:GPR 0 "gpc_reg_operand")
3211 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3212 (match_operand:GPR 2 "gpc_reg_operand")))
3213 (set (match_operand:GPR 3 "gpc_reg_operand")
3214 (umod:GPR (match_dup 1)
3217 && ! reg_mentioned_p (operands[0], operands[1])
3218 && ! reg_mentioned_p (operands[0], operands[2])
3219 && ! reg_mentioned_p (operands[3], operands[1])
3220 && ! reg_mentioned_p (operands[3], operands[2])"
3222 (udiv:GPR (match_dup 1)
3225 (mult:GPR (match_dup 0)
3228 (minus:GPR (match_dup 1)
3232 ;; Logical instructions
3233 ;; The logical instructions are mostly combined by using match_operator,
3234 ;; but the plain AND insns are somewhat different because there is no
3235 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3236 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3238 (define_expand "and<mode>3"
3239 [(set (match_operand:SDI 0 "gpc_reg_operand")
3240 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3241 (match_operand:SDI 2 "reg_or_cint_operand")))]
3244 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3246 rs6000_split_logical (operands, AND, false, false, false);
3250 if (CONST_INT_P (operands[2]))
3252 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3254 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3258 if (logical_const_operand (operands[2], <MODE>mode))
3260 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3264 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3266 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3270 operands[2] = force_reg (<MODE>mode, operands[2]);
3275 (define_insn "and<mode>3_imm"
3276 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3277 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3278 (match_operand:GPR 2 "logical_const_operand" "n")))
3279 (clobber (match_scratch:CC 3 "=x"))]
3280 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3281 "andi%e2. %0,%1,%u2"
3282 [(set_attr "type" "logical")
3283 (set_attr "dot" "yes")])
3285 (define_insn_and_split "*and<mode>3_imm_dot"
3286 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3287 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3288 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3290 (clobber (match_scratch:GPR 0 "=r,r"))
3291 (clobber (match_scratch:CC 4 "=X,x"))]
3292 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3293 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3297 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3298 [(parallel [(set (match_dup 0)
3299 (and:GPR (match_dup 1)
3301 (clobber (match_dup 4))])
3303 (compare:CC (match_dup 0)
3306 [(set_attr "type" "logical")
3307 (set_attr "dot" "yes")
3308 (set_attr "length" "4,8")])
3310 (define_insn_and_split "*and<mode>3_imm_dot2"
3311 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3312 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3313 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3315 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3316 (and:GPR (match_dup 1)
3318 (clobber (match_scratch:CC 4 "=X,x"))]
3319 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3320 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3324 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3325 [(parallel [(set (match_dup 0)
3326 (and:GPR (match_dup 1)
3328 (clobber (match_dup 4))])
3330 (compare:CC (match_dup 0)
3333 [(set_attr "type" "logical")
3334 (set_attr "dot" "yes")
3335 (set_attr "length" "4,8")])
3337 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3338 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3339 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3340 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3342 (clobber (match_scratch:GPR 0 "=r,r"))]
3343 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3344 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3348 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3350 (and:GPR (match_dup 1)
3353 (compare:CC (match_dup 0)
3356 [(set_attr "type" "logical")
3357 (set_attr "dot" "yes")
3358 (set_attr "length" "4,8")])
3360 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3361 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3362 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3363 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3365 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3366 (and:GPR (match_dup 1)
3368 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3369 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3373 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3375 (and:GPR (match_dup 1)
3378 (compare:CC (match_dup 0)
3381 [(set_attr "type" "logical")
3382 (set_attr "dot" "yes")
3383 (set_attr "length" "4,8")])
3385 (define_insn "*and<mode>3_imm_dot_shifted"
3386 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3389 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3390 (match_operand:SI 4 "const_int_operand" "n"))
3391 (match_operand:GPR 2 "const_int_operand" "n"))
3393 (clobber (match_scratch:GPR 0 "=r"))]
3394 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3395 << INTVAL (operands[4])),
3397 && (<MODE>mode == Pmode
3398 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3400 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3401 return "andi%e2. %0,%1,%u2";
3403 [(set_attr "type" "logical")
3404 (set_attr "dot" "yes")])
3407 (define_insn "and<mode>3_mask"
3408 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3409 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3410 (match_operand:GPR 2 "const_int_operand" "n")))]
3411 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3413 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3415 [(set_attr "type" "shift")])
3417 (define_insn_and_split "*and<mode>3_mask_dot"
3418 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3419 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3420 (match_operand:GPR 2 "const_int_operand" "n,n"))
3422 (clobber (match_scratch:GPR 0 "=r,r"))]
3423 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3424 && !logical_const_operand (operands[2], <MODE>mode)
3425 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3427 if (which_alternative == 0)
3428 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3432 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3434 (and:GPR (match_dup 1)
3437 (compare:CC (match_dup 0)
3440 [(set_attr "type" "shift")
3441 (set_attr "dot" "yes")
3442 (set_attr "length" "4,8")])
3444 (define_insn_and_split "*and<mode>3_mask_dot2"
3445 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3446 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3447 (match_operand:GPR 2 "const_int_operand" "n,n"))
3449 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3450 (and:GPR (match_dup 1)
3452 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3453 && !logical_const_operand (operands[2], <MODE>mode)
3454 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3456 if (which_alternative == 0)
3457 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3461 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3463 (and:GPR (match_dup 1)
3466 (compare:CC (match_dup 0)
3469 [(set_attr "type" "shift")
3470 (set_attr "dot" "yes")
3471 (set_attr "length" "4,8")])
3474 (define_insn_and_split "*and<mode>3_2insn"
3475 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3476 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3477 (match_operand:GPR 2 "const_int_operand" "n")))]
3478 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3479 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3480 || logical_const_operand (operands[2], <MODE>mode))"
3485 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3488 [(set_attr "type" "shift")
3489 (set_attr "length" "8")])
3491 (define_insn_and_split "*and<mode>3_2insn_dot"
3492 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3493 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3494 (match_operand:GPR 2 "const_int_operand" "n,n"))
3496 (clobber (match_scratch:GPR 0 "=r,r"))]
3497 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3498 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3499 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3500 || logical_const_operand (operands[2], <MODE>mode))"
3502 "&& reload_completed"
3505 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3508 [(set_attr "type" "shift")
3509 (set_attr "dot" "yes")
3510 (set_attr "length" "8,12")])
3512 (define_insn_and_split "*and<mode>3_2insn_dot2"
3513 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3514 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3515 (match_operand:GPR 2 "const_int_operand" "n,n"))
3517 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3518 (and:GPR (match_dup 1)
3520 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3521 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3522 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3523 || logical_const_operand (operands[2], <MODE>mode))"
3525 "&& reload_completed"
3528 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3531 [(set_attr "type" "shift")
3532 (set_attr "dot" "yes")
3533 (set_attr "length" "8,12")])
3536 (define_expand "<code><mode>3"
3537 [(set (match_operand:SDI 0 "gpc_reg_operand")
3538 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3539 (match_operand:SDI 2 "reg_or_cint_operand")))]
3542 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3544 rs6000_split_logical (operands, <CODE>, false, false, false);
3548 if (non_logical_cint_operand (operands[2], <MODE>mode))
3550 rtx tmp = ((!can_create_pseudo_p ()
3551 || rtx_equal_p (operands[0], operands[1]))
3552 ? operands[0] : gen_reg_rtx (<MODE>mode));
3554 HOST_WIDE_INT value = INTVAL (operands[2]);
3555 HOST_WIDE_INT lo = value & 0xffff;
3556 HOST_WIDE_INT hi = value - lo;
3558 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3559 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3563 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3564 operands[2] = force_reg (<MODE>mode, operands[2]);
3568 [(set (match_operand:GPR 0 "gpc_reg_operand")
3569 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3570 (match_operand:GPR 2 "non_logical_cint_operand")))]
3573 (iorxor:GPR (match_dup 1)
3576 (iorxor:GPR (match_dup 3)
3579 operands[3] = ((!can_create_pseudo_p ()
3580 || rtx_equal_p (operands[0], operands[1]))
3581 ? operands[0] : gen_reg_rtx (<MODE>mode));
3583 HOST_WIDE_INT value = INTVAL (operands[2]);
3584 HOST_WIDE_INT lo = value & 0xffff;
3585 HOST_WIDE_INT hi = value - lo;
3587 operands[4] = GEN_INT (hi);
3588 operands[5] = GEN_INT (lo);
3591 (define_insn "*bool<mode>3_imm"
3592 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3593 (match_operator:GPR 3 "boolean_or_operator"
3594 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3595 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3598 [(set_attr "type" "logical")])
3600 (define_insn "*bool<mode>3"
3601 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3602 (match_operator:GPR 3 "boolean_operator"
3603 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3604 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3607 [(set_attr "type" "logical")])
3609 (define_insn_and_split "*bool<mode>3_dot"
3610 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3611 (compare:CC (match_operator:GPR 3 "boolean_operator"
3612 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3613 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3615 (clobber (match_scratch:GPR 0 "=r,r"))]
3616 "<MODE>mode == Pmode"
3620 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3624 (compare:CC (match_dup 0)
3627 [(set_attr "type" "logical")
3628 (set_attr "dot" "yes")
3629 (set_attr "length" "4,8")])
3631 (define_insn_and_split "*bool<mode>3_dot2"
3632 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3633 (compare:CC (match_operator:GPR 3 "boolean_operator"
3634 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3635 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3637 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3639 "<MODE>mode == Pmode"
3643 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3647 (compare:CC (match_dup 0)
3650 [(set_attr "type" "logical")
3651 (set_attr "dot" "yes")
3652 (set_attr "length" "4,8")])
3655 (define_insn "*boolc<mode>3"
3656 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3657 (match_operator:GPR 3 "boolean_operator"
3658 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3659 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3662 [(set_attr "type" "logical")])
3664 (define_insn_and_split "*boolc<mode>3_dot"
3665 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3666 (compare:CC (match_operator:GPR 3 "boolean_operator"
3667 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3668 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3670 (clobber (match_scratch:GPR 0 "=r,r"))]
3671 "<MODE>mode == Pmode"
3675 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3679 (compare:CC (match_dup 0)
3682 [(set_attr "type" "logical")
3683 (set_attr "dot" "yes")
3684 (set_attr "length" "4,8")])
3686 (define_insn_and_split "*boolc<mode>3_dot2"
3687 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3688 (compare:CC (match_operator:GPR 3 "boolean_operator"
3689 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3690 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3692 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3694 "<MODE>mode == Pmode"
3698 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3702 (compare:CC (match_dup 0)
3705 [(set_attr "type" "logical")
3706 (set_attr "dot" "yes")
3707 (set_attr "length" "4,8")])
3710 (define_insn "*boolcc<mode>3"
3711 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3712 (match_operator:GPR 3 "boolean_operator"
3713 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3714 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3717 [(set_attr "type" "logical")])
3719 (define_insn_and_split "*boolcc<mode>3_dot"
3720 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3721 (compare:CC (match_operator:GPR 3 "boolean_operator"
3722 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3723 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3725 (clobber (match_scratch:GPR 0 "=r,r"))]
3726 "<MODE>mode == Pmode"
3730 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3734 (compare:CC (match_dup 0)
3737 [(set_attr "type" "logical")
3738 (set_attr "dot" "yes")
3739 (set_attr "length" "4,8")])
3741 (define_insn_and_split "*boolcc<mode>3_dot2"
3742 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3743 (compare:CC (match_operator:GPR 3 "boolean_operator"
3744 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3745 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3747 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3749 "<MODE>mode == Pmode"
3753 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3757 (compare:CC (match_dup 0)
3760 [(set_attr "type" "logical")
3761 (set_attr "dot" "yes")
3762 (set_attr "length" "4,8")])
3765 ;; TODO: Should have dots of this as well.
3766 (define_insn "*eqv<mode>3"
3767 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3768 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3769 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3772 [(set_attr "type" "logical")])
3774 ;; Rotate-and-mask and insert.
3776 (define_insn "*rotl<mode>3_mask"
3777 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3778 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3779 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3780 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3781 (match_operand:GPR 3 "const_int_operand" "n")))]
3782 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3784 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3786 [(set_attr "type" "shift")
3787 (set_attr "maybe_var_shift" "yes")])
3789 (define_insn_and_split "*rotl<mode>3_mask_dot"
3790 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3792 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3793 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3794 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3795 (match_operand:GPR 3 "const_int_operand" "n,n"))
3797 (clobber (match_scratch:GPR 0 "=r,r"))]
3798 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3799 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3801 if (which_alternative == 0)
3802 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3806 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3808 (and:GPR (match_dup 4)
3811 (compare:CC (match_dup 0)
3814 [(set_attr "type" "shift")
3815 (set_attr "maybe_var_shift" "yes")
3816 (set_attr "dot" "yes")
3817 (set_attr "length" "4,8")])
3819 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3820 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3822 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3823 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3824 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3825 (match_operand:GPR 3 "const_int_operand" "n,n"))
3827 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3828 (and:GPR (match_dup 4)
3830 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3831 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3833 if (which_alternative == 0)
3834 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3838 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3840 (and:GPR (match_dup 4)
3843 (compare:CC (match_dup 0)
3846 [(set_attr "type" "shift")
3847 (set_attr "maybe_var_shift" "yes")
3848 (set_attr "dot" "yes")
3849 (set_attr "length" "4,8")])
3851 ; Special case for less-than-0. We can do it with just one machine
3852 ; instruction, but the generic optimizers do not realise it is cheap.
3853 (define_insn "*lt0_<mode>di"
3854 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3855 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3859 [(set_attr "type" "shift")])
3861 (define_insn "*lt0_<mode>si"
3862 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3863 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3866 "rlwinm %0,%1,1,31,31"
3867 [(set_attr "type" "shift")])
3871 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3872 ; both are an AND so are the same precedence).
3873 (define_insn "*rotl<mode>3_insert"
3874 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3875 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3876 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3877 (match_operand:SI 2 "const_int_operand" "n")])
3878 (match_operand:GPR 3 "const_int_operand" "n"))
3879 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3880 (match_operand:GPR 6 "const_int_operand" "n"))))]
3881 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3882 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3884 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3886 [(set_attr "type" "insert")])
3887 ; FIXME: this needs an attr "size", so that the scheduler can see the
3888 ; difference between rlwimi and rldimi. We also might want dot forms,
3889 ; but not for rlwimi on POWER4 and similar processors.
3891 (define_insn "*rotl<mode>3_insert_2"
3892 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3893 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3894 (match_operand:GPR 6 "const_int_operand" "n"))
3895 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3896 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3897 (match_operand:SI 2 "const_int_operand" "n")])
3898 (match_operand:GPR 3 "const_int_operand" "n"))))]
3899 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3900 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3902 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3904 [(set_attr "type" "insert")])
3906 ; There are also some forms without one of the ANDs.
3907 (define_insn "*rotl<mode>3_insert_3"
3908 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3909 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3910 (match_operand:GPR 4 "const_int_operand" "n"))
3911 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3912 (match_operand:SI 2 "const_int_operand" "n"))))]
3913 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3915 if (<MODE>mode == SImode)
3916 return "rlwimi %0,%1,%h2,0,31-%h2";
3918 return "rldimi %0,%1,%H2,0";
3920 [(set_attr "type" "insert")])
3922 (define_insn "*rotl<mode>3_insert_4"
3923 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3924 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3925 (match_operand:GPR 4 "const_int_operand" "n"))
3926 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3927 (match_operand:SI 2 "const_int_operand" "n"))))]
3928 "<MODE>mode == SImode &&
3929 GET_MODE_PRECISION (<MODE>mode)
3930 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3932 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3933 - INTVAL (operands[2]));
3934 if (<MODE>mode == SImode)
3935 return "rlwimi %0,%1,%h2,32-%h2,31";
3937 return "rldimi %0,%1,%H2,64-%H2";
3939 [(set_attr "type" "insert")])
3941 (define_insn "*rotlsi3_insert_5"
3942 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3943 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3944 (match_operand:SI 2 "const_int_operand" "n,n"))
3945 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3946 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3947 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3948 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3949 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3953 [(set_attr "type" "insert")])
3955 (define_insn "*rotldi3_insert_6"
3956 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3957 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3958 (match_operand:DI 2 "const_int_operand" "n"))
3959 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3960 (match_operand:DI 4 "const_int_operand" "n"))))]
3961 "exact_log2 (-UINTVAL (operands[2])) > 0
3962 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3964 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3965 return "rldimi %0,%3,0,%5";
3967 [(set_attr "type" "insert")
3968 (set_attr "size" "64")])
3970 (define_insn "*rotldi3_insert_7"
3971 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3972 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3973 (match_operand:DI 4 "const_int_operand" "n"))
3974 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3975 (match_operand:DI 2 "const_int_operand" "n"))))]
3976 "exact_log2 (-UINTVAL (operands[2])) > 0
3977 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3979 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3980 return "rldimi %0,%3,0,%5";
3982 [(set_attr "type" "insert")
3983 (set_attr "size" "64")])
3986 ; This handles the important case of multiple-precision shifts. There is
3987 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3989 [(set (match_operand:GPR 0 "gpc_reg_operand")
3990 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3991 (match_operand:SI 3 "const_int_operand"))
3992 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3993 (match_operand:SI 4 "const_int_operand"))))]
3994 "can_create_pseudo_p ()
3995 && INTVAL (operands[3]) + INTVAL (operands[4])
3996 >= GET_MODE_PRECISION (<MODE>mode)"
3998 (lshiftrt:GPR (match_dup 2)
4001 (ior:GPR (and:GPR (match_dup 5)
4003 (ashift:GPR (match_dup 1)
4006 unsigned HOST_WIDE_INT mask = 1;
4007 mask = (mask << INTVAL (operands[3])) - 1;
4008 operands[5] = gen_reg_rtx (<MODE>mode);
4009 operands[6] = GEN_INT (mask);
4013 [(set (match_operand:GPR 0 "gpc_reg_operand")
4014 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4015 (match_operand:SI 4 "const_int_operand"))
4016 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4017 (match_operand:SI 3 "const_int_operand"))))]
4018 "can_create_pseudo_p ()
4019 && INTVAL (operands[3]) + INTVAL (operands[4])
4020 >= GET_MODE_PRECISION (<MODE>mode)"
4022 (lshiftrt:GPR (match_dup 2)
4025 (ior:GPR (and:GPR (match_dup 5)
4027 (ashift:GPR (match_dup 1)
4030 unsigned HOST_WIDE_INT mask = 1;
4031 mask = (mask << INTVAL (operands[3])) - 1;
4032 operands[5] = gen_reg_rtx (<MODE>mode);
4033 operands[6] = GEN_INT (mask);
4037 ; Another important case is setting some bits to 1; we can do that with
4038 ; an insert instruction, in many cases.
4039 (define_insn_and_split "*ior<mode>_mask"
4040 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4041 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4042 (match_operand:GPR 2 "const_int_operand" "n")))
4043 (clobber (match_scratch:GPR 3 "=r"))]
4044 "!logical_const_operand (operands[2], <MODE>mode)
4045 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4051 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4054 (and:GPR (match_dup 1)
4058 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4059 if (GET_CODE (operands[3]) == SCRATCH)
4060 operands[3] = gen_reg_rtx (<MODE>mode);
4061 operands[4] = GEN_INT (ne);
4062 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4064 [(set_attr "type" "two")
4065 (set_attr "length" "8")])
4068 ;; Now the simple shifts.
4070 (define_insn "rotl<mode>3"
4071 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4072 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4073 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4075 "rotl<wd>%I2 %0,%1,%<hH>2"
4076 [(set_attr "type" "shift")
4077 (set_attr "maybe_var_shift" "yes")])
4079 (define_insn "*rotlsi3_64"
4080 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4082 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4083 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4085 "rotlw%I2 %0,%1,%h2"
4086 [(set_attr "type" "shift")
4087 (set_attr "maybe_var_shift" "yes")])
4089 (define_insn_and_split "*rotl<mode>3_dot"
4090 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4091 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4092 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4094 (clobber (match_scratch:GPR 0 "=r,r"))]
4095 "<MODE>mode == Pmode"
4097 rotl<wd>%I2. %0,%1,%<hH>2
4099 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4101 (rotate:GPR (match_dup 1)
4104 (compare:CC (match_dup 0)
4107 [(set_attr "type" "shift")
4108 (set_attr "maybe_var_shift" "yes")
4109 (set_attr "dot" "yes")
4110 (set_attr "length" "4,8")])
4112 (define_insn_and_split "*rotl<mode>3_dot2"
4113 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4114 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4115 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4117 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4118 (rotate:GPR (match_dup 1)
4120 "<MODE>mode == Pmode"
4122 rotl<wd>%I2. %0,%1,%<hH>2
4124 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4126 (rotate:GPR (match_dup 1)
4129 (compare:CC (match_dup 0)
4132 [(set_attr "type" "shift")
4133 (set_attr "maybe_var_shift" "yes")
4134 (set_attr "dot" "yes")
4135 (set_attr "length" "4,8")])
4138 (define_insn "ashl<mode>3"
4139 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4140 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4141 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4143 "sl<wd>%I2 %0,%1,%<hH>2"
4144 [(set_attr "type" "shift")
4145 (set_attr "maybe_var_shift" "yes")])
4147 (define_insn "*ashlsi3_64"
4148 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4150 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4151 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4154 [(set_attr "type" "shift")
4155 (set_attr "maybe_var_shift" "yes")])
4157 (define_insn_and_split "*ashl<mode>3_dot"
4158 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4159 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4160 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4162 (clobber (match_scratch:GPR 0 "=r,r"))]
4163 "<MODE>mode == Pmode"
4165 sl<wd>%I2. %0,%1,%<hH>2
4167 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4169 (ashift:GPR (match_dup 1)
4172 (compare:CC (match_dup 0)
4175 [(set_attr "type" "shift")
4176 (set_attr "maybe_var_shift" "yes")
4177 (set_attr "dot" "yes")
4178 (set_attr "length" "4,8")])
4180 (define_insn_and_split "*ashl<mode>3_dot2"
4181 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4182 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4183 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4185 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4186 (ashift:GPR (match_dup 1)
4188 "<MODE>mode == Pmode"
4190 sl<wd>%I2. %0,%1,%<hH>2
4192 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4194 (ashift:GPR (match_dup 1)
4197 (compare:CC (match_dup 0)
4200 [(set_attr "type" "shift")
4201 (set_attr "maybe_var_shift" "yes")
4202 (set_attr "dot" "yes")
4203 (set_attr "length" "4,8")])
4205 ;; Pretend we have a memory form of extswsli until register allocation is done
4206 ;; so that we use LWZ to load the value from memory, instead of LWA.
4207 (define_insn_and_split "ashdi3_extswsli"
4208 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4210 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4211 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4216 "&& reload_completed && MEM_P (operands[1])"
4220 (ashift:DI (sign_extend:DI (match_dup 3))
4223 operands[3] = gen_lowpart (SImode, operands[0]);
4225 [(set_attr "type" "shift")
4226 (set_attr "maybe_var_shift" "no")])
4229 (define_insn_and_split "ashdi3_extswsli_dot"
4230 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4233 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4234 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4236 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4243 "&& reload_completed
4244 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4245 || memory_operand (operands[1], SImode))"
4248 rtx dest = operands[0];
4249 rtx src = operands[1];
4250 rtx shift = operands[2];
4251 rtx cr = operands[3];
4258 src2 = gen_lowpart (SImode, dest);
4259 emit_move_insn (src2, src);
4262 if (REGNO (cr) == CR0_REGNO)
4264 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4268 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4269 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4272 [(set_attr "type" "shift")
4273 (set_attr "maybe_var_shift" "no")
4274 (set_attr "dot" "yes")
4275 (set_attr "length" "4,8,8,12")])
4277 (define_insn_and_split "ashdi3_extswsli_dot2"
4278 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4281 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4282 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4284 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4285 (ashift:DI (sign_extend:DI (match_dup 1))
4293 "&& reload_completed
4294 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4295 || memory_operand (operands[1], SImode))"
4298 rtx dest = operands[0];
4299 rtx src = operands[1];
4300 rtx shift = operands[2];
4301 rtx cr = operands[3];
4308 src2 = gen_lowpart (SImode, dest);
4309 emit_move_insn (src2, src);
4312 if (REGNO (cr) == CR0_REGNO)
4314 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4318 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4319 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4322 [(set_attr "type" "shift")
4323 (set_attr "maybe_var_shift" "no")
4324 (set_attr "dot" "yes")
4325 (set_attr "length" "4,8,8,12")])
4327 (define_insn "lshr<mode>3"
4328 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4329 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4330 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4332 "sr<wd>%I2 %0,%1,%<hH>2"
4333 [(set_attr "type" "shift")
4334 (set_attr "maybe_var_shift" "yes")])
4336 (define_insn "*lshrsi3_64"
4337 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4339 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4340 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4343 [(set_attr "type" "shift")
4344 (set_attr "maybe_var_shift" "yes")])
4346 (define_insn_and_split "*lshr<mode>3_dot"
4347 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4348 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4349 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4351 (clobber (match_scratch:GPR 0 "=r,r"))]
4352 "<MODE>mode == Pmode"
4354 sr<wd>%I2. %0,%1,%<hH>2
4356 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4358 (lshiftrt:GPR (match_dup 1)
4361 (compare:CC (match_dup 0)
4364 [(set_attr "type" "shift")
4365 (set_attr "maybe_var_shift" "yes")
4366 (set_attr "dot" "yes")
4367 (set_attr "length" "4,8")])
4369 (define_insn_and_split "*lshr<mode>3_dot2"
4370 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4371 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4372 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4374 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4375 (lshiftrt:GPR (match_dup 1)
4377 "<MODE>mode == Pmode"
4379 sr<wd>%I2. %0,%1,%<hH>2
4381 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4383 (lshiftrt:GPR (match_dup 1)
4386 (compare:CC (match_dup 0)
4389 [(set_attr "type" "shift")
4390 (set_attr "maybe_var_shift" "yes")
4391 (set_attr "dot" "yes")
4392 (set_attr "length" "4,8")])
4395 (define_insn "ashr<mode>3"
4396 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4397 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4398 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4399 (clobber (reg:GPR CA_REGNO))]
4401 "sra<wd>%I2 %0,%1,%<hH>2"
4402 [(set_attr "type" "shift")
4403 (set_attr "maybe_var_shift" "yes")])
4405 (define_insn "*ashrsi3_64"
4406 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4408 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4409 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4410 (clobber (reg:SI CA_REGNO))]
4413 [(set_attr "type" "shift")
4414 (set_attr "maybe_var_shift" "yes")])
4416 (define_insn_and_split "*ashr<mode>3_dot"
4417 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4418 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4419 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4421 (clobber (match_scratch:GPR 0 "=r,r"))
4422 (clobber (reg:GPR CA_REGNO))]
4423 "<MODE>mode == Pmode"
4425 sra<wd>%I2. %0,%1,%<hH>2
4427 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4428 [(parallel [(set (match_dup 0)
4429 (ashiftrt:GPR (match_dup 1)
4431 (clobber (reg:GPR CA_REGNO))])
4433 (compare:CC (match_dup 0)
4436 [(set_attr "type" "shift")
4437 (set_attr "maybe_var_shift" "yes")
4438 (set_attr "dot" "yes")
4439 (set_attr "length" "4,8")])
4441 (define_insn_and_split "*ashr<mode>3_dot2"
4442 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4443 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4444 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4446 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4447 (ashiftrt:GPR (match_dup 1)
4449 (clobber (reg:GPR CA_REGNO))]
4450 "<MODE>mode == Pmode"
4452 sra<wd>%I2. %0,%1,%<hH>2
4454 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4455 [(parallel [(set (match_dup 0)
4456 (ashiftrt:GPR (match_dup 1)
4458 (clobber (reg:GPR CA_REGNO))])
4460 (compare:CC (match_dup 0)
4463 [(set_attr "type" "shift")
4464 (set_attr "maybe_var_shift" "yes")
4465 (set_attr "dot" "yes")
4466 (set_attr "length" "4,8")])
4468 ;; Builtins to replace a division to generate FRE reciprocal estimate
4469 ;; instructions and the necessary fixup instructions
4470 (define_expand "recip<mode>3"
4471 [(match_operand:RECIPF 0 "gpc_reg_operand")
4472 (match_operand:RECIPF 1 "gpc_reg_operand")
4473 (match_operand:RECIPF 2 "gpc_reg_operand")]
4474 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4476 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4480 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4481 ;; hardware division. This is only done before register allocation and with
4482 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4483 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4484 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4486 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4487 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4488 (match_operand 2 "gpc_reg_operand")))]
4489 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4490 && can_create_pseudo_p () && flag_finite_math_only
4491 && !flag_trapping_math && flag_reciprocal_math"
4494 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4498 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4499 ;; appropriate fixup.
4500 (define_expand "rsqrt<mode>2"
4501 [(match_operand:RECIPF 0 "gpc_reg_operand")
4502 (match_operand:RECIPF 1 "gpc_reg_operand")]
4503 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4505 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4509 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4510 ;; modes here, and also add in conditional vsx/power8-vector support to access
4511 ;; values in the traditional Altivec registers if the appropriate
4512 ;; -mupper-regs-{df,sf} option is enabled.
4514 (define_expand "abs<mode>2"
4515 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4516 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4520 (define_insn "*abs<mode>2_fpr"
4521 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4522 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4527 [(set_attr "type" "fpsimple")])
4529 (define_insn "*nabs<mode>2_fpr"
4530 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4533 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4538 [(set_attr "type" "fpsimple")])
4540 (define_expand "neg<mode>2"
4541 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4542 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4546 (define_insn "*neg<mode>2_fpr"
4547 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4548 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4553 [(set_attr "type" "fpsimple")])
4555 (define_expand "add<mode>3"
4556 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4557 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4558 (match_operand:SFDF 2 "gpc_reg_operand")))]
4562 (define_insn "*add<mode>3_fpr"
4563 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4564 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4565 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4568 fadd<Ftrad> %0,%1,%2
4569 xsadd<Fvsx> %x0,%x1,%x2"
4570 [(set_attr "type" "fp")])
4572 (define_expand "sub<mode>3"
4573 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4574 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4575 (match_operand:SFDF 2 "gpc_reg_operand")))]
4579 (define_insn "*sub<mode>3_fpr"
4580 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4581 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4582 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4585 fsub<Ftrad> %0,%1,%2
4586 xssub<Fvsx> %x0,%x1,%x2"
4587 [(set_attr "type" "fp")])
4589 (define_expand "mul<mode>3"
4590 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4591 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4592 (match_operand:SFDF 2 "gpc_reg_operand")))]
4596 (define_insn "*mul<mode>3_fpr"
4597 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4598 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4599 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4602 fmul<Ftrad> %0,%1,%2
4603 xsmul<Fvsx> %x0,%x1,%x2"
4604 [(set_attr "type" "dmul")])
4606 (define_expand "div<mode>3"
4607 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4608 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4609 (match_operand:SFDF 2 "gpc_reg_operand")))]
4612 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4613 && can_create_pseudo_p () && flag_finite_math_only
4614 && !flag_trapping_math && flag_reciprocal_math)
4616 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4621 (define_insn "*div<mode>3_fpr"
4622 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4623 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4624 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4627 fdiv<Ftrad> %0,%1,%2
4628 xsdiv<Fvsx> %x0,%x1,%x2"
4629 [(set_attr "type" "<Fs>div")])
4631 (define_insn "*sqrt<mode>2_internal"
4632 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4633 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4634 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4637 xssqrt<Fvsx> %x0,%x1"
4638 [(set_attr "type" "<Fs>sqrt")])
4640 (define_expand "sqrt<mode>2"
4641 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4642 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4643 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4645 if (<MODE>mode == SFmode
4646 && TARGET_RECIP_PRECISION
4647 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4648 && !optimize_function_for_size_p (cfun)
4649 && flag_finite_math_only && !flag_trapping_math
4650 && flag_unsafe_math_optimizations)
4652 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4657 ;; Floating point reciprocal approximation
4658 (define_insn "fre<Fs>"
4659 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4660 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4666 [(set_attr "type" "fp")])
4668 (define_insn "*rsqrt<mode>2"
4669 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4670 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4672 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4674 frsqrte<Ftrad> %0,%1
4675 xsrsqrte<Fvsx> %x0,%x1"
4676 [(set_attr "type" "fp")])
4678 ;; Floating point comparisons
4679 (define_insn "*cmp<mode>_fpr"
4680 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4681 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4682 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4686 xscmpudp %0,%x1,%x2"
4687 [(set_attr "type" "fpcompare")])
4689 ;; Floating point conversions
4690 (define_expand "extendsfdf2"
4691 [(set (match_operand:DF 0 "gpc_reg_operand")
4692 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4695 if (HONOR_SNANS (SFmode))
4696 operands[1] = force_reg (SFmode, operands[1]);
4699 (define_insn_and_split "*extendsfdf2_fpr"
4700 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4701 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4702 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4708 xscpsgndp %x0,%x1,%x1
4711 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4714 emit_note (NOTE_INSN_DELETED);
4717 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4719 (define_insn "*extendsfdf2_snan"
4720 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4721 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4722 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4726 [(set_attr "type" "fp")])
4728 (define_expand "truncdfsf2"
4729 [(set (match_operand:SF 0 "gpc_reg_operand")
4730 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4734 (define_insn "*truncdfsf2_fpr"
4735 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4736 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4741 [(set_attr "type" "fp")])
4743 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4744 ;; builtins.c and optabs.c that are not correct for IBM long double
4745 ;; when little-endian.
4746 (define_expand "signbit<mode>2"
4748 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4750 (subreg:DI (match_dup 2) 0))
4753 (set (match_operand:SI 0 "gpc_reg_operand")
4756 && (!FLOAT128_IEEE_P (<MODE>mode)
4757 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4759 if (FLOAT128_IEEE_P (<MODE>mode))
4761 rtx dest = operands[0];
4762 rtx src = operands[1];
4763 rtx tmp = gen_reg_rtx (DImode);
4764 rtx dest_di = gen_lowpart (DImode, dest);
4766 if (<MODE>mode == KFmode)
4767 emit_insn (gen_signbitkf2_dm (tmp, src));
4768 else if (<MODE>mode == TFmode)
4769 emit_insn (gen_signbittf2_dm (tmp, src));
4773 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4776 operands[2] = gen_reg_rtx (DFmode);
4777 operands[3] = gen_reg_rtx (DImode);
4778 if (TARGET_POWERPC64)
4780 operands[4] = gen_reg_rtx (DImode);
4781 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4782 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4783 WORDS_BIG_ENDIAN ? 4 : 0);
4787 operands[4] = gen_reg_rtx (SImode);
4788 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4789 WORDS_BIG_ENDIAN ? 0 : 4);
4790 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4794 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4795 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4796 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4797 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4799 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4800 ;; split allows the post reload phases to eliminate the move, and do the shift
4801 ;; directly with the register that contains the signbit.
4802 (define_insn_and_split "signbit<mode>2_dm"
4803 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4804 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4806 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4810 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4814 operands[2] = gen_highpart (DImode, operands[1]);
4816 [(set_attr "type" "mftgpr,*")])
4818 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4819 ;; register and then doing a direct move if the value comes from memory. On
4820 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4821 (define_insn_and_split "*signbit<mode>2_dm_mem"
4822 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4823 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4825 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4831 rtx dest = operands[0];
4832 rtx src = operands[1];
4833 rtx addr = XEXP (src, 0);
4835 if (WORDS_BIG_ENDIAN)
4836 operands[2] = adjust_address (src, DImode, 0);
4838 else if (REG_P (addr) || SUBREG_P (addr))
4839 operands[2] = adjust_address (src, DImode, 8);
4841 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4842 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4843 operands[2] = adjust_address (src, DImode, 8);
4847 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4848 emit_insn (gen_rtx_SET (tmp, addr));
4849 operands[2] = change_address (src, DImode,
4850 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4854 (define_expand "copysign<mode>3"
4856 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4858 (neg:SFDF (abs:SFDF (match_dup 1))))
4859 (set (match_operand:SFDF 0 "gpc_reg_operand")
4860 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4865 && ((TARGET_PPC_GFXOPT
4866 && !HONOR_NANS (<MODE>mode)
4867 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4869 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4871 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4873 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4878 operands[3] = gen_reg_rtx (<MODE>mode);
4879 operands[4] = gen_reg_rtx (<MODE>mode);
4880 operands[5] = CONST0_RTX (<MODE>mode);
4883 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4884 ;; compiler from optimizing -0.0
4885 (define_insn "copysign<mode>3_fcpsgn"
4886 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4887 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4888 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4890 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4893 xscpsgndp %x0,%x2,%x1"
4894 [(set_attr "type" "fpsimple")])
4896 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4897 ;; fsel instruction and some auxiliary computations. Then we just have a
4898 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4900 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4901 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4902 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4903 ;; define_splits to make them if made by combine. On VSX machines we have the
4904 ;; min/max instructions.
4906 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4907 ;; to allow either DF/SF to use only traditional registers.
4909 (define_expand "s<minmax><mode>3"
4910 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4911 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4912 (match_operand:SFDF 2 "gpc_reg_operand")))]
4915 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4919 (define_insn "*s<minmax><mode>3_vsx"
4920 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4921 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4922 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4923 "TARGET_VSX && TARGET_HARD_FLOAT"
4925 return (TARGET_P9_MINMAX
4926 ? "xs<minmax>cdp %x0,%x1,%x2"
4927 : "xs<minmax>dp %x0,%x1,%x2");
4929 [(set_attr "type" "fp")])
4931 ;; The conditional move instructions allow us to perform max and min operations
4932 ;; even when we don't have the appropriate max/min instruction using the FSEL
4935 (define_insn_and_split "*s<minmax><mode>3_fpr"
4936 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4937 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4938 (match_operand:SFDF 2 "gpc_reg_operand")))]
4939 "!TARGET_VSX && TARGET_MINMAX"
4944 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4948 (define_expand "mov<mode>cc"
4949 [(set (match_operand:GPR 0 "gpc_reg_operand")
4950 (if_then_else:GPR (match_operand 1 "comparison_operator")
4951 (match_operand:GPR 2 "gpc_reg_operand")
4952 (match_operand:GPR 3 "gpc_reg_operand")))]
4955 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4961 ;; We use the BASE_REGS for the isel input operands because, if rA is
4962 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4963 ;; because we may switch the operands and rB may end up being rA.
4965 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4966 ;; leave out the mode in operand 4 and use one pattern, but reload can
4967 ;; change the mode underneath our feet and then gets confused trying
4968 ;; to reload the value.
4969 (define_insn "isel_signed_<mode>"
4970 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4972 (match_operator 1 "scc_comparison_operator"
4973 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4975 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4976 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4979 [(set_attr "type" "isel")])
4981 (define_insn "isel_unsigned_<mode>"
4982 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4984 (match_operator 1 "scc_comparison_operator"
4985 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4987 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4988 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4991 [(set_attr "type" "isel")])
4993 ;; These patterns can be useful for combine; they let combine know that
4994 ;; isel can handle reversed comparisons so long as the operands are
4997 (define_insn "*isel_reversed_signed_<mode>"
4998 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5000 (match_operator 1 "scc_rev_comparison_operator"
5001 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5003 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5004 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5007 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5008 return "isel %0,%3,%2,%j1";
5010 [(set_attr "type" "isel")])
5012 (define_insn "*isel_reversed_unsigned_<mode>"
5013 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5015 (match_operator 1 "scc_rev_comparison_operator"
5016 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5018 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5019 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5022 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5023 return "isel %0,%3,%2,%j1";
5025 [(set_attr "type" "isel")])
5027 ;; Floating point conditional move
5028 (define_expand "mov<mode>cc"
5029 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5030 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5031 (match_operand:SFDF 2 "gpc_reg_operand")
5032 (match_operand:SFDF 3 "gpc_reg_operand")))]
5033 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5035 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5041 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5042 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5044 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5045 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5046 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5047 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5048 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5050 [(set_attr "type" "fp")])
5052 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5053 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5055 (match_operator:CCFP 1 "fpmask_comparison_operator"
5056 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5057 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5058 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5059 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5060 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5065 (if_then_else:V2DI (match_dup 1)
5069 (if_then_else:SFDF (ne (match_dup 6)
5074 if (GET_CODE (operands[6]) == SCRATCH)
5075 operands[6] = gen_reg_rtx (V2DImode);
5077 operands[7] = CONSTM1_RTX (V2DImode);
5078 operands[8] = CONST0_RTX (V2DImode);
5080 [(set_attr "length" "8")
5081 (set_attr "type" "vecperm")])
5083 ;; Handle inverting the fpmask comparisons.
5084 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5085 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5087 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5088 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5089 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5090 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5091 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5092 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5097 (if_then_else:V2DI (match_dup 9)
5101 (if_then_else:SFDF (ne (match_dup 6)
5106 rtx op1 = operands[1];
5107 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5109 if (GET_CODE (operands[6]) == SCRATCH)
5110 operands[6] = gen_reg_rtx (V2DImode);
5112 operands[7] = CONSTM1_RTX (V2DImode);
5113 operands[8] = CONST0_RTX (V2DImode);
5115 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5117 [(set_attr "length" "8")
5118 (set_attr "type" "vecperm")])
5120 (define_insn "*fpmask<mode>"
5121 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5123 (match_operator:CCFP 1 "fpmask_comparison_operator"
5124 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5125 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5126 (match_operand:V2DI 4 "all_ones_constant" "")
5127 (match_operand:V2DI 5 "zero_constant" "")))]
5129 "xscmp%V1dp %x0,%x2,%x3"
5130 [(set_attr "type" "fpcompare")])
5132 (define_insn "*xxsel<mode>"
5133 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5134 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5135 (match_operand:V2DI 2 "zero_constant" ""))
5136 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5137 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5139 "xxsel %x0,%x4,%x3,%x1"
5140 [(set_attr "type" "vecmove")])
5143 ;; Conversions to and from floating-point.
5145 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5146 ; don't want to support putting SImode in FPR registers.
5147 (define_insn "lfiwax"
5148 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5149 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5151 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5157 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5159 ; This split must be run before register allocation because it allocates the
5160 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5161 ; it earlier to allow for the combiner to merge insns together where it might
5162 ; not be needed and also in case the insns are deleted as dead code.
5164 (define_insn_and_split "floatsi<mode>2_lfiwax"
5165 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5166 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5167 (clobber (match_scratch:DI 2 "=wi"))]
5168 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5169 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5174 rtx dest = operands[0];
5175 rtx src = operands[1];
5178 if (!MEM_P (src) && TARGET_POWERPC64
5179 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5180 tmp = convert_to_mode (DImode, src, false);
5184 if (GET_CODE (tmp) == SCRATCH)
5185 tmp = gen_reg_rtx (DImode);
5188 src = rs6000_address_for_fpconvert (src);
5189 emit_insn (gen_lfiwax (tmp, src));
5193 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5194 emit_move_insn (stack, src);
5195 emit_insn (gen_lfiwax (tmp, stack));
5198 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5201 [(set_attr "length" "12")
5202 (set_attr "type" "fpload")])
5204 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5205 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5208 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5209 (clobber (match_scratch:DI 2 "=wi"))]
5210 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5215 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5216 if (GET_CODE (operands[2]) == SCRATCH)
5217 operands[2] = gen_reg_rtx (DImode);
5218 if (TARGET_P8_VECTOR)
5219 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5221 emit_insn (gen_lfiwax (operands[2], operands[1]));
5222 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5225 [(set_attr "length" "8")
5226 (set_attr "type" "fpload")])
5228 (define_insn "lfiwzx"
5229 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5230 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5232 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5237 xxextractuw %x0,%x1,4"
5238 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5240 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5241 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5242 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5243 (clobber (match_scratch:DI 2 "=wi"))]
5244 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5249 rtx dest = operands[0];
5250 rtx src = operands[1];
5253 if (!MEM_P (src) && TARGET_POWERPC64
5254 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5255 tmp = convert_to_mode (DImode, src, true);
5259 if (GET_CODE (tmp) == SCRATCH)
5260 tmp = gen_reg_rtx (DImode);
5263 src = rs6000_address_for_fpconvert (src);
5264 emit_insn (gen_lfiwzx (tmp, src));
5268 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5269 emit_move_insn (stack, src);
5270 emit_insn (gen_lfiwzx (tmp, stack));
5273 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5276 [(set_attr "length" "12")
5277 (set_attr "type" "fpload")])
5279 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5280 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5281 (unsigned_float:SFDF
5283 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5284 (clobber (match_scratch:DI 2 "=wi"))]
5285 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5290 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5291 if (GET_CODE (operands[2]) == SCRATCH)
5292 operands[2] = gen_reg_rtx (DImode);
5293 if (TARGET_P8_VECTOR)
5294 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5296 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5297 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5300 [(set_attr "length" "8")
5301 (set_attr "type" "fpload")])
5303 ; For each of these conversions, there is a define_expand, a define_insn
5304 ; with a '#' template, and a define_split (with C code). The idea is
5305 ; to allow constant folding with the template of the define_insn,
5306 ; then to have the insns split later (between sched1 and final).
5308 (define_expand "floatsidf2"
5309 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5310 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5313 (clobber (match_dup 4))
5314 (clobber (match_dup 5))
5315 (clobber (match_dup 6))])]
5318 if (TARGET_LFIWAX && TARGET_FCFID)
5320 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5323 else if (TARGET_FCFID)
5325 rtx dreg = operands[1];
5327 dreg = force_reg (SImode, dreg);
5328 dreg = convert_to_mode (DImode, dreg, false);
5329 emit_insn (gen_floatdidf2 (operands[0], dreg));
5333 if (!REG_P (operands[1]))
5334 operands[1] = force_reg (SImode, operands[1]);
5335 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5336 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5337 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5338 operands[5] = gen_reg_rtx (DFmode);
5339 operands[6] = gen_reg_rtx (SImode);
5342 (define_insn_and_split "*floatsidf2_internal"
5343 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5344 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5345 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5346 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5347 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5348 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5349 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5350 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5355 rtx lowword, highword;
5356 gcc_assert (MEM_P (operands[4]));
5357 highword = adjust_address (operands[4], SImode, 0);
5358 lowword = adjust_address (operands[4], SImode, 4);
5359 if (! WORDS_BIG_ENDIAN)
5360 std::swap (lowword, highword);
5362 emit_insn (gen_xorsi3 (operands[6], operands[1],
5363 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5364 emit_move_insn (lowword, operands[6]);
5365 emit_move_insn (highword, operands[2]);
5366 emit_move_insn (operands[5], operands[4]);
5367 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5370 [(set_attr "length" "24")
5371 (set_attr "type" "fp")])
5373 ;; If we don't have a direct conversion to single precision, don't enable this
5374 ;; conversion for 32-bit without fast math, because we don't have the insn to
5375 ;; generate the fixup swizzle to avoid double rounding problems.
5376 (define_expand "floatunssisf2"
5377 [(set (match_operand:SF 0 "gpc_reg_operand")
5378 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5380 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5382 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5384 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5386 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5391 rtx dreg = operands[1];
5393 dreg = force_reg (SImode, dreg);
5394 dreg = convert_to_mode (DImode, dreg, true);
5395 emit_insn (gen_floatdisf2 (operands[0], dreg));
5400 (define_expand "floatunssidf2"
5401 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5402 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5405 (clobber (match_dup 4))
5406 (clobber (match_dup 5))])]
5409 if (TARGET_LFIWZX && TARGET_FCFID)
5411 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5414 else if (TARGET_FCFID)
5416 rtx dreg = operands[1];
5418 dreg = force_reg (SImode, dreg);
5419 dreg = convert_to_mode (DImode, dreg, true);
5420 emit_insn (gen_floatdidf2 (operands[0], dreg));
5424 if (!REG_P (operands[1]))
5425 operands[1] = force_reg (SImode, operands[1]);
5426 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5427 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5428 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5429 operands[5] = gen_reg_rtx (DFmode);
5432 (define_insn_and_split "*floatunssidf2_internal"
5433 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5434 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5435 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5436 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5437 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5438 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5439 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5440 && !(TARGET_FCFID && TARGET_POWERPC64)"
5445 rtx lowword, highword;
5446 gcc_assert (MEM_P (operands[4]));
5447 highword = adjust_address (operands[4], SImode, 0);
5448 lowword = adjust_address (operands[4], SImode, 4);
5449 if (! WORDS_BIG_ENDIAN)
5450 std::swap (lowword, highword);
5452 emit_move_insn (lowword, operands[1]);
5453 emit_move_insn (highword, operands[2]);
5454 emit_move_insn (operands[5], operands[4]);
5455 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5458 [(set_attr "length" "20")
5459 (set_attr "type" "fp")])
5461 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5462 ;; vector registers. These insns favor doing the sign/zero extension in
5463 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5464 ;; extension and then a direct move.
5466 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5467 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5469 (match_operand:QHI 1 "input_operand")))
5470 (clobber (match_scratch:DI 2))
5471 (clobber (match_scratch:DI 3))
5472 (clobber (match_scratch:<QHI:MODE> 4))])]
5473 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5475 if (MEM_P (operands[1]))
5476 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5479 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5480 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5482 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5483 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5484 (clobber (match_scratch:DI 3 "=X,r,X"))
5485 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5486 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5488 "&& reload_completed"
5491 rtx result = operands[0];
5492 rtx input = operands[1];
5493 rtx di = operands[2];
5497 rtx tmp = operands[3];
5498 if (altivec_register_operand (input, <QHI:MODE>mode))
5499 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5500 else if (GET_CODE (tmp) == SCRATCH)
5501 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5504 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5505 emit_move_insn (di, tmp);
5510 rtx tmp = operands[4];
5511 emit_move_insn (tmp, input);
5512 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5515 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5519 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5520 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5521 (unsigned_float:FP_ISA3
5522 (match_operand:QHI 1 "input_operand")))
5523 (clobber (match_scratch:DI 2))
5524 (clobber (match_scratch:DI 3))])]
5525 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5527 if (MEM_P (operands[1]))
5528 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5531 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5532 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5533 (unsigned_float:FP_ISA3
5534 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5535 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5536 (clobber (match_scratch:DI 3 "=X,r,X"))]
5537 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5539 "&& reload_completed"
5542 rtx result = operands[0];
5543 rtx input = operands[1];
5544 rtx di = operands[2];
5546 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5547 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5550 rtx tmp = operands[3];
5551 if (GET_CODE (tmp) == SCRATCH)
5552 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5555 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5556 emit_move_insn (di, tmp);
5560 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5564 (define_expand "fix_trunc<mode>si2"
5565 [(set (match_operand:SI 0 "gpc_reg_operand")
5566 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5569 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5571 rtx src = force_reg (<MODE>mode, operands[1]);
5574 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5577 rtx tmp = gen_reg_rtx (DImode);
5578 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5579 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5586 ; Like the convert to float patterns, this insn must be split before
5587 ; register allocation so that it can allocate the memory slot if it
5589 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5590 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5591 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5592 (clobber (match_scratch:DI 2 "=d"))]
5593 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5594 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5599 rtx dest = operands[0];
5600 rtx src = operands[1];
5601 rtx tmp = operands[2];
5603 if (GET_CODE (tmp) == SCRATCH)
5604 tmp = gen_reg_rtx (DImode);
5606 emit_insn (gen_fctiwz_<mode> (tmp, src));
5609 dest = rs6000_address_for_fpconvert (dest);
5610 emit_insn (gen_stfiwx (dest, tmp));
5613 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5615 dest = gen_lowpart (DImode, dest);
5616 emit_move_insn (dest, tmp);
5621 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5622 emit_insn (gen_stfiwx (stack, tmp));
5623 emit_move_insn (dest, stack);
5627 [(set_attr "length" "12")
5628 (set_attr "type" "fp")])
5630 (define_insn_and_split "fix_trunc<mode>si2_internal"
5631 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5632 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5633 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5634 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5636 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5642 gcc_assert (MEM_P (operands[3]));
5643 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5645 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5646 emit_move_insn (operands[3], operands[2]);
5647 emit_move_insn (operands[0], lowword);
5650 [(set_attr "length" "16")
5651 (set_attr "type" "fp")])
5653 (define_expand "fix_trunc<mode>di2"
5654 [(set (match_operand:DI 0 "gpc_reg_operand")
5655 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5656 "TARGET_HARD_FLOAT && TARGET_FCFID"
5659 (define_insn "*fix_trunc<mode>di2_fctidz"
5660 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5661 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5662 "TARGET_HARD_FLOAT && TARGET_FCFID"
5666 [(set_attr "type" "fp")])
5668 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5669 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5670 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5671 ;; values can go in VSX registers. Keeping the direct move part through
5672 ;; register allocation prevents the register allocator from doing a direct move
5673 ;; of the SImode value to a GPR, and then a store/load.
5674 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5675 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5676 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5677 (clobber (match_scratch:SI 2 "=X,X,wi"))]
5678 "TARGET_DIRECT_MOVE"
5681 xscvdp<su>xws %x0,%x1
5683 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5685 (any_fix:SI (match_dup 1)))
5689 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5691 [(set_attr "length" "4,4,8")
5692 (set_attr "type" "fp")])
5694 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5695 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5696 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5697 "TARGET_DIRECT_MOVE"
5700 xscvdp<su>xws %x0,%x1"
5701 [(set_attr "type" "fp")])
5703 ;; Keep the convert and store together through register allocation to prevent
5704 ;; the register allocator from getting clever and doing a direct move to a GPR
5705 ;; and then store for reg+offset stores.
5706 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5707 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5708 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5709 (clobber (match_scratch:SI 2 "=wa"))]
5710 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5712 "&& reload_completed"
5714 (any_fix:SI (match_dup 1)))
5718 operands[3] = (<QHSI:MODE>mode == SImode
5720 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5723 (define_expand "fixuns_trunc<mode>si2"
5724 [(set (match_operand:SI 0 "gpc_reg_operand")
5725 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5726 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5728 if (!TARGET_P8_VECTOR)
5730 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5735 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5736 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5737 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5738 (clobber (match_scratch:DI 2 "=d"))]
5739 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5740 && TARGET_STFIWX && can_create_pseudo_p ()
5741 && !TARGET_P8_VECTOR"
5746 rtx dest = operands[0];
5747 rtx src = operands[1];
5748 rtx tmp = operands[2];
5750 if (GET_CODE (tmp) == SCRATCH)
5751 tmp = gen_reg_rtx (DImode);
5753 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5756 dest = rs6000_address_for_fpconvert (dest);
5757 emit_insn (gen_stfiwx (dest, tmp));
5760 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5762 dest = gen_lowpart (DImode, dest);
5763 emit_move_insn (dest, tmp);
5768 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5769 emit_insn (gen_stfiwx (stack, tmp));
5770 emit_move_insn (dest, stack);
5774 [(set_attr "length" "12")
5775 (set_attr "type" "fp")])
5777 (define_insn "fixuns_trunc<mode>di2"
5778 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5779 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5780 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5784 [(set_attr "type" "fp")])
5786 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5787 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5788 ;; because the first makes it clear that operand 0 is not live
5789 ;; before the instruction.
5790 (define_insn "fctiwz_<mode>"
5791 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5793 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5799 [(set_attr "type" "fp")])
5801 (define_insn "fctiwuz_<mode>"
5802 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5803 (unspec:DI [(unsigned_fix:SI
5804 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5806 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5810 [(set_attr "type" "fp")])
5812 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5813 ;; since the friz instruction does not truncate the value if the floating
5814 ;; point value is < LONG_MIN or > LONG_MAX.
5815 (define_insn "*friz"
5816 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5817 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5818 "TARGET_HARD_FLOAT && TARGET_FPRND
5819 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5823 [(set_attr "type" "fp")])
5825 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5826 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5827 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5828 ;; extend it, store it back on the stack from the GPR, load it back into the
5829 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5830 ;; disable using store and load to sign/zero extend the value.
5831 (define_insn_and_split "*round32<mode>2_fprs"
5832 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5834 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5835 (clobber (match_scratch:DI 2 "=d"))
5836 (clobber (match_scratch:DI 3 "=d"))]
5838 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5839 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5844 rtx dest = operands[0];
5845 rtx src = operands[1];
5846 rtx tmp1 = operands[2];
5847 rtx tmp2 = operands[3];
5848 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5850 if (GET_CODE (tmp1) == SCRATCH)
5851 tmp1 = gen_reg_rtx (DImode);
5852 if (GET_CODE (tmp2) == SCRATCH)
5853 tmp2 = gen_reg_rtx (DImode);
5855 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5856 emit_insn (gen_stfiwx (stack, tmp1));
5857 emit_insn (gen_lfiwax (tmp2, stack));
5858 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5861 [(set_attr "type" "fpload")
5862 (set_attr "length" "16")])
5864 (define_insn_and_split "*roundu32<mode>2_fprs"
5865 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5866 (unsigned_float:SFDF
5867 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5868 (clobber (match_scratch:DI 2 "=d"))
5869 (clobber (match_scratch:DI 3 "=d"))]
5871 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5872 && can_create_pseudo_p ()"
5877 rtx dest = operands[0];
5878 rtx src = operands[1];
5879 rtx tmp1 = operands[2];
5880 rtx tmp2 = operands[3];
5881 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5883 if (GET_CODE (tmp1) == SCRATCH)
5884 tmp1 = gen_reg_rtx (DImode);
5885 if (GET_CODE (tmp2) == SCRATCH)
5886 tmp2 = gen_reg_rtx (DImode);
5888 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5889 emit_insn (gen_stfiwx (stack, tmp1));
5890 emit_insn (gen_lfiwzx (tmp2, stack));
5891 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5894 [(set_attr "type" "fpload")
5895 (set_attr "length" "16")])
5897 ;; No VSX equivalent to fctid
5898 (define_insn "lrint<mode>di2"
5899 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5900 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5902 "TARGET_HARD_FLOAT && TARGET_FPRND"
5904 [(set_attr "type" "fp")])
5906 (define_insn "btrunc<mode>2"
5907 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5908 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5910 "TARGET_HARD_FLOAT && TARGET_FPRND"
5914 [(set_attr "type" "fp")])
5916 (define_insn "ceil<mode>2"
5917 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5918 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5920 "TARGET_HARD_FLOAT && TARGET_FPRND"
5924 [(set_attr "type" "fp")])
5926 (define_insn "floor<mode>2"
5927 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5928 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5930 "TARGET_HARD_FLOAT && TARGET_FPRND"
5934 [(set_attr "type" "fp")])
5936 ;; No VSX equivalent to frin
5937 (define_insn "round<mode>2"
5938 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5939 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5941 "TARGET_HARD_FLOAT && TARGET_FPRND"
5943 [(set_attr "type" "fp")])
5945 (define_insn "*xsrdpi<mode>2"
5946 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5947 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5949 "TARGET_HARD_FLOAT && TARGET_VSX"
5951 [(set_attr "type" "fp")])
5953 (define_expand "lround<mode>di2"
5955 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
5957 (set (match_operand:DI 0 "gpc_reg_operand")
5958 (unspec:DI [(match_dup 2)]
5960 "TARGET_HARD_FLOAT && TARGET_VSX"
5962 operands[2] = gen_reg_rtx (<MODE>mode);
5965 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5966 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5967 ; is only generated for Power8 or later.
5968 (define_insn "stfiwx"
5969 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5970 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
5976 [(set_attr "type" "fpstore")])
5978 ;; If we don't have a direct conversion to single precision, don't enable this
5979 ;; conversion for 32-bit without fast math, because we don't have the insn to
5980 ;; generate the fixup swizzle to avoid double rounding problems.
5981 (define_expand "floatsisf2"
5982 [(set (match_operand:SF 0 "gpc_reg_operand")
5983 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5985 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5987 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5989 if (TARGET_FCFIDS && TARGET_LFIWAX)
5991 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5994 else if (TARGET_FCFID && TARGET_LFIWAX)
5996 rtx dfreg = gen_reg_rtx (DFmode);
5997 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5998 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6003 rtx dreg = operands[1];
6005 dreg = force_reg (SImode, dreg);
6006 dreg = convert_to_mode (DImode, dreg, false);
6007 emit_insn (gen_floatdisf2 (operands[0], dreg));
6012 (define_insn "floatdidf2"
6013 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6014 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6015 "TARGET_FCFID && TARGET_HARD_FLOAT"
6019 [(set_attr "type" "fp")])
6021 ; Allow the combiner to merge source memory operands to the conversion so that
6022 ; the optimizer/register allocator doesn't try to load the value too early in a
6023 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6024 ; hit. We will split after reload to avoid the trip through the GPRs
6026 (define_insn_and_split "*floatdidf2_mem"
6027 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6028 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6029 (clobber (match_scratch:DI 2 "=d,wi"))]
6030 "TARGET_HARD_FLOAT && TARGET_FCFID"
6032 "&& reload_completed"
6033 [(set (match_dup 2) (match_dup 1))
6034 (set (match_dup 0) (float:DF (match_dup 2)))]
6036 [(set_attr "length" "8")
6037 (set_attr "type" "fpload")])
6039 (define_expand "floatunsdidf2"
6040 [(set (match_operand:DF 0 "gpc_reg_operand")
6042 (match_operand:DI 1 "gpc_reg_operand")))]
6043 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6046 (define_insn "*floatunsdidf2_fcfidu"
6047 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6048 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6049 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6053 [(set_attr "type" "fp")
6054 (set_attr "length" "4")])
6056 (define_insn_and_split "*floatunsdidf2_mem"
6057 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6058 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6059 (clobber (match_scratch:DI 2 "=d,wi"))]
6060 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6062 "&& reload_completed"
6063 [(set (match_dup 2) (match_dup 1))
6064 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6066 [(set_attr "length" "8")
6067 (set_attr "type" "fpload")])
6069 (define_expand "floatdisf2"
6070 [(set (match_operand:SF 0 "gpc_reg_operand")
6071 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6072 "TARGET_FCFID && TARGET_HARD_FLOAT
6073 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6077 rtx val = operands[1];
6078 if (!flag_unsafe_math_optimizations)
6080 rtx label = gen_label_rtx ();
6081 val = gen_reg_rtx (DImode);
6082 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6085 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6090 (define_insn "floatdisf2_fcfids"
6091 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6092 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6093 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6097 [(set_attr "type" "fp")])
6099 (define_insn_and_split "*floatdisf2_mem"
6100 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6101 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6102 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6103 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6105 "&& reload_completed"
6108 emit_move_insn (operands[2], operands[1]);
6109 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6112 [(set_attr "length" "8")])
6114 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6115 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6116 ;; from double rounding.
6117 ;; Instead of creating a new cpu type for two FP operations, just use fp
6118 (define_insn_and_split "floatdisf2_internal1"
6119 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6120 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6121 (clobber (match_scratch:DF 2 "=d"))]
6122 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6124 "&& reload_completed"
6126 (float:DF (match_dup 1)))
6128 (float_truncate:SF (match_dup 2)))]
6130 [(set_attr "length" "8")
6131 (set_attr "type" "fp")])
6133 ;; Twiddles bits to avoid double rounding.
6134 ;; Bits that might be truncated when converting to DFmode are replaced
6135 ;; by a bit that won't be lost at that stage, but is below the SFmode
6136 ;; rounding position.
6137 (define_expand "floatdisf2_internal2"
6138 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6140 (clobber (reg:DI CA_REGNO))])
6141 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6143 (set (match_dup 3) (plus:DI (match_dup 3)
6145 (set (match_dup 0) (plus:DI (match_dup 0)
6147 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6149 (set (match_dup 0) (ior:DI (match_dup 0)
6151 (set (match_dup 0) (and:DI (match_dup 0)
6153 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6154 (label_ref (match_operand:DI 2 ""))
6156 (set (match_dup 0) (match_dup 1))]
6157 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6159 operands[3] = gen_reg_rtx (DImode);
6160 operands[4] = gen_reg_rtx (CCUNSmode);
6163 (define_expand "floatunsdisf2"
6164 [(set (match_operand:SF 0 "gpc_reg_operand")
6165 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6166 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6169 (define_insn "floatunsdisf2_fcfidus"
6170 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6171 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6172 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6176 [(set_attr "type" "fp")])
6178 (define_insn_and_split "*floatunsdisf2_mem"
6179 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6180 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6181 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6182 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6184 "&& reload_completed"
6187 emit_move_insn (operands[2], operands[1]);
6188 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6191 [(set_attr "length" "8")
6192 (set_attr "type" "fpload")])
6194 ;; Define the TImode operations that can be done in a small number
6195 ;; of instructions. The & constraints are to prevent the register
6196 ;; allocator from allocating registers that overlap with the inputs
6197 ;; (for example, having an input in 7,8 and an output in 6,7). We
6198 ;; also allow for the output being the same as one of the inputs.
6200 (define_expand "addti3"
6201 [(set (match_operand:TI 0 "gpc_reg_operand")
6202 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6203 (match_operand:TI 2 "reg_or_short_operand")))]
6206 rtx lo0 = gen_lowpart (DImode, operands[0]);
6207 rtx lo1 = gen_lowpart (DImode, operands[1]);
6208 rtx lo2 = gen_lowpart (DImode, operands[2]);
6209 rtx hi0 = gen_highpart (DImode, operands[0]);
6210 rtx hi1 = gen_highpart (DImode, operands[1]);
6211 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6213 if (!reg_or_short_operand (lo2, DImode))
6214 lo2 = force_reg (DImode, lo2);
6215 if (!adde_operand (hi2, DImode))
6216 hi2 = force_reg (DImode, hi2);
6218 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6219 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6223 (define_expand "subti3"
6224 [(set (match_operand:TI 0 "gpc_reg_operand")
6225 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6226 (match_operand:TI 2 "gpc_reg_operand")))]
6229 rtx lo0 = gen_lowpart (DImode, operands[0]);
6230 rtx lo1 = gen_lowpart (DImode, operands[1]);
6231 rtx lo2 = gen_lowpart (DImode, operands[2]);
6232 rtx hi0 = gen_highpart (DImode, operands[0]);
6233 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6234 rtx hi2 = gen_highpart (DImode, operands[2]);
6236 if (!reg_or_short_operand (lo1, DImode))
6237 lo1 = force_reg (DImode, lo1);
6238 if (!adde_operand (hi1, DImode))
6239 hi1 = force_reg (DImode, hi1);
6241 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6242 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6246 ;; 128-bit logical operations expanders
6248 (define_expand "and<mode>3"
6249 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6250 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6251 (match_operand:BOOL_128 2 "vlogical_operand")))]
6255 (define_expand "ior<mode>3"
6256 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6257 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6258 (match_operand:BOOL_128 2 "vlogical_operand")))]
6262 (define_expand "xor<mode>3"
6263 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6264 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6265 (match_operand:BOOL_128 2 "vlogical_operand")))]
6269 (define_expand "one_cmpl<mode>2"
6270 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6271 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6275 (define_expand "nor<mode>3"
6276 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6278 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6279 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6283 (define_expand "andc<mode>3"
6284 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6286 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6287 (match_operand:BOOL_128 1 "vlogical_operand")))]
6291 ;; Power8 vector logical instructions.
6292 (define_expand "eqv<mode>3"
6293 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6295 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6296 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6297 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6300 ;; Rewrite nand into canonical form
6301 (define_expand "nand<mode>3"
6302 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6304 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6305 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6306 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6309 ;; The canonical form is to have the negated element first, so we need to
6310 ;; reverse arguments.
6311 (define_expand "orc<mode>3"
6312 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6314 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6315 (match_operand:BOOL_128 1 "vlogical_operand")))]
6316 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6319 ;; 128-bit logical operations insns and split operations
6320 (define_insn_and_split "*and<mode>3_internal"
6321 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6323 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6324 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6327 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6328 return "xxland %x0,%x1,%x2";
6330 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6331 return "vand %0,%1,%2";
6335 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6338 rs6000_split_logical (operands, AND, false, false, false);
6343 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6344 (const_string "veclogical")
6345 (const_string "integer")))
6346 (set (attr "length")
6348 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6351 (match_test "TARGET_POWERPC64")
6353 (const_string "16"))))])
6356 (define_insn_and_split "*bool<mode>3_internal"
6357 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6358 (match_operator:BOOL_128 3 "boolean_or_operator"
6359 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6360 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6363 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6364 return "xxl%q3 %x0,%x1,%x2";
6366 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6367 return "v%q3 %0,%1,%2";
6371 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6374 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6379 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6380 (const_string "veclogical")
6381 (const_string "integer")))
6382 (set (attr "length")
6384 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6387 (match_test "TARGET_POWERPC64")
6389 (const_string "16"))))])
6392 (define_insn_and_split "*boolc<mode>3_internal1"
6393 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6394 (match_operator:BOOL_128 3 "boolean_operator"
6396 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6397 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6398 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6400 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6401 return "xxl%q3 %x0,%x1,%x2";
6403 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6404 return "v%q3 %0,%1,%2";
6408 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6409 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6412 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6417 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6418 (const_string "veclogical")
6419 (const_string "integer")))
6420 (set (attr "length")
6422 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6425 (match_test "TARGET_POWERPC64")
6427 (const_string "16"))))])
6429 (define_insn_and_split "*boolc<mode>3_internal2"
6430 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6431 (match_operator:TI2 3 "boolean_operator"
6433 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6434 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6435 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6437 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6440 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6443 [(set_attr "type" "integer")
6444 (set (attr "length")
6446 (match_test "TARGET_POWERPC64")
6448 (const_string "16")))])
6451 (define_insn_and_split "*boolcc<mode>3_internal1"
6452 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6453 (match_operator:BOOL_128 3 "boolean_operator"
6455 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6457 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6458 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6460 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6461 return "xxl%q3 %x0,%x1,%x2";
6463 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6464 return "v%q3 %0,%1,%2";
6468 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6469 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6472 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6477 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6478 (const_string "veclogical")
6479 (const_string "integer")))
6480 (set (attr "length")
6482 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6485 (match_test "TARGET_POWERPC64")
6487 (const_string "16"))))])
6489 (define_insn_and_split "*boolcc<mode>3_internal2"
6490 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6491 (match_operator:TI2 3 "boolean_operator"
6493 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6495 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6496 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6498 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6501 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6504 [(set_attr "type" "integer")
6505 (set (attr "length")
6507 (match_test "TARGET_POWERPC64")
6509 (const_string "16")))])
6513 (define_insn_and_split "*eqv<mode>3_internal1"
6514 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6517 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6518 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6521 if (vsx_register_operand (operands[0], <MODE>mode))
6522 return "xxleqv %x0,%x1,%x2";
6526 "TARGET_P8_VECTOR && reload_completed
6527 && int_reg_operand (operands[0], <MODE>mode)"
6530 rs6000_split_logical (operands, XOR, true, false, false);
6535 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6536 (const_string "veclogical")
6537 (const_string "integer")))
6538 (set (attr "length")
6540 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6543 (match_test "TARGET_POWERPC64")
6545 (const_string "16"))))])
6547 (define_insn_and_split "*eqv<mode>3_internal2"
6548 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6551 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6552 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6555 "reload_completed && !TARGET_P8_VECTOR"
6558 rs6000_split_logical (operands, XOR, true, false, false);
6561 [(set_attr "type" "integer")
6562 (set (attr "length")
6564 (match_test "TARGET_POWERPC64")
6566 (const_string "16")))])
6568 ;; 128-bit one's complement
6569 (define_insn_and_split "*one_cmpl<mode>3_internal"
6570 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6572 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6575 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6576 return "xxlnor %x0,%x1,%x1";
6578 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6579 return "vnor %0,%1,%1";
6583 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6586 rs6000_split_logical (operands, NOT, false, false, false);
6591 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6592 (const_string "veclogical")
6593 (const_string "integer")))
6594 (set (attr "length")
6596 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6599 (match_test "TARGET_POWERPC64")
6601 (const_string "16"))))])
6604 ;; Now define ways of moving data around.
6606 ;; Set up a register with a value from the GOT table
6608 (define_expand "movsi_got"
6609 [(set (match_operand:SI 0 "gpc_reg_operand")
6610 (unspec:SI [(match_operand:SI 1 "got_operand")
6611 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6612 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6614 if (GET_CODE (operands[1]) == CONST)
6616 rtx offset = const0_rtx;
6617 HOST_WIDE_INT value;
6619 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6620 value = INTVAL (offset);
6623 rtx tmp = (!can_create_pseudo_p ()
6625 : gen_reg_rtx (Pmode));
6626 emit_insn (gen_movsi_got (tmp, operands[1]));
6627 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6632 operands[2] = rs6000_got_register (operands[1]);
6635 (define_insn "*movsi_got_internal"
6636 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6637 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6638 (match_operand:SI 2 "gpc_reg_operand" "b")]
6640 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6641 "lwz %0,%a1@got(%2)"
6642 [(set_attr "type" "load")])
6644 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6645 ;; didn't get allocated to a hard register.
6647 [(set (match_operand:SI 0 "gpc_reg_operand")
6648 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6649 (match_operand:SI 2 "memory_operand")]
6651 "DEFAULT_ABI == ABI_V4
6653 && reload_completed"
6654 [(set (match_dup 0) (match_dup 2))
6655 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6659 ;; For SI, we special-case integers that can't be loaded in one insn. We
6660 ;; do the load 16-bits at a time. We could do this by loading from memory,
6661 ;; and this is even supposed to be faster, but it is simpler not to get
6662 ;; integers in the TOC.
6663 (define_insn "movsi_low"
6664 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6665 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6666 (match_operand 2 "" ""))))]
6667 "TARGET_MACHO && ! TARGET_64BIT"
6668 "lwz %0,lo16(%2)(%1)"
6669 [(set_attr "type" "load")
6670 (set_attr "length" "4")])
6672 ;; MR LA LWZ LFIWZX LXSIWZX
6673 ;; STW STFIWX STXSIWX LI LIS
6674 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6675 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6676 ;; MF%1 MT%0 MT%0 NOP
6677 (define_insn "*movsi_internal1"
6678 [(set (match_operand:SI 0 "nonimmediate_operand"
6679 "=r, r, r, ?*wI, ?*wH,
6681 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6682 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6685 (match_operand:SI 1 "input_operand"
6692 "gpc_reg_operand (operands[0], SImode)
6693 || gpc_reg_operand (operands[1], SImode)"
6720 "*, *, load, fpload, fpload,
6721 store, fpstore, fpstore, *, *,
6722 *, veclogical, vecsimple, vecsimple, vecsimple,
6723 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6733 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6734 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6736 ;; Because SF values are actually stored as DF values within the vector
6737 ;; registers, we need to convert the value to the vector SF format when
6738 ;; we need to use the bits in a union or similar cases. We only need
6739 ;; to do this transformation when the value is a vector register. Loads,
6740 ;; stores, and transfers within GPRs are assumed to be safe.
6742 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6743 ;; no alternatives, because the call is created as part of secondary_reload,
6744 ;; and operand #2's register class is used to allocate the temporary register.
6745 ;; This function is called before reload, and it creates the temporary as
6748 ;; MR LWZ LFIWZX LXSIWZX STW
6749 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6752 (define_insn_and_split "movsi_from_sf"
6753 [(set (match_operand:SI 0 "nonimmediate_operand"
6754 "=r, r, ?*wI, ?*wH, m,
6755 m, wY, Z, r, ?*wIwH,
6758 (unspec:SI [(match_operand:SF 1 "input_operand"
6760 f, wb, wu, wIwH, wIwH,
6764 (clobber (match_scratch:V4SF 2
6769 "TARGET_NO_SF_SUBREG
6770 && (register_operand (operands[0], SImode)
6771 || register_operand (operands[1], SFmode))"
6784 "&& reload_completed
6785 && int_reg_operand (operands[0], SImode)
6786 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6789 rtx op0 = operands[0];
6790 rtx op1 = operands[1];
6791 rtx op2 = operands[2];
6792 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6793 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6795 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6796 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6800 "*, load, fpload, fpload, store,
6801 fpstore, fpstore, fpstore, mftgpr, fp,
6809 ;; movsi_from_sf with zero extension
6811 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6814 (define_insn_and_split "*movdi_from_sf_zero_ext"
6815 [(set (match_operand:DI 0 "gpc_reg_operand"
6816 "=r, r, ?*wI, ?*wH, r,
6820 (unspec:SI [(match_operand:SF 1 "input_operand"
6823 UNSPEC_SI_FROM_SF)))
6825 (clobber (match_scratch:V4SF 2
6829 "TARGET_DIRECT_MOVE_64BIT
6830 && (register_operand (operands[0], DImode)
6831 || register_operand (operands[1], SImode))"
6840 "&& reload_completed
6841 && register_operand (operands[0], DImode)
6842 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6845 rtx op0 = operands[0];
6846 rtx op1 = operands[1];
6847 rtx op2 = operands[2];
6848 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6850 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6851 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6855 "*, load, fpload, fpload, two,
6862 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6863 ;; moving it to SImode. We can do a SFmode store without having to do the
6864 ;; conversion explicitly. If we are doing a register->register conversion, use
6865 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6866 ;; input will not fit in a SFmode, and the later assumes the value has already
6868 (define_insn "*movsi_from_df"
6869 [(set (match_operand:SI 0 "nonimmediate_operand" "=wa,m,wY,Z")
6870 (unspec:SI [(float_truncate:SF
6871 (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6872 UNSPEC_SI_FROM_SF))]
6874 "TARGET_NO_SF_SUBREG"
6880 [(set_attr "type" "fp,fpstore,fpstore,fpstore")])
6882 ;; Split a load of a large constant into the appropriate two-insn
6886 [(set (match_operand:SI 0 "gpc_reg_operand")
6887 (match_operand:SI 1 "const_int_operand"))]
6888 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6889 && (INTVAL (operands[1]) & 0xffff) != 0"
6893 (ior:SI (match_dup 0)
6896 if (rs6000_emit_set_const (operands[0], operands[1]))
6902 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6904 [(set (match_operand:DI 0 "altivec_register_operand")
6905 (match_operand:DI 1 "xxspltib_constant_split"))]
6906 "TARGET_P9_VECTOR && reload_completed"
6909 rtx op0 = operands[0];
6910 rtx op1 = operands[1];
6911 int r = REGNO (op0);
6912 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6914 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6915 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6919 (define_insn "*mov<mode>_internal2"
6920 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6921 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6923 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6929 [(set_attr "type" "cmp,logical,cmp")
6930 (set_attr "dot" "yes")
6931 (set_attr "length" "4,4,8")])
6934 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
6935 (compare:CC (match_operand:P 1 "gpc_reg_operand")
6937 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
6939 [(set (match_dup 0) (match_dup 1))
6941 (compare:CC (match_dup 0)
6945 (define_expand "mov<mode>"
6946 [(set (match_operand:INT 0 "general_operand")
6947 (match_operand:INT 1 "any_operand"))]
6950 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
6954 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
6955 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
6956 ;; MTVSRWZ MF%1 MT%1 NOP
6957 (define_insn "*mov<mode>_internal"
6958 [(set (match_operand:QHI 0 "nonimmediate_operand"
6959 "=r, r, ?*wJwK, m, Z, r,
6960 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
6961 ?*wJwK, r, *c*l, *h")
6963 (match_operand:QHI 1 "input_operand"
6964 "r, m, Z, r, wJwK, i,
6965 wJwK, O, wM, wB, wS, ?*wJwK,
6968 "gpc_reg_operand (operands[0], <MODE>mode)
6969 || gpc_reg_operand (operands[1], <MODE>mode)"
6988 "*, load, fpload, store, fpstore, *,
6989 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
6990 mffgpr, mfjmpr, mtjmpr, *")
6998 ;; Here is how to move condition codes around. When we store CC data in
6999 ;; an integer register or memory, we store just the high-order 4 bits.
7000 ;; This lets us not shift in the most common case of CR0.
7001 (define_expand "movcc"
7002 [(set (match_operand:CC 0 "nonimmediate_operand")
7003 (match_operand:CC 1 "nonimmediate_operand"))]
7007 (define_insn "*movcc_internal1"
7008 [(set (match_operand:CC 0 "nonimmediate_operand"
7009 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7010 (match_operand:CC 1 "general_operand"
7011 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7012 "register_operand (operands[0], CCmode)
7013 || register_operand (operands[1], CCmode)"
7017 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7020 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7028 (cond [(eq_attr "alternative" "0,3")
7029 (const_string "cr_logical")
7030 (eq_attr "alternative" "1,2")
7031 (const_string "mtcr")
7032 (eq_attr "alternative" "6,7")
7033 (const_string "integer")
7034 (eq_attr "alternative" "8")
7035 (const_string "mfjmpr")
7036 (eq_attr "alternative" "9")
7037 (const_string "mtjmpr")
7038 (eq_attr "alternative" "10")
7039 (const_string "load")
7040 (eq_attr "alternative" "11")
7041 (const_string "store")
7042 (match_test "TARGET_MFCRF")
7043 (const_string "mfcrf")
7045 (const_string "mfcr")))
7046 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7048 ;; For floating-point, we normally deal with the floating-point registers
7049 ;; unless -msoft-float is used. The sole exception is that parameter passing
7050 ;; can produce floating-point values in fixed-point registers. Unless the
7051 ;; value is a simple constant or already in memory, we deal with this by
7052 ;; allocating memory and copying the value explicitly via that memory location.
7054 ;; Move 32-bit binary/decimal floating point
7055 (define_expand "mov<mode>"
7056 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7057 (match_operand:FMOVE32 1 "any_operand"))]
7060 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7065 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7066 (match_operand:FMOVE32 1 "const_double_operand"))]
7068 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7069 || (GET_CODE (operands[0]) == SUBREG
7070 && GET_CODE (SUBREG_REG (operands[0])) == REG
7071 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7072 [(set (match_dup 2) (match_dup 3))]
7076 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7078 if (! TARGET_POWERPC64)
7079 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7081 operands[2] = gen_lowpart (SImode, operands[0]);
7083 operands[3] = gen_int_mode (l, SImode);
7086 ;; Originally, we tried to keep movsf and movsd common, but the differences
7087 ;; addressing was making it rather difficult to hide with mode attributes. In
7088 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7089 ;; before the VSX stores meant that the register allocator would tend to do a
7090 ;; direct move to the GPR (which involves conversion from scalar to
7091 ;; vector/memory formats) to save values in the traditional Altivec registers,
7092 ;; while SDmode had problems on power6 if the GPR store was not first due to
7093 ;; the power6 not having an integer store operation.
7095 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7096 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7097 ;; MR MT<x> MF<x> NOP
7099 (define_insn "movsf_hardfloat"
7100 [(set (match_operand:SF 0 "nonimmediate_operand"
7101 "=!r, f, wb, wu, m, wY,
7102 Z, m, ww, !r, f, ww,
7104 (match_operand:SF 1 "input_operand"
7105 "m, m, wY, Z, f, wb,
7108 "(register_operand (operands[0], SFmode)
7109 || register_operand (operands[1], SFmode))
7110 && TARGET_HARD_FLOAT
7111 && (TARGET_ALLOW_SF_SUBREG
7112 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7125 xscpsgndp %x0,%x1,%x1
7131 "load, fpload, fpload, fpload, fpstore, fpstore,
7132 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7133 *, mtjmpr, mfjmpr, *")])
7135 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7136 ;; FMR MR MT%0 MF%1 NOP
7137 (define_insn "movsd_hardfloat"
7138 [(set (match_operand:SD 0 "nonimmediate_operand"
7139 "=!r, wz, m, Z, ?wh, ?r,
7140 f, !r, *c*l, !r, *h")
7141 (match_operand:SD 1 "input_operand"
7142 "m, Z, r, wx, r, wh,
7144 "(register_operand (operands[0], SDmode)
7145 || register_operand (operands[1], SDmode))
7146 && TARGET_HARD_FLOAT"
7160 "load, fpload, store, fpstore, mffgpr, mftgpr,
7161 fpsimple, *, mtjmpr, mfjmpr, *")])
7163 ;; MR MT%0 MF%0 LWZ STW LI
7164 ;; LIS G-const. F/n-const NOP
7165 (define_insn "*mov<mode>_softfloat"
7166 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7167 "=r, cl, r, r, m, r,
7170 (match_operand:FMOVE32 1 "input_operand"
7174 "(gpc_reg_operand (operands[0], <MODE>mode)
7175 || gpc_reg_operand (operands[1], <MODE>mode))
7176 && TARGET_SOFT_FLOAT"
7189 "*, mtjmpr, mfjmpr, load, store, *,
7196 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7197 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7199 ;; Because SF values are actually stored as DF values within the vector
7200 ;; registers, we need to convert the value to the vector SF format when
7201 ;; we need to use the bits in a union or similar cases. We only need
7202 ;; to do this transformation when the value is a vector register. Loads,
7203 ;; stores, and transfers within GPRs are assumed to be safe.
7205 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7206 ;; no alternatives, because the call is created as part of secondary_reload,
7207 ;; and operand #2's register class is used to allocate the temporary register.
7208 ;; This function is called before reload, and it creates the temporary as
7211 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7212 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7213 (define_insn_and_split "movsf_from_si"
7214 [(set (match_operand:SF 0 "nonimmediate_operand"
7215 "=!r, f, wb, wu, m, Z,
7218 (unspec:SF [(match_operand:SI 1 "input_operand"
7223 (clobber (match_scratch:DI 2
7227 "TARGET_NO_SF_SUBREG
7228 && (register_operand (operands[0], SFmode)
7229 || register_operand (operands[1], SImode))"
7242 "&& reload_completed
7243 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7244 && int_reg_operand_not_pseudo (operands[1], SImode)"
7247 rtx op0 = operands[0];
7248 rtx op1 = operands[1];
7249 rtx op2 = operands[2];
7250 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7252 /* Move SF value to upper 32-bits for xscvspdpn. */
7253 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7254 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7255 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7262 "load, fpload, fpload, fpload, store, fpstore,
7263 fpstore, vecfloat, mffgpr, *")])
7266 ;; Move 64-bit binary/decimal floating point
7267 (define_expand "mov<mode>"
7268 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7269 (match_operand:FMOVE64 1 "any_operand"))]
7272 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7277 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7278 (match_operand:FMOVE64 1 "const_int_operand"))]
7279 "! TARGET_POWERPC64 && reload_completed
7280 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7281 || (GET_CODE (operands[0]) == SUBREG
7282 && GET_CODE (SUBREG_REG (operands[0])) == REG
7283 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7284 [(set (match_dup 2) (match_dup 4))
7285 (set (match_dup 3) (match_dup 1))]
7287 int endian = (WORDS_BIG_ENDIAN == 0);
7288 HOST_WIDE_INT value = INTVAL (operands[1]);
7290 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7291 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7292 operands[4] = GEN_INT (value >> 32);
7293 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7297 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7298 (match_operand:FMOVE64 1 "const_double_operand"))]
7299 "! TARGET_POWERPC64 && reload_completed
7300 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7301 || (GET_CODE (operands[0]) == SUBREG
7302 && GET_CODE (SUBREG_REG (operands[0])) == REG
7303 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7304 [(set (match_dup 2) (match_dup 4))
7305 (set (match_dup 3) (match_dup 5))]
7307 int endian = (WORDS_BIG_ENDIAN == 0);
7310 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7312 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7313 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7314 operands[4] = gen_int_mode (l[endian], SImode);
7315 operands[5] = gen_int_mode (l[1 - endian], SImode);
7319 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7320 (match_operand:FMOVE64 1 "const_double_operand"))]
7321 "TARGET_POWERPC64 && reload_completed
7322 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7323 || (GET_CODE (operands[0]) == SUBREG
7324 && GET_CODE (SUBREG_REG (operands[0])) == REG
7325 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7326 [(set (match_dup 2) (match_dup 3))]
7328 int endian = (WORDS_BIG_ENDIAN == 0);
7332 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7334 operands[2] = gen_lowpart (DImode, operands[0]);
7335 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7336 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7337 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7339 operands[3] = gen_int_mode (val, DImode);
7342 ;; Don't have reload use general registers to load a constant. It is
7343 ;; less efficient than loading the constant into an FP register, since
7344 ;; it will probably be used there.
7346 ;; The move constraints are ordered to prefer floating point registers before
7347 ;; general purpose registers to avoid doing a store and a load to get the value
7348 ;; into a floating point register when it is needed for a floating point
7349 ;; operation. Prefer traditional floating point registers over VSX registers,
7350 ;; since the D-form version of the memory instructions does not need a GPR for
7351 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7354 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7355 ;; except for 0.0 which can be created on VSX with an xor instruction.
7357 ;; STFD LFD FMR LXSD STXSD
7358 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7362 (define_insn "*mov<mode>_hardfloat32"
7363 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7364 "=m, d, d, <f64_p9>, wY,
7365 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7368 (match_operand:FMOVE64 1 "input_operand"
7369 "d, m, d, wY, <f64_p9>,
7370 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7373 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7374 && (gpc_reg_operand (operands[0], <MODE>mode)
7375 || gpc_reg_operand (operands[1], <MODE>mode))"
7391 "fpstore, fpload, fpsimple, fpload, fpstore,
7392 fpload, fpstore, veclogical, veclogical, two,
7395 (set_attr "size" "64")
7401 ;; STW LWZ MR G-const H-const F-const
7403 (define_insn "*mov<mode>_softfloat32"
7404 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7405 "=Y, r, r, r, r, r")
7407 (match_operand:FMOVE64 1 "input_operand"
7408 "r, Y, r, G, H, F"))]
7411 && (gpc_reg_operand (operands[0], <MODE>mode)
7412 || gpc_reg_operand (operands[1], <MODE>mode))"
7415 "store, load, two, *, *, *")
7418 "8, 8, 8, 8, 12, 16")])
7420 ; ld/std require word-aligned displacements -> 'Y' constraint.
7421 ; List Y->r and r->Y before r->r for reload.
7423 ;; STFD LFD FMR LXSD STXSD
7424 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7425 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7426 ;; NOP MFTGPR MFFGPR MFVSRD MTVSRD
7428 (define_insn "*mov<mode>_hardfloat64"
7429 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7430 "=m, d, d, <f64_p9>, wY,
7431 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7433 *h, r, wg, r, <f64_dm>")
7435 (match_operand:FMOVE64 1 "input_operand"
7436 "d, m, d, wY, <f64_p9>,
7437 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7439 0, wg, r, <f64_dm>, r"))]
7441 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7442 && (gpc_reg_operand (operands[0], <MODE>mode)
7443 || gpc_reg_operand (operands[1], <MODE>mode))"
7466 "fpstore, fpload, fpsimple, fpload, fpstore,
7467 fpload, fpstore, veclogical, veclogical, integer,
7468 store, load, *, mtjmpr, mfjmpr,
7469 *, mftgpr, mffgpr, mftgpr, mffgpr")
7471 (set_attr "size" "64")
7472 (set_attr "length" "4")])
7474 ;; STD LD MR MT<SPR> MF<SPR> G-const
7475 ;; H-const F-const Special
7477 (define_insn "*mov<mode>_softfloat64"
7478 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7479 "=Y, r, r, cl, r, r,
7482 (match_operand:FMOVE64 1 "input_operand"
7486 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7487 && (gpc_reg_operand (operands[0], <MODE>mode)
7488 || gpc_reg_operand (operands[1], <MODE>mode))"
7500 "store, load, *, mtjmpr, mfjmpr, *,
7507 (define_expand "mov<mode>"
7508 [(set (match_operand:FMOVE128 0 "general_operand")
7509 (match_operand:FMOVE128 1 "any_operand"))]
7512 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7516 ;; It's important to list Y->r and r->Y before r->r because otherwise
7517 ;; reload, given m->r, will try to pick r->r and reload it, which
7518 ;; doesn't make progress.
7520 ;; We can't split little endian direct moves of TDmode, because the words are
7521 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7522 ;; problematical. Don't allow direct move for this case.
7524 (define_insn_and_split "*mov<mode>_64bit_dm"
7525 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7526 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7527 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7528 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7529 && (gpc_reg_operand (operands[0], <MODE>mode)
7530 || gpc_reg_operand (operands[1], <MODE>mode))"
7532 "&& reload_completed"
7534 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7535 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7537 (define_insn_and_split "*movtd_64bit_nodm"
7538 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7539 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7540 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7541 && (gpc_reg_operand (operands[0], TDmode)
7542 || gpc_reg_operand (operands[1], TDmode))"
7544 "&& reload_completed"
7546 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7547 [(set_attr "length" "8,8,8,12,12,8")])
7549 (define_insn_and_split "*mov<mode>_32bit"
7550 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7551 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7552 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7553 && (FLOAT128_2REG_P (<MODE>mode)
7554 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7555 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7556 && (gpc_reg_operand (operands[0], <MODE>mode)
7557 || gpc_reg_operand (operands[1], <MODE>mode))"
7559 "&& reload_completed"
7561 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7562 [(set_attr "length" "8,8,8,8,20,20,16")])
7564 (define_insn_and_split "*mov<mode>_softfloat"
7565 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7566 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7568 && (gpc_reg_operand (operands[0], <MODE>mode)
7569 || gpc_reg_operand (operands[1], <MODE>mode))"
7571 "&& reload_completed"
7573 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7574 [(set_attr "length" "20,20,16")])
7576 (define_expand "extenddf<mode>2"
7577 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7578 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7579 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7581 if (FLOAT128_IEEE_P (<MODE>mode))
7582 rs6000_expand_float128_convert (operands[0], operands[1], false);
7583 else if (TARGET_VSX)
7585 if (<MODE>mode == TFmode)
7586 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7587 else if (<MODE>mode == IFmode)
7588 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7594 rtx zero = gen_reg_rtx (DFmode);
7595 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7597 if (<MODE>mode == TFmode)
7598 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7599 else if (<MODE>mode == IFmode)
7600 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7607 ;; Allow memory operands for the source to be created by the combiner.
7608 (define_insn_and_split "extenddf<mode>2_fprs"
7609 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7610 (float_extend:IBM128
7611 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7612 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7613 "!TARGET_VSX && TARGET_HARD_FLOAT
7614 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7616 "&& reload_completed"
7617 [(set (match_dup 3) (match_dup 1))
7618 (set (match_dup 4) (match_dup 2))]
7620 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7621 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7623 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7624 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7627 (define_insn_and_split "extenddf<mode>2_vsx"
7628 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7629 (float_extend:IBM128
7630 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7631 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7633 "&& reload_completed"
7634 [(set (match_dup 2) (match_dup 1))
7635 (set (match_dup 3) (match_dup 4))]
7637 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7638 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7640 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7641 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7642 operands[4] = CONST0_RTX (DFmode);
7645 (define_expand "extendsf<mode>2"
7646 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7647 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7648 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7650 if (FLOAT128_IEEE_P (<MODE>mode))
7651 rs6000_expand_float128_convert (operands[0], operands[1], false);
7654 rtx tmp = gen_reg_rtx (DFmode);
7655 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7656 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7661 (define_expand "trunc<mode>df2"
7662 [(set (match_operand:DF 0 "gpc_reg_operand")
7663 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7664 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7666 if (FLOAT128_IEEE_P (<MODE>mode))
7668 rs6000_expand_float128_convert (operands[0], operands[1], false);
7673 (define_insn_and_split "trunc<mode>df2_internal1"
7674 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7676 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7677 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7678 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7682 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7685 emit_note (NOTE_INSN_DELETED);
7688 [(set_attr "type" "fpsimple")])
7690 (define_insn "trunc<mode>df2_internal2"
7691 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7692 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7693 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7694 && TARGET_LONG_DOUBLE_128"
7696 [(set_attr "type" "fp")])
7698 (define_expand "trunc<mode>sf2"
7699 [(set (match_operand:SF 0 "gpc_reg_operand")
7700 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7701 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7703 if (FLOAT128_IEEE_P (<MODE>mode))
7704 rs6000_expand_float128_convert (operands[0], operands[1], false);
7705 else if (<MODE>mode == TFmode)
7706 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7707 else if (<MODE>mode == IFmode)
7708 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7714 (define_insn_and_split "trunc<mode>sf2_fprs"
7715 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7716 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7717 (clobber (match_scratch:DF 2 "=d"))]
7718 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7720 "&& reload_completed"
7722 (float_truncate:DF (match_dup 1)))
7724 (float_truncate:SF (match_dup 2)))]
7727 (define_expand "floatsi<mode>2"
7728 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7729 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7730 (clobber (match_scratch:DI 2))])]
7731 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7733 rtx op0 = operands[0];
7734 rtx op1 = operands[1];
7736 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7738 else if (FLOAT128_IEEE_P (<MODE>mode))
7740 rs6000_expand_float128_convert (op0, op1, false);
7745 rtx tmp = gen_reg_rtx (DFmode);
7746 expand_float (tmp, op1, false);
7747 if (<MODE>mode == TFmode)
7748 emit_insn (gen_extenddftf2 (op0, tmp));
7749 else if (<MODE>mode == IFmode)
7750 emit_insn (gen_extenddfif2 (op0, tmp));
7757 ; fadd, but rounding towards zero.
7758 ; This is probably not the optimal code sequence.
7759 (define_insn "fix_trunc_helper<mode>"
7760 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7761 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7762 UNSPEC_FIX_TRUNC_TF))
7763 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7764 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7765 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7766 [(set_attr "type" "fp")
7767 (set_attr "length" "20")])
7769 (define_expand "fix_trunc<mode>si2"
7770 [(set (match_operand:SI 0 "gpc_reg_operand")
7771 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7772 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7774 rtx op0 = operands[0];
7775 rtx op1 = operands[1];
7777 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7781 if (FLOAT128_IEEE_P (<MODE>mode))
7782 rs6000_expand_float128_convert (op0, op1, false);
7783 else if (<MODE>mode == TFmode)
7784 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7785 else if (<MODE>mode == IFmode)
7786 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7793 (define_expand "fix_trunc<mode>si2_fprs"
7794 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7795 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7796 (clobber (match_dup 2))
7797 (clobber (match_dup 3))
7798 (clobber (match_dup 4))
7799 (clobber (match_dup 5))])]
7800 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7802 operands[2] = gen_reg_rtx (DFmode);
7803 operands[3] = gen_reg_rtx (DFmode);
7804 operands[4] = gen_reg_rtx (DImode);
7805 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7808 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7809 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7810 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7811 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7812 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7813 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7814 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7815 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7821 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7824 gcc_assert (MEM_P (operands[5]));
7825 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7827 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7828 emit_move_insn (operands[5], operands[4]);
7829 emit_move_insn (operands[0], lowword);
7833 (define_expand "fix_trunc<mode>di2"
7834 [(set (match_operand:DI 0 "gpc_reg_operand")
7835 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7836 "TARGET_FLOAT128_TYPE"
7838 if (!TARGET_FLOAT128_HW)
7840 rs6000_expand_float128_convert (operands[0], operands[1], false);
7845 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7846 [(set (match_operand:SDI 0 "gpc_reg_operand")
7847 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7848 "TARGET_FLOAT128_TYPE"
7850 rs6000_expand_float128_convert (operands[0], operands[1], true);
7854 (define_expand "floatdi<mode>2"
7855 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7856 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7857 "TARGET_FLOAT128_TYPE"
7859 if (!TARGET_FLOAT128_HW)
7861 rs6000_expand_float128_convert (operands[0], operands[1], false);
7866 (define_expand "floatunsdi<IEEE128:mode>2"
7867 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7868 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7869 "TARGET_FLOAT128_TYPE"
7871 if (!TARGET_FLOAT128_HW)
7873 rs6000_expand_float128_convert (operands[0], operands[1], true);
7878 (define_expand "floatuns<IEEE128:mode>2"
7879 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7880 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
7881 "TARGET_FLOAT128_TYPE"
7883 rtx op0 = operands[0];
7884 rtx op1 = operands[1];
7886 if (TARGET_FLOAT128_HW)
7887 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7889 rs6000_expand_float128_convert (op0, op1, true);
7893 (define_expand "neg<mode>2"
7894 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7895 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7896 "FLOAT128_IEEE_P (<MODE>mode)
7897 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7899 if (FLOAT128_IEEE_P (<MODE>mode))
7901 if (TARGET_FLOAT128_HW)
7903 if (<MODE>mode == TFmode)
7904 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7905 else if (<MODE>mode == KFmode)
7906 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7910 else if (TARGET_FLOAT128_TYPE)
7912 if (<MODE>mode == TFmode)
7913 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7914 else if (<MODE>mode == KFmode)
7915 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7921 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7922 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7924 operands[1], <MODE>mode);
7926 if (target && !rtx_equal_p (target, operands[0]))
7927 emit_move_insn (operands[0], target);
7933 (define_insn "neg<mode>2_internal"
7934 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7935 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7936 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7938 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7939 return "fneg %L0,%L1\;fneg %0,%1";
7941 return "fneg %0,%1\;fneg %L0,%L1";
7943 [(set_attr "type" "fpsimple")
7944 (set_attr "length" "8")])
7946 (define_expand "abs<mode>2"
7947 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7948 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7949 "FLOAT128_IEEE_P (<MODE>mode)
7950 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7954 if (FLOAT128_IEEE_P (<MODE>mode))
7956 if (TARGET_FLOAT128_HW)
7958 if (<MODE>mode == TFmode)
7959 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7960 else if (<MODE>mode == KFmode)
7961 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7966 else if (TARGET_FLOAT128_TYPE)
7968 if (<MODE>mode == TFmode)
7969 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7970 else if (<MODE>mode == KFmode)
7971 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7980 label = gen_label_rtx ();
7981 if (<MODE>mode == TFmode)
7982 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7983 else if (<MODE>mode == IFmode)
7984 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7991 (define_expand "abs<mode>2_internal"
7992 [(set (match_operand:IBM128 0 "gpc_reg_operand")
7993 (match_operand:IBM128 1 "gpc_reg_operand"))
7994 (set (match_dup 3) (match_dup 5))
7995 (set (match_dup 5) (abs:DF (match_dup 5)))
7996 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7997 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7998 (label_ref (match_operand 2 ""))
8000 (set (match_dup 6) (neg:DF (match_dup 6)))]
8001 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8003 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8004 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8005 operands[3] = gen_reg_rtx (DFmode);
8006 operands[4] = gen_reg_rtx (CCFPmode);
8007 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8008 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8012 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8015 (define_expand "ieee_128bit_negative_zero"
8016 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8017 "TARGET_FLOAT128_TYPE"
8019 rtvec v = rtvec_alloc (16);
8022 for (i = 0; i < 16; i++)
8023 RTVEC_ELT (v, i) = const0_rtx;
8025 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8026 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8028 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8032 ;; IEEE 128-bit negate
8034 ;; We have 2 insns here for negate and absolute value. The first uses
8035 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8036 ;; insns, and second insn after the first split pass loads up the bit to
8037 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8038 ;; neg/abs to create the constant just once.
8040 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8041 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8042 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8043 (clobber (match_scratch:V16QI 2 "=v"))]
8044 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8047 [(parallel [(set (match_dup 0)
8048 (neg:IEEE128 (match_dup 1)))
8049 (use (match_dup 2))])]
8051 if (GET_CODE (operands[2]) == SCRATCH)
8052 operands[2] = gen_reg_rtx (V16QImode);
8054 operands[3] = gen_reg_rtx (V16QImode);
8055 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8057 [(set_attr "length" "8")
8058 (set_attr "type" "vecsimple")])
8060 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8061 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8062 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8063 (use (match_operand:V16QI 2 "register_operand" "v"))]
8064 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8065 "xxlxor %x0,%x1,%x2"
8066 [(set_attr "type" "veclogical")])
8068 ;; IEEE 128-bit absolute value
8069 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8070 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8071 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8072 (clobber (match_scratch:V16QI 2 "=v"))]
8073 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8076 [(parallel [(set (match_dup 0)
8077 (abs:IEEE128 (match_dup 1)))
8078 (use (match_dup 2))])]
8080 if (GET_CODE (operands[2]) == SCRATCH)
8081 operands[2] = gen_reg_rtx (V16QImode);
8083 operands[3] = gen_reg_rtx (V16QImode);
8084 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8086 [(set_attr "length" "8")
8087 (set_attr "type" "vecsimple")])
8089 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8090 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8091 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8092 (use (match_operand:V16QI 2 "register_operand" "v"))]
8093 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8094 "xxlandc %x0,%x1,%x2"
8095 [(set_attr "type" "veclogical")])
8097 ;; IEEE 128-bit negative absolute value
8098 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8099 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8102 (match_operand:IEEE128 1 "register_operand" "wa"))))
8103 (clobber (match_scratch:V16QI 2 "=v"))]
8104 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8105 && FLOAT128_IEEE_P (<MODE>mode)"
8108 [(parallel [(set (match_dup 0)
8109 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8110 (use (match_dup 2))])]
8112 if (GET_CODE (operands[2]) == SCRATCH)
8113 operands[2] = gen_reg_rtx (V16QImode);
8115 operands[3] = gen_reg_rtx (V16QImode);
8116 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8118 [(set_attr "length" "8")
8119 (set_attr "type" "vecsimple")])
8121 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8122 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8125 (match_operand:IEEE128 1 "register_operand" "wa"))))
8126 (use (match_operand:V16QI 2 "register_operand" "v"))]
8127 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8129 [(set_attr "type" "veclogical")])
8131 ;; Float128 conversion functions. These expand to library function calls.
8132 ;; We use expand to convert from IBM double double to IEEE 128-bit
8133 ;; and trunc for the opposite.
8134 (define_expand "extendiftf2"
8135 [(set (match_operand:TF 0 "gpc_reg_operand")
8136 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8137 "TARGET_FLOAT128_TYPE"
8139 rs6000_expand_float128_convert (operands[0], operands[1], false);
8143 (define_expand "extendifkf2"
8144 [(set (match_operand:KF 0 "gpc_reg_operand")
8145 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8146 "TARGET_FLOAT128_TYPE"
8148 rs6000_expand_float128_convert (operands[0], operands[1], false);
8152 (define_expand "extendtfkf2"
8153 [(set (match_operand:KF 0 "gpc_reg_operand")
8154 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8155 "TARGET_FLOAT128_TYPE"
8157 rs6000_expand_float128_convert (operands[0], operands[1], false);
8161 (define_expand "extendtfif2"
8162 [(set (match_operand:IF 0 "gpc_reg_operand")
8163 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8164 "TARGET_FLOAT128_TYPE"
8166 rs6000_expand_float128_convert (operands[0], operands[1], false);
8170 (define_expand "trunciftf2"
8171 [(set (match_operand:TF 0 "gpc_reg_operand")
8172 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8173 "TARGET_FLOAT128_TYPE"
8175 rs6000_expand_float128_convert (operands[0], operands[1], false);
8179 (define_expand "truncifkf2"
8180 [(set (match_operand:KF 0 "gpc_reg_operand")
8181 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8182 "TARGET_FLOAT128_TYPE"
8184 rs6000_expand_float128_convert (operands[0], operands[1], false);
8188 (define_expand "trunckftf2"
8189 [(set (match_operand:TF 0 "gpc_reg_operand")
8190 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8191 "TARGET_FLOAT128_TYPE"
8193 rs6000_expand_float128_convert (operands[0], operands[1], false);
8197 (define_expand "trunctfif2"
8198 [(set (match_operand:IF 0 "gpc_reg_operand")
8199 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8200 "TARGET_FLOAT128_TYPE"
8202 rs6000_expand_float128_convert (operands[0], operands[1], false);
8206 (define_insn_and_split "*extend<mode>tf2_internal"
8207 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8209 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8210 "TARGET_FLOAT128_TYPE
8211 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8213 "&& reload_completed"
8214 [(set (match_dup 0) (match_dup 2))]
8216 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8219 (define_insn_and_split "*extendtf<mode>2_internal"
8220 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8222 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8223 "TARGET_FLOAT128_TYPE
8224 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8226 "&& reload_completed"
8227 [(set (match_dup 0) (match_dup 2))]
8229 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8233 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8234 ;; must have 3 arguments, and scratch register constraint must be a single
8237 ;; Reload patterns to support gpr load/store with misaligned mem.
8238 ;; and multiple gpr load/store at offset >= 0xfffc
8239 (define_expand "reload_<mode>_store"
8240 [(parallel [(match_operand 0 "memory_operand" "=m")
8241 (match_operand 1 "gpc_reg_operand" "r")
8242 (match_operand:GPR 2 "register_operand" "=&b")])]
8245 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8249 (define_expand "reload_<mode>_load"
8250 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8251 (match_operand 1 "memory_operand" "m")
8252 (match_operand:GPR 2 "register_operand" "=b")])]
8255 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8260 ;; Reload patterns for various types using the vector registers. We may need
8261 ;; an additional base register to convert the reg+offset addressing to reg+reg
8262 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8263 ;; index register for gpr registers.
8264 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8265 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8266 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8267 (match_operand:P 2 "register_operand" "=b")])]
8270 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8274 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8275 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8276 (match_operand:RELOAD 1 "memory_operand" "m")
8277 (match_operand:P 2 "register_operand" "=b")])]
8280 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8285 ;; Reload sometimes tries to move the address to a GPR, and can generate
8286 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8287 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8289 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8290 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8291 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8292 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8294 "TARGET_ALTIVEC && reload_completed"
8296 "&& reload_completed"
8298 (plus:P (match_dup 1)
8301 (and:P (match_dup 0)
8304 ;; Power8 merge instructions to allow direct move to/from floating point
8305 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8306 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8307 ;; value, since it is allocated in reload and not all of the flow information
8308 ;; is setup for it. We have two patterns to do the two moves between gprs and
8309 ;; fprs. There isn't a dependancy between the two, but we could potentially
8310 ;; schedule other instructions between the two instructions.
8312 (define_insn "p8_fmrgow_<mode>"
8313 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8315 (match_operand:DF 1 "register_operand" "d")
8316 (match_operand:DF 2 "register_operand" "d")]
8317 UNSPEC_P8V_FMRGOW))]
8318 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8320 [(set_attr "type" "fpsimple")])
8322 (define_insn "p8_mtvsrwz"
8323 [(set (match_operand:DF 0 "register_operand" "=d")
8324 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8325 UNSPEC_P8V_MTVSRWZ))]
8326 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8328 [(set_attr "type" "mftgpr")])
8330 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8331 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8332 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8333 UNSPEC_P8V_RELOAD_FROM_GPR))
8334 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8335 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8337 "&& reload_completed"
8340 rtx dest = operands[0];
8341 rtx src = operands[1];
8342 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8343 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8344 rtx gpr_hi_reg = gen_highpart (SImode, src);
8345 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8347 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8348 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8349 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8352 [(set_attr "length" "12")
8353 (set_attr "type" "three")])
8355 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8356 (define_insn "p8_mtvsrd_df"
8357 [(set (match_operand:DF 0 "register_operand" "=wa")
8358 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8359 UNSPEC_P8V_MTVSRD))]
8360 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8362 [(set_attr "type" "mftgpr")])
8364 (define_insn "p8_xxpermdi_<mode>"
8365 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8366 (unspec:FMOVE128_GPR [
8367 (match_operand:DF 1 "register_operand" "wa")
8368 (match_operand:DF 2 "register_operand" "wa")]
8369 UNSPEC_P8V_XXPERMDI))]
8370 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8371 "xxpermdi %x0,%x1,%x2,0"
8372 [(set_attr "type" "vecperm")])
8374 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8375 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8376 (unspec:FMOVE128_GPR
8377 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8378 UNSPEC_P8V_RELOAD_FROM_GPR))
8379 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8380 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8382 "&& reload_completed"
8385 rtx dest = operands[0];
8386 rtx src = operands[1];
8387 /* You might think that we could use op0 as one temp and a DF clobber
8388 as op2, but you'd be wrong. Secondary reload move patterns don't
8389 check for overlap of the clobber and the destination. */
8390 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8391 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8392 rtx gpr_hi_reg = gen_highpart (DImode, src);
8393 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8395 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8396 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8397 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8400 [(set_attr "length" "12")
8401 (set_attr "type" "three")])
8404 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8405 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8407 && (int_reg_operand (operands[0], <MODE>mode)
8408 || int_reg_operand (operands[1], <MODE>mode))
8409 && (!TARGET_DIRECT_MOVE_128
8410 || (!vsx_register_operand (operands[0], <MODE>mode)
8411 && !vsx_register_operand (operands[1], <MODE>mode)))"
8413 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8415 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8416 ;; type is stored internally as double precision in the VSX registers, we have
8417 ;; to convert it from the vector format.
8418 (define_insn "p8_mtvsrd_sf"
8419 [(set (match_operand:SF 0 "register_operand" "=wa")
8420 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8421 UNSPEC_P8V_MTVSRD))]
8422 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8424 [(set_attr "type" "mftgpr")])
8426 (define_insn_and_split "reload_vsx_from_gprsf"
8427 [(set (match_operand:SF 0 "register_operand" "=wa")
8428 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8429 UNSPEC_P8V_RELOAD_FROM_GPR))
8430 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8431 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8433 "&& reload_completed"
8436 rtx op0 = operands[0];
8437 rtx op1 = operands[1];
8438 rtx op2 = operands[2];
8439 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8441 /* Move SF value to upper 32-bits for xscvspdpn. */
8442 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8443 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8444 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8447 [(set_attr "length" "8")
8448 (set_attr "type" "two")])
8450 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8451 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8452 ;; and then doing a move of that.
8453 (define_insn "p8_mfvsrd_3_<mode>"
8454 [(set (match_operand:DF 0 "register_operand" "=r")
8455 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8456 UNSPEC_P8V_RELOAD_FROM_VSX))]
8457 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8459 [(set_attr "type" "mftgpr")])
8461 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8462 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8463 (unspec:FMOVE128_GPR
8464 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8465 UNSPEC_P8V_RELOAD_FROM_VSX))
8466 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8467 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8469 "&& reload_completed"
8472 rtx dest = operands[0];
8473 rtx src = operands[1];
8474 rtx tmp = operands[2];
8475 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8476 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8478 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8479 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8480 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8483 [(set_attr "length" "12")
8484 (set_attr "type" "three")])
8486 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8487 ;; type is stored internally as double precision, we have to convert it to the
8490 (define_insn_and_split "reload_gpr_from_vsxsf"
8491 [(set (match_operand:SF 0 "register_operand" "=r")
8492 (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8493 UNSPEC_P8V_RELOAD_FROM_VSX))
8494 (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8495 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8497 "&& reload_completed"
8500 rtx op0 = operands[0];
8501 rtx op1 = operands[1];
8502 rtx op2 = operands[2];
8503 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8504 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8506 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8507 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8510 [(set_attr "length" "8")
8511 (set_attr "type" "two")])
8514 ;; Next come the multi-word integer load and store and the load and store
8517 ;; List r->r after r->Y, otherwise reload will try to reload a
8518 ;; non-offsettable address by using r->r which won't make progress.
8519 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8520 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8522 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8523 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8524 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8527 (define_insn "*movdi_internal32"
8528 [(set (match_operand:DI 0 "nonimmediate_operand"
8529 "=Y, r, r, m, ^d, ^d,
8530 r, wY, Z, ^wb, $wv, ^wi,
8531 *wo, *wo, *wv, *wi, *wi, *wv,
8534 (match_operand:DI 1 "input_operand"
8535 "r, Y, r, ^d, m, ^d,
8536 IJKnGHF, ^wb, $wv, wY, Z, ^wi,
8537 Oj, wM, OjwM, Oj, wM, wS,
8541 && (gpc_reg_operand (operands[0], DImode)
8542 || gpc_reg_operand (operands[1], DImode))"
8564 "store, load, *, fpstore, fpload, fpsimple,
8565 *, fpstore, fpstore, fpload, fpload, veclogical,
8566 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8568 (set_attr "size" "64")])
8571 [(set (match_operand:DI 0 "gpc_reg_operand")
8572 (match_operand:DI 1 "const_int_operand"))]
8573 "! TARGET_POWERPC64 && reload_completed
8574 && gpr_or_gpr_p (operands[0], operands[1])
8575 && !direct_move_p (operands[0], operands[1])"
8576 [(set (match_dup 2) (match_dup 4))
8577 (set (match_dup 3) (match_dup 1))]
8579 HOST_WIDE_INT value = INTVAL (operands[1]);
8580 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8582 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8584 operands[4] = GEN_INT (value >> 32);
8585 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8589 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8590 (match_operand:DIFD 1 "input_operand"))]
8591 "reload_completed && !TARGET_POWERPC64
8592 && gpr_or_gpr_p (operands[0], operands[1])
8593 && !direct_move_p (operands[0], operands[1])"
8595 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8597 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8598 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8599 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8600 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8601 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8602 (define_insn "*movdi_internal64"
8603 [(set (match_operand:DI 0 "nonimmediate_operand"
8604 "=YZ, r, r, r, r, r,
8605 m, ^d, ^d, wY, Z, $wb,
8606 $wv, ^wi, *wo, *wo, *wv, *wi,
8607 *wi, *wv, *wv, r, *h, *h,
8608 ?*r, ?*wg, ?*r, ?*wj")
8610 (match_operand:DI 1 "input_operand"
8611 "r, YZ, r, I, L, nF,
8612 ^d, m, ^d, ^wb, $wv, wY,
8613 Z, ^wi, Oj, wM, OjwM, Oj,
8614 wM, wS, wB, *h, r, 0,
8618 && (gpc_reg_operand (operands[0], DImode)
8619 || gpc_reg_operand (operands[1], DImode))"
8650 "store, load, *, *, *, *,
8651 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8652 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8653 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8654 mftgpr, mffgpr, mftgpr, mffgpr")
8656 (set_attr "size" "64")
8664 ; Some DImode loads are best done as a load of -1 followed by a mask
8667 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8668 (match_operand:DI 1 "const_int_operand"))]
8670 && num_insns_constant (operands[1], DImode) > 1
8671 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8672 && rs6000_is_valid_and_mask (operands[1], DImode)"
8676 (and:DI (match_dup 0)
8680 ;; Split a load of a large constant into the appropriate five-instruction
8681 ;; sequence. Handle anything in a constant number of insns.
8682 ;; When non-easy constants can go in the TOC, this should use
8683 ;; easy_fp_constant predicate.
8685 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8686 (match_operand:DI 1 "const_int_operand"))]
8687 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8688 [(set (match_dup 0) (match_dup 2))
8689 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8691 if (rs6000_emit_set_const (operands[0], operands[1]))
8698 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8699 (match_operand:DI 1 "const_scalar_int_operand"))]
8700 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8701 [(set (match_dup 0) (match_dup 2))
8702 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8704 if (rs6000_emit_set_const (operands[0], operands[1]))
8711 [(set (match_operand:DI 0 "altivec_register_operand")
8712 (match_operand:DI 1 "s5bit_cint_operand"))]
8713 "TARGET_VSX && reload_completed"
8716 rtx op0 = operands[0];
8717 rtx op1 = operands[1];
8718 int r = REGNO (op0);
8719 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8721 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8722 if (op1 != const0_rtx && op1 != constm1_rtx)
8724 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8725 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8730 ;; Split integer constants that can be loaded with XXSPLTIB and a
8731 ;; sign extend operation.
8733 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8734 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8735 "TARGET_P9_VECTOR && reload_completed"
8738 rtx op0 = operands[0];
8739 rtx op1 = operands[1];
8740 int r = REGNO (op0);
8741 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8743 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8744 if (<MODE>mode == DImode)
8745 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8746 else if (<MODE>mode == SImode)
8747 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8748 else if (<MODE>mode == HImode)
8750 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8751 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8757 ;; TImode/PTImode is similar, except that we usually want to compute the
8758 ;; address into a register and use lsi/stsi (the exception is during reload).
8760 (define_insn "*mov<mode>_string"
8761 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8762 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8764 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8765 && (gpc_reg_operand (operands[0], <MODE>mode)
8766 || gpc_reg_operand (operands[1], <MODE>mode))"
8768 [(set_attr "type" "store,store,load,load,*,*")
8769 (set_attr "update" "yes")
8770 (set_attr "indexed" "yes")
8771 (set_attr "cell_micro" "conditional")])
8773 (define_insn "*mov<mode>_ppc64"
8774 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8775 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8776 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8777 && (gpc_reg_operand (operands[0], <MODE>mode)
8778 || gpc_reg_operand (operands[1], <MODE>mode)))"
8780 return rs6000_output_move_128bit (operands);
8782 [(set_attr "type" "store,store,load,load,*,*")
8783 (set_attr "length" "8")])
8786 [(set (match_operand:TI2 0 "int_reg_operand")
8787 (match_operand:TI2 1 "const_scalar_int_operand"))]
8789 && (VECTOR_MEM_NONE_P (<MODE>mode)
8790 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8791 [(set (match_dup 2) (match_dup 4))
8792 (set (match_dup 3) (match_dup 5))]
8794 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8796 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8798 if (CONST_WIDE_INT_P (operands[1]))
8800 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8801 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8803 else if (CONST_INT_P (operands[1]))
8805 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8806 operands[5] = operands[1];
8813 [(set (match_operand:TI2 0 "nonimmediate_operand")
8814 (match_operand:TI2 1 "input_operand"))]
8816 && gpr_or_gpr_p (operands[0], operands[1])
8817 && !direct_move_p (operands[0], operands[1])
8818 && !quad_load_store_p (operands[0], operands[1])"
8820 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8822 (define_expand "setmemsi"
8823 [(parallel [(set (match_operand:BLK 0 "")
8824 (match_operand 2 "const_int_operand"))
8825 (use (match_operand:SI 1 ""))
8826 (use (match_operand:SI 3 ""))])]
8829 /* If value to set is not zero, use the library routine. */
8830 if (operands[2] != const0_rtx)
8833 if (expand_block_clear (operands))
8839 ;; String compare N insn.
8840 ;; Argument 0 is the target (result)
8841 ;; Argument 1 is the destination
8842 ;; Argument 2 is the source
8843 ;; Argument 3 is the length
8844 ;; Argument 4 is the alignment
8846 (define_expand "cmpstrnsi"
8847 [(parallel [(set (match_operand:SI 0)
8848 (compare:SI (match_operand:BLK 1)
8849 (match_operand:BLK 2)))
8850 (use (match_operand:SI 3))
8851 (use (match_operand:SI 4))])]
8852 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8854 if (optimize_insn_for_size_p ())
8857 if (expand_strn_compare (operands, 0))
8863 ;; String compare insn.
8864 ;; Argument 0 is the target (result)
8865 ;; Argument 1 is the destination
8866 ;; Argument 2 is the source
8867 ;; Argument 3 is the alignment
8869 (define_expand "cmpstrsi"
8870 [(parallel [(set (match_operand:SI 0)
8871 (compare:SI (match_operand:BLK 1)
8872 (match_operand:BLK 2)))
8873 (use (match_operand:SI 3))])]
8874 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8876 if (optimize_insn_for_size_p ())
8879 if (expand_strn_compare (operands, 1))
8885 ;; Block compare insn.
8886 ;; Argument 0 is the target (result)
8887 ;; Argument 1 is the destination
8888 ;; Argument 2 is the source
8889 ;; Argument 3 is the length
8890 ;; Argument 4 is the alignment
8892 (define_expand "cmpmemsi"
8893 [(parallel [(set (match_operand:SI 0)
8894 (compare:SI (match_operand:BLK 1)
8895 (match_operand:BLK 2)))
8896 (use (match_operand:SI 3))
8897 (use (match_operand:SI 4))])]
8900 if (expand_block_compare (operands))
8906 ;; String/block move insn.
8907 ;; Argument 0 is the destination
8908 ;; Argument 1 is the source
8909 ;; Argument 2 is the length
8910 ;; Argument 3 is the alignment
8912 (define_expand "movmemsi"
8913 [(parallel [(set (match_operand:BLK 0 "")
8914 (match_operand:BLK 1 ""))
8915 (use (match_operand:SI 2 ""))
8916 (use (match_operand:SI 3 ""))])]
8919 if (expand_block_move (operands))
8925 ;; Define insns that do load or store with update. Some of these we can
8926 ;; get by using pre-decrement or pre-increment, but the hardware can also
8927 ;; do cases where the increment is not the size of the object.
8929 ;; In all these cases, we use operands 0 and 1 for the register being
8930 ;; incremented because those are the operands that local-alloc will
8931 ;; tie and these are the pair most likely to be tieable (and the ones
8932 ;; that will benefit the most).
8934 (define_insn "*movdi_update1"
8935 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8936 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8937 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8938 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8939 (plus:DI (match_dup 1) (match_dup 2)))]
8940 "TARGET_POWERPC64 && TARGET_UPDATE
8941 && (!avoiding_indexed_address_p (DImode)
8942 || !gpc_reg_operand (operands[2], DImode))"
8946 [(set_attr "type" "load")
8947 (set_attr "update" "yes")
8948 (set_attr "indexed" "yes,no")])
8950 (define_insn "movdi_<mode>_update"
8951 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8952 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8953 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8954 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8955 (plus:P (match_dup 1) (match_dup 2)))]
8956 "TARGET_POWERPC64 && TARGET_UPDATE
8957 && (!avoiding_indexed_address_p (Pmode)
8958 || !gpc_reg_operand (operands[2], Pmode)
8959 || (REG_P (operands[0])
8960 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8964 [(set_attr "type" "store")
8965 (set_attr "update" "yes")
8966 (set_attr "indexed" "yes,no")])
8968 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8969 ;; needed for stack allocation, even if the user passes -mno-update.
8970 (define_insn "movdi_<mode>_update_stack"
8971 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8972 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8973 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8974 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8975 (plus:P (match_dup 1) (match_dup 2)))]
8980 [(set_attr "type" "store")
8981 (set_attr "update" "yes")
8982 (set_attr "indexed" "yes,no")])
8984 (define_insn "*movsi_update1"
8985 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8986 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8987 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8988 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8989 (plus:SI (match_dup 1) (match_dup 2)))]
8991 && (!avoiding_indexed_address_p (SImode)
8992 || !gpc_reg_operand (operands[2], SImode))"
8996 [(set_attr "type" "load")
8997 (set_attr "update" "yes")
8998 (set_attr "indexed" "yes,no")])
9000 (define_insn "*movsi_update2"
9001 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9003 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9004 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9005 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9006 (plus:DI (match_dup 1) (match_dup 2)))]
9007 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9009 [(set_attr "type" "load")
9010 (set_attr "sign_extend" "yes")
9011 (set_attr "update" "yes")
9012 (set_attr "indexed" "yes")])
9014 (define_insn "movsi_update"
9015 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9016 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9017 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9018 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9019 (plus:SI (match_dup 1) (match_dup 2)))]
9021 && (!avoiding_indexed_address_p (SImode)
9022 || !gpc_reg_operand (operands[2], SImode)
9023 || (REG_P (operands[0])
9024 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9028 [(set_attr "type" "store")
9029 (set_attr "update" "yes")
9030 (set_attr "indexed" "yes,no")])
9032 ;; This is an unconditional pattern; needed for stack allocation, even
9033 ;; if the user passes -mno-update.
9034 (define_insn "movsi_update_stack"
9035 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9036 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9037 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9038 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9039 (plus:SI (match_dup 1) (match_dup 2)))]
9044 [(set_attr "type" "store")
9045 (set_attr "update" "yes")
9046 (set_attr "indexed" "yes,no")])
9048 (define_insn "*movhi_update1"
9049 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9050 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9051 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9052 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9053 (plus:SI (match_dup 1) (match_dup 2)))]
9055 && (!avoiding_indexed_address_p (SImode)
9056 || !gpc_reg_operand (operands[2], SImode))"
9060 [(set_attr "type" "load")
9061 (set_attr "update" "yes")
9062 (set_attr "indexed" "yes,no")])
9064 (define_insn "*movhi_update2"
9065 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9067 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9068 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9069 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9070 (plus:SI (match_dup 1) (match_dup 2)))]
9072 && (!avoiding_indexed_address_p (SImode)
9073 || !gpc_reg_operand (operands[2], SImode))"
9077 [(set_attr "type" "load")
9078 (set_attr "update" "yes")
9079 (set_attr "indexed" "yes,no")])
9081 (define_insn "*movhi_update3"
9082 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9084 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9085 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9086 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9087 (plus:SI (match_dup 1) (match_dup 2)))]
9089 && !(avoiding_indexed_address_p (SImode)
9090 && gpc_reg_operand (operands[2], SImode))"
9094 [(set_attr "type" "load")
9095 (set_attr "sign_extend" "yes")
9096 (set_attr "update" "yes")
9097 (set_attr "indexed" "yes,no")])
9099 (define_insn "*movhi_update4"
9100 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9101 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9102 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9103 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9104 (plus:SI (match_dup 1) (match_dup 2)))]
9106 && (!avoiding_indexed_address_p (SImode)
9107 || !gpc_reg_operand (operands[2], SImode))"
9111 [(set_attr "type" "store")
9112 (set_attr "update" "yes")
9113 (set_attr "indexed" "yes,no")])
9115 (define_insn "*movqi_update1"
9116 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9117 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9118 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9119 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9120 (plus:SI (match_dup 1) (match_dup 2)))]
9122 && (!avoiding_indexed_address_p (SImode)
9123 || !gpc_reg_operand (operands[2], SImode))"
9127 [(set_attr "type" "load")
9128 (set_attr "update" "yes")
9129 (set_attr "indexed" "yes,no")])
9131 (define_insn "*movqi_update2"
9132 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9134 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9135 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9136 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9137 (plus:SI (match_dup 1) (match_dup 2)))]
9139 && (!avoiding_indexed_address_p (SImode)
9140 || !gpc_reg_operand (operands[2], SImode))"
9144 [(set_attr "type" "load")
9145 (set_attr "update" "yes")
9146 (set_attr "indexed" "yes,no")])
9148 (define_insn "*movqi_update3"
9149 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9150 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9151 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9152 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9153 (plus:SI (match_dup 1) (match_dup 2)))]
9155 && (!avoiding_indexed_address_p (SImode)
9156 || !gpc_reg_operand (operands[2], SImode))"
9160 [(set_attr "type" "store")
9161 (set_attr "update" "yes")
9162 (set_attr "indexed" "yes,no")])
9164 (define_insn "*movsf_update1"
9165 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9166 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9167 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9168 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9169 (plus:SI (match_dup 1) (match_dup 2)))]
9170 "TARGET_HARD_FLOAT && TARGET_UPDATE
9171 && (!avoiding_indexed_address_p (SImode)
9172 || !gpc_reg_operand (operands[2], SImode))"
9176 [(set_attr "type" "fpload")
9177 (set_attr "update" "yes")
9178 (set_attr "indexed" "yes,no")])
9180 (define_insn "*movsf_update2"
9181 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9182 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9183 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9184 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9185 (plus:SI (match_dup 1) (match_dup 2)))]
9186 "TARGET_HARD_FLOAT && TARGET_UPDATE
9187 && (!avoiding_indexed_address_p (SImode)
9188 || !gpc_reg_operand (operands[2], SImode))"
9192 [(set_attr "type" "fpstore")
9193 (set_attr "update" "yes")
9194 (set_attr "indexed" "yes,no")])
9196 (define_insn "*movsf_update3"
9197 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9198 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9199 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9200 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9201 (plus:SI (match_dup 1) (match_dup 2)))]
9202 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9203 && (!avoiding_indexed_address_p (SImode)
9204 || !gpc_reg_operand (operands[2], SImode))"
9208 [(set_attr "type" "load")
9209 (set_attr "update" "yes")
9210 (set_attr "indexed" "yes,no")])
9212 (define_insn "*movsf_update4"
9213 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9214 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9215 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9216 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9217 (plus:SI (match_dup 1) (match_dup 2)))]
9218 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9219 && (!avoiding_indexed_address_p (SImode)
9220 || !gpc_reg_operand (operands[2], SImode))"
9224 [(set_attr "type" "store")
9225 (set_attr "update" "yes")
9226 (set_attr "indexed" "yes,no")])
9228 (define_insn "*movdf_update1"
9229 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9230 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9231 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9232 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9233 (plus:SI (match_dup 1) (match_dup 2)))]
9234 "TARGET_HARD_FLOAT && TARGET_UPDATE
9235 && (!avoiding_indexed_address_p (SImode)
9236 || !gpc_reg_operand (operands[2], SImode))"
9240 [(set_attr "type" "fpload")
9241 (set_attr "update" "yes")
9242 (set_attr "indexed" "yes,no")
9243 (set_attr "size" "64")])
9245 (define_insn "*movdf_update2"
9246 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9247 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9248 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9249 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9250 (plus:SI (match_dup 1) (match_dup 2)))]
9251 "TARGET_HARD_FLOAT && TARGET_UPDATE
9252 && (!avoiding_indexed_address_p (SImode)
9253 || !gpc_reg_operand (operands[2], SImode))"
9257 [(set_attr "type" "fpstore")
9258 (set_attr "update" "yes")
9259 (set_attr "indexed" "yes,no")])
9262 ;; After inserting conditional returns we can sometimes have
9263 ;; unnecessary register moves. Unfortunately we cannot have a
9264 ;; modeless peephole here, because some single SImode sets have early
9265 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9266 ;; sequences, using get_attr_length here will smash the operands
9267 ;; array. Neither is there an early_cobbler_p predicate.
9268 ;; Also this optimization interferes with scalars going into
9269 ;; altivec registers (the code does reloading through the FPRs).
9271 [(set (match_operand:DF 0 "gpc_reg_operand")
9272 (match_operand:DF 1 "any_operand"))
9273 (set (match_operand:DF 2 "gpc_reg_operand")
9276 && peep2_reg_dead_p (2, operands[0])"
9277 [(set (match_dup 2) (match_dup 1))])
9280 [(set (match_operand:SF 0 "gpc_reg_operand")
9281 (match_operand:SF 1 "any_operand"))
9282 (set (match_operand:SF 2 "gpc_reg_operand")
9285 && peep2_reg_dead_p (2, operands[0])"
9286 [(set (match_dup 2) (match_dup 1))])
9291 ;; Mode attributes for different ABIs.
9292 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9293 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9294 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9295 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9297 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9298 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9299 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9300 (match_operand 4 "" "g")))
9301 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9302 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9304 (clobber (reg:SI LR_REGNO))]
9305 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9307 if (TARGET_CMODEL != CMODEL_SMALL)
9308 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9311 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9313 "&& TARGET_TLS_MARKERS"
9315 (unspec:TLSmode [(match_dup 1)
9318 (parallel [(set (match_dup 0)
9319 (call (mem:TLSmode (match_dup 3))
9321 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9322 (clobber (reg:SI LR_REGNO))])]
9324 [(set_attr "type" "two")
9325 (set (attr "length")
9326 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9330 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9331 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9332 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9333 (match_operand 4 "" "g")))
9334 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9335 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9337 (clobber (reg:SI LR_REGNO))]
9338 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9342 if (TARGET_SECURE_PLT && flag_pic == 2)
9343 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9345 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9348 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9350 "&& TARGET_TLS_MARKERS"
9352 (unspec:TLSmode [(match_dup 1)
9355 (parallel [(set (match_dup 0)
9356 (call (mem:TLSmode (match_dup 3))
9358 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9359 (clobber (reg:SI LR_REGNO))])]
9361 [(set_attr "type" "two")
9362 (set_attr "length" "8")])
9364 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9365 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9366 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9367 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9369 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9370 "addi %0,%1,%2@got@tlsgd"
9371 "&& TARGET_CMODEL != CMODEL_SMALL"
9374 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9376 (lo_sum:TLSmode (match_dup 3)
9377 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9379 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9381 [(set (attr "length")
9382 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9386 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9387 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9389 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9390 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9392 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9393 "addis %0,%1,%2@got@tlsgd@ha"
9394 [(set_attr "length" "4")])
9396 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9397 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9398 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9399 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9400 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9402 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9403 "addi %0,%1,%2@got@tlsgd@l"
9404 [(set_attr "length" "4")])
9406 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9407 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9408 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9409 (match_operand 2 "" "g")))
9410 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9412 (clobber (reg:SI LR_REGNO))]
9413 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9414 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9415 "bl %z1(%3@tlsgd)\;nop"
9416 [(set_attr "type" "branch")
9417 (set_attr "length" "8")])
9419 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9420 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9421 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9422 (match_operand 2 "" "g")))
9423 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9425 (clobber (reg:SI LR_REGNO))]
9426 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9430 if (TARGET_SECURE_PLT && flag_pic == 2)
9431 return "bl %z1+32768(%3@tlsgd)@plt";
9432 return "bl %z1(%3@tlsgd)@plt";
9434 return "bl %z1(%3@tlsgd)";
9436 [(set_attr "type" "branch")
9437 (set_attr "length" "4")])
9439 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9440 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9441 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9442 (match_operand 3 "" "g")))
9443 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9445 (clobber (reg:SI LR_REGNO))]
9446 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9448 if (TARGET_CMODEL != CMODEL_SMALL)
9449 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9452 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9454 "&& TARGET_TLS_MARKERS"
9456 (unspec:TLSmode [(match_dup 1)]
9458 (parallel [(set (match_dup 0)
9459 (call (mem:TLSmode (match_dup 2))
9461 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9462 (clobber (reg:SI LR_REGNO))])]
9464 [(set_attr "type" "two")
9465 (set (attr "length")
9466 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9470 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9471 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9472 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9473 (match_operand 3 "" "g")))
9474 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9476 (clobber (reg:SI LR_REGNO))]
9477 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9481 if (TARGET_SECURE_PLT && flag_pic == 2)
9482 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9484 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9487 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9489 "&& TARGET_TLS_MARKERS"
9491 (unspec:TLSmode [(match_dup 1)]
9493 (parallel [(set (match_dup 0)
9494 (call (mem:TLSmode (match_dup 2))
9496 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9497 (clobber (reg:SI LR_REGNO))])]
9499 [(set_attr "length" "8")])
9501 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9502 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9503 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9505 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9506 "addi %0,%1,%&@got@tlsld"
9507 "&& TARGET_CMODEL != CMODEL_SMALL"
9510 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9512 (lo_sum:TLSmode (match_dup 2)
9513 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9515 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9517 [(set (attr "length")
9518 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9522 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9523 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9525 (unspec:TLSmode [(const_int 0)
9526 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9528 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9529 "addis %0,%1,%&@got@tlsld@ha"
9530 [(set_attr "length" "4")])
9532 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9533 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9534 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9535 (unspec:TLSmode [(const_int 0)
9536 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9538 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9539 "addi %0,%1,%&@got@tlsld@l"
9540 [(set_attr "length" "4")])
9542 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9543 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9544 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9545 (match_operand 2 "" "g")))
9546 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9547 (clobber (reg:SI LR_REGNO))]
9548 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9549 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9550 "bl %z1(%&@tlsld)\;nop"
9551 [(set_attr "type" "branch")
9552 (set_attr "length" "8")])
9554 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9555 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9556 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9557 (match_operand 2 "" "g")))
9558 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9559 (clobber (reg:SI LR_REGNO))]
9560 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9564 if (TARGET_SECURE_PLT && flag_pic == 2)
9565 return "bl %z1+32768(%&@tlsld)@plt";
9566 return "bl %z1(%&@tlsld)@plt";
9568 return "bl %z1(%&@tlsld)";
9570 [(set_attr "type" "branch")
9571 (set_attr "length" "4")])
9573 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9574 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9575 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9576 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9579 "addi %0,%1,%2@dtprel")
9581 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9582 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9583 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9584 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9585 UNSPEC_TLSDTPRELHA))]
9587 "addis %0,%1,%2@dtprel@ha")
9589 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9590 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9591 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9592 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9593 UNSPEC_TLSDTPRELLO))]
9595 "addi %0,%1,%2@dtprel@l")
9597 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9598 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9599 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9600 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9601 UNSPEC_TLSGOTDTPREL))]
9603 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9604 "&& TARGET_CMODEL != CMODEL_SMALL"
9607 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9609 (lo_sum:TLSmode (match_dup 3)
9610 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9612 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9614 [(set (attr "length")
9615 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9619 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9620 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9622 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9623 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9624 UNSPEC_TLSGOTDTPREL)))]
9625 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9626 "addis %0,%1,%2@got@dtprel@ha"
9627 [(set_attr "length" "4")])
9629 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9630 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9631 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9632 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9633 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9634 UNSPEC_TLSGOTDTPREL)))]
9635 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9636 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9637 [(set_attr "length" "4")])
9639 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9640 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9641 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9642 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9645 "addi %0,%1,%2@tprel")
9647 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9648 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9649 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9650 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9651 UNSPEC_TLSTPRELHA))]
9653 "addis %0,%1,%2@tprel@ha")
9655 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9656 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9657 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9658 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9659 UNSPEC_TLSTPRELLO))]
9661 "addi %0,%1,%2@tprel@l")
9663 ;; "b" output constraint here and on tls_tls input to support linker tls
9664 ;; optimization. The linker may edit the instructions emitted by a
9665 ;; tls_got_tprel/tls_tls pair to addis,addi.
9666 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9667 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9668 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9669 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9670 UNSPEC_TLSGOTTPREL))]
9672 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9673 "&& TARGET_CMODEL != CMODEL_SMALL"
9676 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9678 (lo_sum:TLSmode (match_dup 3)
9679 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9681 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9683 [(set (attr "length")
9684 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9688 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9689 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9691 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9692 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9693 UNSPEC_TLSGOTTPREL)))]
9694 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9695 "addis %0,%1,%2@got@tprel@ha"
9696 [(set_attr "length" "4")])
9698 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9699 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9700 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9701 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9702 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9703 UNSPEC_TLSGOTTPREL)))]
9704 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9705 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9706 [(set_attr "length" "4")])
9708 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9709 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9710 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9711 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9713 "TARGET_ELF && HAVE_AS_TLS"
9716 (define_expand "tls_get_tpointer"
9717 [(set (match_operand:SI 0 "gpc_reg_operand")
9718 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9719 "TARGET_XCOFF && HAVE_AS_TLS"
9721 emit_insn (gen_tls_get_tpointer_internal ());
9722 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9726 (define_insn "tls_get_tpointer_internal"
9728 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9729 (clobber (reg:SI LR_REGNO))]
9730 "TARGET_XCOFF && HAVE_AS_TLS"
9731 "bla __get_tpointer")
9733 (define_expand "tls_get_addr<mode>"
9734 [(set (match_operand:P 0 "gpc_reg_operand")
9735 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9736 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9737 "TARGET_XCOFF && HAVE_AS_TLS"
9739 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9740 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9741 emit_insn (gen_tls_get_addr_internal<mode> ());
9742 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9746 (define_insn "tls_get_addr_internal<mode>"
9748 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9752 (clobber (reg:P 11))
9753 (clobber (reg:CC CR0_REGNO))
9754 (clobber (reg:P LR_REGNO))]
9755 "TARGET_XCOFF && HAVE_AS_TLS"
9756 "bla __tls_get_addr")
9758 ;; Next come insns related to the calling sequence.
9760 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9761 ;; We move the back-chain and decrement the stack pointer.
9763 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9764 ;; constant alloca, using that predicate will force the generic code to put
9765 ;; the constant size into a register before calling the expander.
9767 ;; As a result the expander would not have the constant size information
9768 ;; in those cases and would have to generate less efficient code.
9770 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9771 ;; the constant size. The value is forced into a register if necessary.
9773 (define_expand "allocate_stack"
9774 [(set (match_operand 0 "gpc_reg_operand")
9775 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9777 (minus (reg 1) (match_dup 1)))]
9780 rtx chain = gen_reg_rtx (Pmode);
9781 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9783 rtx insn, par, set, mem;
9785 /* By allowing reg_or_cint_operand as the predicate we can get
9786 better code for stack-clash-protection because we do not lose
9787 size information. But the rest of the code expects the operand
9788 to be reg_or_short_operand. If it isn't, then force it into
9790 rtx orig_op1 = operands[1];
9791 if (!reg_or_short_operand (operands[1], Pmode))
9792 operands[1] = force_reg (Pmode, operands[1]);
9794 emit_move_insn (chain, stack_bot);
9796 /* Check stack bounds if necessary. */
9797 if (crtl->limit_stack)
9800 available = expand_binop (Pmode, sub_optab,
9801 stack_pointer_rtx, stack_limit_rtx,
9802 NULL_RTX, 1, OPTAB_WIDEN);
9803 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9806 /* Allocate and probe if requested.
9807 This may look similar to the loop we use for prologue allocations,
9808 but it is critically different. For the former we know the loop
9809 will iterate, but do not know that generally here. The former
9810 uses that knowledge to rotate the loop. Combining them would be
9811 possible with some performance cost. */
9812 if (flag_stack_clash_protection)
9814 rtx rounded_size, last_addr, residual;
9815 HOST_WIDE_INT probe_interval;
9816 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9817 &residual, &probe_interval,
9820 /* We do occasionally get in here with constant sizes, we might
9821 as well do a reasonable job when we obviously can. */
9822 if (rounded_size != const0_rtx)
9824 rtx loop_lab, end_loop;
9825 bool rotated = CONST_INT_P (rounded_size);
9826 rtx update = GEN_INT (-probe_interval);
9827 if (probe_interval > 32768)
9828 update = force_reg (Pmode, update);
9830 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9831 last_addr, rotated);
9833 if (Pmode == SImode)
9834 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9838 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9841 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9842 last_addr, rotated);
9845 /* Now handle residuals. We just have to set operands[1] correctly
9846 and let the rest of the expander run. */
9847 operands[1] = residual;
9850 if (!(CONST_INT_P (operands[1])
9851 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9853 operands[1] = force_reg (Pmode, operands[1]);
9854 neg_op0 = gen_reg_rtx (Pmode);
9856 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9858 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9861 neg_op0 = GEN_INT (-INTVAL (operands[1]));
9863 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9864 : gen_movdi_di_update_stack))
9865 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9867 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9868 it now and set the alias set/attributes. The above gen_*_update
9869 calls will generate a PARALLEL with the MEM set being the first
9871 par = PATTERN (insn);
9872 gcc_assert (GET_CODE (par) == PARALLEL);
9873 set = XVECEXP (par, 0, 0);
9874 gcc_assert (GET_CODE (set) == SET);
9875 mem = SET_DEST (set);
9876 gcc_assert (MEM_P (mem));
9877 MEM_NOTRAP_P (mem) = 1;
9878 set_mem_alias_set (mem, get_frame_alias_set ());
9880 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9884 ;; These patterns say how to save and restore the stack pointer. We need not
9885 ;; save the stack pointer at function level since we are careful to
9886 ;; preserve the backchain. At block level, we have to restore the backchain
9887 ;; when we restore the stack pointer.
9889 ;; For nonlocal gotos, we must save both the stack pointer and its
9890 ;; backchain and restore both. Note that in the nonlocal case, the
9891 ;; save area is a memory location.
9893 (define_expand "save_stack_function"
9894 [(match_operand 0 "any_operand")
9895 (match_operand 1 "any_operand")]
9899 (define_expand "restore_stack_function"
9900 [(match_operand 0 "any_operand")
9901 (match_operand 1 "any_operand")]
9905 ;; Adjust stack pointer (op0) to a new value (op1).
9906 ;; First copy old stack backchain to new location, and ensure that the
9907 ;; scheduler won't reorder the sp assignment before the backchain write.
9908 (define_expand "restore_stack_block"
9909 [(set (match_dup 2) (match_dup 3))
9910 (set (match_dup 4) (match_dup 2))
9912 (set (match_operand 0 "register_operand")
9913 (match_operand 1 "register_operand"))]
9918 operands[1] = force_reg (Pmode, operands[1]);
9919 operands[2] = gen_reg_rtx (Pmode);
9920 operands[3] = gen_frame_mem (Pmode, operands[0]);
9921 operands[4] = gen_frame_mem (Pmode, operands[1]);
9922 p = rtvec_alloc (1);
9923 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9925 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9928 (define_expand "save_stack_nonlocal"
9929 [(set (match_dup 3) (match_dup 4))
9930 (set (match_operand 0 "memory_operand") (match_dup 3))
9931 (set (match_dup 2) (match_operand 1 "register_operand"))]
9934 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9936 /* Copy the backchain to the first word, sp to the second. */
9937 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9938 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9939 operands[3] = gen_reg_rtx (Pmode);
9940 operands[4] = gen_frame_mem (Pmode, operands[1]);
9943 (define_expand "restore_stack_nonlocal"
9944 [(set (match_dup 2) (match_operand 1 "memory_operand"))
9945 (set (match_dup 3) (match_dup 4))
9946 (set (match_dup 5) (match_dup 2))
9948 (set (match_operand 0 "register_operand") (match_dup 3))]
9951 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9954 /* Restore the backchain from the first word, sp from the second. */
9955 operands[2] = gen_reg_rtx (Pmode);
9956 operands[3] = gen_reg_rtx (Pmode);
9957 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9958 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9959 operands[5] = gen_frame_mem (Pmode, operands[3]);
9960 p = rtvec_alloc (1);
9961 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9963 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9966 ;; TOC register handling.
9968 ;; Code to initialize the TOC register...
9970 (define_insn "load_toc_aix_si"
9971 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9972 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9974 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9977 extern int need_toc_init;
9979 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9980 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9981 operands[2] = gen_rtx_REG (Pmode, 2);
9982 return "lwz %0,%1(%2)";
9984 [(set_attr "type" "load")
9985 (set_attr "update" "no")
9986 (set_attr "indexed" "no")])
9988 (define_insn "load_toc_aix_di"
9989 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9990 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9992 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9995 extern int need_toc_init;
9997 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9998 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10000 strcat (buf, "@toc");
10001 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10002 operands[2] = gen_rtx_REG (Pmode, 2);
10003 return "ld %0,%1(%2)";
10005 [(set_attr "type" "load")
10006 (set_attr "update" "no")
10007 (set_attr "indexed" "no")])
10009 (define_insn "load_toc_v4_pic_si"
10010 [(set (reg:SI LR_REGNO)
10011 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10012 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10013 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10014 [(set_attr "type" "branch")
10015 (set_attr "length" "4")])
10017 (define_expand "load_toc_v4_PIC_1"
10018 [(parallel [(set (reg:SI LR_REGNO)
10019 (match_operand:SI 0 "immediate_operand" "s"))
10020 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10021 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10022 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10025 (define_insn "load_toc_v4_PIC_1_normal"
10026 [(set (reg:SI LR_REGNO)
10027 (match_operand:SI 0 "immediate_operand" "s"))
10028 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10029 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10030 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10031 "bcl 20,31,%0\n%0:"
10032 [(set_attr "type" "branch")
10033 (set_attr "length" "4")
10034 (set_attr "cannot_copy" "yes")])
10036 (define_insn "load_toc_v4_PIC_1_476"
10037 [(set (reg:SI LR_REGNO)
10038 (match_operand:SI 0 "immediate_operand" "s"))
10039 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10040 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10041 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10044 static char templ[32];
10046 get_ppc476_thunk_name (name);
10047 sprintf (templ, "bl %s\n%%0:", name);
10050 [(set_attr "type" "branch")
10051 (set_attr "length" "4")
10052 (set_attr "cannot_copy" "yes")])
10054 (define_expand "load_toc_v4_PIC_1b"
10055 [(parallel [(set (reg:SI LR_REGNO)
10056 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10057 (label_ref (match_operand 1 ""))]
10060 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10063 (define_insn "load_toc_v4_PIC_1b_normal"
10064 [(set (reg:SI LR_REGNO)
10065 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10066 (label_ref (match_operand 1 "" ""))]
10069 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10070 "bcl 20,31,$+8\;.long %0-$"
10071 [(set_attr "type" "branch")
10072 (set_attr "length" "8")])
10074 (define_insn "load_toc_v4_PIC_1b_476"
10075 [(set (reg:SI LR_REGNO)
10076 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10077 (label_ref (match_operand 1 "" ""))]
10080 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10083 static char templ[32];
10085 get_ppc476_thunk_name (name);
10086 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10089 [(set_attr "type" "branch")
10090 (set_attr "length" "16")])
10092 (define_insn "load_toc_v4_PIC_2"
10093 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10095 (match_operand:SI 1 "gpc_reg_operand" "b")
10097 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10098 (match_operand:SI 3 "immediate_operand" "s"))))))]
10099 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10101 [(set_attr "type" "load")])
10103 (define_insn "load_toc_v4_PIC_3b"
10104 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10106 (match_operand:SI 1 "gpc_reg_operand" "b")
10109 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10110 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10111 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10112 "addis %0,%1,%2-%3@ha")
10114 (define_insn "load_toc_v4_PIC_3c"
10115 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10117 (match_operand:SI 1 "gpc_reg_operand" "b")
10119 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10120 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10121 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10122 "addi %0,%1,%2-%3@l")
10124 ;; If the TOC is shared over a translation unit, as happens with all
10125 ;; the kinds of PIC that we support, we need to restore the TOC
10126 ;; pointer only when jumping over units of translation.
10127 ;; On Darwin, we need to reload the picbase.
10129 (define_expand "builtin_setjmp_receiver"
10130 [(use (label_ref (match_operand 0 "")))]
10131 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10132 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10133 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10136 if (DEFAULT_ABI == ABI_DARWIN)
10138 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10139 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10143 crtl->uses_pic_offset_table = 1;
10144 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10145 CODE_LABEL_NUMBER (operands[0]));
10146 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10148 emit_insn (gen_load_macho_picbase (tmplabrtx));
10149 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10150 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10154 rs6000_emit_load_toc_table (FALSE);
10158 ;; Largetoc support
10159 (define_insn "*largetoc_high"
10160 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10162 (unspec [(match_operand:DI 1 "" "")
10163 (match_operand:DI 2 "gpc_reg_operand" "b")]
10165 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10166 "addis %0,%2,%1@toc@ha")
10168 (define_insn "*largetoc_high_aix<mode>"
10169 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10171 (unspec [(match_operand:P 1 "" "")
10172 (match_operand:P 2 "gpc_reg_operand" "b")]
10174 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10175 "addis %0,%1@u(%2)")
10177 (define_insn "*largetoc_high_plus"
10178 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10181 (unspec [(match_operand:DI 1 "" "")
10182 (match_operand:DI 2 "gpc_reg_operand" "b")]
10184 (match_operand:DI 3 "add_cint_operand" "n"))))]
10185 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10186 "addis %0,%2,%1+%3@toc@ha")
10188 (define_insn "*largetoc_high_plus_aix<mode>"
10189 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10192 (unspec [(match_operand:P 1 "" "")
10193 (match_operand:P 2 "gpc_reg_operand" "b")]
10195 (match_operand:P 3 "add_cint_operand" "n"))))]
10196 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10197 "addis %0,%1+%3@u(%2)")
10199 (define_insn "*largetoc_low"
10200 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10201 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10202 (match_operand:DI 2 "" "")))]
10203 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10206 (define_insn "*largetoc_low_aix<mode>"
10207 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10208 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10209 (match_operand:P 2 "" "")))]
10210 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10213 (define_insn_and_split "*tocref<mode>"
10214 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10215 (match_operand:P 1 "small_toc_ref" "R"))]
10218 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10219 [(set (match_dup 0) (high:P (match_dup 1)))
10220 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10222 ;; Elf specific ways of loading addresses for non-PIC code.
10223 ;; The output of this could be r0, but we make a very strong
10224 ;; preference for a base register because it will usually
10225 ;; be needed there.
10226 (define_insn "elf_high"
10227 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10228 (high:SI (match_operand 1 "" "")))]
10229 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10232 (define_insn "elf_low"
10233 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10234 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10235 (match_operand 2 "" "")))]
10236 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10239 ;; Call and call_value insns
10240 (define_expand "call"
10241 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10242 (match_operand 1 ""))
10243 (use (match_operand 2 ""))
10244 (clobber (reg:SI LR_REGNO))])]
10248 if (MACHOPIC_INDIRECT)
10249 operands[0] = machopic_indirect_call_target (operands[0]);
10252 gcc_assert (GET_CODE (operands[0]) == MEM);
10253 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10255 operands[0] = XEXP (operands[0], 0);
10257 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10259 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10263 if (GET_CODE (operands[0]) != SYMBOL_REF
10264 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10266 if (INTVAL (operands[2]) & CALL_LONG)
10267 operands[0] = rs6000_longcall_ref (operands[0]);
10269 switch (DEFAULT_ABI)
10273 operands[0] = force_reg (Pmode, operands[0]);
10277 gcc_unreachable ();
10282 (define_expand "call_value"
10283 [(parallel [(set (match_operand 0 "")
10284 (call (mem:SI (match_operand 1 "address_operand"))
10285 (match_operand 2 "")))
10286 (use (match_operand 3 ""))
10287 (clobber (reg:SI LR_REGNO))])]
10291 if (MACHOPIC_INDIRECT)
10292 operands[1] = machopic_indirect_call_target (operands[1]);
10295 gcc_assert (GET_CODE (operands[1]) == MEM);
10296 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10298 operands[1] = XEXP (operands[1], 0);
10300 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10302 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10306 if (GET_CODE (operands[1]) != SYMBOL_REF
10307 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10309 if (INTVAL (operands[3]) & CALL_LONG)
10310 operands[1] = rs6000_longcall_ref (operands[1]);
10312 switch (DEFAULT_ABI)
10316 operands[1] = force_reg (Pmode, operands[1]);
10320 gcc_unreachable ();
10325 ;; Call to function in current module. No TOC pointer reload needed.
10326 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10327 ;; either the function was not prototyped, or it was prototyped as a
10328 ;; variable argument function. It is > 0 if FP registers were passed
10329 ;; and < 0 if they were not.
10331 (define_insn "*call_local32"
10332 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10333 (match_operand 1 "" "g,g"))
10334 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10335 (clobber (reg:SI LR_REGNO))]
10336 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10338 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10339 output_asm_insn ("crxor 6,6,6", operands);
10341 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10342 output_asm_insn ("creqv 6,6,6", operands);
10344 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10346 [(set_attr "type" "branch")
10347 (set_attr "length" "4,8")])
10349 (define_insn "*call_local64"
10350 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10351 (match_operand 1 "" "g,g"))
10352 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10353 (clobber (reg:SI LR_REGNO))]
10354 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10356 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10357 output_asm_insn ("crxor 6,6,6", operands);
10359 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10360 output_asm_insn ("creqv 6,6,6", operands);
10362 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10364 [(set_attr "type" "branch")
10365 (set_attr "length" "4,8")])
10367 (define_insn "*call_value_local32"
10368 [(set (match_operand 0 "" "")
10369 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10370 (match_operand 2 "" "g,g")))
10371 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10372 (clobber (reg:SI LR_REGNO))]
10373 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10375 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10376 output_asm_insn ("crxor 6,6,6", operands);
10378 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10379 output_asm_insn ("creqv 6,6,6", operands);
10381 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10383 [(set_attr "type" "branch")
10384 (set_attr "length" "4,8")])
10387 (define_insn "*call_value_local64"
10388 [(set (match_operand 0 "" "")
10389 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10390 (match_operand 2 "" "g,g")))
10391 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10392 (clobber (reg:SI LR_REGNO))]
10393 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10395 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10396 output_asm_insn ("crxor 6,6,6", operands);
10398 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10399 output_asm_insn ("creqv 6,6,6", operands);
10401 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10403 [(set_attr "type" "branch")
10404 (set_attr "length" "4,8")])
10407 ;; A function pointer under System V is just a normal pointer
10408 ;; operands[0] is the function pointer
10409 ;; operands[1] is the stack size to clean up
10410 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10411 ;; which indicates how to set cr1
10413 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10414 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10415 (match_operand 1 "" "g,g,g,g"))
10416 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10417 (clobber (reg:SI LR_REGNO))]
10418 "DEFAULT_ABI == ABI_V4
10419 || DEFAULT_ABI == ABI_DARWIN"
10421 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10422 output_asm_insn ("crxor 6,6,6", operands);
10424 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10425 output_asm_insn ("creqv 6,6,6", operands);
10427 if (rs6000_speculate_indirect_jumps
10428 || which_alternative == 1 || which_alternative == 3)
10431 return "crset 2\;beq%T0l-";
10433 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10434 (set (attr "length")
10435 (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10436 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10439 (and (eq (symbol_ref "which_alternative") (const_int 2))
10440 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10443 (and (eq (symbol_ref "which_alternative") (const_int 2))
10444 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10446 (const_string "12")
10447 (eq (symbol_ref "which_alternative") (const_int 3))
10448 (const_string "8")]
10449 (const_string "4")))])
10451 (define_insn_and_split "*call_nonlocal_sysv<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 (clobber (reg:SI LR_REGNO))]
10456 "(DEFAULT_ABI == ABI_DARWIN
10457 || (DEFAULT_ABI == ABI_V4
10458 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10460 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10461 output_asm_insn ("crxor 6,6,6", operands);
10463 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10464 output_asm_insn ("creqv 6,6,6", operands);
10467 return output_call(insn, operands, 0, 2);
10469 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10471 gcc_assert (!TARGET_SECURE_PLT);
10472 return "bl %z0@plt";
10478 "DEFAULT_ABI == ABI_V4
10479 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10480 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10481 [(parallel [(call (mem:SI (match_dup 0))
10483 (use (match_dup 2))
10484 (use (match_dup 3))
10485 (clobber (reg:SI LR_REGNO))])]
10487 operands[3] = pic_offset_table_rtx;
10489 [(set_attr "type" "branch,branch")
10490 (set_attr "length" "4,8")])
10492 (define_insn "*call_nonlocal_sysv_secure<mode>"
10493 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10494 (match_operand 1 "" "g,g"))
10495 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10496 (use (match_operand:SI 3 "register_operand" "r,r"))
10497 (clobber (reg:SI LR_REGNO))]
10498 "(DEFAULT_ABI == ABI_V4
10499 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10500 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10502 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10503 output_asm_insn ("crxor 6,6,6", operands);
10505 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10506 output_asm_insn ("creqv 6,6,6", operands);
10509 /* The magic 32768 offset here and in the other sysv call insns
10510 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10511 See sysv4.h:toc_section. */
10512 return "bl %z0+32768@plt";
10514 return "bl %z0@plt";
10516 [(set_attr "type" "branch,branch")
10517 (set_attr "length" "4,8")])
10519 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10520 [(set (match_operand 0 "" "")
10521 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10522 (match_operand 2 "" "g,g,g,g")))
10523 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10524 (clobber (reg:SI LR_REGNO))]
10525 "DEFAULT_ABI == ABI_V4
10526 || DEFAULT_ABI == ABI_DARWIN"
10528 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10529 output_asm_insn ("crxor 6,6,6", operands);
10531 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10532 output_asm_insn ("creqv 6,6,6", operands);
10534 if (rs6000_speculate_indirect_jumps
10535 || which_alternative == 1 || which_alternative == 3)
10538 return "crset 2\;beq%T1l-";
10540 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10541 (set (attr "length")
10542 (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10543 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10546 (and (eq (symbol_ref "which_alternative") (const_int 2))
10547 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10550 (and (eq (symbol_ref "which_alternative") (const_int 2))
10551 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10553 (const_string "12")
10554 (eq (symbol_ref "which_alternative") (const_int 3))
10555 (const_string "8")]
10556 (const_string "4")))])
10558 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10559 [(set (match_operand 0 "" "")
10560 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10561 (match_operand 2 "" "g,g")))
10562 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10563 (clobber (reg:SI LR_REGNO))]
10564 "(DEFAULT_ABI == ABI_DARWIN
10565 || (DEFAULT_ABI == ABI_V4
10566 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10568 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10569 output_asm_insn ("crxor 6,6,6", operands);
10571 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10572 output_asm_insn ("creqv 6,6,6", operands);
10575 return output_call(insn, operands, 1, 3);
10577 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10579 gcc_assert (!TARGET_SECURE_PLT);
10580 return "bl %z1@plt";
10586 "DEFAULT_ABI == ABI_V4
10587 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10588 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10589 [(parallel [(set (match_dup 0)
10590 (call (mem:SI (match_dup 1))
10592 (use (match_dup 3))
10593 (use (match_dup 4))
10594 (clobber (reg:SI LR_REGNO))])]
10596 operands[4] = pic_offset_table_rtx;
10598 [(set_attr "type" "branch,branch")
10599 (set_attr "length" "4,8")])
10601 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10602 [(set (match_operand 0 "" "")
10603 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10604 (match_operand 2 "" "g,g")))
10605 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10606 (use (match_operand:SI 4 "register_operand" "r,r"))
10607 (clobber (reg:SI LR_REGNO))]
10608 "(DEFAULT_ABI == ABI_V4
10609 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10610 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10612 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10613 output_asm_insn ("crxor 6,6,6", operands);
10615 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10616 output_asm_insn ("creqv 6,6,6", operands);
10619 return "bl %z1+32768@plt";
10621 return "bl %z1@plt";
10623 [(set_attr "type" "branch,branch")
10624 (set_attr "length" "4,8")])
10627 ;; Call to AIX abi function in the same module.
10629 (define_insn "*call_local_aix<mode>"
10630 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10631 (match_operand 1 "" "g"))
10632 (clobber (reg:P LR_REGNO))]
10633 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10635 [(set_attr "type" "branch")
10636 (set_attr "length" "4")])
10638 (define_insn "*call_value_local_aix<mode>"
10639 [(set (match_operand 0 "" "")
10640 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10641 (match_operand 2 "" "g")))
10642 (clobber (reg:P LR_REGNO))]
10643 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10645 [(set_attr "type" "branch")
10646 (set_attr "length" "4")])
10648 ;; Call to AIX abi function which may be in another module.
10649 ;; Restore the TOC pointer (r2) after the call.
10651 (define_insn "*call_nonlocal_aix<mode>"
10652 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10653 (match_operand 1 "" "g"))
10654 (clobber (reg:P LR_REGNO))]
10655 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10657 [(set_attr "type" "branch")
10658 (set_attr "length" "8")])
10660 (define_insn "*call_value_nonlocal_aix<mode>"
10661 [(set (match_operand 0 "" "")
10662 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10663 (match_operand 2 "" "g")))
10664 (clobber (reg:P LR_REGNO))]
10665 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10667 [(set_attr "type" "branch")
10668 (set_attr "length" "8")])
10670 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10671 ;; Operand0 is the addresss of the function to call
10672 ;; Operand2 is the location in the function descriptor to load r2 from
10673 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10675 (define_insn "*call_indirect_aix<mode>"
10676 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10677 (match_operand 1 "" "g,g"))
10678 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10679 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10680 (clobber (reg:P LR_REGNO))]
10681 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10682 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10683 [(set_attr "type" "jmpreg")
10684 (set_attr "length" "12")])
10686 (define_insn "*call_indirect_aix<mode>_nospec"
10687 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10688 (match_operand 1 "" "g,g"))
10689 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10690 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10691 (clobber (reg:P LR_REGNO))]
10692 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10693 "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10694 [(set_attr "type" "jmpreg")
10695 (set_attr "length" "16")])
10697 (define_insn "*call_value_indirect_aix<mode>"
10698 [(set (match_operand 0 "" "")
10699 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10700 (match_operand 2 "" "g,g")))
10701 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10702 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10703 (clobber (reg:P LR_REGNO))]
10704 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10705 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10706 [(set_attr "type" "jmpreg")
10707 (set_attr "length" "12")])
10709 (define_insn "*call_value_indirect_aix<mode>_nospec"
10710 [(set (match_operand 0 "" "")
10711 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10712 (match_operand 2 "" "g,g")))
10713 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10714 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10715 (clobber (reg:P LR_REGNO))]
10716 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10717 "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10718 [(set_attr "type" "jmpreg")
10719 (set_attr "length" "16")])
10721 ;; Call to indirect functions with the ELFv2 ABI.
10722 ;; Operand0 is the addresss of the function to call
10723 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10725 (define_insn "*call_indirect_elfv2<mode>"
10726 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10727 (match_operand 1 "" "g,g"))
10728 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10729 (clobber (reg:P LR_REGNO))]
10730 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10731 "b%T0l\;<ptrload> 2,%2(1)"
10732 [(set_attr "type" "jmpreg")
10733 (set_attr "length" "8")])
10735 ;; Variant with deliberate misprediction.
10736 (define_insn "*call_indirect_elfv2<mode>_nospec"
10737 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10738 (match_operand 1 "" "g,g"))
10739 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10740 (clobber (reg:P LR_REGNO))]
10741 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10742 "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10743 [(set_attr "type" "jmpreg")
10744 (set_attr "length" "12")])
10746 (define_insn "*call_value_indirect_elfv2<mode>"
10747 [(set (match_operand 0 "" "")
10748 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10749 (match_operand 2 "" "g,g")))
10750 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10751 (clobber (reg:P LR_REGNO))]
10752 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10753 "b%T1l\;<ptrload> 2,%3(1)"
10754 [(set_attr "type" "jmpreg")
10755 (set_attr "length" "8")])
10757 ; Variant with deliberate misprediction.
10758 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10759 [(set (match_operand 0 "" "")
10760 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10761 (match_operand 2 "" "g,g")))
10762 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10763 (clobber (reg:P LR_REGNO))]
10764 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10765 "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10766 [(set_attr "type" "jmpreg")
10767 (set_attr "length" "12")])
10769 ;; Call subroutine returning any type.
10770 (define_expand "untyped_call"
10771 [(parallel [(call (match_operand 0 "")
10773 (match_operand 1 "")
10774 (match_operand 2 "")])]
10779 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10781 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10783 rtx set = XVECEXP (operands[2], 0, i);
10784 emit_move_insn (SET_DEST (set), SET_SRC (set));
10787 /* The optimizer does not know that the call sets the function value
10788 registers we stored in the result block. We avoid problems by
10789 claiming that all hard registers are used and clobbered at this
10791 emit_insn (gen_blockage ());
10796 ;; sibling call patterns
10797 (define_expand "sibcall"
10798 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10799 (match_operand 1 ""))
10800 (use (match_operand 2 ""))
10805 if (MACHOPIC_INDIRECT)
10806 operands[0] = machopic_indirect_call_target (operands[0]);
10809 gcc_assert (GET_CODE (operands[0]) == MEM);
10810 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10812 operands[0] = XEXP (operands[0], 0);
10814 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10816 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10821 (define_expand "sibcall_value"
10822 [(parallel [(set (match_operand 0 "register_operand")
10823 (call (mem:SI (match_operand 1 "address_operand"))
10824 (match_operand 2 "")))
10825 (use (match_operand 3 ""))
10830 if (MACHOPIC_INDIRECT)
10831 operands[1] = machopic_indirect_call_target (operands[1]);
10834 gcc_assert (GET_CODE (operands[1]) == MEM);
10835 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10837 operands[1] = XEXP (operands[1], 0);
10839 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10841 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10846 (define_insn "*sibcall_local32"
10847 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10848 (match_operand 1 "" "g,g"))
10849 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10851 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10853 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10854 output_asm_insn ("crxor 6,6,6", operands);
10856 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10857 output_asm_insn ("creqv 6,6,6", operands);
10859 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10861 [(set_attr "type" "branch")
10862 (set_attr "length" "4,8")])
10864 (define_insn "*sibcall_local64"
10865 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10866 (match_operand 1 "" "g,g"))
10867 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10869 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10871 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10872 output_asm_insn ("crxor 6,6,6", operands);
10874 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10875 output_asm_insn ("creqv 6,6,6", operands);
10877 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10879 [(set_attr "type" "branch")
10880 (set_attr "length" "4,8")])
10882 (define_insn "*sibcall_value_local32"
10883 [(set (match_operand 0 "" "")
10884 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10885 (match_operand 2 "" "g,g")))
10886 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10888 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10890 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10891 output_asm_insn ("crxor 6,6,6", operands);
10893 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10894 output_asm_insn ("creqv 6,6,6", operands);
10896 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10898 [(set_attr "type" "branch")
10899 (set_attr "length" "4,8")])
10901 (define_insn "*sibcall_value_local64"
10902 [(set (match_operand 0 "" "")
10903 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10904 (match_operand 2 "" "g,g")))
10905 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10907 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10909 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10910 output_asm_insn ("crxor 6,6,6", operands);
10912 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10913 output_asm_insn ("creqv 6,6,6", operands);
10915 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10917 [(set_attr "type" "branch")
10918 (set_attr "length" "4,8")])
10920 (define_insn "*sibcall_nonlocal_sysv<mode>"
10921 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10922 (match_operand 1 "" ""))
10923 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10925 "(DEFAULT_ABI == ABI_DARWIN
10926 || DEFAULT_ABI == ABI_V4)
10927 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10929 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10930 output_asm_insn ("crxor 6,6,6", operands);
10932 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10933 output_asm_insn ("creqv 6,6,6", operands);
10935 if (which_alternative >= 2)
10937 if (rs6000_speculate_indirect_jumps)
10940 /* Can use CR0 since it is volatile across sibcalls. */
10941 return "crset 2\;beq%T0-\;b $";
10943 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10945 gcc_assert (!TARGET_SECURE_PLT);
10946 return "b %z0@plt";
10951 [(set_attr "type" "branch")
10952 (set (attr "length")
10953 (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10955 (and (eq (symbol_ref "which_alternative") (const_int 2))
10956 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10958 (const_string "12")
10959 (and (eq (symbol_ref "which_alternative") (const_int 3))
10960 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10963 (and (eq (symbol_ref "which_alternative") (const_int 3))
10964 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10966 (const_string "16")]
10967 (const_string "4")))])
10969 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10970 [(set (match_operand 0 "" "")
10971 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10972 (match_operand 2 "" "")))
10973 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10975 "(DEFAULT_ABI == ABI_DARWIN
10976 || DEFAULT_ABI == ABI_V4)
10977 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10979 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10980 output_asm_insn ("crxor 6,6,6", operands);
10982 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10983 output_asm_insn ("creqv 6,6,6", operands);
10985 if (which_alternative >= 2)
10987 if (rs6000_speculate_indirect_jumps)
10990 /* Can use CR0 since it is volatile across sibcalls. */
10991 return "crset 2\;beq%T1-\;b $";
10993 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10995 gcc_assert (!TARGET_SECURE_PLT);
10996 return "b %z1@plt";
11001 [(set_attr "type" "branch")
11002 (set (attr "length")
11003 (cond [(eq (symbol_ref "which_alternative") (const_int 1))
11005 (and (eq (symbol_ref "which_alternative") (const_int 2))
11006 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11008 (const_string "12")
11009 (and (eq (symbol_ref "which_alternative") (const_int 3))
11010 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
11013 (and (eq (symbol_ref "which_alternative") (const_int 3))
11014 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11016 (const_string "16")]
11017 (const_string "4")))])
11019 ;; AIX ABI sibling call patterns.
11021 (define_insn "*sibcall_aix<mode>"
11022 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11023 (match_operand 1 "" "g,g"))
11025 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11029 [(set_attr "type" "branch")
11030 (set_attr "length" "4")])
11032 (define_insn "*sibcall_value_aix<mode>"
11033 [(set (match_operand 0 "" "")
11034 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11035 (match_operand 2 "" "g,g")))
11037 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11041 [(set_attr "type" "branch")
11042 (set_attr "length" "4")])
11044 (define_expand "sibcall_epilogue"
11045 [(use (const_int 0))]
11048 if (!TARGET_SCHED_PROLOG)
11049 emit_insn (gen_blockage ());
11050 rs6000_emit_epilogue (TRUE);
11054 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11055 ;; all of memory. This blocks insns from being moved across this point.
11057 (define_insn "blockage"
11058 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11061 [(set_attr "length" "0")])
11063 (define_expand "probe_stack_address"
11064 [(use (match_operand 0 "address_operand"))]
11067 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11068 MEM_VOLATILE_P (operands[0]) = 1;
11071 emit_insn (gen_probe_stack_di (operands[0]));
11073 emit_insn (gen_probe_stack_si (operands[0]));
11077 (define_insn "probe_stack_<mode>"
11078 [(set (match_operand:P 0 "memory_operand" "=m")
11079 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11082 operands[1] = gen_rtx_REG (Pmode, 0);
11083 return "st<wd>%U0%X0 %1,%0";
11085 [(set_attr "type" "store")
11086 (set (attr "update")
11087 (if_then_else (match_operand 0 "update_address_mem")
11088 (const_string "yes")
11089 (const_string "no")))
11090 (set (attr "indexed")
11091 (if_then_else (match_operand 0 "indexed_address_mem")
11092 (const_string "yes")
11093 (const_string "no")))
11094 (set_attr "length" "4")])
11096 (define_insn "probe_stack_range<P:mode>"
11097 [(set (match_operand:P 0 "register_operand" "=&r")
11098 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11099 (match_operand:P 2 "register_operand" "r")
11100 (match_operand:P 3 "register_operand" "r")]
11101 UNSPECV_PROBE_STACK_RANGE))]
11103 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11104 [(set_attr "type" "three")])
11106 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11107 ;; signed & unsigned, and one type of branch.
11109 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11110 ;; insns, and branches.
11112 (define_expand "cbranch<mode>4"
11113 [(use (match_operator 0 "comparison_operator"
11114 [(match_operand:GPR 1 "gpc_reg_operand")
11115 (match_operand:GPR 2 "reg_or_short_operand")]))
11116 (use (match_operand 3))]
11119 /* Take care of the possibility that operands[2] might be negative but
11120 this might be a logical operation. That insn doesn't exist. */
11121 if (GET_CODE (operands[2]) == CONST_INT
11122 && INTVAL (operands[2]) < 0)
11124 operands[2] = force_reg (<MODE>mode, operands[2]);
11125 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11126 GET_MODE (operands[0]),
11127 operands[1], operands[2]);
11130 rs6000_emit_cbranch (<MODE>mode, operands);
11134 (define_expand "cbranch<mode>4"
11135 [(use (match_operator 0 "comparison_operator"
11136 [(match_operand:FP 1 "gpc_reg_operand")
11137 (match_operand:FP 2 "gpc_reg_operand")]))
11138 (use (match_operand 3))]
11141 rs6000_emit_cbranch (<MODE>mode, operands);
11145 (define_expand "cstore<mode>4_signed"
11146 [(use (match_operator 1 "signed_comparison_operator"
11147 [(match_operand:P 2 "gpc_reg_operand")
11148 (match_operand:P 3 "gpc_reg_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 == GE || cond_code == LT)
11160 cond_code = swap_condition (cond_code);
11161 std::swap (op1, op2);
11164 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11165 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11166 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11168 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11169 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11170 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11172 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11174 if (cond_code == LE)
11175 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11178 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11179 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11180 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11186 (define_expand "cstore<mode>4_unsigned"
11187 [(use (match_operator 1 "unsigned_comparison_operator"
11188 [(match_operand:P 2 "gpc_reg_operand")
11189 (match_operand:P 3 "reg_or_short_operand")]))
11190 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11193 enum rtx_code cond_code = GET_CODE (operands[1]);
11195 rtx op0 = operands[0];
11196 rtx op1 = operands[2];
11197 rtx op2 = operands[3];
11199 if (cond_code == GEU || cond_code == LTU)
11201 cond_code = swap_condition (cond_code);
11202 std::swap (op1, op2);
11205 if (!gpc_reg_operand (op1, <MODE>mode))
11206 op1 = force_reg (<MODE>mode, op1);
11207 if (!reg_or_short_operand (op2, <MODE>mode))
11208 op2 = force_reg (<MODE>mode, op2);
11210 rtx tmp = gen_reg_rtx (<MODE>mode);
11211 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11213 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11214 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11216 if (cond_code == LEU)
11217 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11219 emit_insn (gen_neg<mode>2 (op0, tmp2));
11224 (define_expand "cstore_si_as_di"
11225 [(use (match_operator 1 "unsigned_comparison_operator"
11226 [(match_operand:SI 2 "gpc_reg_operand")
11227 (match_operand:SI 3 "reg_or_short_operand")]))
11228 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11231 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11232 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11234 operands[2] = force_reg (SImode, operands[2]);
11235 operands[3] = force_reg (SImode, operands[3]);
11236 rtx op1 = gen_reg_rtx (DImode);
11237 rtx op2 = gen_reg_rtx (DImode);
11238 convert_move (op1, operands[2], uns_flag);
11239 convert_move (op2, operands[3], uns_flag);
11241 if (cond_code == GT || cond_code == LE)
11243 cond_code = swap_condition (cond_code);
11244 std::swap (op1, op2);
11247 rtx tmp = gen_reg_rtx (DImode);
11248 rtx tmp2 = gen_reg_rtx (DImode);
11249 emit_insn (gen_subdi3 (tmp, op1, op2));
11250 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11256 gcc_unreachable ();
11261 tmp3 = gen_reg_rtx (DImode);
11262 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11266 convert_move (operands[0], tmp3, 1);
11271 (define_expand "cstore<mode>4_signed_imm"
11272 [(use (match_operator 1 "signed_comparison_operator"
11273 [(match_operand:GPR 2 "gpc_reg_operand")
11274 (match_operand:GPR 3 "immediate_operand")]))
11275 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11278 bool invert = false;
11280 enum rtx_code cond_code = GET_CODE (operands[1]);
11282 rtx op0 = operands[0];
11283 rtx op1 = operands[2];
11284 HOST_WIDE_INT val = INTVAL (operands[3]);
11286 if (cond_code == GE || cond_code == GT)
11288 cond_code = reverse_condition (cond_code);
11292 if (cond_code == LE)
11295 rtx tmp = gen_reg_rtx (<MODE>mode);
11296 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11297 rtx x = gen_reg_rtx (<MODE>mode);
11299 emit_insn (gen_and<mode>3 (x, op1, tmp));
11301 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11305 rtx tmp = gen_reg_rtx (<MODE>mode);
11306 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11310 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11311 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11316 (define_expand "cstore<mode>4_unsigned_imm"
11317 [(use (match_operator 1 "unsigned_comparison_operator"
11318 [(match_operand:GPR 2 "gpc_reg_operand")
11319 (match_operand:GPR 3 "immediate_operand")]))
11320 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11323 bool invert = false;
11325 enum rtx_code cond_code = GET_CODE (operands[1]);
11327 rtx op0 = operands[0];
11328 rtx op1 = operands[2];
11329 HOST_WIDE_INT val = INTVAL (operands[3]);
11331 if (cond_code == GEU || cond_code == GTU)
11333 cond_code = reverse_condition (cond_code);
11337 if (cond_code == LEU)
11340 rtx tmp = gen_reg_rtx (<MODE>mode);
11341 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11342 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11343 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11344 rtx x = gen_reg_rtx (<MODE>mode);
11346 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11348 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11352 rtx tmp = gen_reg_rtx (<MODE>mode);
11353 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11357 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11358 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11363 (define_expand "cstore<mode>4"
11364 [(use (match_operator 1 "comparison_operator"
11365 [(match_operand:GPR 2 "gpc_reg_operand")
11366 (match_operand:GPR 3 "reg_or_short_operand")]))
11367 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11370 /* Expanding EQ and NE directly to some machine instructions does not help
11371 but does hurt combine. So don't. */
11372 if (GET_CODE (operands[1]) == EQ)
11373 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11374 else if (<MODE>mode == Pmode
11375 && GET_CODE (operands[1]) == NE)
11376 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11377 else if (GET_CODE (operands[1]) == NE)
11379 rtx tmp = gen_reg_rtx (<MODE>mode);
11380 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11381 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11384 /* If ISEL is fast, expand to it. */
11385 else if (TARGET_ISEL)
11386 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11388 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11389 etc. combinations magically work out just right. */
11390 else if (<MODE>mode == Pmode
11391 && unsigned_comparison_operator (operands[1], VOIDmode))
11392 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11393 operands[2], operands[3]));
11395 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11396 else if (<MODE>mode == SImode && Pmode == DImode)
11397 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11398 operands[2], operands[3]));
11400 /* For signed comparisons against a constant, we can do some simple
11402 else if (signed_comparison_operator (operands[1], VOIDmode)
11403 && CONST_INT_P (operands[3]))
11404 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11405 operands[2], operands[3]));
11407 /* And similarly for unsigned comparisons. */
11408 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11409 && CONST_INT_P (operands[3]))
11410 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11411 operands[2], operands[3]));
11413 /* We also do not want to use mfcr for signed comparisons. */
11414 else if (<MODE>mode == Pmode
11415 && signed_comparison_operator (operands[1], VOIDmode))
11416 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11417 operands[2], operands[3]));
11419 /* Everything else, use the mfcr brute force. */
11421 rs6000_emit_sCOND (<MODE>mode, operands);
11426 (define_expand "cstore<mode>4"
11427 [(use (match_operator 1 "comparison_operator"
11428 [(match_operand:FP 2 "gpc_reg_operand")
11429 (match_operand:FP 3 "gpc_reg_operand")]))
11430 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11433 rs6000_emit_sCOND (<MODE>mode, operands);
11438 (define_expand "stack_protect_set"
11439 [(match_operand 0 "memory_operand")
11440 (match_operand 1 "memory_operand")]
11443 if (rs6000_stack_protector_guard == SSP_TLS)
11445 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11446 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11447 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11448 operands[1] = gen_rtx_MEM (Pmode, addr);
11452 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11454 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11459 (define_insn "stack_protect_setsi"
11460 [(set (match_operand:SI 0 "memory_operand" "=m")
11461 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11462 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11464 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11465 [(set_attr "type" "three")
11466 (set_attr "length" "12")])
11468 (define_insn "stack_protect_setdi"
11469 [(set (match_operand:DI 0 "memory_operand" "=Y")
11470 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11471 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11473 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11474 [(set_attr "type" "three")
11475 (set_attr "length" "12")])
11477 (define_expand "stack_protect_test"
11478 [(match_operand 0 "memory_operand")
11479 (match_operand 1 "memory_operand")
11480 (match_operand 2 "")]
11483 rtx guard = operands[1];
11485 if (rs6000_stack_protector_guard == SSP_TLS)
11487 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11488 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11489 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11490 guard = gen_rtx_MEM (Pmode, addr);
11493 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11494 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11495 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11496 emit_jump_insn (jump);
11501 (define_insn "stack_protect_testsi"
11502 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11503 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11504 (match_operand:SI 2 "memory_operand" "m,m")]
11506 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11507 (clobber (match_scratch:SI 3 "=&r,&r"))]
11510 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11511 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11512 [(set_attr "length" "16,20")])
11514 (define_insn "stack_protect_testdi"
11515 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11516 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11517 (match_operand:DI 2 "memory_operand" "Y,Y")]
11519 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11520 (clobber (match_scratch:DI 3 "=&r,&r"))]
11523 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11524 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11525 [(set_attr "length" "16,20")])
11528 ;; Here are the actual compare insns.
11529 (define_insn "*cmp<mode>_signed"
11530 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11531 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11532 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11534 "cmp<wd>%I2 %0,%1,%2"
11535 [(set_attr "type" "cmp")])
11537 (define_insn "*cmp<mode>_unsigned"
11538 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11539 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11540 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11542 "cmpl<wd>%I2 %0,%1,%2"
11543 [(set_attr "type" "cmp")])
11545 ;; If we are comparing a register for equality with a large constant,
11546 ;; we can do this with an XOR followed by a compare. But this is profitable
11547 ;; only if the large constant is only used for the comparison (and in this
11548 ;; case we already have a register to reuse as scratch).
11550 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11551 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11554 [(set (match_operand:SI 0 "register_operand")
11555 (match_operand:SI 1 "logical_const_operand"))
11556 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11558 (match_operand:SI 2 "logical_const_operand")]))
11559 (set (match_operand:CC 4 "cc_reg_operand")
11560 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11563 (if_then_else (match_operator 6 "equality_operator"
11564 [(match_dup 4) (const_int 0)])
11565 (match_operand 7 "")
11566 (match_operand 8 "")))]
11567 "peep2_reg_dead_p (3, operands[0])
11568 && peep2_reg_dead_p (4, operands[4])
11569 && REGNO (operands[0]) != REGNO (operands[5])"
11570 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11571 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11572 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11575 /* Get the constant we are comparing against, and see what it looks like
11576 when sign-extended from 16 to 32 bits. Then see what constant we could
11577 XOR with SEXTC to get the sign-extended value. */
11578 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11580 operands[1], operands[2]);
11581 HOST_WIDE_INT c = INTVAL (cnst);
11582 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11583 HOST_WIDE_INT xorv = c ^ sextc;
11585 operands[9] = GEN_INT (xorv);
11586 operands[10] = GEN_INT (sextc);
11589 ;; The following two insns don't exist as single insns, but if we provide
11590 ;; them, we can swap an add and compare, which will enable us to overlap more
11591 ;; of the required delay between a compare and branch. We generate code for
11592 ;; them by splitting.
11595 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11596 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11597 (match_operand:SI 2 "short_cint_operand" "i")))
11598 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11599 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11602 [(set_attr "length" "8")])
11605 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11606 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11607 (match_operand:SI 2 "u_short_cint_operand" "i")))
11608 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11609 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11612 [(set_attr "length" "8")])
11615 [(set (match_operand:CC 3 "cc_reg_operand")
11616 (compare:CC (match_operand:SI 1 "gpc_reg_operand")
11617 (match_operand:SI 2 "short_cint_operand")))
11618 (set (match_operand:SI 0 "gpc_reg_operand")
11619 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11621 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11622 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11625 [(set (match_operand:CCUNS 3 "cc_reg_operand")
11626 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand")
11627 (match_operand:SI 2 "u_short_cint_operand")))
11628 (set (match_operand:SI 0 "gpc_reg_operand")
11629 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11631 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11632 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11634 ;; Only need to compare second words if first words equal
11635 (define_insn "*cmp<mode>_internal1"
11636 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11637 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11638 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11639 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11640 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11641 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11642 [(set_attr "type" "fpcompare")
11643 (set_attr "length" "12")])
11645 (define_insn_and_split "*cmp<mode>_internal2"
11646 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11647 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11648 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11649 (clobber (match_scratch:DF 3 "=d"))
11650 (clobber (match_scratch:DF 4 "=d"))
11651 (clobber (match_scratch:DF 5 "=d"))
11652 (clobber (match_scratch:DF 6 "=d"))
11653 (clobber (match_scratch:DF 7 "=d"))
11654 (clobber (match_scratch:DF 8 "=d"))
11655 (clobber (match_scratch:DF 9 "=d"))
11656 (clobber (match_scratch:DF 10 "=d"))
11657 (clobber (match_scratch:GPR 11 "=b"))]
11658 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11659 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11661 "&& reload_completed"
11662 [(set (match_dup 3) (match_dup 14))
11663 (set (match_dup 4) (match_dup 15))
11664 (set (match_dup 9) (abs:DF (match_dup 5)))
11665 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11666 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11667 (label_ref (match_dup 12))
11669 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11670 (set (pc) (label_ref (match_dup 13)))
11672 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11673 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11674 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11675 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11678 REAL_VALUE_TYPE rv;
11679 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11680 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11682 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11683 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11684 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11685 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11686 operands[12] = gen_label_rtx ();
11687 operands[13] = gen_label_rtx ();
11689 operands[14] = force_const_mem (DFmode,
11690 const_double_from_real_value (rv, DFmode));
11691 operands[15] = force_const_mem (DFmode,
11692 const_double_from_real_value (dconst0,
11697 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11698 operands[14] = gen_const_mem (DFmode, tocref);
11699 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11700 operands[15] = gen_const_mem (DFmode, tocref);
11701 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11702 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11706 ;; Now we have the scc insns. We can do some combinations because of the
11707 ;; way the machine works.
11709 ;; Note that this is probably faster if we can put an insn between the
11710 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11711 ;; cases the insns below which don't use an intermediate CR field will
11712 ;; be used instead.
11714 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11715 (match_operator:SI 1 "scc_comparison_operator"
11716 [(match_operand 2 "cc_reg_operand" "y")
11719 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11720 [(set (attr "type")
11721 (cond [(match_test "TARGET_MFCRF")
11722 (const_string "mfcrf")
11724 (const_string "mfcr")))
11725 (set_attr "length" "8")])
11728 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11729 (match_operator:DI 1 "scc_comparison_operator"
11730 [(match_operand 2 "cc_reg_operand" "y")
11733 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11734 [(set (attr "type")
11735 (cond [(match_test "TARGET_MFCRF")
11736 (const_string "mfcrf")
11738 (const_string "mfcr")))
11739 (set_attr "length" "8")])
11742 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11743 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11744 [(match_operand 2 "cc_reg_operand" "y,y")
11747 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11748 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11751 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11753 [(set_attr "type" "shift")
11754 (set_attr "dot" "yes")
11755 (set_attr "length" "8,16")])
11758 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11759 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11760 [(match_operand 2 "cc_reg_operand")
11763 (set (match_operand:SI 3 "gpc_reg_operand")
11764 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11765 "TARGET_32BIT && reload_completed"
11766 [(set (match_dup 3)
11767 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11769 (compare:CC (match_dup 3)
11774 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11775 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11776 [(match_operand 2 "cc_reg_operand" "y")
11778 (match_operand:SI 3 "const_int_operand" "n")))]
11781 int is_bit = ccr_bit (operands[1], 1);
11782 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11785 if (is_bit >= put_bit)
11786 count = is_bit - put_bit;
11788 count = 32 - (put_bit - is_bit);
11790 operands[4] = GEN_INT (count);
11791 operands[5] = GEN_INT (put_bit);
11793 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11795 [(set (attr "type")
11796 (cond [(match_test "TARGET_MFCRF")
11797 (const_string "mfcrf")
11799 (const_string "mfcr")))
11800 (set_attr "length" "8")])
11803 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11805 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11806 [(match_operand 2 "cc_reg_operand" "y,y")
11808 (match_operand:SI 3 "const_int_operand" "n,n"))
11810 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11811 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11815 int is_bit = ccr_bit (operands[1], 1);
11816 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11819 /* Force split for non-cc0 compare. */
11820 if (which_alternative == 1)
11823 if (is_bit >= put_bit)
11824 count = is_bit - put_bit;
11826 count = 32 - (put_bit - is_bit);
11828 operands[5] = GEN_INT (count);
11829 operands[6] = GEN_INT (put_bit);
11831 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11833 [(set_attr "type" "shift")
11834 (set_attr "dot" "yes")
11835 (set_attr "length" "8,16")])
11838 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11840 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11841 [(match_operand 2 "cc_reg_operand")
11843 (match_operand:SI 3 "const_int_operand"))
11845 (set (match_operand:SI 4 "gpc_reg_operand")
11846 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11849 [(set (match_dup 4)
11850 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11853 (compare:CC (match_dup 4)
11858 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11859 (define_code_attr UNS [(eq "CC")
11861 (lt "CC") (ltu "CCUNS")
11862 (gt "CC") (gtu "CCUNS")
11863 (le "CC") (leu "CCUNS")
11864 (ge "CC") (geu "CCUNS")])
11865 (define_code_attr UNSu_ [(eq "")
11870 (ge "") (geu "u_")])
11871 (define_code_attr UNSIK [(eq "I")
11876 (ge "I") (geu "K")])
11878 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11879 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11880 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11881 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11882 (clobber (match_scratch:GPR 3 "=r"))
11883 (clobber (match_scratch:GPR 4 "=r"))
11884 (clobber (match_scratch:<UNS> 5 "=y"))]
11886 && !(<CODE> == EQ && operands[2] == const0_rtx)
11887 && !(<CODE> == NE && operands[2] == const0_rtx
11888 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11893 rtx_code code = <CODE>;
11894 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11896 HOST_WIDE_INT val = INTVAL (operands[2]);
11897 if (code == LT && val != -0x8000)
11902 if (code == GT && val != 0x7fff)
11907 if (code == LTU && val != 0)
11912 if (code == GTU && val != 0xffff)
11917 operands[2] = GEN_INT (val);
11920 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11921 operands[3] = const0_rtx;
11924 if (GET_CODE (operands[3]) == SCRATCH)
11925 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11926 emit_move_insn (operands[3], const0_rtx);
11929 if (GET_CODE (operands[4]) == SCRATCH)
11930 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11931 emit_move_insn (operands[4], const1_rtx);
11933 if (GET_CODE (operands[5]) == SCRATCH)
11934 operands[5] = gen_reg_rtx (<UNS>mode);
11936 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11937 emit_insn (gen_rtx_SET (operands[5], c1));
11939 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11940 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11941 emit_move_insn (operands[0], x);
11945 [(set (attr "cost")
11946 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11948 || <CODE> == LE || <CODE> == GE
11949 || <CODE> == LEU || <CODE> == GEU")
11951 (const_string "10")))])
11953 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11956 (define_expand "eq<mode>3"
11958 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11959 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11960 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11961 (clobber (match_scratch:GPR 3 "=r"))
11962 (clobber (match_scratch:GPR 4 "=r"))])]
11965 if (TARGET_ISEL && operands[2] != const0_rtx)
11967 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11973 (define_insn_and_split "*eq<mode>3"
11974 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11975 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11976 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11977 (clobber (match_scratch:GPR 3 "=r"))
11978 (clobber (match_scratch:GPR 4 "=r"))]
11979 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11982 [(set (match_dup 4)
11983 (clz:GPR (match_dup 3)))
11985 (lshiftrt:GPR (match_dup 4)
11988 operands[3] = rs6000_emit_eqne (<MODE>mode,
11989 operands[1], operands[2], operands[3]);
11991 if (GET_CODE (operands[4]) == SCRATCH)
11992 operands[4] = gen_reg_rtx (<MODE>mode);
11994 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11996 [(set (attr "length")
11997 (if_then_else (match_test "operands[2] == const0_rtx")
11999 (const_string "12")))])
12001 (define_expand "ne<mode>3"
12003 (set (match_operand:P 0 "gpc_reg_operand" "=r")
12004 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12005 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12006 (clobber (match_scratch:P 3 "=r"))
12007 (clobber (match_scratch:P 4 "=r"))
12008 (clobber (reg:P CA_REGNO))])]
12011 if (TARGET_ISEL && operands[2] != const0_rtx)
12013 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12019 (define_insn_and_split "*ne<mode>3"
12020 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12021 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12022 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12023 (clobber (match_scratch:P 3 "=r"))
12024 (clobber (match_scratch:P 4 "=r"))
12025 (clobber (reg:P CA_REGNO))]
12026 "!(TARGET_ISEL && operands[2] != const0_rtx)"
12029 [(parallel [(set (match_dup 4)
12030 (plus:P (match_dup 3)
12032 (set (reg:P CA_REGNO)
12033 (ne:P (match_dup 3)
12035 (parallel [(set (match_dup 0)
12036 (plus:P (plus:P (not:P (match_dup 4))
12039 (clobber (reg:P CA_REGNO))])]
12041 operands[3] = rs6000_emit_eqne (<MODE>mode,
12042 operands[1], operands[2], operands[3]);
12044 if (GET_CODE (operands[4]) == SCRATCH)
12045 operands[4] = gen_reg_rtx (<MODE>mode);
12047 [(set (attr "length")
12048 (if_then_else (match_test "operands[2] == const0_rtx")
12050 (const_string "12")))])
12052 (define_insn_and_split "*neg_eq_<mode>"
12053 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12054 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12055 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12056 (clobber (match_scratch:P 3 "=r"))
12057 (clobber (match_scratch:P 4 "=r"))
12058 (clobber (reg:P CA_REGNO))]
12062 [(parallel [(set (match_dup 4)
12063 (plus:P (match_dup 3)
12065 (set (reg:P CA_REGNO)
12066 (ne:P (match_dup 3)
12068 (parallel [(set (match_dup 0)
12069 (plus:P (reg:P CA_REGNO)
12071 (clobber (reg:P CA_REGNO))])]
12073 operands[3] = rs6000_emit_eqne (<MODE>mode,
12074 operands[1], operands[2], operands[3]);
12076 if (GET_CODE (operands[4]) == SCRATCH)
12077 operands[4] = gen_reg_rtx (<MODE>mode);
12079 [(set (attr "length")
12080 (if_then_else (match_test "operands[2] == const0_rtx")
12082 (const_string "12")))])
12084 (define_insn_and_split "*neg_ne_<mode>"
12085 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12086 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12087 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12088 (clobber (match_scratch:P 3 "=r"))
12089 (clobber (match_scratch:P 4 "=r"))
12090 (clobber (reg:P CA_REGNO))]
12094 [(parallel [(set (match_dup 4)
12095 (neg:P (match_dup 3)))
12096 (set (reg:P CA_REGNO)
12097 (eq:P (match_dup 3)
12099 (parallel [(set (match_dup 0)
12100 (plus:P (reg:P CA_REGNO)
12102 (clobber (reg:P CA_REGNO))])]
12104 operands[3] = rs6000_emit_eqne (<MODE>mode,
12105 operands[1], operands[2], operands[3]);
12107 if (GET_CODE (operands[4]) == SCRATCH)
12108 operands[4] = gen_reg_rtx (<MODE>mode);
12110 [(set (attr "length")
12111 (if_then_else (match_test "operands[2] == const0_rtx")
12113 (const_string "12")))])
12115 (define_insn_and_split "*plus_eq_<mode>"
12116 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12117 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12118 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12119 (match_operand:P 3 "gpc_reg_operand" "r")))
12120 (clobber (match_scratch:P 4 "=r"))
12121 (clobber (match_scratch:P 5 "=r"))
12122 (clobber (reg:P CA_REGNO))]
12126 [(parallel [(set (match_dup 5)
12127 (neg:P (match_dup 4)))
12128 (set (reg:P CA_REGNO)
12129 (eq:P (match_dup 4)
12131 (parallel [(set (match_dup 0)
12132 (plus:P (match_dup 3)
12134 (clobber (reg:P CA_REGNO))])]
12136 operands[4] = rs6000_emit_eqne (<MODE>mode,
12137 operands[1], operands[2], operands[4]);
12139 if (GET_CODE (operands[5]) == SCRATCH)
12140 operands[5] = gen_reg_rtx (<MODE>mode);
12142 [(set (attr "length")
12143 (if_then_else (match_test "operands[2] == const0_rtx")
12145 (const_string "12")))])
12147 (define_insn_and_split "*plus_ne_<mode>"
12148 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12149 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12150 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12151 (match_operand:P 3 "gpc_reg_operand" "r")))
12152 (clobber (match_scratch:P 4 "=r"))
12153 (clobber (match_scratch:P 5 "=r"))
12154 (clobber (reg:P CA_REGNO))]
12158 [(parallel [(set (match_dup 5)
12159 (plus:P (match_dup 4)
12161 (set (reg:P CA_REGNO)
12162 (ne:P (match_dup 4)
12164 (parallel [(set (match_dup 0)
12165 (plus:P (match_dup 3)
12167 (clobber (reg:P CA_REGNO))])]
12169 operands[4] = rs6000_emit_eqne (<MODE>mode,
12170 operands[1], operands[2], operands[4]);
12172 if (GET_CODE (operands[5]) == SCRATCH)
12173 operands[5] = gen_reg_rtx (<MODE>mode);
12175 [(set (attr "length")
12176 (if_then_else (match_test "operands[2] == const0_rtx")
12178 (const_string "12")))])
12180 (define_insn_and_split "*minus_eq_<mode>"
12181 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12182 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12183 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12184 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12185 (clobber (match_scratch:P 4 "=r"))
12186 (clobber (match_scratch:P 5 "=r"))
12187 (clobber (reg:P CA_REGNO))]
12191 [(parallel [(set (match_dup 5)
12192 (plus:P (match_dup 4)
12194 (set (reg:P CA_REGNO)
12195 (ne:P (match_dup 4)
12197 (parallel [(set (match_dup 0)
12198 (plus:P (plus:P (match_dup 3)
12201 (clobber (reg:P CA_REGNO))])]
12203 operands[4] = rs6000_emit_eqne (<MODE>mode,
12204 operands[1], operands[2], operands[4]);
12206 if (GET_CODE (operands[5]) == SCRATCH)
12207 operands[5] = gen_reg_rtx (<MODE>mode);
12209 [(set (attr "length")
12210 (if_then_else (match_test "operands[2] == const0_rtx")
12212 (const_string "12")))])
12214 (define_insn_and_split "*minus_ne_<mode>"
12215 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12216 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12217 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12218 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12219 (clobber (match_scratch:P 4 "=r"))
12220 (clobber (match_scratch:P 5 "=r"))
12221 (clobber (reg:P CA_REGNO))]
12225 [(parallel [(set (match_dup 5)
12226 (neg:P (match_dup 4)))
12227 (set (reg:P CA_REGNO)
12228 (eq:P (match_dup 4)
12230 (parallel [(set (match_dup 0)
12231 (plus:P (plus:P (match_dup 3)
12234 (clobber (reg:P CA_REGNO))])]
12236 operands[4] = rs6000_emit_eqne (<MODE>mode,
12237 operands[1], operands[2], operands[4]);
12239 if (GET_CODE (operands[5]) == SCRATCH)
12240 operands[5] = gen_reg_rtx (<MODE>mode);
12242 [(set (attr "length")
12243 (if_then_else (match_test "operands[2] == const0_rtx")
12245 (const_string "12")))])
12247 (define_insn_and_split "*eqsi3_ext<mode>"
12248 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12249 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12250 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12251 (clobber (match_scratch:SI 3 "=r"))
12252 (clobber (match_scratch:SI 4 "=r"))]
12256 [(set (match_dup 4)
12257 (clz:SI (match_dup 3)))
12260 (lshiftrt:SI (match_dup 4)
12263 operands[3] = rs6000_emit_eqne (SImode,
12264 operands[1], operands[2], operands[3]);
12266 if (GET_CODE (operands[4]) == SCRATCH)
12267 operands[4] = gen_reg_rtx (SImode);
12269 [(set (attr "length")
12270 (if_then_else (match_test "operands[2] == const0_rtx")
12272 (const_string "12")))])
12274 (define_insn_and_split "*nesi3_ext<mode>"
12275 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12276 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12277 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12278 (clobber (match_scratch:SI 3 "=r"))
12279 (clobber (match_scratch:SI 4 "=r"))
12280 (clobber (match_scratch:EXTSI 5 "=r"))]
12284 [(set (match_dup 4)
12285 (clz:SI (match_dup 3)))
12288 (lshiftrt:SI (match_dup 4)
12291 (xor:EXTSI (match_dup 5)
12294 operands[3] = rs6000_emit_eqne (SImode,
12295 operands[1], operands[2], operands[3]);
12297 if (GET_CODE (operands[4]) == SCRATCH)
12298 operands[4] = gen_reg_rtx (SImode);
12299 if (GET_CODE (operands[5]) == SCRATCH)
12300 operands[5] = gen_reg_rtx (<MODE>mode);
12302 [(set (attr "length")
12303 (if_then_else (match_test "operands[2] == const0_rtx")
12304 (const_string "12")
12305 (const_string "16")))])
12307 ;; Define both directions of branch and return. If we need a reload
12308 ;; register, we'd rather use CR0 since it is much easier to copy a
12309 ;; register CC value to there.
12313 (if_then_else (match_operator 1 "branch_comparison_operator"
12314 [(match_operand 2 "cc_reg_operand" "y")
12316 (label_ref (match_operand 0))
12320 return output_cbranch (operands[1], "%l0", 0, insn);
12322 [(set_attr "type" "branch")])
12326 (if_then_else (match_operator 0 "branch_comparison_operator"
12327 [(match_operand 1 "cc_reg_operand" "y")
12333 return output_cbranch (operands[0], NULL, 0, insn);
12335 [(set_attr "type" "jmpreg")
12336 (set_attr "length" "4")])
12338 ;; Logic on condition register values.
12340 ; This pattern matches things like
12341 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12342 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12344 ; which are generated by the branch logic.
12345 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12347 (define_insn "cceq_ior_compare"
12348 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12349 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12350 [(match_operator:SI 2
12351 "branch_positive_comparison_operator"
12353 "cc_reg_operand" "y,y")
12355 (match_operator:SI 4
12356 "branch_positive_comparison_operator"
12358 "cc_reg_operand" "0,y")
12362 "cr%q1 %E0,%j2,%j4"
12363 [(set_attr "type" "cr_logical")
12364 (set_attr "cr_logical_3op" "no,yes")])
12366 ; Why is the constant -1 here, but 1 in the previous pattern?
12367 ; Because ~1 has all but the low bit set.
12368 (define_insn "cceq_ior_compare_complement"
12369 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12370 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12371 [(not:SI (match_operator:SI 2
12372 "branch_positive_comparison_operator"
12374 "cc_reg_operand" "y,y")
12376 (match_operator:SI 4
12377 "branch_positive_comparison_operator"
12379 "cc_reg_operand" "0,y")
12383 "cr%q1 %E0,%j2,%j4"
12384 [(set_attr "type" "cr_logical")
12385 (set_attr "cr_logical_3op" "no,yes")])
12387 (define_insn "*cceq_rev_compare"
12388 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12389 (compare:CCEQ (match_operator:SI 1
12390 "branch_positive_comparison_operator"
12392 "cc_reg_operand" "0,y")
12397 [(set_attr "type" "cr_logical")
12398 (set_attr "cr_logical_3op" "no,yes")])
12400 ;; If we are comparing the result of two comparisons, this can be done
12401 ;; using creqv or crxor.
12403 (define_insn_and_split ""
12404 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12405 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12406 [(match_operand 2 "cc_reg_operand" "y")
12408 (match_operator 3 "branch_comparison_operator"
12409 [(match_operand 4 "cc_reg_operand" "y")
12414 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12417 int positive_1, positive_2;
12419 positive_1 = branch_positive_comparison_operator (operands[1],
12420 GET_MODE (operands[1]));
12421 positive_2 = branch_positive_comparison_operator (operands[3],
12422 GET_MODE (operands[3]));
12425 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12426 GET_CODE (operands[1])),
12428 operands[2], const0_rtx);
12429 else if (GET_MODE (operands[1]) != SImode)
12430 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12431 operands[2], const0_rtx);
12434 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12435 GET_CODE (operands[3])),
12437 operands[4], const0_rtx);
12438 else if (GET_MODE (operands[3]) != SImode)
12439 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12440 operands[4], const0_rtx);
12442 if (positive_1 == positive_2)
12444 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12445 operands[5] = constm1_rtx;
12449 operands[5] = const1_rtx;
12453 ;; Unconditional branch and return.
12455 (define_insn "jump"
12457 (label_ref (match_operand 0)))]
12460 [(set_attr "type" "branch")])
12462 (define_insn "<return_str>return"
12466 [(set_attr "type" "jmpreg")])
12468 (define_expand "indirect_jump"
12469 [(set (pc) (match_operand 0 "register_operand"))]
12472 if (!rs6000_speculate_indirect_jumps) {
12473 rtx ccreg = gen_reg_rtx (CCmode);
12474 if (Pmode == DImode)
12475 emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12477 emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12482 (define_insn "*indirect_jump<mode>"
12484 (match_operand:P 0 "register_operand" "c,*l"))]
12485 "rs6000_speculate_indirect_jumps"
12487 [(set_attr "type" "jmpreg")])
12489 (define_insn "indirect_jump<mode>_nospec"
12490 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12491 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12492 "!rs6000_speculate_indirect_jumps"
12493 "crset %E1\;beq%T0- %1\;b $"
12494 [(set_attr "type" "jmpreg")
12495 (set_attr "length" "12")])
12497 ;; Table jump for switch statements:
12498 (define_expand "tablejump"
12499 [(use (match_operand 0))
12500 (use (label_ref (match_operand 1)))]
12503 if (rs6000_speculate_indirect_jumps)
12506 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12508 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12512 rtx ccreg = gen_reg_rtx (CCmode);
12515 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12517 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12518 emit_jump_insn (jump);
12523 (define_expand "tablejumpsi"
12524 [(set (match_dup 3)
12525 (plus:SI (match_operand:SI 0)
12527 (parallel [(set (pc)
12529 (use (label_ref (match_operand 1)))])]
12530 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12532 operands[0] = force_reg (SImode, operands[0]);
12533 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12534 operands[3] = gen_reg_rtx (SImode);
12537 (define_expand "tablejumpsi_nospec"
12538 [(set (match_dup 4)
12539 (plus:SI (match_operand:SI 0)
12541 (parallel [(set (pc)
12543 (use (label_ref (match_operand 1)))
12544 (clobber (match_operand 2))])]
12545 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12547 operands[0] = force_reg (SImode, operands[0]);
12548 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12549 operands[4] = gen_reg_rtx (SImode);
12552 (define_expand "tablejumpdi"
12553 [(set (match_dup 4)
12554 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12556 (plus:DI (match_dup 4)
12558 (parallel [(set (pc)
12560 (use (label_ref (match_operand 1)))])]
12561 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12563 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12564 operands[3] = gen_reg_rtx (DImode);
12565 operands[4] = gen_reg_rtx (DImode);
12568 (define_expand "tablejumpdi_nospec"
12569 [(set (match_dup 5)
12570 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12572 (plus:DI (match_dup 5)
12574 (parallel [(set (pc)
12576 (use (label_ref (match_operand 1)))
12577 (clobber (match_operand 2))])]
12578 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12580 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12581 operands[4] = gen_reg_rtx (DImode);
12582 operands[5] = gen_reg_rtx (DImode);
12585 (define_insn "*tablejump<mode>_internal1"
12587 (match_operand:P 0 "register_operand" "c,*l"))
12588 (use (label_ref (match_operand 1)))]
12589 "rs6000_speculate_indirect_jumps"
12591 [(set_attr "type" "jmpreg")])
12593 (define_insn "*tablejump<mode>_internal1_nospec"
12595 (match_operand:P 0 "register_operand" "c,*l"))
12596 (use (label_ref (match_operand 1)))
12597 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12598 "!rs6000_speculate_indirect_jumps"
12599 "crset %E2\;beq%T0- %2\;b $"
12600 [(set_attr "type" "jmpreg")
12601 (set_attr "length" "12")])
12604 [(unspec [(const_int 0)] UNSPEC_NOP)]
12608 (define_insn "group_ending_nop"
12609 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12612 if (rs6000_tune == PROCESSOR_POWER6)
12613 return "ori 1,1,0";
12614 return "ori 2,2,0";
12617 (define_insn "rs6000_speculation_barrier"
12618 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12622 ;; Define the subtract-one-and-jump insns, starting with the template
12623 ;; so loop.c knows what to generate.
12625 (define_expand "doloop_end"
12626 [(use (match_operand 0)) ; loop pseudo
12627 (use (match_operand 1))] ; label
12632 if (GET_MODE (operands[0]) != DImode)
12634 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12638 if (GET_MODE (operands[0]) != SImode)
12640 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12645 (define_expand "ctr<mode>"
12646 [(parallel [(set (pc)
12647 (if_then_else (ne (match_operand:P 0 "register_operand")
12649 (label_ref (match_operand 1))
12652 (plus:P (match_dup 0)
12654 (clobber (match_scratch:CC 2))
12655 (clobber (match_scratch:P 3))])]
12659 ;; We need to be able to do this for any operand, including MEM, or we
12660 ;; will cause reload to blow up since we don't allow output reloads on
12662 ;; For the length attribute to be calculated correctly, the
12663 ;; label MUST be operand 0.
12664 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12665 ;; the ctr<mode> insns.
12667 (define_code_iterator eqne [eq ne])
12668 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12669 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12671 (define_insn "<bd>_<mode>"
12673 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12675 (label_ref (match_operand 0))
12677 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12678 (plus:P (match_dup 1)
12680 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12681 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12684 if (which_alternative != 0)
12686 else if (get_attr_length (insn) == 4)
12689 return "<bd_neg> $+8\;b %l0";
12691 [(set_attr "type" "branch")
12692 (set_attr "length" "*,16,20,20")])
12694 ;; Now the splitter if we could not allocate the CTR register
12697 (if_then_else (match_operator 2 "comparison_operator"
12698 [(match_operand:P 1 "gpc_reg_operand")
12701 (match_operand 6)))
12702 (set (match_operand:P 0 "nonimmediate_operand")
12703 (plus:P (match_dup 1)
12705 (clobber (match_scratch:CC 3))
12706 (clobber (match_scratch:P 4))]
12709 (if_then_else (match_dup 7)
12713 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12715 emit_insn (gen_rtx_SET (operands[3],
12716 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12717 if (gpc_reg_operand (operands[0], <MODE>mode))
12718 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12721 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12722 emit_move_insn (operands[0], operands[4]);
12724 /* No DONE so branch comes from the pattern. */
12727 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12728 ;; Note that in the case of long branches we have to decompose this into
12729 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12730 ;; and the CR bit, which means there is no way to conveniently invert the
12731 ;; comparison as is done with plain bdnz/bdz.
12733 (define_insn "<bd>tf_<mode>"
12737 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12739 (match_operator 3 "branch_comparison_operator"
12740 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12742 (label_ref (match_operand 0))
12744 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12745 (plus:P (match_dup 1)
12747 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12748 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12749 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12752 if (which_alternative != 0)
12754 else if (get_attr_length (insn) == 4)
12756 if (branch_positive_comparison_operator (operands[3],
12757 GET_MODE (operands[3])))
12758 return "<bd>t %j3,%l0";
12760 return "<bd>f %j3,%l0";
12764 static char seq[96];
12765 char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12766 sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12770 [(set_attr "type" "branch")
12771 (set_attr "length" "*,16,20,20")])
12773 ;; Now the splitter if we could not allocate the CTR register
12778 (match_operator 1 "comparison_operator"
12779 [(match_operand:P 0 "gpc_reg_operand")
12781 (match_operator 3 "branch_comparison_operator"
12782 [(match_operand 2 "cc_reg_operand")
12785 (match_operand 5)))
12786 (set (match_operand:P 6 "int_reg_operand")
12787 (plus:P (match_dup 0)
12789 (clobber (match_scratch:P 7))
12790 (clobber (match_scratch:CC 8))
12791 (clobber (match_scratch:CCEQ 9))]
12795 rtx ctr = operands[0];
12796 rtx ctrcmp = operands[1];
12797 rtx ccin = operands[2];
12798 rtx cccmp = operands[3];
12799 rtx dst1 = operands[4];
12800 rtx dst2 = operands[5];
12801 rtx ctrout = operands[6];
12802 rtx ctrtmp = operands[7];
12803 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12804 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12806 cmpcode = reverse_condition (cmpcode);
12807 /* Generate crand/crandc here. */
12808 emit_insn (gen_rtx_SET (operands[8],
12809 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12810 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12812 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12814 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12815 operands[8], cccmp, ccin));
12817 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12818 operands[8], cccmp, ccin));
12819 if (gpc_reg_operand (operands[0], <MODE>mode))
12820 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12823 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12824 emit_move_insn (ctrout, ctrtmp);
12826 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12827 emit_jump_insn (gen_rtx_SET (pc_rtx,
12828 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12834 (define_insn "trap"
12835 [(trap_if (const_int 1) (const_int 0))]
12838 [(set_attr "type" "trap")])
12840 (define_expand "ctrap<mode>4"
12841 [(trap_if (match_operator 0 "ordered_comparison_operator"
12842 [(match_operand:GPR 1 "register_operand")
12843 (match_operand:GPR 2 "reg_or_short_operand")])
12844 (match_operand 3 "zero_constant" ""))]
12849 [(trap_if (match_operator 0 "ordered_comparison_operator"
12850 [(match_operand:GPR 1 "register_operand" "r")
12851 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12854 "t<wd>%V0%I2 %1,%2"
12855 [(set_attr "type" "trap")])
12857 ;; Insns related to generating the function prologue and epilogue.
12859 (define_expand "prologue"
12860 [(use (const_int 0))]
12863 rs6000_emit_prologue ();
12864 if (!TARGET_SCHED_PROLOG)
12865 emit_insn (gen_blockage ());
12869 (define_insn "*movesi_from_cr_one"
12870 [(match_parallel 0 "mfcr_operation"
12871 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12872 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12873 (match_operand 3 "immediate_operand" "n")]
12874 UNSPEC_MOVESI_FROM_CR))])]
12879 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12881 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12882 operands[4] = GEN_INT (mask);
12883 output_asm_insn ("mfcr %1,%4", operands);
12887 [(set_attr "type" "mfcrf")])
12889 ;; Don't include the volatile CRs since their values are not used wrt CR save
12890 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12891 ;; prologue past an insn (early exit test) that defines a register used in the
12893 (define_insn "prologue_movesi_from_cr"
12894 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12895 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12896 (reg:CC CR4_REGNO)]
12897 UNSPEC_MOVESI_FROM_CR))]
12900 [(set_attr "type" "mfcr")])
12902 (define_insn "*crsave"
12903 [(match_parallel 0 "crsave_operation"
12904 [(set (match_operand:SI 1 "memory_operand" "=m")
12905 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12908 [(set_attr "type" "store")])
12910 (define_insn "*stmw"
12911 [(match_parallel 0 "stmw_operation"
12912 [(set (match_operand:SI 1 "memory_operand" "=m")
12913 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12916 [(set_attr "type" "store")
12917 (set_attr "update" "yes")
12918 (set_attr "indexed" "yes")])
12920 ; The following comment applies to:
12924 ; return_and_restore_gpregs*
12925 ; return_and_restore_fpregs*
12926 ; return_and_restore_fpregs_aix*
12928 ; The out-of-line save / restore functions expects one input argument.
12929 ; Since those are not standard call_insn's, we must avoid using
12930 ; MATCH_OPERAND for that argument. That way the register rename
12931 ; optimization will not try to rename this register.
12932 ; Each pattern is repeated for each possible register number used in
12933 ; various ABIs (r11, r1, and for some functions r12)
12935 (define_insn "*save_gpregs_<mode>_r11"
12936 [(match_parallel 0 "any_parallel_operand"
12937 [(clobber (reg:P LR_REGNO))
12938 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12940 (set (match_operand:P 2 "memory_operand" "=m")
12941 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12944 [(set_attr "type" "branch")
12945 (set_attr "length" "4")])
12947 (define_insn "*save_gpregs_<mode>_r12"
12948 [(match_parallel 0 "any_parallel_operand"
12949 [(clobber (reg:P LR_REGNO))
12950 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12952 (set (match_operand:P 2 "memory_operand" "=m")
12953 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12956 [(set_attr "type" "branch")
12957 (set_attr "length" "4")])
12959 (define_insn "*save_gpregs_<mode>_r1"
12960 [(match_parallel 0 "any_parallel_operand"
12961 [(clobber (reg:P LR_REGNO))
12962 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12964 (set (match_operand:P 2 "memory_operand" "=m")
12965 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12968 [(set_attr "type" "branch")
12969 (set_attr "length" "4")])
12971 (define_insn "*save_fpregs_<mode>_r11"
12972 [(match_parallel 0 "any_parallel_operand"
12973 [(clobber (reg:P LR_REGNO))
12974 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12976 (set (match_operand:DF 2 "memory_operand" "=m")
12977 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12980 [(set_attr "type" "branch")
12981 (set_attr "length" "4")])
12983 (define_insn "*save_fpregs_<mode>_r12"
12984 [(match_parallel 0 "any_parallel_operand"
12985 [(clobber (reg:P LR_REGNO))
12986 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12988 (set (match_operand:DF 2 "memory_operand" "=m")
12989 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12992 [(set_attr "type" "branch")
12993 (set_attr "length" "4")])
12995 (define_insn "*save_fpregs_<mode>_r1"
12996 [(match_parallel 0 "any_parallel_operand"
12997 [(clobber (reg:P LR_REGNO))
12998 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13000 (set (match_operand:DF 2 "memory_operand" "=m")
13001 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13004 [(set_attr "type" "branch")
13005 (set_attr "length" "4")])
13007 ; This is to explain that changes to the stack pointer should
13008 ; not be moved over loads from or stores to stack memory.
13009 (define_insn "stack_tie"
13010 [(match_parallel 0 "tie_operand"
13011 [(set (mem:BLK (reg 1)) (const_int 0))])]
13014 [(set_attr "length" "0")])
13016 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13017 ; stay behind all restores from the stack, it cannot be reordered to before
13018 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13019 (define_insn "stack_restore_tie"
13020 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13021 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13022 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13023 (set (mem:BLK (scratch)) (const_int 0))]
13028 [(set_attr "type" "*,add")])
13030 (define_expand "epilogue"
13031 [(use (const_int 0))]
13034 if (!TARGET_SCHED_PROLOG)
13035 emit_insn (gen_blockage ());
13036 rs6000_emit_epilogue (FALSE);
13040 ; On some processors, doing the mtcrf one CC register at a time is
13041 ; faster (like on the 604e). On others, doing them all at once is
13042 ; faster; for instance, on the 601 and 750.
13044 (define_expand "movsi_to_cr_one"
13045 [(set (match_operand:CC 0 "cc_reg_operand")
13046 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13047 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13049 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13051 (define_insn "*movsi_to_cr"
13052 [(match_parallel 0 "mtcrf_operation"
13053 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13054 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13055 (match_operand 3 "immediate_operand" "n")]
13056 UNSPEC_MOVESI_TO_CR))])]
13061 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13062 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13063 operands[4] = GEN_INT (mask);
13064 return "mtcrf %4,%2";
13066 [(set_attr "type" "mtcr")])
13068 (define_insn "*mtcrfsi"
13069 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13070 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13071 (match_operand 2 "immediate_operand" "n")]
13072 UNSPEC_MOVESI_TO_CR))]
13073 "GET_CODE (operands[0]) == REG
13074 && CR_REGNO_P (REGNO (operands[0]))
13075 && GET_CODE (operands[2]) == CONST_INT
13076 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13078 [(set_attr "type" "mtcr")])
13080 ; The load-multiple instructions have similar properties.
13081 ; Note that "load_multiple" is a name known to the machine-independent
13082 ; code that actually corresponds to the PowerPC load-string.
13084 (define_insn "*lmw"
13085 [(match_parallel 0 "lmw_operation"
13086 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13087 (match_operand:SI 2 "memory_operand" "m"))])]
13090 [(set_attr "type" "load")
13091 (set_attr "update" "yes")
13092 (set_attr "indexed" "yes")
13093 (set_attr "cell_micro" "always")])
13095 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13096 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13098 ; The following comment applies to:
13102 ; return_and_restore_gpregs*
13103 ; return_and_restore_fpregs*
13104 ; return_and_restore_fpregs_aix*
13106 ; The out-of-line save / restore functions expects one input argument.
13107 ; Since those are not standard call_insn's, we must avoid using
13108 ; MATCH_OPERAND for that argument. That way the register rename
13109 ; optimization will not try to rename this register.
13110 ; Each pattern is repeated for each possible register number used in
13111 ; various ABIs (r11, r1, and for some functions r12)
13113 (define_insn "*restore_gpregs_<mode>_r11"
13114 [(match_parallel 0 "any_parallel_operand"
13115 [(clobber (reg:P LR_REGNO))
13116 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13118 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13119 (match_operand:P 3 "memory_operand" "m"))])]
13122 [(set_attr "type" "branch")
13123 (set_attr "length" "4")])
13125 (define_insn "*restore_gpregs_<mode>_r12"
13126 [(match_parallel 0 "any_parallel_operand"
13127 [(clobber (reg:P LR_REGNO))
13128 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13130 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13131 (match_operand:P 3 "memory_operand" "m"))])]
13134 [(set_attr "type" "branch")
13135 (set_attr "length" "4")])
13137 (define_insn "*restore_gpregs_<mode>_r1"
13138 [(match_parallel 0 "any_parallel_operand"
13139 [(clobber (reg:P LR_REGNO))
13140 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13142 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13143 (match_operand:P 3 "memory_operand" "m"))])]
13146 [(set_attr "type" "branch")
13147 (set_attr "length" "4")])
13149 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13150 [(match_parallel 0 "any_parallel_operand"
13152 (clobber (reg:P LR_REGNO))
13153 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13155 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13156 (match_operand:P 3 "memory_operand" "m"))])]
13159 [(set_attr "type" "branch")
13160 (set_attr "length" "4")])
13162 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13163 [(match_parallel 0 "any_parallel_operand"
13165 (clobber (reg:P LR_REGNO))
13166 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13168 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13169 (match_operand:P 3 "memory_operand" "m"))])]
13172 [(set_attr "type" "branch")
13173 (set_attr "length" "4")])
13175 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13176 [(match_parallel 0 "any_parallel_operand"
13178 (clobber (reg:P LR_REGNO))
13179 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13181 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13182 (match_operand:P 3 "memory_operand" "m"))])]
13185 [(set_attr "type" "branch")
13186 (set_attr "length" "4")])
13188 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13189 [(match_parallel 0 "any_parallel_operand"
13191 (clobber (reg:P LR_REGNO))
13192 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13194 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13195 (match_operand:DF 3 "memory_operand" "m"))])]
13198 [(set_attr "type" "branch")
13199 (set_attr "length" "4")])
13201 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13202 [(match_parallel 0 "any_parallel_operand"
13204 (clobber (reg:P LR_REGNO))
13205 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13207 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13208 (match_operand:DF 3 "memory_operand" "m"))])]
13211 [(set_attr "type" "branch")
13212 (set_attr "length" "4")])
13214 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13215 [(match_parallel 0 "any_parallel_operand"
13217 (clobber (reg:P LR_REGNO))
13218 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13220 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13221 (match_operand:DF 3 "memory_operand" "m"))])]
13224 [(set_attr "type" "branch")
13225 (set_attr "length" "4")])
13227 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13228 [(match_parallel 0 "any_parallel_operand"
13230 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13232 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13233 (match_operand:DF 3 "memory_operand" "m"))])]
13236 [(set_attr "type" "branch")
13237 (set_attr "length" "4")])
13239 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13240 [(match_parallel 0 "any_parallel_operand"
13242 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13244 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13245 (match_operand:DF 3 "memory_operand" "m"))])]
13248 [(set_attr "type" "branch")
13249 (set_attr "length" "4")])
13251 ; This is used in compiling the unwind routines.
13252 (define_expand "eh_return"
13253 [(use (match_operand 0 "general_operand"))]
13257 emit_insn (gen_eh_set_lr_si (operands[0]));
13259 emit_insn (gen_eh_set_lr_di (operands[0]));
13263 ; We can't expand this before we know where the link register is stored.
13264 (define_insn "eh_set_lr_<mode>"
13265 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13267 (clobber (match_scratch:P 1 "=&b"))]
13272 [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13273 (clobber (match_scratch 1))]
13277 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13281 (define_insn "prefetch"
13282 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13283 (match_operand:SI 1 "const_int_operand" "n")
13284 (match_operand:SI 2 "const_int_operand" "n"))]
13289 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13290 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13291 The AIX assembler does not support the three operand form of dcbt
13292 and dcbtst on Power 7 (-mpwr7). */
13293 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13295 if (REG_P (operands[0]))
13297 if (INTVAL (operands[1]) == 0)
13298 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13300 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13304 if (INTVAL (operands[1]) == 0)
13305 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13307 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13310 [(set_attr "type" "load")])
13312 ;; Handle -fsplit-stack.
13314 (define_expand "split_stack_prologue"
13318 rs6000_expand_split_stack_prologue ();
13322 (define_expand "load_split_stack_limit"
13323 [(set (match_operand 0)
13324 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13327 emit_insn (gen_rtx_SET (operands[0],
13328 gen_rtx_UNSPEC (Pmode,
13329 gen_rtvec (1, const0_rtx),
13330 UNSPEC_STACK_CHECK)));
13334 (define_insn "load_split_stack_limit_di"
13335 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13336 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13338 "ld %0,-0x7040(13)"
13339 [(set_attr "type" "load")
13340 (set_attr "update" "no")
13341 (set_attr "indexed" "no")])
13343 (define_insn "load_split_stack_limit_si"
13344 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13345 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13347 "lwz %0,-0x7020(2)"
13348 [(set_attr "type" "load")
13349 (set_attr "update" "no")
13350 (set_attr "indexed" "no")])
13352 ;; A return instruction which the middle-end doesn't see.
13353 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13354 ;; after the call to __morestack.
13355 (define_insn "split_stack_return"
13356 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13359 [(set_attr "type" "jmpreg")])
13361 ;; If there are operand 0 bytes available on the stack, jump to
13363 (define_expand "split_stack_space_check"
13364 [(set (match_dup 2)
13365 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13367 (minus (reg STACK_POINTER_REGNUM)
13368 (match_operand 0)))
13369 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13370 (set (pc) (if_then_else
13371 (geu (match_dup 4) (const_int 0))
13372 (label_ref (match_operand 1))
13376 rs6000_split_stack_space_check (operands[0], operands[1]);
13380 (define_insn "bpermd_<mode>"
13381 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13382 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13383 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13386 [(set_attr "type" "popcnt")])
13389 ;; Builtin fma support. Handle
13390 ;; Note that the conditions for expansion are in the FMA_F iterator.
13392 (define_expand "fma<mode>4"
13393 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13395 (match_operand:FMA_F 1 "gpc_reg_operand")
13396 (match_operand:FMA_F 2 "gpc_reg_operand")
13397 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13401 (define_insn "*fma<mode>4_fpr"
13402 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13404 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13405 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13406 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13407 "TARGET_HARD_FLOAT"
13409 fmadd<Ftrad> %0,%1,%2,%3
13410 xsmadda<Fvsx> %x0,%x1,%x2
13411 xsmaddm<Fvsx> %x0,%x1,%x3"
13412 [(set_attr "type" "fp")])
13414 ; Altivec only has fma and nfms.
13415 (define_expand "fms<mode>4"
13416 [(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 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13421 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13424 (define_insn "*fms<mode>4_fpr"
13425 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13427 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13428 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13429 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13430 "TARGET_HARD_FLOAT"
13432 fmsub<Ftrad> %0,%1,%2,%3
13433 xsmsuba<Fvsx> %x0,%x1,%x2
13434 xsmsubm<Fvsx> %x0,%x1,%x3"
13435 [(set_attr "type" "fp")])
13437 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13438 (define_expand "fnma<mode>4"
13439 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13442 (match_operand:FMA_F 1 "gpc_reg_operand")
13443 (match_operand:FMA_F 2 "gpc_reg_operand")
13444 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13445 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13448 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13449 (define_expand "fnms<mode>4"
13450 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13453 (match_operand:FMA_F 1 "gpc_reg_operand")
13454 (match_operand:FMA_F 2 "gpc_reg_operand")
13455 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13456 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13459 ; Not an official optab name, but used from builtins.
13460 (define_expand "nfma<mode>4"
13461 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13464 (match_operand:FMA_F 1 "gpc_reg_operand")
13465 (match_operand:FMA_F 2 "gpc_reg_operand")
13466 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13467 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13470 (define_insn "*nfma<mode>4_fpr"
13471 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13474 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13475 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13476 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13477 "TARGET_HARD_FLOAT"
13479 fnmadd<Ftrad> %0,%1,%2,%3
13480 xsnmadda<Fvsx> %x0,%x1,%x2
13481 xsnmaddm<Fvsx> %x0,%x1,%x3"
13482 [(set_attr "type" "fp")])
13484 ; Not an official optab name, but used from builtins.
13485 (define_expand "nfms<mode>4"
13486 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13489 (match_operand:FMA_F 1 "gpc_reg_operand")
13490 (match_operand:FMA_F 2 "gpc_reg_operand")
13491 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13495 (define_insn "*nfmssf4_fpr"
13496 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13499 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13500 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13502 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13503 "TARGET_HARD_FLOAT"
13505 fnmsub<Ftrad> %0,%1,%2,%3
13506 xsnmsuba<Fvsx> %x0,%x1,%x2
13507 xsnmsubm<Fvsx> %x0,%x1,%x3"
13508 [(set_attr "type" "fp")])
13511 (define_expand "rs6000_get_timebase"
13512 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13515 if (TARGET_POWERPC64)
13516 emit_insn (gen_rs6000_mftb_di (operands[0]));
13518 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13522 (define_insn "rs6000_get_timebase_ppc32"
13523 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13524 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13525 (clobber (match_scratch:SI 1 "=r"))
13526 (clobber (match_scratch:CC 2 "=y"))]
13527 "!TARGET_POWERPC64"
13529 if (WORDS_BIG_ENDIAN)
13532 return "mfspr %0,269\;"
13540 return "mftbu %0\;"
13549 return "mfspr %L0,269\;"
13557 return "mftbu %L0\;"
13564 [(set_attr "length" "20")])
13566 (define_insn "rs6000_mftb_<mode>"
13567 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13568 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13572 return "mfspr %0,268";
13578 (define_insn "rs6000_mffs"
13579 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13580 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13581 "TARGET_HARD_FLOAT"
13584 (define_insn "rs6000_mtfsf"
13585 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13586 (match_operand:DF 1 "gpc_reg_operand" "d")]
13588 "TARGET_HARD_FLOAT"
13592 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13593 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13594 ;; register that is being loaded. The fused ops must be physically adjacent.
13596 ;; There are two parts to addis fusion. The support for fused TOCs occur
13597 ;; before register allocation, and is meant to reduce the lifetime for the
13598 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13599 ;; to use the register that is being load. The peephole2 then gathers any
13600 ;; other fused possibilities that it can find after register allocation. If
13601 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13603 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13604 ;; before register allocation, so that we can avoid allocating a temporary base
13605 ;; register that won't be used, and that we try to load into base registers,
13606 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13607 ;; (addis followed by load) even on power8.
13610 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand")
13611 (match_operand:INT1 1 "toc_fusion_mem_raw"))]
13612 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13613 [(parallel [(set (match_dup 0) (match_dup 2))
13614 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13615 (use (match_dup 3))
13616 (clobber (scratch:DI))])]
13618 operands[2] = fusion_wrap_memory_address (operands[1]);
13619 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13622 (define_insn "*toc_fusionload_<mode>"
13623 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13624 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13625 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13626 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13627 (clobber (match_scratch:DI 3 "=X,&b"))]
13628 "TARGET_TOC_FUSION_INT"
13630 if (base_reg_operand (operands[0], <MODE>mode))
13631 return emit_fusion_gpr_load (operands[0], operands[1]);
13633 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13635 [(set_attr "type" "load")
13636 (set_attr "length" "8")])
13638 (define_insn "*toc_fusionload_di"
13639 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13640 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13641 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13642 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13643 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13644 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13645 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13647 if (base_reg_operand (operands[0], DImode))
13648 return emit_fusion_gpr_load (operands[0], operands[1]);
13650 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13652 [(set_attr "type" "load")
13653 (set_attr "length" "8")])
13656 ;; Find cases where the addis that feeds into a load instruction is either used
13657 ;; once or is the same as the target register, and replace it with the fusion
13661 [(set (match_operand:P 0 "base_reg_operand")
13662 (match_operand:P 1 "fusion_gpr_addis"))
13663 (set (match_operand:INT1 2 "base_reg_operand")
13664 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13666 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13670 expand_fusion_gpr_load (operands);
13674 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13677 (define_insn "fusion_gpr_load_<mode>"
13678 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13679 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13680 UNSPEC_FUSION_GPR))]
13683 return emit_fusion_gpr_load (operands[0], operands[1]);
13685 [(set_attr "type" "load")
13686 (set_attr "length" "8")])
13689 ;; ISA 3.0 (power9) fusion support
13690 ;; Merge addis with floating load/store to FPRs (or GPRs).
13692 [(set (match_operand:P 0 "base_reg_operand")
13693 (match_operand:P 1 "fusion_gpr_addis"))
13694 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand")
13695 (match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
13696 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13697 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13700 expand_fusion_p9_load (operands);
13705 [(set (match_operand:P 0 "base_reg_operand")
13706 (match_operand:P 1 "fusion_gpr_addis"))
13707 (set (match_operand:SFDF 2 "offsettable_mem_operand")
13708 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand"))]
13709 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13710 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13711 && !rtx_equal_p (operands[0], operands[3])"
13714 expand_fusion_p9_store (operands);
13719 [(set (match_operand:SDI 0 "int_reg_operand")
13720 (match_operand:SDI 1 "upper16_cint_operand"))
13722 (ior:SDI (match_dup 0)
13723 (match_operand:SDI 2 "u_short_cint_operand")))]
13725 [(set (match_dup 0)
13726 (unspec:SDI [(match_dup 1)
13727 (match_dup 2)] UNSPEC_FUSION_P9))])
13730 [(set (match_operand:SDI 0 "int_reg_operand")
13731 (match_operand:SDI 1 "upper16_cint_operand"))
13732 (set (match_operand:SDI 2 "int_reg_operand")
13733 (ior:SDI (match_dup 0)
13734 (match_operand:SDI 3 "u_short_cint_operand")))]
13736 && !rtx_equal_p (operands[0], operands[2])
13737 && peep2_reg_dead_p (2, operands[0])"
13738 [(set (match_dup 2)
13739 (unspec:SDI [(match_dup 1)
13740 (match_dup 3)] UNSPEC_FUSION_P9))])
13742 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13743 ;; reload). Because we want to eventually have secondary_reload generate
13744 ;; these, they have to have a single alternative that gives the register
13745 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13746 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13747 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13749 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13751 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13754 /* This insn is a secondary reload insn, which cannot have alternatives.
13755 If we are not loading up register 0, use the power8 fusion instead. */
13756 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13757 return emit_fusion_gpr_load (operands[0], operands[1]);
13759 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13761 [(set_attr "type" "load")
13762 (set_attr "length" "8")])
13764 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13765 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13767 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13769 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13772 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13774 [(set_attr "type" "store")
13775 (set_attr "length" "8")])
13777 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13778 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13780 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13782 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13785 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13787 [(set_attr "type" "fpload")
13788 (set_attr "length" "8")])
13790 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13791 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13793 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13795 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13798 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13800 [(set_attr "type" "fpstore")
13801 (set_attr "length" "8")])
13803 (define_insn "*fusion_p9_<mode>_constant"
13804 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13805 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13806 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13807 UNSPEC_FUSION_P9))]
13810 emit_fusion_addis (operands[0], operands[1]);
13811 return "ori %0,%0,%2";
13813 [(set_attr "type" "two")
13814 (set_attr "length" "8")])
13817 ;; Optimize cases where we want to do a D-form load (register+offset) on
13818 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13823 ;; and we change this to:
13828 [(match_scratch:P 0 "b")
13829 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13830 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13831 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13833 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13834 [(set (match_dup 0)
13839 rtx tmp_reg = operands[0];
13840 rtx mem = operands[2];
13841 rtx addr = XEXP (mem, 0);
13842 rtx add_op0, add_op1, new_addr;
13844 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13845 add_op0 = XEXP (addr, 0);
13846 add_op1 = XEXP (addr, 1);
13847 gcc_assert (REG_P (add_op0));
13848 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13850 operands[4] = add_op1;
13851 operands[5] = change_address (mem, <MODE>mode, new_addr);
13854 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13855 ;; Altivec register, and the register allocator has generated:
13859 ;; and we change this to:
13864 [(match_scratch:P 0 "b")
13865 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13866 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13867 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13869 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13870 [(set (match_dup 0)
13875 rtx tmp_reg = operands[0];
13876 rtx mem = operands[3];
13877 rtx addr = XEXP (mem, 0);
13878 rtx add_op0, add_op1, new_addr;
13880 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13881 add_op0 = XEXP (addr, 0);
13882 add_op1 = XEXP (addr, 1);
13883 gcc_assert (REG_P (add_op0));
13884 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13886 operands[4] = add_op1;
13887 operands[5] = change_address (mem, <MODE>mode, new_addr);
13891 ;; Miscellaneous ISA 2.06 (power7) instructions
13892 (define_insn "addg6s"
13893 [(set (match_operand:SI 0 "register_operand" "=r")
13894 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13895 (match_operand:SI 2 "register_operand" "r")]
13899 [(set_attr "type" "integer")
13900 (set_attr "length" "4")])
13902 (define_insn "cdtbcd"
13903 [(set (match_operand:SI 0 "register_operand" "=r")
13904 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13908 [(set_attr "type" "integer")
13909 (set_attr "length" "4")])
13911 (define_insn "cbcdtd"
13912 [(set (match_operand:SI 0 "register_operand" "=r")
13913 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13917 [(set_attr "type" "integer")
13918 (set_attr "length" "4")])
13920 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13923 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13924 (UNSPEC_DIVEU "eu")])
13926 (define_insn "div<div_extend>_<mode>"
13927 [(set (match_operand:GPR 0 "register_operand" "=r")
13928 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13929 (match_operand:GPR 2 "register_operand" "r")]
13930 UNSPEC_DIV_EXTEND))]
13932 "div<wd><div_extend> %0,%1,%2"
13933 [(set_attr "type" "div")
13934 (set_attr "size" "<bits>")])
13937 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13939 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13940 (define_mode_attr FP128_64 [(TF "DF")
13945 (define_expand "unpack<mode>"
13946 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13948 [(match_operand:FMOVE128 1 "register_operand")
13949 (match_operand:QI 2 "const_0_to_1_operand")]
13950 UNSPEC_UNPACK_128BIT))]
13951 "FLOAT128_2REG_P (<MODE>mode)"
13954 (define_insn_and_split "unpack<mode>_dm"
13955 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13957 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13958 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13959 UNSPEC_UNPACK_128BIT))]
13960 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13962 "&& reload_completed"
13963 [(set (match_dup 0) (match_dup 3))]
13965 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13967 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13969 emit_note (NOTE_INSN_DELETED);
13973 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13975 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13976 (set_attr "length" "4")])
13978 (define_insn_and_split "unpack<mode>_nodm"
13979 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13981 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13982 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13983 UNSPEC_UNPACK_128BIT))]
13984 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13986 "&& reload_completed"
13987 [(set (match_dup 0) (match_dup 3))]
13989 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13991 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13993 emit_note (NOTE_INSN_DELETED);
13997 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13999 [(set_attr "type" "fp,fpstore")
14000 (set_attr "length" "4")])
14002 (define_insn_and_split "pack<mode>"
14003 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
14005 [(match_operand:<FP128_64> 1 "register_operand" "d")
14006 (match_operand:<FP128_64> 2 "register_operand" "d")]
14007 UNSPEC_PACK_128BIT))]
14008 "FLOAT128_2REG_P (<MODE>mode)"
14010 "&& reload_completed"
14011 [(set (match_dup 3) (match_dup 1))
14012 (set (match_dup 4) (match_dup 2))]
14014 unsigned dest_hi = REGNO (operands[0]);
14015 unsigned dest_lo = dest_hi + 1;
14017 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14018 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14020 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14021 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14023 [(set_attr "type" "fp")
14024 (set_attr "length" "8")])
14026 (define_insn "unpack<mode>"
14027 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14028 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14029 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14030 UNSPEC_UNPACK_128BIT))]
14031 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14033 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14034 return ASM_COMMENT_START " xxpermdi to same register";
14036 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14037 return "xxpermdi %x0,%x1,%x1,%3";
14039 [(set_attr "type" "vecperm")])
14041 (define_insn "pack<mode>"
14042 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14043 (unspec:FMOVE128_VSX
14044 [(match_operand:DI 1 "register_operand" "wa")
14045 (match_operand:DI 2 "register_operand" "wa")]
14046 UNSPEC_PACK_128BIT))]
14048 "xxpermdi %x0,%x1,%x2,0"
14049 [(set_attr "type" "vecperm")])
14053 ;; ISA 2.08 IEEE 128-bit floating point support.
14055 (define_insn "add<mode>3"
14056 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14058 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14059 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14060 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14062 [(set_attr "type" "vecfloat")
14063 (set_attr "size" "128")])
14065 (define_insn "sub<mode>3"
14066 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14068 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14069 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14070 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14072 [(set_attr "type" "vecfloat")
14073 (set_attr "size" "128")])
14075 (define_insn "mul<mode>3"
14076 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14078 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14079 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14080 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14082 [(set_attr "type" "qmul")
14083 (set_attr "size" "128")])
14085 (define_insn "div<mode>3"
14086 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14088 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14089 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14090 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14092 [(set_attr "type" "vecdiv")
14093 (set_attr "size" "128")])
14095 (define_insn "sqrt<mode>2"
14096 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14098 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14099 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14101 [(set_attr "type" "vecdiv")
14102 (set_attr "size" "128")])
14104 (define_expand "copysign<mode>3"
14105 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14106 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14107 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14108 "FLOAT128_IEEE_P (<MODE>mode)"
14110 if (TARGET_FLOAT128_HW)
14111 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14114 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14119 (define_insn "copysign<mode>3_hard"
14120 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14122 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14123 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14125 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14126 "xscpsgnqp %0,%2,%1"
14127 [(set_attr "type" "vecmove")
14128 (set_attr "size" "128")])
14130 (define_insn "copysign<mode>3_soft"
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")]
14136 (clobber (match_scratch:IEEE128 3 "=&v"))]
14137 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14138 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14139 [(set_attr "type" "veccomplex")
14140 (set_attr "length" "8")])
14142 (define_insn "neg<mode>2_hw"
14143 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14145 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14146 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14148 [(set_attr "type" "vecmove")
14149 (set_attr "size" "128")])
14152 (define_insn "abs<mode>2_hw"
14153 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14155 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14156 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14158 [(set_attr "type" "vecmove")
14159 (set_attr "size" "128")])
14162 (define_insn "*nabs<mode>2_hw"
14163 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14166 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14167 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14169 [(set_attr "type" "vecmove")
14170 (set_attr "size" "128")])
14172 ;; Initially don't worry about doing fusion
14173 (define_insn "fma<mode>4_hw"
14174 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14176 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14177 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14178 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14179 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14180 "xsmaddqp %0,%1,%2"
14181 [(set_attr "type" "qmul")
14182 (set_attr "size" "128")])
14184 (define_insn "*fms<mode>4_hw"
14185 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14187 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14188 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14190 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14191 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14192 "xsmsubqp %0,%1,%2"
14193 [(set_attr "type" "qmul")
14194 (set_attr "size" "128")])
14196 (define_insn "*nfma<mode>4_hw"
14197 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14200 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14201 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14202 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14203 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14204 "xsnmaddqp %0,%1,%2"
14205 [(set_attr "type" "qmul")
14206 (set_attr "size" "128")])
14208 (define_insn "*nfms<mode>4_hw"
14209 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14212 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14213 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14215 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14216 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14217 "xsnmsubqp %0,%1,%2"
14218 [(set_attr "type" "qmul")
14219 (set_attr "size" "128")])
14221 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14222 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14223 (float_extend:IEEE128
14224 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14225 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14227 [(set_attr "type" "vecfloat")
14228 (set_attr "size" "128")])
14230 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14231 ;; point is a simple copy.
14232 (define_insn_and_split "extendkftf2"
14233 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14234 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14235 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14239 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14242 emit_note (NOTE_INSN_DELETED);
14245 [(set_attr "type" "*,veclogical")
14246 (set_attr "length" "0,4")])
14248 (define_insn_and_split "trunctfkf2"
14249 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14250 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14251 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14255 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14258 emit_note (NOTE_INSN_DELETED);
14261 [(set_attr "type" "*,veclogical")
14262 (set_attr "length" "0,4")])
14264 (define_insn "trunc<mode>df2_hw"
14265 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14267 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14268 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14270 [(set_attr "type" "vecfloat")
14271 (set_attr "size" "128")])
14273 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14274 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14276 (define_insn_and_split "trunc<mode>sf2_hw"
14277 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14279 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14280 (clobber (match_scratch:DF 2 "=v"))]
14281 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14284 [(set (match_dup 2)
14285 (unspec:DF [(match_dup 1)]
14286 UNSPEC_TRUNC_ROUND_TO_ODD))
14288 (float_truncate:SF (match_dup 2)))]
14290 if (GET_CODE (operands[2]) == SCRATCH)
14291 operands[2] = gen_reg_rtx (DFmode);
14293 [(set_attr "type" "vecfloat")
14294 (set_attr "length" "8")])
14296 ;; Conversion between IEEE 128-bit and integer types
14298 ;; The fix function for DImode and SImode was declared earlier as a
14299 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14300 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14301 ;; unless we have the IEEE 128-bit hardware.
14303 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14304 ;; to provide a GPR target that used direct move and a conversion in the GPR
14305 ;; which works around QImode/HImode not being allowed in vector registers in
14306 ;; ISA 2.07 (power8).
14307 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14308 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14309 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14310 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14311 "xscvqp<su><wd>z %0,%1"
14312 [(set_attr "type" "vecfloat")
14313 (set_attr "size" "128")])
14315 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14316 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14318 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14319 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14320 "xscvqp<su>wz %0,%1"
14321 [(set_attr "type" "vecfloat")
14322 (set_attr "size" "128")])
14324 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14325 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14326 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14327 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14329 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14330 (clobber (match_scratch:QHSI 2 "=v"))]
14331 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14333 "&& reload_completed"
14334 [(set (match_dup 2)
14335 (any_fix:QHSI (match_dup 1)))
14339 (define_insn "float_<mode>di2_hw"
14340 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14341 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14342 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14344 [(set_attr "type" "vecfloat")
14345 (set_attr "size" "128")])
14347 (define_insn_and_split "float_<mode>si2_hw"
14348 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14349 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14350 (clobber (match_scratch:DI 2 "=v"))]
14351 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14354 [(set (match_dup 2)
14355 (sign_extend:DI (match_dup 1)))
14357 (float:IEEE128 (match_dup 2)))]
14359 if (GET_CODE (operands[2]) == SCRATCH)
14360 operands[2] = gen_reg_rtx (DImode);
14362 if (MEM_P (operands[1]))
14363 operands[1] = rs6000_address_for_fpconvert (operands[1]);
14366 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14367 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14368 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14369 (clobber (match_scratch:DI 2 "=X,r,X"))]
14370 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14372 "&& reload_completed"
14375 rtx dest = operands[0];
14376 rtx src = operands[1];
14377 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14379 if (altivec_register_operand (src, <QHI:MODE>mode))
14380 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14381 else if (int_reg_operand (src, <QHI:MODE>mode))
14383 rtx ext_di = operands[2];
14384 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14385 emit_move_insn (dest_di, ext_di);
14387 else if (MEM_P (src))
14389 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14390 emit_move_insn (dest_qhi, src);
14391 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14394 gcc_unreachable ();
14396 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14399 [(set_attr "length" "8,12,12")
14400 (set_attr "type" "vecfloat")
14401 (set_attr "size" "128")])
14403 (define_insn "floatuns_<mode>di2_hw"
14404 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14405 (unsigned_float:IEEE128
14406 (match_operand:DI 1 "altivec_register_operand" "v")))]
14407 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14409 [(set_attr "type" "vecfloat")
14410 (set_attr "size" "128")])
14412 (define_insn_and_split "floatuns_<mode>si2_hw"
14413 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14414 (unsigned_float:IEEE128
14415 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14416 (clobber (match_scratch:DI 2 "=v"))]
14417 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14420 [(set (match_dup 2)
14421 (zero_extend:DI (match_dup 1)))
14423 (float:IEEE128 (match_dup 2)))]
14425 if (GET_CODE (operands[2]) == SCRATCH)
14426 operands[2] = gen_reg_rtx (DImode);
14428 if (MEM_P (operands[1]))
14429 operands[1] = rs6000_address_for_fpconvert (operands[1]);
14432 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14433 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14434 (unsigned_float:IEEE128
14435 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14436 (clobber (match_scratch:DI 2 "=X,r,X"))]
14437 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14439 "&& reload_completed"
14442 rtx dest = operands[0];
14443 rtx src = operands[1];
14444 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14446 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14447 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14448 else if (int_reg_operand (src, <QHI:MODE>mode))
14450 rtx ext_di = operands[2];
14451 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14452 emit_move_insn (dest_di, ext_di);
14455 gcc_unreachable ();
14457 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14460 [(set_attr "length" "8,12,8")
14461 (set_attr "type" "vecfloat")
14462 (set_attr "size" "128")])
14464 ;; IEEE 128-bit round to integer built-in functions
14465 (define_insn "floor<mode>2"
14466 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14468 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14470 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14472 [(set_attr "type" "vecfloat")
14473 (set_attr "size" "128")])
14475 (define_insn "ceil<mode>2"
14476 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14478 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14480 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14482 [(set_attr "type" "vecfloat")
14483 (set_attr "size" "128")])
14485 (define_insn "btrunc<mode>2"
14486 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14488 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14490 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14492 [(set_attr "type" "vecfloat")
14493 (set_attr "size" "128")])
14495 (define_insn "round<mode>2"
14496 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14498 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14500 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14502 [(set_attr "type" "vecfloat")
14503 (set_attr "size" "128")])
14505 ;; IEEE 128-bit instructions with round to odd semantics
14506 (define_insn "add<mode>3_odd"
14507 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14509 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14510 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14511 UNSPEC_ADD_ROUND_TO_ODD))]
14512 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14513 "xsaddqpo %0,%1,%2"
14514 [(set_attr "type" "vecfloat")
14515 (set_attr "size" "128")])
14517 (define_insn "sub<mode>3_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 UNSPEC_SUB_ROUND_TO_ODD))]
14523 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14524 "xssubqpo %0,%1,%2"
14525 [(set_attr "type" "vecfloat")
14526 (set_attr "size" "128")])
14528 (define_insn "mul<mode>3_odd"
14529 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14531 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14532 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14533 UNSPEC_MUL_ROUND_TO_ODD))]
14534 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14535 "xsmulqpo %0,%1,%2"
14536 [(set_attr "type" "qmul")
14537 (set_attr "size" "128")])
14539 (define_insn "div<mode>3_odd"
14540 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14542 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14543 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14544 UNSPEC_DIV_ROUND_TO_ODD))]
14545 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14546 "xsdivqpo %0,%1,%2"
14547 [(set_attr "type" "vecdiv")
14548 (set_attr "size" "128")])
14550 (define_insn "sqrt<mode>2_odd"
14551 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14553 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14554 UNSPEC_SQRT_ROUND_TO_ODD))]
14555 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14557 [(set_attr "type" "vecdiv")
14558 (set_attr "size" "128")])
14560 (define_insn "fma<mode>4_odd"
14561 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14563 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14564 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14565 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14566 UNSPEC_FMA_ROUND_TO_ODD))]
14567 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14568 "xsmaddqpo %0,%1,%2"
14569 [(set_attr "type" "qmul")
14570 (set_attr "size" "128")])
14572 (define_insn "*fms<mode>4_odd"
14573 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14575 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14576 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14578 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14579 UNSPEC_FMA_ROUND_TO_ODD))]
14580 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14581 "xsmsubqpo %0,%1,%2"
14582 [(set_attr "type" "qmul")
14583 (set_attr "size" "128")])
14585 (define_insn "*nfma<mode>4_odd"
14586 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14589 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14590 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14591 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14592 UNSPEC_FMA_ROUND_TO_ODD)))]
14593 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14594 "xsnmaddqpo %0,%1,%2"
14595 [(set_attr "type" "qmul")
14596 (set_attr "size" "128")])
14598 (define_insn "*nfms<mode>4_odd"
14599 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14602 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14603 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14605 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14606 UNSPEC_FMA_ROUND_TO_ODD)))]
14607 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14608 "xsnmsubqpo %0,%1,%2"
14609 [(set_attr "type" "qmul")
14610 (set_attr "size" "128")])
14612 (define_insn "trunc<mode>df2_odd"
14613 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14614 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14615 UNSPEC_TRUNC_ROUND_TO_ODD))]
14616 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14618 [(set_attr "type" "vecfloat")
14619 (set_attr "size" "128")])
14621 ;; IEEE 128-bit comparisons
14622 (define_insn "*cmp<mode>_hw"
14623 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14624 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14625 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14626 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14627 "xscmpuqp %0,%1,%2"
14628 [(set_attr "type" "veccmp")
14629 (set_attr "size" "128")])
14633 (include "sync.md")
14634 (include "vector.md")
14636 (include "altivec.md")
14638 (include "crypto.md")