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
139 UNSPEC_ADD_ROUND_TO_ODD
140 UNSPEC_SUB_ROUND_TO_ODD
141 UNSPEC_MUL_ROUND_TO_ODD
142 UNSPEC_DIV_ROUND_TO_ODD
143 UNSPEC_FMA_ROUND_TO_ODD
144 UNSPEC_SQRT_ROUND_TO_ODD
145 UNSPEC_TRUNC_ROUND_TO_ODD
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
160 UNSPECV_LL ; load-locked
161 UNSPECV_SC ; store-conditional
162 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
163 UNSPECV_EH_RR ; eh_reg_restore
164 UNSPECV_ISYNC ; isync instruction
165 UNSPECV_MFTB ; move from time base
166 UNSPECV_NLGR ; non-local goto receiver
167 UNSPECV_MFFS ; Move from FPSCR
168 UNSPECV_MFFSL ; Move from FPSCR light instruction version
169 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
170 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
171 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
172 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
173 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
174 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
175 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
176 UNSPECV_SPEC_BARRIER ; Speculation barrier
180 ;; Define an insn type attribute. This is used in function unit delay
184 add,logical,shift,insert,
186 exts,cntlz,popcnt,isel,
187 load,store,fpload,fpstore,vecload,vecstore,
189 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
190 cr_logical,mfcr,mfcrf,mtcr,
191 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
192 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
193 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
194 veclogical,veccmpfx,vecexts,vecmove,
196 (const_string "integer"))
198 ;; What data size does this instruction work on?
199 ;; This is used for insert, mul and others as necessary.
200 (define_attr "size" "8,16,32,64,128" (const_string "32"))
202 ;; What is the insn_cost for this insn? The target hook can still override
203 ;; this. For optimizing for size the "length" attribute is used instead.
204 (define_attr "cost" "" (const_int 0))
206 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
207 ;; This is used for add, logical, shift, exts, mul.
208 (define_attr "dot" "no,yes" (const_string "no"))
210 ;; Does this instruction sign-extend its result?
211 ;; This is used for load insns.
212 (define_attr "sign_extend" "no,yes" (const_string "no"))
214 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
215 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
217 ;; Does this instruction use indexed (that is, reg+reg) addressing?
218 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
219 ;; it is automatically set based on that. If a load or store instruction
220 ;; has fewer than two operands it needs to set this attribute manually
221 ;; or the compiler will crash.
222 (define_attr "indexed" "no,yes"
223 (if_then_else (ior (match_operand 0 "indexed_address_mem")
224 (match_operand 1 "indexed_address_mem"))
226 (const_string "no")))
228 ;; Does this instruction use update addressing?
229 ;; This is used for load and store insns. See the comments for "indexed".
230 (define_attr "update" "no,yes"
231 (if_then_else (ior (match_operand 0 "update_address_mem")
232 (match_operand 1 "update_address_mem"))
234 (const_string "no")))
236 ;; Is this instruction using operands[2] as shift amount, and can that be a
238 ;; This is used for shift insns.
239 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
241 ;; Is this instruction using a shift amount from a register?
242 ;; This is used for shift insns.
243 (define_attr "var_shift" "no,yes"
244 (if_then_else (and (eq_attr "type" "shift")
245 (eq_attr "maybe_var_shift" "yes"))
246 (if_then_else (match_operand 2 "gpc_reg_operand")
249 (const_string "no")))
251 ;; Is copying of this instruction disallowed?
252 (define_attr "cannot_copy" "no,yes" (const_string "no"))
254 ;; Length of the instruction (in bytes).
255 (define_attr "length" "" (const_int 4))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
260 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261 ppc750,ppc7400,ppc7450,
262 ppc403,ppc405,ppc440,ppc476,
263 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264 power4,power5,power6,power7,power8,power9,
265 rs64a,mpccore,cell,ppca2,titan"
266 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273 (eq_attr "dot" "yes"))
274 (and (eq_attr "type" "load")
275 (eq_attr "sign_extend" "yes"))
276 (and (eq_attr "type" "shift")
277 (eq_attr "var_shift" "yes")))
278 (const_string "always")
279 (const_string "not")))
281 (automata_option "ndfa")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
309 (include "predicates.md")
310 (include "constraints.md")
312 (include "darwin.md")
317 ; This mode iterator allows :GPR to be used to indicate the allowable size
318 ; of whole values in GPRs.
319 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
321 ; And again, for patterns that need two (potentially) different integer modes.
322 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
324 ; Any supported integer mode.
325 (define_mode_iterator INT [QI HI SI DI TI PTI])
327 ; Any supported integer mode that fits in one register.
328 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
330 ; Integer modes supported in VSX registers with ISA 3.0 instructions
331 (define_mode_iterator INT_ISA3 [QI HI SI DI])
333 ; Everything we can extend QImode to.
334 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
336 ; Everything we can extend HImode to.
337 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
339 ; Everything we can extend SImode to.
340 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
342 ; QImode or HImode for small integer moves and small atomic ops
343 (define_mode_iterator QHI [QI HI])
345 ; QImode, HImode, SImode for fused ops only for GPR loads
346 (define_mode_iterator QHSI [QI HI SI])
348 ; HImode or SImode for sign extended fusion ops
349 (define_mode_iterator HSI [HI SI])
351 ; SImode or DImode, even if DImode doesn't fit in GPRs.
352 (define_mode_iterator SDI [SI DI])
354 ; The size of a pointer. Also, the size of the value that a record-condition
355 ; (one with a '.') will compare; and the size used for arithmetic carries.
356 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
358 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
359 ; PTImode is GPR only)
360 (define_mode_iterator TI2 [TI PTI])
362 ; Any hardware-supported floating-point mode
363 (define_mode_iterator FP [
364 (SF "TARGET_HARD_FLOAT")
365 (DF "TARGET_HARD_FLOAT")
366 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
367 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
368 (KF "TARGET_FLOAT128_TYPE")
372 ; Any fma capable floating-point mode.
373 (define_mode_iterator FMA_F [
374 (SF "TARGET_HARD_FLOAT")
375 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
376 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
377 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
378 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
379 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
382 ; Floating point move iterators to combine binary and decimal moves
383 (define_mode_iterator FMOVE32 [SF SD])
384 (define_mode_iterator FMOVE64 [DF DD])
385 (define_mode_iterator FMOVE64X [DI DF DD])
386 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
387 (IF "FLOAT128_IBM_P (IFmode)")
388 (TD "TARGET_HARD_FLOAT")])
390 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
391 (IF "FLOAT128_2REG_P (IFmode)")
392 (TD "TARGET_HARD_FLOAT")])
394 ; Iterators for 128 bit types for direct move
395 (define_mode_iterator FMOVE128_GPR [TI
403 (KF "FLOAT128_VECTOR_P (KFmode)")
404 (TF "FLOAT128_VECTOR_P (TFmode)")])
406 ; Iterator for 128-bit VSX types for pack/unpack
407 (define_mode_iterator FMOVE128_VSX [V1TI KF])
409 ; Iterators for converting to/from TFmode
410 (define_mode_iterator IFKF [IF KF])
412 ; Constraints for moving IF/KFmode.
413 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
415 ; Whether a floating point move is ok, don't allow SD without hardware FP
416 (define_mode_attr fmove_ok [(SF "")
418 (SD "TARGET_HARD_FLOAT")
421 ; Convert REAL_VALUE to the appropriate bits
422 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
423 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
424 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
425 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
427 ; Whether 0.0 has an all-zero bit pattern
428 (define_mode_attr zero_fp [(SF "j")
437 ; Definitions for 64-bit VSX
438 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
440 ; Definitions for 64-bit direct move
441 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
443 ; Definitions for 64-bit use of altivec registers
444 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
446 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
447 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
449 ; These modes do not fit in integer registers in 32-bit mode.
450 (define_mode_iterator DIFD [DI DF DD])
452 ; Iterator for reciprocal estimate instructions
453 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
455 ; Iterator for just SF/DF
456 (define_mode_iterator SFDF [SF DF])
458 ; Like SFDF, but a different name to match conditional move where the
459 ; comparison operands may be a different mode than the input operands.
460 (define_mode_iterator SFDF2 [SF DF])
462 ; Iterator for 128-bit floating point that uses the IBM double-double format
463 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
464 (TF "FLOAT128_IBM_P (TFmode)")])
466 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
467 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
468 (TF "FLOAT128_IEEE_P (TFmode)")])
470 ; Iterator for 128-bit floating point
471 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
472 (IF "TARGET_FLOAT128_TYPE")
473 (TF "TARGET_LONG_DOUBLE_128")])
475 ; Iterator for signbit on 64-bit machines with direct move
476 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
477 (TF "FLOAT128_VECTOR_P (TFmode)")])
479 ; Iterator for ISA 3.0 supported floating point types
480 (define_mode_iterator FP_ISA3 [SF DF])
482 ; SF/DF suffix for traditional floating instructions
483 (define_mode_attr Ftrad [(SF "s") (DF "")])
485 ; SF/DF suffix for VSX instructions
486 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
488 ; SF/DF constraint for arithmetic on traditional floating point registers
489 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
491 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
492 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
493 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
495 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
497 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
498 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
499 ; instructions added in ISA 2.07 (power8)
500 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
502 ; SF/DF constraint for arithmetic on altivec registers
503 (define_mode_attr Fa [(SF "wu") (DF "wv")])
505 ; s/d suffix for things like sdiv/ddiv
506 (define_mode_attr Fs [(SF "s") (DF "d")])
509 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
510 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
512 ; Conditional returns.
513 (define_code_iterator any_return [return simple_return])
514 (define_code_attr return_pred [(return "direct_return ()")
515 (simple_return "1")])
516 (define_code_attr return_str [(return "") (simple_return "simple_")])
519 (define_code_iterator iorxor [ior xor])
520 (define_code_iterator and_ior_xor [and ior xor])
522 ; Signed/unsigned variants of ops.
523 (define_code_iterator any_extend [sign_extend zero_extend])
524 (define_code_iterator any_fix [fix unsigned_fix])
525 (define_code_iterator any_float [float unsigned_float])
527 (define_code_attr u [(sign_extend "")
532 (define_code_attr su [(sign_extend "s")
537 (unsigned_float "u")])
539 (define_code_attr az [(sign_extend "a")
544 (unsigned_float "z")])
546 (define_code_attr uns [(fix "")
549 (unsigned_float "uns")])
551 ; Various instructions that come in SI and DI forms.
552 ; A generic w/d attribute, for things like cmpw/cmpd.
553 (define_mode_attr wd [(QI "b")
564 ;; How many bits in this mode?
565 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
568 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
570 ;; Bitmask for shift instructions
571 (define_mode_attr hH [(SI "h") (DI "H")])
573 ;; A mode twice the size of the given mode
574 (define_mode_attr dmode [(SI "di") (DI "ti")])
575 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
577 ;; Suffix for reload patterns
578 (define_mode_attr ptrsize [(SI "32bit")
581 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
582 (DI "TARGET_64BIT")])
584 (define_mode_attr mptrsize [(SI "si")
587 (define_mode_attr ptrload [(SI "lwz")
590 (define_mode_attr ptrm [(SI "m")
593 (define_mode_attr rreg [(SF "f")
600 (define_mode_attr rreg2 [(SF "f")
603 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
604 (DF "TARGET_FCFID")])
606 ;; Mode iterator for logical operations on 128-bit types
607 (define_mode_iterator BOOL_128 [TI
609 (V16QI "TARGET_ALTIVEC")
610 (V8HI "TARGET_ALTIVEC")
611 (V4SI "TARGET_ALTIVEC")
612 (V4SF "TARGET_ALTIVEC")
613 (V2DI "TARGET_ALTIVEC")
614 (V2DF "TARGET_ALTIVEC")
615 (V1TI "TARGET_ALTIVEC")])
617 ;; For the GPRs we use 3 constraints for register outputs, two that are the
618 ;; same as the output register, and a third where the output register is an
619 ;; early clobber, so we don't have to deal with register overlaps. For the
620 ;; vector types, we prefer to use the vector registers. For TI mode, allow
623 ;; Mode attribute for boolean operation register constraints for output
624 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
626 (V16QI "wa,v,&?r,?r,?r")
627 (V8HI "wa,v,&?r,?r,?r")
628 (V4SI "wa,v,&?r,?r,?r")
629 (V4SF "wa,v,&?r,?r,?r")
630 (V2DI "wa,v,&?r,?r,?r")
631 (V2DF "wa,v,&?r,?r,?r")
632 (V1TI "wa,v,&?r,?r,?r")])
634 ;; Mode attribute for boolean operation register constraints for operand1
635 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
643 (V1TI "wa,v,r,0,r")])
645 ;; Mode attribute for boolean operation register constraints for operand2
646 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
654 (V1TI "wa,v,r,r,0")])
656 ;; Mode attribute for boolean operation register constraints for operand1
657 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
658 ;; is used for operand1 or operand2
659 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
667 (V1TI "wa,v,r,0,0")])
669 ;; Reload iterator for creating the function to allocate a base register to
670 ;; supplement addressing modes.
671 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
672 SF SD SI DF DD DI TI PTI KF IF TF])
674 ;; Iterate over smin, smax
675 (define_code_iterator fp_minmax [smin smax])
677 (define_code_attr minmax [(smin "min")
680 (define_code_attr SMINMAX [(smin "SMIN")
683 ;; Iterator to optimize the following cases:
684 ;; D-form load to FPR register & move to Altivec register
685 ;; Move Altivec register to FPR register and store
686 (define_mode_iterator ALTIVEC_DFORM [DF
687 (SF "TARGET_P8_VECTOR")
688 (DI "TARGET_POWERPC64")])
691 ;; Start with fixed-point load and store insns. Here we put only the more
692 ;; complex forms. Basic data transfer is done later.
694 (define_insn "zero_extendqi<mode>2"
695 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
696 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
703 [(set_attr "type" "load,shift,fpload,vecperm")])
705 (define_insn_and_split "*zero_extendqi<mode>2_dot"
706 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
707 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
709 (clobber (match_scratch:EXTQI 0 "=r,r"))]
714 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
716 (zero_extend:EXTQI (match_dup 1)))
718 (compare:CC (match_dup 0)
721 [(set_attr "type" "logical")
722 (set_attr "dot" "yes")
723 (set_attr "length" "4,8")])
725 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
726 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
727 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
729 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
730 (zero_extend:EXTQI (match_dup 1)))]
735 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
737 (zero_extend:EXTQI (match_dup 1)))
739 (compare:CC (match_dup 0)
742 [(set_attr "type" "logical")
743 (set_attr "dot" "yes")
744 (set_attr "length" "4,8")])
747 (define_insn "zero_extendhi<mode>2"
748 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
749 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
753 rlwinm %0,%1,0,0xffff
756 [(set_attr "type" "load,shift,fpload,vecperm")])
758 (define_insn_and_split "*zero_extendhi<mode>2_dot"
759 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
760 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
762 (clobber (match_scratch:EXTHI 0 "=r,r"))]
767 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
769 (zero_extend:EXTHI (match_dup 1)))
771 (compare:CC (match_dup 0)
774 [(set_attr "type" "logical")
775 (set_attr "dot" "yes")
776 (set_attr "length" "4,8")])
778 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
779 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
780 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
782 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
783 (zero_extend:EXTHI (match_dup 1)))]
788 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
790 (zero_extend:EXTHI (match_dup 1)))
792 (compare:CC (match_dup 0)
795 [(set_attr "type" "logical")
796 (set_attr "dot" "yes")
797 (set_attr "length" "4,8")])
800 (define_insn "zero_extendsi<mode>2"
801 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
802 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
811 xxextractuw %x0,%x1,4"
812 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
814 (define_insn_and_split "*zero_extendsi<mode>2_dot"
815 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
816 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
818 (clobber (match_scratch:EXTSI 0 "=r,r"))]
823 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
825 (zero_extend:DI (match_dup 1)))
827 (compare:CC (match_dup 0)
830 [(set_attr "type" "shift")
831 (set_attr "dot" "yes")
832 (set_attr "length" "4,8")])
834 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
835 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
836 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
838 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
839 (zero_extend:EXTSI (match_dup 1)))]
844 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
846 (zero_extend:EXTSI (match_dup 1)))
848 (compare:CC (match_dup 0)
851 [(set_attr "type" "shift")
852 (set_attr "dot" "yes")
853 (set_attr "length" "4,8")])
856 (define_insn "extendqi<mode>2"
857 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
858 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
863 [(set_attr "type" "exts,vecperm")])
865 (define_insn_and_split "*extendqi<mode>2_dot"
866 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
867 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
869 (clobber (match_scratch:EXTQI 0 "=r,r"))]
874 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
876 (sign_extend:EXTQI (match_dup 1)))
878 (compare:CC (match_dup 0)
881 [(set_attr "type" "exts")
882 (set_attr "dot" "yes")
883 (set_attr "length" "4,8")])
885 (define_insn_and_split "*extendqi<mode>2_dot2"
886 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
887 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
889 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
890 (sign_extend:EXTQI (match_dup 1)))]
895 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
897 (sign_extend:EXTQI (match_dup 1)))
899 (compare:CC (match_dup 0)
902 [(set_attr "type" "exts")
903 (set_attr "dot" "yes")
904 (set_attr "length" "4,8")])
907 (define_expand "extendhi<mode>2"
908 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
909 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
913 (define_insn "*extendhi<mode>2"
914 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
915 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
922 [(set_attr "type" "load,exts,fpload,vecperm")
923 (set_attr "sign_extend" "yes")
924 (set_attr "length" "4,4,8,4")])
927 [(set (match_operand:EXTHI 0 "altivec_register_operand")
929 (match_operand:HI 1 "indexed_or_indirect_operand")))]
930 "TARGET_P9_VECTOR && reload_completed"
934 (sign_extend:EXTHI (match_dup 2)))]
936 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
939 (define_insn_and_split "*extendhi<mode>2_dot"
940 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
941 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
943 (clobber (match_scratch:EXTHI 0 "=r,r"))]
948 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
950 (sign_extend:EXTHI (match_dup 1)))
952 (compare:CC (match_dup 0)
955 [(set_attr "type" "exts")
956 (set_attr "dot" "yes")
957 (set_attr "length" "4,8")])
959 (define_insn_and_split "*extendhi<mode>2_dot2"
960 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
961 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
963 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
964 (sign_extend:EXTHI (match_dup 1)))]
969 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
971 (sign_extend:EXTHI (match_dup 1)))
973 (compare:CC (match_dup 0)
976 [(set_attr "type" "exts")
977 (set_attr "dot" "yes")
978 (set_attr "length" "4,8")])
981 (define_insn "extendsi<mode>2"
982 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
983 "=r, r, wl, wu, wj, wK, wH, wr")
985 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
986 "YZ, r, Z, Z, r, wK, wH, ?wIwH")))]
997 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
998 (set_attr "sign_extend" "yes")
999 (set_attr "length" "4,4,4,4,4,4,8,8")])
1002 [(set (match_operand:EXTSI 0 "int_reg_operand")
1003 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1004 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1008 (sign_extend:DI (match_dup 2)))]
1010 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1014 [(set (match_operand:DI 0 "altivec_register_operand")
1015 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1016 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1019 rtx dest = operands[0];
1020 rtx src = operands[1];
1021 int dest_regno = REGNO (dest);
1022 int src_regno = REGNO (src);
1023 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1024 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1026 if (BYTES_BIG_ENDIAN)
1028 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1029 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1033 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1034 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1039 (define_insn_and_split "*extendsi<mode>2_dot"
1040 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1041 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1043 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1048 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1050 (sign_extend:EXTSI (match_dup 1)))
1052 (compare:CC (match_dup 0)
1055 [(set_attr "type" "exts")
1056 (set_attr "dot" "yes")
1057 (set_attr "length" "4,8")])
1059 (define_insn_and_split "*extendsi<mode>2_dot2"
1060 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1061 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1063 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1064 (sign_extend:EXTSI (match_dup 1)))]
1069 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1071 (sign_extend:EXTSI (match_dup 1)))
1073 (compare:CC (match_dup 0)
1076 [(set_attr "type" "exts")
1077 (set_attr "dot" "yes")
1078 (set_attr "length" "4,8")])
1080 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1082 (define_insn "*macchwc"
1083 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1084 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1085 (match_operand:SI 2 "gpc_reg_operand" "r")
1088 (match_operand:HI 1 "gpc_reg_operand" "r")))
1089 (match_operand:SI 4 "gpc_reg_operand" "0"))
1091 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1092 (plus:SI (mult:SI (ashiftrt:SI
1100 [(set_attr "type" "halfmul")])
1102 (define_insn "*macchw"
1103 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1104 (plus:SI (mult:SI (ashiftrt:SI
1105 (match_operand:SI 2 "gpc_reg_operand" "r")
1108 (match_operand:HI 1 "gpc_reg_operand" "r")))
1109 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1112 [(set_attr "type" "halfmul")])
1114 (define_insn "*macchwuc"
1115 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1116 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1117 (match_operand:SI 2 "gpc_reg_operand" "r")
1120 (match_operand:HI 1 "gpc_reg_operand" "r")))
1121 (match_operand:SI 4 "gpc_reg_operand" "0"))
1123 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1124 (plus:SI (mult:SI (lshiftrt:SI
1132 [(set_attr "type" "halfmul")])
1134 (define_insn "*macchwu"
1135 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1136 (plus:SI (mult:SI (lshiftrt:SI
1137 (match_operand:SI 2 "gpc_reg_operand" "r")
1140 (match_operand:HI 1 "gpc_reg_operand" "r")))
1141 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1144 [(set_attr "type" "halfmul")])
1146 (define_insn "*machhwc"
1147 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1148 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1149 (match_operand:SI 1 "gpc_reg_operand" "%r")
1152 (match_operand:SI 2 "gpc_reg_operand" "r")
1154 (match_operand:SI 4 "gpc_reg_operand" "0"))
1156 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1157 (plus:SI (mult:SI (ashiftrt:SI
1166 [(set_attr "type" "halfmul")])
1168 (define_insn "*machhw"
1169 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1170 (plus:SI (mult:SI (ashiftrt:SI
1171 (match_operand:SI 1 "gpc_reg_operand" "%r")
1174 (match_operand:SI 2 "gpc_reg_operand" "r")
1176 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1179 [(set_attr "type" "halfmul")])
1181 (define_insn "*machhwuc"
1182 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1183 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1184 (match_operand:SI 1 "gpc_reg_operand" "%r")
1187 (match_operand:SI 2 "gpc_reg_operand" "r")
1189 (match_operand:SI 4 "gpc_reg_operand" "0"))
1191 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1192 (plus:SI (mult:SI (lshiftrt:SI
1201 [(set_attr "type" "halfmul")])
1203 (define_insn "*machhwu"
1204 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1205 (plus:SI (mult:SI (lshiftrt:SI
1206 (match_operand:SI 1 "gpc_reg_operand" "%r")
1209 (match_operand:SI 2 "gpc_reg_operand" "r")
1211 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1214 [(set_attr "type" "halfmul")])
1216 (define_insn "*maclhwc"
1217 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1218 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1219 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1221 (match_operand:HI 2 "gpc_reg_operand" "r")))
1222 (match_operand:SI 4 "gpc_reg_operand" "0"))
1224 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1225 (plus:SI (mult:SI (sign_extend:SI
1232 [(set_attr "type" "halfmul")])
1234 (define_insn "*maclhw"
1235 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1236 (plus:SI (mult:SI (sign_extend:SI
1237 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1239 (match_operand:HI 2 "gpc_reg_operand" "r")))
1240 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1243 [(set_attr "type" "halfmul")])
1245 (define_insn "*maclhwuc"
1246 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1247 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1248 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1250 (match_operand:HI 2 "gpc_reg_operand" "r")))
1251 (match_operand:SI 4 "gpc_reg_operand" "0"))
1253 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1254 (plus:SI (mult:SI (zero_extend:SI
1261 [(set_attr "type" "halfmul")])
1263 (define_insn "*maclhwu"
1264 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265 (plus:SI (mult:SI (zero_extend:SI
1266 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1268 (match_operand:HI 2 "gpc_reg_operand" "r")))
1269 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1272 [(set_attr "type" "halfmul")])
1274 (define_insn "*nmacchwc"
1275 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1276 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1277 (mult:SI (ashiftrt:SI
1278 (match_operand:SI 2 "gpc_reg_operand" "r")
1281 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1283 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1284 (minus:SI (match_dup 4)
1285 (mult:SI (ashiftrt:SI
1292 [(set_attr "type" "halfmul")])
1294 (define_insn "*nmacchw"
1295 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1296 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1297 (mult:SI (ashiftrt:SI
1298 (match_operand:SI 2 "gpc_reg_operand" "r")
1301 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1304 [(set_attr "type" "halfmul")])
1306 (define_insn "*nmachhwc"
1307 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1308 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1309 (mult:SI (ashiftrt:SI
1310 (match_operand:SI 1 "gpc_reg_operand" "%r")
1313 (match_operand:SI 2 "gpc_reg_operand" "r")
1316 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1317 (minus:SI (match_dup 4)
1318 (mult:SI (ashiftrt:SI
1326 [(set_attr "type" "halfmul")])
1328 (define_insn "*nmachhw"
1329 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1331 (mult:SI (ashiftrt:SI
1332 (match_operand:SI 1 "gpc_reg_operand" "%r")
1335 (match_operand:SI 2 "gpc_reg_operand" "r")
1339 [(set_attr "type" "halfmul")])
1341 (define_insn "*nmaclhwc"
1342 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1343 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1344 (mult:SI (sign_extend:SI
1345 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1347 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1349 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1350 (minus:SI (match_dup 4)
1351 (mult:SI (sign_extend:SI
1357 [(set_attr "type" "halfmul")])
1359 (define_insn "*nmaclhw"
1360 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1361 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1362 (mult:SI (sign_extend:SI
1363 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1365 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1368 [(set_attr "type" "halfmul")])
1370 (define_insn "*mulchwc"
1371 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1372 (compare:CC (mult:SI (ashiftrt:SI
1373 (match_operand:SI 2 "gpc_reg_operand" "r")
1376 (match_operand:HI 1 "gpc_reg_operand" "r")))
1378 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1379 (mult:SI (ashiftrt:SI
1386 [(set_attr "type" "halfmul")])
1388 (define_insn "*mulchw"
1389 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390 (mult:SI (ashiftrt:SI
1391 (match_operand:SI 2 "gpc_reg_operand" "r")
1394 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1397 [(set_attr "type" "halfmul")])
1399 (define_insn "*mulchwuc"
1400 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1401 (compare:CC (mult:SI (lshiftrt:SI
1402 (match_operand:SI 2 "gpc_reg_operand" "r")
1405 (match_operand:HI 1 "gpc_reg_operand" "r")))
1407 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1408 (mult:SI (lshiftrt:SI
1415 [(set_attr "type" "halfmul")])
1417 (define_insn "*mulchwu"
1418 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1419 (mult:SI (lshiftrt:SI
1420 (match_operand:SI 2 "gpc_reg_operand" "r")
1423 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1426 [(set_attr "type" "halfmul")])
1428 (define_insn "*mulhhwc"
1429 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1430 (compare:CC (mult:SI (ashiftrt:SI
1431 (match_operand:SI 1 "gpc_reg_operand" "%r")
1434 (match_operand:SI 2 "gpc_reg_operand" "r")
1437 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1438 (mult:SI (ashiftrt:SI
1446 [(set_attr "type" "halfmul")])
1448 (define_insn "*mulhhw"
1449 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1450 (mult:SI (ashiftrt:SI
1451 (match_operand:SI 1 "gpc_reg_operand" "%r")
1454 (match_operand:SI 2 "gpc_reg_operand" "r")
1458 [(set_attr "type" "halfmul")])
1460 (define_insn "*mulhhwuc"
1461 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1462 (compare:CC (mult:SI (lshiftrt:SI
1463 (match_operand:SI 1 "gpc_reg_operand" "%r")
1466 (match_operand:SI 2 "gpc_reg_operand" "r")
1469 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1470 (mult:SI (lshiftrt:SI
1478 [(set_attr "type" "halfmul")])
1480 (define_insn "*mulhhwu"
1481 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1482 (mult:SI (lshiftrt:SI
1483 (match_operand:SI 1 "gpc_reg_operand" "%r")
1486 (match_operand:SI 2 "gpc_reg_operand" "r")
1490 [(set_attr "type" "halfmul")])
1492 (define_insn "*mullhwc"
1493 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1494 (compare:CC (mult:SI (sign_extend:SI
1495 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1497 (match_operand:HI 2 "gpc_reg_operand" "r")))
1499 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1500 (mult:SI (sign_extend:SI
1506 [(set_attr "type" "halfmul")])
1508 (define_insn "*mullhw"
1509 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1510 (mult:SI (sign_extend:SI
1511 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1513 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1516 [(set_attr "type" "halfmul")])
1518 (define_insn "*mullhwuc"
1519 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1520 (compare:CC (mult:SI (zero_extend:SI
1521 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1523 (match_operand:HI 2 "gpc_reg_operand" "r")))
1525 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1526 (mult:SI (zero_extend:SI
1532 [(set_attr "type" "halfmul")])
1534 (define_insn "*mullhwu"
1535 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1536 (mult:SI (zero_extend:SI
1537 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1539 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1542 [(set_attr "type" "halfmul")])
1544 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1545 (define_insn "dlmzb"
1546 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1547 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1548 (match_operand:SI 2 "gpc_reg_operand" "r")]
1550 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1551 (unspec:SI [(match_dup 1)
1557 (define_expand "strlensi"
1558 [(set (match_operand:SI 0 "gpc_reg_operand")
1559 (unspec:SI [(match_operand:BLK 1 "general_operand")
1560 (match_operand:QI 2 "const_int_operand")
1561 (match_operand 3 "const_int_operand")]
1562 UNSPEC_DLMZB_STRLEN))
1563 (clobber (match_scratch:CC 4))]
1564 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1566 rtx result = operands[0];
1567 rtx src = operands[1];
1568 rtx search_char = operands[2];
1569 rtx align = operands[3];
1570 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1571 rtx loop_label, end_label, mem, cr0, cond;
1572 if (search_char != const0_rtx
1573 || GET_CODE (align) != CONST_INT
1574 || INTVAL (align) < 8)
1576 word1 = gen_reg_rtx (SImode);
1577 word2 = gen_reg_rtx (SImode);
1578 scratch_dlmzb = gen_reg_rtx (SImode);
1579 scratch_string = gen_reg_rtx (Pmode);
1580 loop_label = gen_label_rtx ();
1581 end_label = gen_label_rtx ();
1582 addr = force_reg (Pmode, XEXP (src, 0));
1583 emit_move_insn (scratch_string, addr);
1584 emit_label (loop_label);
1585 mem = change_address (src, SImode, scratch_string);
1586 emit_move_insn (word1, mem);
1587 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1588 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1589 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1590 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1591 emit_jump_insn (gen_rtx_SET (pc_rtx,
1592 gen_rtx_IF_THEN_ELSE (VOIDmode,
1598 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1599 emit_jump_insn (gen_rtx_SET (pc_rtx,
1600 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1602 emit_label (end_label);
1603 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1604 emit_insn (gen_subsi3 (result, scratch_string, addr));
1605 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1609 ;; Fixed-point arithmetic insns.
1611 (define_expand "add<mode>3"
1612 [(set (match_operand:SDI 0 "gpc_reg_operand")
1613 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1614 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1617 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1619 rtx lo0 = gen_lowpart (SImode, operands[0]);
1620 rtx lo1 = gen_lowpart (SImode, operands[1]);
1621 rtx lo2 = gen_lowpart (SImode, operands[2]);
1622 rtx hi0 = gen_highpart (SImode, operands[0]);
1623 rtx hi1 = gen_highpart (SImode, operands[1]);
1624 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1626 if (!reg_or_short_operand (lo2, SImode))
1627 lo2 = force_reg (SImode, lo2);
1628 if (!adde_operand (hi2, SImode))
1629 hi2 = force_reg (SImode, hi2);
1631 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1632 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1636 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1638 rtx tmp = ((!can_create_pseudo_p ()
1639 || rtx_equal_p (operands[0], operands[1]))
1640 ? operands[0] : gen_reg_rtx (<MODE>mode));
1642 /* Adding a constant to r0 is not a valid insn, so use a different
1643 strategy in that case. */
1644 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1646 if (operands[0] == operands[1])
1648 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1649 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1653 HOST_WIDE_INT val = INTVAL (operands[2]);
1654 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1655 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1657 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1660 /* The ordering here is important for the prolog expander.
1661 When space is allocated from the stack, adding 'low' first may
1662 produce a temporary deallocation (which would be bad). */
1663 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1664 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1669 (define_insn "*add<mode>3"
1670 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1671 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1672 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1678 [(set_attr "type" "add")])
1680 (define_insn "*addsi3_high"
1681 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1682 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1683 (high:SI (match_operand 2 "" ""))))]
1684 "TARGET_MACHO && !TARGET_64BIT"
1685 "addis %0,%1,ha16(%2)"
1686 [(set_attr "type" "add")])
1688 (define_insn_and_split "*add<mode>3_dot"
1689 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1690 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1691 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1693 (clobber (match_scratch:GPR 0 "=r,r"))]
1694 "<MODE>mode == Pmode"
1698 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1700 (plus:GPR (match_dup 1)
1703 (compare:CC (match_dup 0)
1706 [(set_attr "type" "add")
1707 (set_attr "dot" "yes")
1708 (set_attr "length" "4,8")])
1710 (define_insn_and_split "*add<mode>3_dot2"
1711 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1712 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1713 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1715 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1716 (plus:GPR (match_dup 1)
1718 "<MODE>mode == Pmode"
1722 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1724 (plus:GPR (match_dup 1)
1727 (compare:CC (match_dup 0)
1730 [(set_attr "type" "add")
1731 (set_attr "dot" "yes")
1732 (set_attr "length" "4,8")])
1734 (define_insn_and_split "*add<mode>3_imm_dot"
1735 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1736 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1737 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1739 (clobber (match_scratch:GPR 0 "=r,r"))
1740 (clobber (reg:GPR CA_REGNO))]
1741 "<MODE>mode == Pmode"
1745 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1747 (plus:GPR (match_dup 1)
1750 (compare:CC (match_dup 0)
1753 [(set_attr "type" "add")
1754 (set_attr "dot" "yes")
1755 (set_attr "length" "4,8")])
1757 (define_insn_and_split "*add<mode>3_imm_dot2"
1758 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1759 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1760 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1762 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1763 (plus:GPR (match_dup 1)
1765 (clobber (reg:GPR CA_REGNO))]
1766 "<MODE>mode == Pmode"
1770 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1772 (plus:GPR (match_dup 1)
1775 (compare:CC (match_dup 0)
1778 [(set_attr "type" "add")
1779 (set_attr "dot" "yes")
1780 (set_attr "length" "4,8")])
1782 ;; Split an add that we can't do in one insn into two insns, each of which
1783 ;; does one 16-bit part. This is used by combine. Note that the low-order
1784 ;; add should be last in case the result gets used in an address.
1787 [(set (match_operand:GPR 0 "gpc_reg_operand")
1788 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1789 (match_operand:GPR 2 "non_add_cint_operand")))]
1791 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1792 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1794 HOST_WIDE_INT val = INTVAL (operands[2]);
1795 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1796 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1798 operands[4] = GEN_INT (low);
1799 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1800 operands[3] = GEN_INT (rest);
1801 else if (can_create_pseudo_p ())
1803 operands[3] = gen_reg_rtx (DImode);
1804 emit_move_insn (operands[3], operands[2]);
1805 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1813 (define_insn "add<mode>3_carry"
1814 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1815 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1816 (match_operand:P 2 "reg_or_short_operand" "rI")))
1817 (set (reg:P CA_REGNO)
1818 (ltu:P (plus:P (match_dup 1)
1823 [(set_attr "type" "add")])
1825 (define_insn "*add<mode>3_imm_carry_pos"
1826 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1827 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1828 (match_operand:P 2 "short_cint_operand" "n")))
1829 (set (reg:P CA_REGNO)
1830 (geu:P (match_dup 1)
1831 (match_operand:P 3 "const_int_operand" "n")))]
1832 "INTVAL (operands[2]) > 0
1833 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1835 [(set_attr "type" "add")])
1837 (define_insn "*add<mode>3_imm_carry_0"
1838 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1839 (match_operand:P 1 "gpc_reg_operand" "r"))
1840 (set (reg:P CA_REGNO)
1844 [(set_attr "type" "add")])
1846 (define_insn "*add<mode>3_imm_carry_m1"
1847 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1848 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1850 (set (reg:P CA_REGNO)
1855 [(set_attr "type" "add")])
1857 (define_insn "*add<mode>3_imm_carry_neg"
1858 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1859 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1860 (match_operand:P 2 "short_cint_operand" "n")))
1861 (set (reg:P CA_REGNO)
1862 (gtu:P (match_dup 1)
1863 (match_operand:P 3 "const_int_operand" "n")))]
1864 "INTVAL (operands[2]) < 0
1865 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1867 [(set_attr "type" "add")])
1870 (define_expand "add<mode>3_carry_in"
1872 (set (match_operand:GPR 0 "gpc_reg_operand")
1873 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1874 (match_operand:GPR 2 "adde_operand"))
1875 (reg:GPR CA_REGNO)))
1876 (clobber (reg:GPR CA_REGNO))])]
1879 if (operands[2] == const0_rtx)
1881 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1884 if (operands[2] == constm1_rtx)
1886 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1891 (define_insn "*add<mode>3_carry_in_internal"
1892 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1893 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1894 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1895 (reg:GPR CA_REGNO)))
1896 (clobber (reg:GPR CA_REGNO))]
1899 [(set_attr "type" "add")])
1901 (define_insn "*add<mode>3_carry_in_internal2"
1902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1903 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1905 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1906 (clobber (reg:GPR CA_REGNO))]
1909 [(set_attr "type" "add")])
1911 (define_insn "add<mode>3_carry_in_0"
1912 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1913 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1914 (reg:GPR CA_REGNO)))
1915 (clobber (reg:GPR CA_REGNO))]
1918 [(set_attr "type" "add")])
1920 (define_insn "add<mode>3_carry_in_m1"
1921 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1922 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1925 (clobber (reg:GPR CA_REGNO))]
1928 [(set_attr "type" "add")])
1931 (define_expand "one_cmpl<mode>2"
1932 [(set (match_operand:SDI 0 "gpc_reg_operand")
1933 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1936 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1938 rs6000_split_logical (operands, NOT, false, false, false);
1943 (define_insn "*one_cmpl<mode>2"
1944 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1945 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1949 (define_insn_and_split "*one_cmpl<mode>2_dot"
1950 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1951 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1953 (clobber (match_scratch:GPR 0 "=r,r"))]
1954 "<MODE>mode == Pmode"
1958 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1960 (not:GPR (match_dup 1)))
1962 (compare:CC (match_dup 0)
1965 [(set_attr "type" "logical")
1966 (set_attr "dot" "yes")
1967 (set_attr "length" "4,8")])
1969 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1970 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1971 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1973 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1974 (not:GPR (match_dup 1)))]
1975 "<MODE>mode == Pmode"
1979 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1981 (not:GPR (match_dup 1)))
1983 (compare:CC (match_dup 0)
1986 [(set_attr "type" "logical")
1987 (set_attr "dot" "yes")
1988 (set_attr "length" "4,8")])
1991 (define_expand "sub<mode>3"
1992 [(set (match_operand:SDI 0 "gpc_reg_operand")
1993 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
1994 (match_operand:SDI 2 "gpc_reg_operand")))]
1997 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1999 rtx lo0 = gen_lowpart (SImode, operands[0]);
2000 rtx lo1 = gen_lowpart (SImode, operands[1]);
2001 rtx lo2 = gen_lowpart (SImode, operands[2]);
2002 rtx hi0 = gen_highpart (SImode, operands[0]);
2003 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2004 rtx hi2 = gen_highpart (SImode, operands[2]);
2006 if (!reg_or_short_operand (lo1, SImode))
2007 lo1 = force_reg (SImode, lo1);
2008 if (!adde_operand (hi1, SImode))
2009 hi1 = force_reg (SImode, hi1);
2011 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2012 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2016 if (short_cint_operand (operands[1], <MODE>mode))
2018 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2023 (define_insn "*subf<mode>3"
2024 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2025 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2026 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2029 [(set_attr "type" "add")])
2031 (define_insn_and_split "*subf<mode>3_dot"
2032 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2033 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2034 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2036 (clobber (match_scratch:GPR 0 "=r,r"))]
2037 "<MODE>mode == Pmode"
2041 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2043 (minus:GPR (match_dup 2)
2046 (compare:CC (match_dup 0)
2049 [(set_attr "type" "add")
2050 (set_attr "dot" "yes")
2051 (set_attr "length" "4,8")])
2053 (define_insn_and_split "*subf<mode>3_dot2"
2054 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2055 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2056 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2058 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2059 (minus:GPR (match_dup 2)
2061 "<MODE>mode == Pmode"
2065 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2067 (minus:GPR (match_dup 2)
2070 (compare:CC (match_dup 0)
2073 [(set_attr "type" "add")
2074 (set_attr "dot" "yes")
2075 (set_attr "length" "4,8")])
2077 (define_insn "subf<mode>3_imm"
2078 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2079 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2080 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2081 (clobber (reg:GPR CA_REGNO))]
2084 [(set_attr "type" "add")])
2086 (define_insn_and_split "subf<mode>3_carry_dot2"
2087 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2088 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2089 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2091 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2092 (minus:P (match_dup 2)
2094 (set (reg:P CA_REGNO)
2095 (leu:P (match_dup 1)
2097 "<MODE>mode == Pmode"
2101 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2102 [(parallel [(set (match_dup 0)
2103 (minus:P (match_dup 2)
2105 (set (reg:P CA_REGNO)
2106 (leu:P (match_dup 1)
2109 (compare:CC (match_dup 0)
2112 [(set_attr "type" "add")
2113 (set_attr "dot" "yes")
2114 (set_attr "length" "4,8")])
2116 (define_insn "subf<mode>3_carry"
2117 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2118 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2119 (match_operand:P 1 "gpc_reg_operand" "r")))
2120 (set (reg:P CA_REGNO)
2121 (leu:P (match_dup 1)
2125 [(set_attr "type" "add")])
2127 (define_insn "*subf<mode>3_imm_carry_0"
2128 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2129 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2130 (set (reg:P CA_REGNO)
2135 [(set_attr "type" "add")])
2137 (define_insn "*subf<mode>3_imm_carry_m1"
2138 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2139 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2140 (set (reg:P CA_REGNO)
2144 [(set_attr "type" "add")])
2147 (define_expand "subf<mode>3_carry_in"
2149 (set (match_operand:GPR 0 "gpc_reg_operand")
2150 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2152 (match_operand:GPR 2 "adde_operand")))
2153 (clobber (reg:GPR CA_REGNO))])]
2156 if (operands[2] == const0_rtx)
2158 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2161 if (operands[2] == constm1_rtx)
2163 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2168 (define_insn "*subf<mode>3_carry_in_internal"
2169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2170 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2172 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2173 (clobber (reg:GPR CA_REGNO))]
2176 [(set_attr "type" "add")])
2178 (define_insn "subf<mode>3_carry_in_0"
2179 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2181 (reg:GPR CA_REGNO)))
2182 (clobber (reg:GPR CA_REGNO))]
2185 [(set_attr "type" "add")])
2187 (define_insn "subf<mode>3_carry_in_m1"
2188 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2190 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2192 (clobber (reg:GPR CA_REGNO))]
2195 [(set_attr "type" "add")])
2197 (define_insn "subf<mode>3_carry_in_xx"
2198 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199 (plus:GPR (reg:GPR CA_REGNO)
2201 (clobber (reg:GPR CA_REGNO))]
2204 [(set_attr "type" "add")])
2207 (define_insn "neg<mode>2"
2208 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2209 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2212 [(set_attr "type" "add")])
2214 (define_insn_and_split "*neg<mode>2_dot"
2215 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2216 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2218 (clobber (match_scratch:GPR 0 "=r,r"))]
2219 "<MODE>mode == Pmode"
2223 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2225 (neg:GPR (match_dup 1)))
2227 (compare:CC (match_dup 0)
2230 [(set_attr "type" "add")
2231 (set_attr "dot" "yes")
2232 (set_attr "length" "4,8")])
2234 (define_insn_and_split "*neg<mode>2_dot2"
2235 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2236 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2238 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2239 (neg:GPR (match_dup 1)))]
2240 "<MODE>mode == Pmode"
2244 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2246 (neg:GPR (match_dup 1)))
2248 (compare:CC (match_dup 0)
2251 [(set_attr "type" "add")
2252 (set_attr "dot" "yes")
2253 (set_attr "length" "4,8")])
2256 (define_insn "clz<mode>2"
2257 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2258 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2261 [(set_attr "type" "cntlz")])
2263 (define_expand "ctz<mode>2"
2264 [(set (match_operand:GPR 0 "gpc_reg_operand")
2265 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2270 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2274 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2275 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2276 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2280 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2281 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2282 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2283 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2287 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2288 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2289 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2290 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2296 (define_insn "ctz<mode>2_hw"
2297 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2298 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2301 [(set_attr "type" "cntlz")])
2303 (define_expand "ffs<mode>2"
2304 [(set (match_operand:GPR 0 "gpc_reg_operand")
2305 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2308 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2309 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2310 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2311 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2312 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2313 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2314 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2319 (define_expand "popcount<mode>2"
2320 [(set (match_operand:GPR 0 "gpc_reg_operand")
2321 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2322 "TARGET_POPCNTB || TARGET_POPCNTD"
2324 rs6000_emit_popcount (operands[0], operands[1]);
2328 (define_insn "popcntb<mode>2"
2329 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2330 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2334 [(set_attr "type" "popcnt")])
2336 (define_insn "popcntd<mode>2"
2337 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2338 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2341 [(set_attr "type" "popcnt")])
2344 (define_expand "parity<mode>2"
2345 [(set (match_operand:GPR 0 "gpc_reg_operand")
2346 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2349 rs6000_emit_parity (operands[0], operands[1]);
2353 (define_insn "parity<mode>2_cmpb"
2354 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2355 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2356 "TARGET_CMPB && TARGET_POPCNTB"
2358 [(set_attr "type" "popcnt")])
2360 (define_insn "cmpb<mode>3"
2361 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2362 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2363 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2366 [(set_attr "type" "cmp")])
2368 ;; Since the hardware zeros the upper part of the register, save generating the
2369 ;; AND immediate if we are converting to unsigned
2370 (define_insn "*bswap<mode>2_extenddi"
2371 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2373 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2376 [(set_attr "type" "load")])
2378 (define_insn "*bswaphi2_extendsi"
2379 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2381 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2384 [(set_attr "type" "load")])
2386 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2387 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2388 ;; load with byte swap, which can be slower than doing it in the registers. It
2389 ;; also prevents certain failures with the RELOAD register allocator.
2391 (define_expand "bswap<mode>2"
2392 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2393 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2396 rtx dest = operands[0];
2397 rtx src = operands[1];
2399 if (!REG_P (dest) && !REG_P (src))
2400 src = force_reg (<MODE>mode, src);
2404 src = rs6000_force_indexed_or_indirect_mem (src);
2405 emit_insn (gen_bswap<mode>2_load (dest, src));
2407 else if (MEM_P (dest))
2409 dest = rs6000_force_indexed_or_indirect_mem (dest);
2410 emit_insn (gen_bswap<mode>2_store (dest, src));
2413 emit_insn (gen_bswap<mode>2_reg (dest, src));
2417 (define_insn "bswap<mode>2_load"
2418 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2419 (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2422 [(set_attr "type" "load")])
2424 (define_insn "bswap<mode>2_store"
2425 [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2426 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2429 [(set_attr "type" "store")])
2431 (define_insn_and_split "bswaphi2_reg"
2432 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2434 (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2435 (clobber (match_scratch:SI 2 "=&r,X"))]
2440 "reload_completed && int_reg_operand (operands[0], HImode)"
2442 (and:SI (lshiftrt:SI (match_dup 4)
2446 (and:SI (ashift:SI (match_dup 4)
2448 (const_int 65280))) ;; 0xff00
2450 (ior:SI (match_dup 3)
2453 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2454 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2456 [(set_attr "length" "12,4")
2457 (set_attr "type" "*,vecperm")])
2459 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2460 ;; zero_extract insns do not change for -mlittle.
2461 (define_insn_and_split "bswapsi2_reg"
2462 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2464 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2469 "reload_completed && int_reg_operand (operands[0], SImode)"
2470 [(set (match_dup 0) ; DABC
2471 (rotate:SI (match_dup 1)
2473 (set (match_dup 0) ; DCBC
2474 (ior:SI (and:SI (ashift:SI (match_dup 1)
2476 (const_int 16711680))
2477 (and:SI (match_dup 0)
2478 (const_int -16711681))))
2479 (set (match_dup 0) ; DCBA
2480 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2483 (and:SI (match_dup 0)
2484 (const_int -256))))]
2486 [(set_attr "length" "12,4")
2487 (set_attr "type" "*,vecperm")])
2489 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2490 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2493 (define_expand "bswapdi2"
2494 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2496 (match_operand:DI 1 "reg_or_mem_operand")))
2497 (clobber (match_scratch:DI 2))
2498 (clobber (match_scratch:DI 3))])]
2501 rtx dest = operands[0];
2502 rtx src = operands[1];
2504 if (!REG_P (dest) && !REG_P (src))
2505 operands[1] = src = force_reg (DImode, src);
2507 if (TARGET_POWERPC64 && TARGET_LDBRX)
2511 src = rs6000_force_indexed_or_indirect_mem (src);
2512 emit_insn (gen_bswapdi2_load (dest, src));
2514 else if (MEM_P (dest))
2516 dest = rs6000_force_indexed_or_indirect_mem (dest);
2517 emit_insn (gen_bswapdi2_store (dest, src));
2519 else if (TARGET_P9_VECTOR)
2520 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2522 emit_insn (gen_bswapdi2_reg (dest, src));
2526 if (!TARGET_POWERPC64)
2528 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2529 that uses 64-bit registers needs the same scratch registers as 64-bit
2531 emit_insn (gen_bswapdi2_32bit (dest, src));
2536 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2537 (define_insn "bswapdi2_load"
2538 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2539 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2540 "TARGET_POWERPC64 && TARGET_LDBRX"
2542 [(set_attr "type" "load")])
2544 (define_insn "bswapdi2_store"
2545 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2546 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2547 "TARGET_POWERPC64 && TARGET_LDBRX"
2549 [(set_attr "type" "store")])
2551 (define_insn "bswapdi2_xxbrd"
2552 [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2553 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2556 [(set_attr "type" "vecperm")])
2558 (define_insn "bswapdi2_reg"
2559 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2560 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2561 (clobber (match_scratch:DI 2 "=&r"))
2562 (clobber (match_scratch:DI 3 "=&r"))]
2563 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2565 [(set_attr "length" "36")])
2567 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2568 (define_insn "*bswapdi2_64bit"
2569 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2570 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2571 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2572 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2573 "TARGET_POWERPC64 && !TARGET_LDBRX
2574 && (REG_P (operands[0]) || REG_P (operands[1]))
2575 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2576 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2578 [(set_attr "length" "16,12,36")])
2581 [(set (match_operand:DI 0 "gpc_reg_operand")
2582 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2583 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2584 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2585 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2588 rtx dest = operands[0];
2589 rtx src = operands[1];
2590 rtx op2 = operands[2];
2591 rtx op3 = operands[3];
2592 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2593 BYTES_BIG_ENDIAN ? 4 : 0);
2594 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2595 BYTES_BIG_ENDIAN ? 4 : 0);
2601 addr1 = XEXP (src, 0);
2602 if (GET_CODE (addr1) == PLUS)
2604 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2605 if (TARGET_AVOID_XFORM)
2607 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2611 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2613 else if (TARGET_AVOID_XFORM)
2615 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2620 emit_move_insn (op2, GEN_INT (4));
2621 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2624 word1 = change_address (src, SImode, addr1);
2625 word2 = change_address (src, SImode, addr2);
2627 if (BYTES_BIG_ENDIAN)
2629 emit_insn (gen_bswapsi2 (op3_32, word2));
2630 emit_insn (gen_bswapsi2 (dest_32, word1));
2634 emit_insn (gen_bswapsi2 (op3_32, word1));
2635 emit_insn (gen_bswapsi2 (dest_32, word2));
2638 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2639 emit_insn (gen_iordi3 (dest, dest, op3));
2644 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2645 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2646 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2647 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2648 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2651 rtx dest = operands[0];
2652 rtx src = operands[1];
2653 rtx op2 = operands[2];
2654 rtx op3 = operands[3];
2655 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2656 BYTES_BIG_ENDIAN ? 4 : 0);
2657 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2658 BYTES_BIG_ENDIAN ? 4 : 0);
2664 addr1 = XEXP (dest, 0);
2665 if (GET_CODE (addr1) == PLUS)
2667 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2668 if (TARGET_AVOID_XFORM)
2670 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2674 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2676 else if (TARGET_AVOID_XFORM)
2678 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2683 emit_move_insn (op2, GEN_INT (4));
2684 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2687 word1 = change_address (dest, SImode, addr1);
2688 word2 = change_address (dest, SImode, addr2);
2690 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2692 if (BYTES_BIG_ENDIAN)
2694 emit_insn (gen_bswapsi2 (word1, src_si));
2695 emit_insn (gen_bswapsi2 (word2, op3_si));
2699 emit_insn (gen_bswapsi2 (word2, src_si));
2700 emit_insn (gen_bswapsi2 (word1, op3_si));
2706 [(set (match_operand:DI 0 "gpc_reg_operand")
2707 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2708 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2709 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2710 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2713 rtx dest = operands[0];
2714 rtx src = operands[1];
2715 rtx op2 = operands[2];
2716 rtx op3 = operands[3];
2717 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2718 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2719 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2720 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2721 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2723 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2724 emit_insn (gen_bswapsi2 (dest_si, src_si));
2725 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2726 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2727 emit_insn (gen_iordi3 (dest, dest, op3));
2731 (define_insn "bswapdi2_32bit"
2732 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2733 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2734 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2735 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2737 [(set_attr "length" "16,12,36")])
2740 [(set (match_operand:DI 0 "gpc_reg_operand")
2741 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2742 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2743 "!TARGET_POWERPC64 && reload_completed"
2746 rtx dest = operands[0];
2747 rtx src = operands[1];
2748 rtx op2 = operands[2];
2749 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2750 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2756 addr1 = XEXP (src, 0);
2757 if (GET_CODE (addr1) == PLUS)
2759 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2760 if (TARGET_AVOID_XFORM
2761 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2763 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2767 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2769 else if (TARGET_AVOID_XFORM
2770 || REGNO (addr1) == REGNO (dest2))
2772 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2777 emit_move_insn (op2, GEN_INT (4));
2778 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2781 word1 = change_address (src, SImode, addr1);
2782 word2 = change_address (src, SImode, addr2);
2784 emit_insn (gen_bswapsi2 (dest2, word1));
2785 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2786 thus allowing us to omit an early clobber on the output. */
2787 emit_insn (gen_bswapsi2 (dest1, word2));
2792 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2793 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2794 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2795 "!TARGET_POWERPC64 && reload_completed"
2798 rtx dest = operands[0];
2799 rtx src = operands[1];
2800 rtx op2 = operands[2];
2801 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2802 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2808 addr1 = XEXP (dest, 0);
2809 if (GET_CODE (addr1) == PLUS)
2811 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2812 if (TARGET_AVOID_XFORM)
2814 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2818 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2820 else if (TARGET_AVOID_XFORM)
2822 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2827 emit_move_insn (op2, GEN_INT (4));
2828 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2831 word1 = change_address (dest, SImode, addr1);
2832 word2 = change_address (dest, SImode, addr2);
2834 emit_insn (gen_bswapsi2 (word2, src1));
2835 emit_insn (gen_bswapsi2 (word1, src2));
2840 [(set (match_operand:DI 0 "gpc_reg_operand")
2841 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2842 (clobber (match_operand:SI 2 ""))]
2843 "!TARGET_POWERPC64 && reload_completed"
2846 rtx dest = operands[0];
2847 rtx src = operands[1];
2848 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2849 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2850 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2851 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2853 emit_insn (gen_bswapsi2 (dest1, src2));
2854 emit_insn (gen_bswapsi2 (dest2, src1));
2859 (define_insn "mul<mode>3"
2860 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2861 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2862 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2867 [(set_attr "type" "mul")
2869 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2871 (match_operand:GPR 2 "short_cint_operand")
2872 (const_string "16")]
2873 (const_string "<bits>")))])
2875 (define_insn_and_split "*mul<mode>3_dot"
2876 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2877 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2878 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2880 (clobber (match_scratch:GPR 0 "=r,r"))]
2881 "<MODE>mode == Pmode"
2885 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2887 (mult:GPR (match_dup 1)
2890 (compare:CC (match_dup 0)
2893 [(set_attr "type" "mul")
2894 (set_attr "size" "<bits>")
2895 (set_attr "dot" "yes")
2896 (set_attr "length" "4,8")])
2898 (define_insn_and_split "*mul<mode>3_dot2"
2899 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2900 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2901 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2903 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2904 (mult:GPR (match_dup 1)
2906 "<MODE>mode == Pmode"
2910 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2912 (mult:GPR (match_dup 1)
2915 (compare:CC (match_dup 0)
2918 [(set_attr "type" "mul")
2919 (set_attr "size" "<bits>")
2920 (set_attr "dot" "yes")
2921 (set_attr "length" "4,8")])
2924 (define_expand "<su>mul<mode>3_highpart"
2925 [(set (match_operand:GPR 0 "gpc_reg_operand")
2927 (mult:<DMODE> (any_extend:<DMODE>
2928 (match_operand:GPR 1 "gpc_reg_operand"))
2930 (match_operand:GPR 2 "gpc_reg_operand")))
2934 if (<MODE>mode == SImode && TARGET_POWERPC64)
2936 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2941 if (!WORDS_BIG_ENDIAN)
2943 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2949 (define_insn "*<su>mul<mode>3_highpart"
2950 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2952 (mult:<DMODE> (any_extend:<DMODE>
2953 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2955 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2957 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2958 "mulh<wd><u> %0,%1,%2"
2959 [(set_attr "type" "mul")
2960 (set_attr "size" "<bits>")])
2962 (define_insn "<su>mulsi3_highpart_le"
2963 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2965 (mult:DI (any_extend:DI
2966 (match_operand:SI 1 "gpc_reg_operand" "r"))
2968 (match_operand:SI 2 "gpc_reg_operand" "r")))
2970 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2972 [(set_attr "type" "mul")])
2974 (define_insn "<su>muldi3_highpart_le"
2975 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2977 (mult:TI (any_extend:TI
2978 (match_operand:DI 1 "gpc_reg_operand" "r"))
2980 (match_operand:DI 2 "gpc_reg_operand" "r")))
2982 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2984 [(set_attr "type" "mul")
2985 (set_attr "size" "64")])
2987 (define_insn "<su>mulsi3_highpart_64"
2988 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2991 (mult:DI (any_extend:DI
2992 (match_operand:SI 1 "gpc_reg_operand" "r"))
2994 (match_operand:SI 2 "gpc_reg_operand" "r")))
2998 [(set_attr "type" "mul")])
3000 (define_expand "<u>mul<mode><dmode>3"
3001 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3002 (mult:<DMODE> (any_extend:<DMODE>
3003 (match_operand:GPR 1 "gpc_reg_operand"))
3005 (match_operand:GPR 2 "gpc_reg_operand"))))]
3006 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3008 rtx l = gen_reg_rtx (<MODE>mode);
3009 rtx h = gen_reg_rtx (<MODE>mode);
3010 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3011 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3012 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3013 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3017 (define_insn "*maddld4"
3018 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3019 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3020 (match_operand:DI 2 "gpc_reg_operand" "r"))
3021 (match_operand:DI 3 "gpc_reg_operand" "r")))]
3023 "maddld %0,%1,%2,%3"
3024 [(set_attr "type" "mul")])
3026 (define_insn "udiv<mode>3"
3027 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3028 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3029 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3032 [(set_attr "type" "div")
3033 (set_attr "size" "<bits>")])
3036 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3037 ;; modulus. If it isn't a power of two, force operands into register and do
3039 (define_expand "div<mode>3"
3040 [(set (match_operand:GPR 0 "gpc_reg_operand")
3041 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3042 (match_operand:GPR 2 "reg_or_cint_operand")))]
3045 if (CONST_INT_P (operands[2])
3046 && INTVAL (operands[2]) > 0
3047 && exact_log2 (INTVAL (operands[2])) >= 0)
3049 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3053 operands[2] = force_reg (<MODE>mode, operands[2]);
3056 (define_insn "*div<mode>3"
3057 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3058 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3059 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3062 [(set_attr "type" "div")
3063 (set_attr "size" "<bits>")])
3065 (define_insn "div<mode>3_sra"
3066 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3067 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3068 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3069 (clobber (reg:GPR CA_REGNO))]
3071 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3072 [(set_attr "type" "two")
3073 (set_attr "length" "8")])
3075 (define_insn_and_split "*div<mode>3_sra_dot"
3076 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3077 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3078 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3080 (clobber (match_scratch:GPR 0 "=r,r"))
3081 (clobber (reg:GPR CA_REGNO))]
3082 "<MODE>mode == Pmode"
3084 sra<wd>i %0,%1,%p2\;addze. %0,%0
3086 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3087 [(parallel [(set (match_dup 0)
3088 (div:GPR (match_dup 1)
3090 (clobber (reg:GPR CA_REGNO))])
3092 (compare:CC (match_dup 0)
3095 [(set_attr "type" "two")
3096 (set_attr "length" "8,12")
3097 (set_attr "cell_micro" "not")])
3099 (define_insn_and_split "*div<mode>3_sra_dot2"
3100 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3101 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3102 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3104 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3105 (div:GPR (match_dup 1)
3107 (clobber (reg:GPR CA_REGNO))]
3108 "<MODE>mode == Pmode"
3110 sra<wd>i %0,%1,%p2\;addze. %0,%0
3112 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3113 [(parallel [(set (match_dup 0)
3114 (div:GPR (match_dup 1)
3116 (clobber (reg:GPR CA_REGNO))])
3118 (compare:CC (match_dup 0)
3121 [(set_attr "type" "two")
3122 (set_attr "length" "8,12")
3123 (set_attr "cell_micro" "not")])
3125 (define_expand "mod<mode>3"
3126 [(set (match_operand:GPR 0 "gpc_reg_operand")
3127 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3128 (match_operand:GPR 2 "reg_or_cint_operand")))]
3135 if (GET_CODE (operands[2]) != CONST_INT
3136 || INTVAL (operands[2]) <= 0
3137 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3142 operands[2] = force_reg (<MODE>mode, operands[2]);
3146 temp1 = gen_reg_rtx (<MODE>mode);
3147 temp2 = gen_reg_rtx (<MODE>mode);
3149 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3150 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3151 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3156 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3157 ;; mod, prefer putting the result of mod into a different register
3158 (define_insn "*mod<mode>3"
3159 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3160 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3161 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3164 [(set_attr "type" "div")
3165 (set_attr "size" "<bits>")])
3168 (define_insn "umod<mode>3"
3169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3170 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3171 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3174 [(set_attr "type" "div")
3175 (set_attr "size" "<bits>")])
3177 ;; On machines with modulo support, do a combined div/mod the old fashioned
3178 ;; method, since the multiply/subtract is faster than doing the mod instruction
3182 [(set (match_operand:GPR 0 "gpc_reg_operand")
3183 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3184 (match_operand:GPR 2 "gpc_reg_operand")))
3185 (set (match_operand:GPR 3 "gpc_reg_operand")
3186 (mod:GPR (match_dup 1)
3189 && ! reg_mentioned_p (operands[0], operands[1])
3190 && ! reg_mentioned_p (operands[0], operands[2])
3191 && ! reg_mentioned_p (operands[3], operands[1])
3192 && ! reg_mentioned_p (operands[3], operands[2])"
3194 (div:GPR (match_dup 1)
3197 (mult:GPR (match_dup 0)
3200 (minus:GPR (match_dup 1)
3204 [(set (match_operand:GPR 0 "gpc_reg_operand")
3205 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3206 (match_operand:GPR 2 "gpc_reg_operand")))
3207 (set (match_operand:GPR 3 "gpc_reg_operand")
3208 (umod:GPR (match_dup 1)
3211 && ! reg_mentioned_p (operands[0], operands[1])
3212 && ! reg_mentioned_p (operands[0], operands[2])
3213 && ! reg_mentioned_p (operands[3], operands[1])
3214 && ! reg_mentioned_p (operands[3], operands[2])"
3216 (udiv:GPR (match_dup 1)
3219 (mult:GPR (match_dup 0)
3222 (minus:GPR (match_dup 1)
3226 ;; Logical instructions
3227 ;; The logical instructions are mostly combined by using match_operator,
3228 ;; but the plain AND insns are somewhat different because there is no
3229 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3230 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3232 (define_expand "and<mode>3"
3233 [(set (match_operand:SDI 0 "gpc_reg_operand")
3234 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3235 (match_operand:SDI 2 "reg_or_cint_operand")))]
3238 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3240 rs6000_split_logical (operands, AND, false, false, false);
3244 if (CONST_INT_P (operands[2]))
3246 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3248 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3252 if (logical_const_operand (operands[2], <MODE>mode))
3254 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3258 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3260 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3264 operands[2] = force_reg (<MODE>mode, operands[2]);
3269 (define_insn "and<mode>3_imm"
3270 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3271 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3272 (match_operand:GPR 2 "logical_const_operand" "n")))
3273 (clobber (match_scratch:CC 3 "=x"))]
3274 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3275 "andi%e2. %0,%1,%u2"
3276 [(set_attr "type" "logical")
3277 (set_attr "dot" "yes")])
3279 (define_insn_and_split "*and<mode>3_imm_dot"
3280 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3281 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3282 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3284 (clobber (match_scratch:GPR 0 "=r,r"))
3285 (clobber (match_scratch:CC 4 "=X,x"))]
3286 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3287 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3291 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3292 [(parallel [(set (match_dup 0)
3293 (and:GPR (match_dup 1)
3295 (clobber (match_dup 4))])
3297 (compare:CC (match_dup 0)
3300 [(set_attr "type" "logical")
3301 (set_attr "dot" "yes")
3302 (set_attr "length" "4,8")])
3304 (define_insn_and_split "*and<mode>3_imm_dot2"
3305 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3306 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3307 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3309 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3310 (and:GPR (match_dup 1)
3312 (clobber (match_scratch:CC 4 "=X,x"))]
3313 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3314 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3318 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3319 [(parallel [(set (match_dup 0)
3320 (and:GPR (match_dup 1)
3322 (clobber (match_dup 4))])
3324 (compare:CC (match_dup 0)
3327 [(set_attr "type" "logical")
3328 (set_attr "dot" "yes")
3329 (set_attr "length" "4,8")])
3331 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3332 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3333 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3334 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3336 (clobber (match_scratch:GPR 0 "=r,r"))]
3337 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3338 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3342 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3344 (and:GPR (match_dup 1)
3347 (compare:CC (match_dup 0)
3350 [(set_attr "type" "logical")
3351 (set_attr "dot" "yes")
3352 (set_attr "length" "4,8")])
3354 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3355 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3356 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3357 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3359 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3360 (and:GPR (match_dup 1)
3362 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3363 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3367 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3369 (and:GPR (match_dup 1)
3372 (compare:CC (match_dup 0)
3375 [(set_attr "type" "logical")
3376 (set_attr "dot" "yes")
3377 (set_attr "length" "4,8")])
3379 (define_insn "*and<mode>3_imm_dot_shifted"
3380 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3383 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3384 (match_operand:SI 4 "const_int_operand" "n"))
3385 (match_operand:GPR 2 "const_int_operand" "n"))
3387 (clobber (match_scratch:GPR 0 "=r"))]
3388 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3389 << INTVAL (operands[4])),
3391 && (<MODE>mode == Pmode
3392 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3394 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3395 return "andi%e2. %0,%1,%u2";
3397 [(set_attr "type" "logical")
3398 (set_attr "dot" "yes")])
3401 (define_insn "and<mode>3_mask"
3402 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3403 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3404 (match_operand:GPR 2 "const_int_operand" "n")))]
3405 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3407 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3409 [(set_attr "type" "shift")])
3411 (define_insn_and_split "*and<mode>3_mask_dot"
3412 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3413 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3414 (match_operand:GPR 2 "const_int_operand" "n,n"))
3416 (clobber (match_scratch:GPR 0 "=r,r"))]
3417 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3418 && !logical_const_operand (operands[2], <MODE>mode)
3419 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3421 if (which_alternative == 0)
3422 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3426 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3428 (and:GPR (match_dup 1)
3431 (compare:CC (match_dup 0)
3434 [(set_attr "type" "shift")
3435 (set_attr "dot" "yes")
3436 (set_attr "length" "4,8")])
3438 (define_insn_and_split "*and<mode>3_mask_dot2"
3439 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3440 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3441 (match_operand:GPR 2 "const_int_operand" "n,n"))
3443 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3444 (and:GPR (match_dup 1)
3446 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3447 && !logical_const_operand (operands[2], <MODE>mode)
3448 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3450 if (which_alternative == 0)
3451 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3455 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3457 (and:GPR (match_dup 1)
3460 (compare:CC (match_dup 0)
3463 [(set_attr "type" "shift")
3464 (set_attr "dot" "yes")
3465 (set_attr "length" "4,8")])
3468 (define_insn_and_split "*and<mode>3_2insn"
3469 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3470 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3471 (match_operand:GPR 2 "const_int_operand" "n")))]
3472 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3473 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3474 || logical_const_operand (operands[2], <MODE>mode))"
3479 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3482 [(set_attr "type" "shift")
3483 (set_attr "length" "8")])
3485 (define_insn_and_split "*and<mode>3_2insn_dot"
3486 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3487 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3488 (match_operand:GPR 2 "const_int_operand" "n,n"))
3490 (clobber (match_scratch:GPR 0 "=r,r"))]
3491 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3492 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3493 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3494 || logical_const_operand (operands[2], <MODE>mode))"
3496 "&& reload_completed"
3499 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3502 [(set_attr "type" "shift")
3503 (set_attr "dot" "yes")
3504 (set_attr "length" "8,12")])
3506 (define_insn_and_split "*and<mode>3_2insn_dot2"
3507 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3508 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3509 (match_operand:GPR 2 "const_int_operand" "n,n"))
3511 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3512 (and:GPR (match_dup 1)
3514 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3515 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3516 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3517 || logical_const_operand (operands[2], <MODE>mode))"
3519 "&& reload_completed"
3522 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3525 [(set_attr "type" "shift")
3526 (set_attr "dot" "yes")
3527 (set_attr "length" "8,12")])
3530 (define_expand "<code><mode>3"
3531 [(set (match_operand:SDI 0 "gpc_reg_operand")
3532 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3533 (match_operand:SDI 2 "reg_or_cint_operand")))]
3536 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3538 rs6000_split_logical (operands, <CODE>, false, false, false);
3542 if (non_logical_cint_operand (operands[2], <MODE>mode))
3544 rtx tmp = ((!can_create_pseudo_p ()
3545 || rtx_equal_p (operands[0], operands[1]))
3546 ? operands[0] : gen_reg_rtx (<MODE>mode));
3548 HOST_WIDE_INT value = INTVAL (operands[2]);
3549 HOST_WIDE_INT lo = value & 0xffff;
3550 HOST_WIDE_INT hi = value - lo;
3552 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3553 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3557 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3558 operands[2] = force_reg (<MODE>mode, operands[2]);
3562 [(set (match_operand:GPR 0 "gpc_reg_operand")
3563 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3564 (match_operand:GPR 2 "non_logical_cint_operand")))]
3567 (iorxor:GPR (match_dup 1)
3570 (iorxor:GPR (match_dup 3)
3573 operands[3] = ((!can_create_pseudo_p ()
3574 || rtx_equal_p (operands[0], operands[1]))
3575 ? operands[0] : gen_reg_rtx (<MODE>mode));
3577 HOST_WIDE_INT value = INTVAL (operands[2]);
3578 HOST_WIDE_INT lo = value & 0xffff;
3579 HOST_WIDE_INT hi = value - lo;
3581 operands[4] = GEN_INT (hi);
3582 operands[5] = GEN_INT (lo);
3585 (define_insn "*bool<mode>3_imm"
3586 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3587 (match_operator:GPR 3 "boolean_or_operator"
3588 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3589 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3592 [(set_attr "type" "logical")])
3594 (define_insn "*bool<mode>3"
3595 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3596 (match_operator:GPR 3 "boolean_operator"
3597 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3598 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3601 [(set_attr "type" "logical")])
3603 (define_insn_and_split "*bool<mode>3_dot"
3604 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3605 (compare:CC (match_operator:GPR 3 "boolean_operator"
3606 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3607 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3609 (clobber (match_scratch:GPR 0 "=r,r"))]
3610 "<MODE>mode == Pmode"
3614 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3618 (compare:CC (match_dup 0)
3621 [(set_attr "type" "logical")
3622 (set_attr "dot" "yes")
3623 (set_attr "length" "4,8")])
3625 (define_insn_and_split "*bool<mode>3_dot2"
3626 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3627 (compare:CC (match_operator:GPR 3 "boolean_operator"
3628 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3629 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3631 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3633 "<MODE>mode == Pmode"
3637 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3641 (compare:CC (match_dup 0)
3644 [(set_attr "type" "logical")
3645 (set_attr "dot" "yes")
3646 (set_attr "length" "4,8")])
3649 (define_insn "*boolc<mode>3"
3650 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3651 (match_operator:GPR 3 "boolean_operator"
3652 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3653 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3656 [(set_attr "type" "logical")])
3658 (define_insn_and_split "*boolc<mode>3_dot"
3659 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3660 (compare:CC (match_operator:GPR 3 "boolean_operator"
3661 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3662 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3664 (clobber (match_scratch:GPR 0 "=r,r"))]
3665 "<MODE>mode == Pmode"
3669 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3673 (compare:CC (match_dup 0)
3676 [(set_attr "type" "logical")
3677 (set_attr "dot" "yes")
3678 (set_attr "length" "4,8")])
3680 (define_insn_and_split "*boolc<mode>3_dot2"
3681 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3682 (compare:CC (match_operator:GPR 3 "boolean_operator"
3683 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3684 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3686 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3688 "<MODE>mode == Pmode"
3692 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3696 (compare:CC (match_dup 0)
3699 [(set_attr "type" "logical")
3700 (set_attr "dot" "yes")
3701 (set_attr "length" "4,8")])
3704 (define_insn "*boolcc<mode>3"
3705 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3706 (match_operator:GPR 3 "boolean_operator"
3707 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3708 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3711 [(set_attr "type" "logical")])
3713 (define_insn_and_split "*boolcc<mode>3_dot"
3714 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3715 (compare:CC (match_operator:GPR 3 "boolean_operator"
3716 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3717 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3719 (clobber (match_scratch:GPR 0 "=r,r"))]
3720 "<MODE>mode == Pmode"
3724 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3728 (compare:CC (match_dup 0)
3731 [(set_attr "type" "logical")
3732 (set_attr "dot" "yes")
3733 (set_attr "length" "4,8")])
3735 (define_insn_and_split "*boolcc<mode>3_dot2"
3736 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3737 (compare:CC (match_operator:GPR 3 "boolean_operator"
3738 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3739 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3741 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3743 "<MODE>mode == Pmode"
3747 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3751 (compare:CC (match_dup 0)
3754 [(set_attr "type" "logical")
3755 (set_attr "dot" "yes")
3756 (set_attr "length" "4,8")])
3759 ;; TODO: Should have dots of this as well.
3760 (define_insn "*eqv<mode>3"
3761 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3762 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3763 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3766 [(set_attr "type" "logical")])
3768 ;; Rotate-and-mask and insert.
3770 (define_insn "*rotl<mode>3_mask"
3771 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3772 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3773 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3774 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3775 (match_operand:GPR 3 "const_int_operand" "n")))]
3776 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3778 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3780 [(set_attr "type" "shift")
3781 (set_attr "maybe_var_shift" "yes")])
3783 (define_insn_and_split "*rotl<mode>3_mask_dot"
3784 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3786 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3787 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3788 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3789 (match_operand:GPR 3 "const_int_operand" "n,n"))
3791 (clobber (match_scratch:GPR 0 "=r,r"))]
3792 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3793 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3795 if (which_alternative == 0)
3796 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3800 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3802 (and:GPR (match_dup 4)
3805 (compare:CC (match_dup 0)
3808 [(set_attr "type" "shift")
3809 (set_attr "maybe_var_shift" "yes")
3810 (set_attr "dot" "yes")
3811 (set_attr "length" "4,8")])
3813 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3814 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3816 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3817 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3818 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3819 (match_operand:GPR 3 "const_int_operand" "n,n"))
3821 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3822 (and:GPR (match_dup 4)
3824 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3825 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3827 if (which_alternative == 0)
3828 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3832 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3834 (and:GPR (match_dup 4)
3837 (compare:CC (match_dup 0)
3840 [(set_attr "type" "shift")
3841 (set_attr "maybe_var_shift" "yes")
3842 (set_attr "dot" "yes")
3843 (set_attr "length" "4,8")])
3845 ; Special case for less-than-0. We can do it with just one machine
3846 ; instruction, but the generic optimizers do not realise it is cheap.
3847 (define_insn "*lt0_<mode>di"
3848 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3849 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3853 [(set_attr "type" "shift")])
3855 (define_insn "*lt0_<mode>si"
3856 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3857 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3860 "rlwinm %0,%1,1,31,31"
3861 [(set_attr "type" "shift")])
3865 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3866 ; both are an AND so are the same precedence).
3867 (define_insn "*rotl<mode>3_insert"
3868 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3869 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3870 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3871 (match_operand:SI 2 "const_int_operand" "n")])
3872 (match_operand:GPR 3 "const_int_operand" "n"))
3873 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3874 (match_operand:GPR 6 "const_int_operand" "n"))))]
3875 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3876 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3878 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3880 [(set_attr "type" "insert")])
3881 ; FIXME: this needs an attr "size", so that the scheduler can see the
3882 ; difference between rlwimi and rldimi. We also might want dot forms,
3883 ; but not for rlwimi on POWER4 and similar processors.
3885 (define_insn "*rotl<mode>3_insert_2"
3886 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3887 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3888 (match_operand:GPR 6 "const_int_operand" "n"))
3889 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3890 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3891 (match_operand:SI 2 "const_int_operand" "n")])
3892 (match_operand:GPR 3 "const_int_operand" "n"))))]
3893 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3894 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3896 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3898 [(set_attr "type" "insert")])
3900 ; There are also some forms without one of the ANDs.
3901 (define_insn "*rotl<mode>3_insert_3"
3902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3903 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3904 (match_operand:GPR 4 "const_int_operand" "n"))
3905 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3906 (match_operand:SI 2 "const_int_operand" "n"))))]
3907 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3909 if (<MODE>mode == SImode)
3910 return "rlwimi %0,%1,%h2,0,31-%h2";
3912 return "rldimi %0,%1,%H2,0";
3914 [(set_attr "type" "insert")])
3916 (define_insn "*rotl<mode>3_insert_4"
3917 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3918 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3919 (match_operand:GPR 4 "const_int_operand" "n"))
3920 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3921 (match_operand:SI 2 "const_int_operand" "n"))))]
3922 "<MODE>mode == SImode &&
3923 GET_MODE_PRECISION (<MODE>mode)
3924 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3926 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3927 - INTVAL (operands[2]));
3928 if (<MODE>mode == SImode)
3929 return "rlwimi %0,%1,%h2,32-%h2,31";
3931 return "rldimi %0,%1,%H2,64-%H2";
3933 [(set_attr "type" "insert")])
3935 (define_insn "*rotlsi3_insert_5"
3936 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3937 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3938 (match_operand:SI 2 "const_int_operand" "n,n"))
3939 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3940 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3941 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3942 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3943 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3947 [(set_attr "type" "insert")])
3949 (define_insn "*rotldi3_insert_6"
3950 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3951 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3952 (match_operand:DI 2 "const_int_operand" "n"))
3953 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3954 (match_operand:DI 4 "const_int_operand" "n"))))]
3955 "exact_log2 (-UINTVAL (operands[2])) > 0
3956 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3958 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3959 return "rldimi %0,%3,0,%5";
3961 [(set_attr "type" "insert")
3962 (set_attr "size" "64")])
3964 (define_insn "*rotldi3_insert_7"
3965 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3966 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3967 (match_operand:DI 4 "const_int_operand" "n"))
3968 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3969 (match_operand:DI 2 "const_int_operand" "n"))))]
3970 "exact_log2 (-UINTVAL (operands[2])) > 0
3971 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3973 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3974 return "rldimi %0,%3,0,%5";
3976 [(set_attr "type" "insert")
3977 (set_attr "size" "64")])
3980 ; This handles the important case of multiple-precision shifts. There is
3981 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3983 [(set (match_operand:GPR 0 "gpc_reg_operand")
3984 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3985 (match_operand:SI 3 "const_int_operand"))
3986 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3987 (match_operand:SI 4 "const_int_operand"))))]
3988 "can_create_pseudo_p ()
3989 && INTVAL (operands[3]) + INTVAL (operands[4])
3990 >= GET_MODE_PRECISION (<MODE>mode)"
3992 (lshiftrt:GPR (match_dup 2)
3995 (ior:GPR (and:GPR (match_dup 5)
3997 (ashift:GPR (match_dup 1)
4000 unsigned HOST_WIDE_INT mask = 1;
4001 mask = (mask << INTVAL (operands[3])) - 1;
4002 operands[5] = gen_reg_rtx (<MODE>mode);
4003 operands[6] = GEN_INT (mask);
4007 [(set (match_operand:GPR 0 "gpc_reg_operand")
4008 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4009 (match_operand:SI 4 "const_int_operand"))
4010 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4011 (match_operand:SI 3 "const_int_operand"))))]
4012 "can_create_pseudo_p ()
4013 && INTVAL (operands[3]) + INTVAL (operands[4])
4014 >= GET_MODE_PRECISION (<MODE>mode)"
4016 (lshiftrt:GPR (match_dup 2)
4019 (ior:GPR (and:GPR (match_dup 5)
4021 (ashift:GPR (match_dup 1)
4024 unsigned HOST_WIDE_INT mask = 1;
4025 mask = (mask << INTVAL (operands[3])) - 1;
4026 operands[5] = gen_reg_rtx (<MODE>mode);
4027 operands[6] = GEN_INT (mask);
4031 ; Another important case is setting some bits to 1; we can do that with
4032 ; an insert instruction, in many cases.
4033 (define_insn_and_split "*ior<mode>_mask"
4034 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4035 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4036 (match_operand:GPR 2 "const_int_operand" "n")))
4037 (clobber (match_scratch:GPR 3 "=r"))]
4038 "!logical_const_operand (operands[2], <MODE>mode)
4039 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4045 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4048 (and:GPR (match_dup 1)
4052 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4053 if (GET_CODE (operands[3]) == SCRATCH)
4054 operands[3] = gen_reg_rtx (<MODE>mode);
4055 operands[4] = GEN_INT (ne);
4056 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4058 [(set_attr "type" "two")
4059 (set_attr "length" "8")])
4062 ; Yet another case is an rldimi with the second value coming from memory.
4063 ; The zero_extend that should become part of the rldimi is merged into the
4064 ; load from memory instead. Split things properly again.
4066 [(set (match_operand:DI 0 "gpc_reg_operand")
4067 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4068 (match_operand:SI 2 "const_int_operand"))
4069 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4070 "INTVAL (operands[2]) == <bits>"
4072 (zero_extend:DI (match_dup 3)))
4074 (ior:DI (and:DI (match_dup 4)
4076 (ashift:DI (match_dup 1)
4079 operands[4] = gen_reg_rtx (DImode);
4080 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4085 [(set (match_operand:SI 0 "gpc_reg_operand")
4086 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4087 (match_operand:SI 2 "const_int_operand"))
4088 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4089 "INTVAL (operands[2]) == <bits>"
4091 (zero_extend:SI (match_dup 3)))
4093 (ior:SI (and:SI (match_dup 4)
4095 (ashift:SI (match_dup 1)
4098 operands[4] = gen_reg_rtx (SImode);
4099 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4103 ;; Now the simple shifts.
4105 (define_insn "rotl<mode>3"
4106 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4107 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4108 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4110 "rotl<wd>%I2 %0,%1,%<hH>2"
4111 [(set_attr "type" "shift")
4112 (set_attr "maybe_var_shift" "yes")])
4114 (define_insn "*rotlsi3_64"
4115 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4117 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4118 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4120 "rotlw%I2 %0,%1,%h2"
4121 [(set_attr "type" "shift")
4122 (set_attr "maybe_var_shift" "yes")])
4124 (define_insn_and_split "*rotl<mode>3_dot"
4125 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4126 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4127 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4129 (clobber (match_scratch:GPR 0 "=r,r"))]
4130 "<MODE>mode == Pmode"
4132 rotl<wd>%I2. %0,%1,%<hH>2
4134 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4136 (rotate:GPR (match_dup 1)
4139 (compare:CC (match_dup 0)
4142 [(set_attr "type" "shift")
4143 (set_attr "maybe_var_shift" "yes")
4144 (set_attr "dot" "yes")
4145 (set_attr "length" "4,8")])
4147 (define_insn_and_split "*rotl<mode>3_dot2"
4148 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4149 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4150 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4152 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4153 (rotate:GPR (match_dup 1)
4155 "<MODE>mode == Pmode"
4157 rotl<wd>%I2. %0,%1,%<hH>2
4159 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4161 (rotate:GPR (match_dup 1)
4164 (compare:CC (match_dup 0)
4167 [(set_attr "type" "shift")
4168 (set_attr "maybe_var_shift" "yes")
4169 (set_attr "dot" "yes")
4170 (set_attr "length" "4,8")])
4173 (define_insn "ashl<mode>3"
4174 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4175 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4176 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4178 "sl<wd>%I2 %0,%1,%<hH>2"
4179 [(set_attr "type" "shift")
4180 (set_attr "maybe_var_shift" "yes")])
4182 (define_insn "*ashlsi3_64"
4183 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4185 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4186 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4189 [(set_attr "type" "shift")
4190 (set_attr "maybe_var_shift" "yes")])
4192 (define_insn_and_split "*ashl<mode>3_dot"
4193 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4194 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4195 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4197 (clobber (match_scratch:GPR 0 "=r,r"))]
4198 "<MODE>mode == Pmode"
4200 sl<wd>%I2. %0,%1,%<hH>2
4202 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4204 (ashift:GPR (match_dup 1)
4207 (compare:CC (match_dup 0)
4210 [(set_attr "type" "shift")
4211 (set_attr "maybe_var_shift" "yes")
4212 (set_attr "dot" "yes")
4213 (set_attr "length" "4,8")])
4215 (define_insn_and_split "*ashl<mode>3_dot2"
4216 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4217 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4218 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4220 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4221 (ashift:GPR (match_dup 1)
4223 "<MODE>mode == Pmode"
4225 sl<wd>%I2. %0,%1,%<hH>2
4227 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4229 (ashift:GPR (match_dup 1)
4232 (compare:CC (match_dup 0)
4235 [(set_attr "type" "shift")
4236 (set_attr "maybe_var_shift" "yes")
4237 (set_attr "dot" "yes")
4238 (set_attr "length" "4,8")])
4240 ;; Pretend we have a memory form of extswsli until register allocation is done
4241 ;; so that we use LWZ to load the value from memory, instead of LWA.
4242 (define_insn_and_split "ashdi3_extswsli"
4243 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4245 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4246 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4251 "&& reload_completed && MEM_P (operands[1])"
4255 (ashift:DI (sign_extend:DI (match_dup 3))
4258 operands[3] = gen_lowpart (SImode, operands[0]);
4260 [(set_attr "type" "shift")
4261 (set_attr "maybe_var_shift" "no")])
4264 (define_insn_and_split "ashdi3_extswsli_dot"
4265 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4268 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4269 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4271 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4278 "&& reload_completed
4279 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4280 || memory_operand (operands[1], SImode))"
4283 rtx dest = operands[0];
4284 rtx src = operands[1];
4285 rtx shift = operands[2];
4286 rtx cr = operands[3];
4293 src2 = gen_lowpart (SImode, dest);
4294 emit_move_insn (src2, src);
4297 if (REGNO (cr) == CR0_REGNO)
4299 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4303 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4304 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4307 [(set_attr "type" "shift")
4308 (set_attr "maybe_var_shift" "no")
4309 (set_attr "dot" "yes")
4310 (set_attr "length" "4,8,8,12")])
4312 (define_insn_and_split "ashdi3_extswsli_dot2"
4313 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4316 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4317 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4319 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4320 (ashift:DI (sign_extend:DI (match_dup 1))
4328 "&& reload_completed
4329 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4330 || memory_operand (operands[1], SImode))"
4333 rtx dest = operands[0];
4334 rtx src = operands[1];
4335 rtx shift = operands[2];
4336 rtx cr = operands[3];
4343 src2 = gen_lowpart (SImode, dest);
4344 emit_move_insn (src2, src);
4347 if (REGNO (cr) == CR0_REGNO)
4349 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4353 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4354 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4357 [(set_attr "type" "shift")
4358 (set_attr "maybe_var_shift" "no")
4359 (set_attr "dot" "yes")
4360 (set_attr "length" "4,8,8,12")])
4362 (define_insn "lshr<mode>3"
4363 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4364 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4365 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4367 "sr<wd>%I2 %0,%1,%<hH>2"
4368 [(set_attr "type" "shift")
4369 (set_attr "maybe_var_shift" "yes")])
4371 (define_insn "*lshrsi3_64"
4372 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4374 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4375 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4378 [(set_attr "type" "shift")
4379 (set_attr "maybe_var_shift" "yes")])
4381 (define_insn_and_split "*lshr<mode>3_dot"
4382 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4383 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4384 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4386 (clobber (match_scratch:GPR 0 "=r,r"))]
4387 "<MODE>mode == Pmode"
4389 sr<wd>%I2. %0,%1,%<hH>2
4391 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4393 (lshiftrt:GPR (match_dup 1)
4396 (compare:CC (match_dup 0)
4399 [(set_attr "type" "shift")
4400 (set_attr "maybe_var_shift" "yes")
4401 (set_attr "dot" "yes")
4402 (set_attr "length" "4,8")])
4404 (define_insn_and_split "*lshr<mode>3_dot2"
4405 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4406 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4407 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4409 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4410 (lshiftrt:GPR (match_dup 1)
4412 "<MODE>mode == Pmode"
4414 sr<wd>%I2. %0,%1,%<hH>2
4416 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4418 (lshiftrt:GPR (match_dup 1)
4421 (compare:CC (match_dup 0)
4424 [(set_attr "type" "shift")
4425 (set_attr "maybe_var_shift" "yes")
4426 (set_attr "dot" "yes")
4427 (set_attr "length" "4,8")])
4430 (define_insn "ashr<mode>3"
4431 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4432 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4433 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4434 (clobber (reg:GPR CA_REGNO))]
4436 "sra<wd>%I2 %0,%1,%<hH>2"
4437 [(set_attr "type" "shift")
4438 (set_attr "maybe_var_shift" "yes")])
4440 (define_insn "*ashrsi3_64"
4441 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4443 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4444 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4445 (clobber (reg:SI CA_REGNO))]
4448 [(set_attr "type" "shift")
4449 (set_attr "maybe_var_shift" "yes")])
4451 (define_insn_and_split "*ashr<mode>3_dot"
4452 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4453 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4454 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4456 (clobber (match_scratch:GPR 0 "=r,r"))
4457 (clobber (reg:GPR CA_REGNO))]
4458 "<MODE>mode == Pmode"
4460 sra<wd>%I2. %0,%1,%<hH>2
4462 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4463 [(parallel [(set (match_dup 0)
4464 (ashiftrt:GPR (match_dup 1)
4466 (clobber (reg:GPR CA_REGNO))])
4468 (compare:CC (match_dup 0)
4471 [(set_attr "type" "shift")
4472 (set_attr "maybe_var_shift" "yes")
4473 (set_attr "dot" "yes")
4474 (set_attr "length" "4,8")])
4476 (define_insn_and_split "*ashr<mode>3_dot2"
4477 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4478 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4479 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4481 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4482 (ashiftrt:GPR (match_dup 1)
4484 (clobber (reg:GPR CA_REGNO))]
4485 "<MODE>mode == Pmode"
4487 sra<wd>%I2. %0,%1,%<hH>2
4489 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4490 [(parallel [(set (match_dup 0)
4491 (ashiftrt:GPR (match_dup 1)
4493 (clobber (reg:GPR CA_REGNO))])
4495 (compare:CC (match_dup 0)
4498 [(set_attr "type" "shift")
4499 (set_attr "maybe_var_shift" "yes")
4500 (set_attr "dot" "yes")
4501 (set_attr "length" "4,8")])
4503 ;; Builtins to replace a division to generate FRE reciprocal estimate
4504 ;; instructions and the necessary fixup instructions
4505 (define_expand "recip<mode>3"
4506 [(match_operand:RECIPF 0 "gpc_reg_operand")
4507 (match_operand:RECIPF 1 "gpc_reg_operand")
4508 (match_operand:RECIPF 2 "gpc_reg_operand")]
4509 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4511 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4515 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4516 ;; hardware division. This is only done before register allocation and with
4517 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4518 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4519 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4521 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4522 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4523 (match_operand 2 "gpc_reg_operand")))]
4524 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4525 && can_create_pseudo_p () && flag_finite_math_only
4526 && !flag_trapping_math && flag_reciprocal_math"
4529 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4533 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4534 ;; appropriate fixup.
4535 (define_expand "rsqrt<mode>2"
4536 [(match_operand:RECIPF 0 "gpc_reg_operand")
4537 (match_operand:RECIPF 1 "gpc_reg_operand")]
4538 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4540 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4544 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4545 ;; modes here, and also add in conditional vsx/power8-vector support to access
4546 ;; values in the traditional Altivec registers if the appropriate
4547 ;; -mupper-regs-{df,sf} option is enabled.
4549 (define_expand "abs<mode>2"
4550 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4551 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4555 (define_insn "*abs<mode>2_fpr"
4556 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4557 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4562 [(set_attr "type" "fpsimple")])
4564 (define_insn "*nabs<mode>2_fpr"
4565 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4568 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4573 [(set_attr "type" "fpsimple")])
4575 (define_expand "neg<mode>2"
4576 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4577 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4581 (define_insn "*neg<mode>2_fpr"
4582 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4583 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4588 [(set_attr "type" "fpsimple")])
4590 (define_expand "add<mode>3"
4591 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4592 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4593 (match_operand:SFDF 2 "gpc_reg_operand")))]
4597 (define_insn "*add<mode>3_fpr"
4598 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4599 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4600 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4603 fadd<Ftrad> %0,%1,%2
4604 xsadd<Fvsx> %x0,%x1,%x2"
4605 [(set_attr "type" "fp")])
4607 (define_expand "sub<mode>3"
4608 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4609 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4610 (match_operand:SFDF 2 "gpc_reg_operand")))]
4614 (define_insn "*sub<mode>3_fpr"
4615 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4616 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4617 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4620 fsub<Ftrad> %0,%1,%2
4621 xssub<Fvsx> %x0,%x1,%x2"
4622 [(set_attr "type" "fp")])
4624 (define_expand "mul<mode>3"
4625 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4626 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4627 (match_operand:SFDF 2 "gpc_reg_operand")))]
4631 (define_insn "*mul<mode>3_fpr"
4632 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4633 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4634 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4637 fmul<Ftrad> %0,%1,%2
4638 xsmul<Fvsx> %x0,%x1,%x2"
4639 [(set_attr "type" "dmul")])
4641 (define_expand "div<mode>3"
4642 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4643 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4644 (match_operand:SFDF 2 "gpc_reg_operand")))]
4647 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4648 && can_create_pseudo_p () && flag_finite_math_only
4649 && !flag_trapping_math && flag_reciprocal_math)
4651 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4656 (define_insn "*div<mode>3_fpr"
4657 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4658 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4659 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4662 fdiv<Ftrad> %0,%1,%2
4663 xsdiv<Fvsx> %x0,%x1,%x2"
4664 [(set_attr "type" "<Fs>div")])
4666 (define_insn "*sqrt<mode>2_internal"
4667 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4668 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4669 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4672 xssqrt<Fvsx> %x0,%x1"
4673 [(set_attr "type" "<Fs>sqrt")])
4675 (define_expand "sqrt<mode>2"
4676 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4677 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4678 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4680 if (<MODE>mode == SFmode
4681 && TARGET_RECIP_PRECISION
4682 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4683 && !optimize_function_for_size_p (cfun)
4684 && flag_finite_math_only && !flag_trapping_math
4685 && flag_unsafe_math_optimizations)
4687 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4692 ;; Floating point reciprocal approximation
4693 (define_insn "fre<Fs>"
4694 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4695 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4701 [(set_attr "type" "fp")])
4703 (define_insn "*rsqrt<mode>2"
4704 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4705 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4707 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4709 frsqrte<Ftrad> %0,%1
4710 xsrsqrte<Fvsx> %x0,%x1"
4711 [(set_attr "type" "fp")])
4713 ;; Floating point comparisons
4714 (define_insn "*cmp<mode>_fpr"
4715 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4716 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4717 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4721 xscmpudp %0,%x1,%x2"
4722 [(set_attr "type" "fpcompare")])
4724 ;; Floating point conversions
4725 (define_expand "extendsfdf2"
4726 [(set (match_operand:DF 0 "gpc_reg_operand")
4727 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4730 if (HONOR_SNANS (SFmode))
4731 operands[1] = force_reg (SFmode, operands[1]);
4734 (define_insn_and_split "*extendsfdf2_fpr"
4735 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4736 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4737 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4743 xscpsgndp %x0,%x1,%x1
4746 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4749 emit_note (NOTE_INSN_DELETED);
4752 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4754 (define_insn "*extendsfdf2_snan"
4755 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4756 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4757 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4761 [(set_attr "type" "fp")])
4763 (define_expand "truncdfsf2"
4764 [(set (match_operand:SF 0 "gpc_reg_operand")
4765 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4769 (define_insn "*truncdfsf2_fpr"
4770 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4771 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4776 [(set_attr "type" "fp")])
4778 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4779 ;; builtins.c and optabs.c that are not correct for IBM long double
4780 ;; when little-endian.
4781 (define_expand "signbit<mode>2"
4783 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4785 (subreg:DI (match_dup 2) 0))
4788 (set (match_operand:SI 0 "gpc_reg_operand")
4791 && (!FLOAT128_IEEE_P (<MODE>mode)
4792 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4794 if (FLOAT128_IEEE_P (<MODE>mode))
4796 rtx dest = operands[0];
4797 rtx src = operands[1];
4798 rtx tmp = gen_reg_rtx (DImode);
4799 rtx dest_di = gen_lowpart (DImode, dest);
4801 if (<MODE>mode == KFmode)
4802 emit_insn (gen_signbitkf2_dm (tmp, src));
4803 else if (<MODE>mode == TFmode)
4804 emit_insn (gen_signbittf2_dm (tmp, src));
4808 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4811 operands[2] = gen_reg_rtx (DFmode);
4812 operands[3] = gen_reg_rtx (DImode);
4813 if (TARGET_POWERPC64)
4815 operands[4] = gen_reg_rtx (DImode);
4816 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4817 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4818 WORDS_BIG_ENDIAN ? 4 : 0);
4822 operands[4] = gen_reg_rtx (SImode);
4823 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4824 WORDS_BIG_ENDIAN ? 0 : 4);
4825 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4829 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4830 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4831 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4832 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4834 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4835 ;; split allows the post reload phases to eliminate the move, and do the shift
4836 ;; directly with the register that contains the signbit.
4837 (define_insn_and_split "signbit<mode>2_dm"
4838 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4839 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4841 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4845 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4849 operands[2] = gen_highpart (DImode, operands[1]);
4851 [(set_attr "type" "mftgpr,*")])
4853 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4854 ;; register and then doing a direct move if the value comes from memory. On
4855 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4856 (define_insn_and_split "*signbit<mode>2_dm_mem"
4857 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4858 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4860 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4866 rtx dest = operands[0];
4867 rtx src = operands[1];
4868 rtx addr = XEXP (src, 0);
4870 if (WORDS_BIG_ENDIAN)
4871 operands[2] = adjust_address (src, DImode, 0);
4873 else if (REG_P (addr) || SUBREG_P (addr))
4874 operands[2] = adjust_address (src, DImode, 8);
4876 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4877 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4878 operands[2] = adjust_address (src, DImode, 8);
4882 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4883 emit_insn (gen_rtx_SET (tmp, addr));
4884 operands[2] = change_address (src, DImode,
4885 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4889 (define_expand "copysign<mode>3"
4891 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4893 (neg:SFDF (abs:SFDF (match_dup 1))))
4894 (set (match_operand:SFDF 0 "gpc_reg_operand")
4895 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4900 && ((TARGET_PPC_GFXOPT
4901 && !HONOR_NANS (<MODE>mode)
4902 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4904 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4906 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4908 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4913 operands[3] = gen_reg_rtx (<MODE>mode);
4914 operands[4] = gen_reg_rtx (<MODE>mode);
4915 operands[5] = CONST0_RTX (<MODE>mode);
4918 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4919 ;; compiler from optimizing -0.0
4920 (define_insn "copysign<mode>3_fcpsgn"
4921 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4922 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4923 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4925 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4928 xscpsgndp %x0,%x2,%x1"
4929 [(set_attr "type" "fpsimple")])
4931 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4932 ;; fsel instruction and some auxiliary computations. Then we just have a
4933 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4935 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4936 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4937 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4938 ;; define_splits to make them if made by combine. On VSX machines we have the
4939 ;; min/max instructions.
4941 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4942 ;; to allow either DF/SF to use only traditional registers.
4944 (define_expand "s<minmax><mode>3"
4945 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4946 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4947 (match_operand:SFDF 2 "gpc_reg_operand")))]
4950 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4954 (define_insn "*s<minmax><mode>3_vsx"
4955 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4956 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4957 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4958 "TARGET_VSX && TARGET_HARD_FLOAT"
4960 return (TARGET_P9_MINMAX
4961 ? "xs<minmax>cdp %x0,%x1,%x2"
4962 : "xs<minmax>dp %x0,%x1,%x2");
4964 [(set_attr "type" "fp")])
4966 ;; The conditional move instructions allow us to perform max and min operations
4967 ;; even when we don't have the appropriate max/min instruction using the FSEL
4970 (define_insn_and_split "*s<minmax><mode>3_fpr"
4971 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4972 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4973 (match_operand:SFDF 2 "gpc_reg_operand")))]
4974 "!TARGET_VSX && TARGET_MINMAX"
4979 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4983 (define_expand "mov<mode>cc"
4984 [(set (match_operand:GPR 0 "gpc_reg_operand")
4985 (if_then_else:GPR (match_operand 1 "comparison_operator")
4986 (match_operand:GPR 2 "gpc_reg_operand")
4987 (match_operand:GPR 3 "gpc_reg_operand")))]
4990 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4996 ;; We use the BASE_REGS for the isel input operands because, if rA is
4997 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4998 ;; because we may switch the operands and rB may end up being rA.
5000 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5001 ;; leave out the mode in operand 4 and use one pattern, but reload can
5002 ;; change the mode underneath our feet and then gets confused trying
5003 ;; to reload the value.
5004 (define_insn "isel_signed_<mode>"
5005 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5007 (match_operator 1 "scc_comparison_operator"
5008 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5010 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5011 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5014 [(set_attr "type" "isel")])
5016 (define_insn "isel_unsigned_<mode>"
5017 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5019 (match_operator 1 "scc_comparison_operator"
5020 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5022 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5023 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5026 [(set_attr "type" "isel")])
5028 ;; These patterns can be useful for combine; they let combine know that
5029 ;; isel can handle reversed comparisons so long as the operands are
5032 (define_insn "*isel_reversed_signed_<mode>"
5033 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5035 (match_operator 1 "scc_rev_comparison_operator"
5036 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5038 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5039 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5042 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5043 return "isel %0,%3,%2,%j1";
5045 [(set_attr "type" "isel")])
5047 (define_insn "*isel_reversed_unsigned_<mode>"
5048 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5050 (match_operator 1 "scc_rev_comparison_operator"
5051 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5053 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5054 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5057 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5058 return "isel %0,%3,%2,%j1";
5060 [(set_attr "type" "isel")])
5062 ;; Floating point conditional move
5063 (define_expand "mov<mode>cc"
5064 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5065 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5066 (match_operand:SFDF 2 "gpc_reg_operand")
5067 (match_operand:SFDF 3 "gpc_reg_operand")))]
5068 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5070 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5076 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5077 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5079 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5080 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5081 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5082 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5083 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5085 [(set_attr "type" "fp")])
5087 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5088 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5090 (match_operator:CCFP 1 "fpmask_comparison_operator"
5091 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5092 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5093 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5094 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5095 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5100 (if_then_else:V2DI (match_dup 1)
5104 (if_then_else:SFDF (ne (match_dup 6)
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 [(set_attr "length" "8")
5116 (set_attr "type" "vecperm")])
5118 ;; Handle inverting the fpmask comparisons.
5119 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5120 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5122 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5123 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5124 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5125 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5126 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5127 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5132 (if_then_else:V2DI (match_dup 9)
5136 (if_then_else:SFDF (ne (match_dup 6)
5141 rtx op1 = operands[1];
5142 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5144 if (GET_CODE (operands[6]) == SCRATCH)
5145 operands[6] = gen_reg_rtx (V2DImode);
5147 operands[7] = CONSTM1_RTX (V2DImode);
5148 operands[8] = CONST0_RTX (V2DImode);
5150 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5152 [(set_attr "length" "8")
5153 (set_attr "type" "vecperm")])
5155 (define_insn "*fpmask<mode>"
5156 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5158 (match_operator:CCFP 1 "fpmask_comparison_operator"
5159 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5160 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5161 (match_operand:V2DI 4 "all_ones_constant" "")
5162 (match_operand:V2DI 5 "zero_constant" "")))]
5164 "xscmp%V1dp %x0,%x2,%x3"
5165 [(set_attr "type" "fpcompare")])
5167 (define_insn "*xxsel<mode>"
5168 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5169 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5170 (match_operand:V2DI 2 "zero_constant" ""))
5171 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5172 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5174 "xxsel %x0,%x4,%x3,%x1"
5175 [(set_attr "type" "vecmove")])
5178 ;; Conversions to and from floating-point.
5180 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5181 ; don't want to support putting SImode in FPR registers.
5182 (define_insn "lfiwax"
5183 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5184 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5186 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5192 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5194 ; This split must be run before register allocation because it allocates the
5195 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5196 ; it earlier to allow for the combiner to merge insns together where it might
5197 ; not be needed and also in case the insns are deleted as dead code.
5199 (define_insn_and_split "floatsi<mode>2_lfiwax"
5200 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5201 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5202 (clobber (match_scratch:DI 2 "=wi"))]
5203 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5204 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5209 rtx dest = operands[0];
5210 rtx src = operands[1];
5213 if (!MEM_P (src) && TARGET_POWERPC64
5214 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5215 tmp = convert_to_mode (DImode, src, false);
5219 if (GET_CODE (tmp) == SCRATCH)
5220 tmp = gen_reg_rtx (DImode);
5223 src = rs6000_force_indexed_or_indirect_mem (src);
5224 emit_insn (gen_lfiwax (tmp, src));
5228 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5229 emit_move_insn (stack, src);
5230 emit_insn (gen_lfiwax (tmp, stack));
5233 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5236 [(set_attr "length" "12")
5237 (set_attr "type" "fpload")])
5239 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5240 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5243 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5244 (clobber (match_scratch:DI 2 "=wi"))]
5245 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5250 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5251 if (GET_CODE (operands[2]) == SCRATCH)
5252 operands[2] = gen_reg_rtx (DImode);
5253 if (TARGET_P8_VECTOR)
5254 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5256 emit_insn (gen_lfiwax (operands[2], operands[1]));
5257 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5260 [(set_attr "length" "8")
5261 (set_attr "type" "fpload")])
5263 (define_insn "lfiwzx"
5264 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5265 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5267 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5272 xxextractuw %x0,%x1,4"
5273 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5275 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5276 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5277 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5278 (clobber (match_scratch:DI 2 "=wi"))]
5279 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5284 rtx dest = operands[0];
5285 rtx src = operands[1];
5288 if (!MEM_P (src) && TARGET_POWERPC64
5289 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5290 tmp = convert_to_mode (DImode, src, true);
5294 if (GET_CODE (tmp) == SCRATCH)
5295 tmp = gen_reg_rtx (DImode);
5298 src = rs6000_force_indexed_or_indirect_mem (src);
5299 emit_insn (gen_lfiwzx (tmp, src));
5303 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5304 emit_move_insn (stack, src);
5305 emit_insn (gen_lfiwzx (tmp, stack));
5308 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5311 [(set_attr "length" "12")
5312 (set_attr "type" "fpload")])
5314 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5315 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5316 (unsigned_float:SFDF
5318 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5319 (clobber (match_scratch:DI 2 "=wi"))]
5320 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5325 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5326 if (GET_CODE (operands[2]) == SCRATCH)
5327 operands[2] = gen_reg_rtx (DImode);
5328 if (TARGET_P8_VECTOR)
5329 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5331 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5332 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5335 [(set_attr "length" "8")
5336 (set_attr "type" "fpload")])
5338 ; For each of these conversions, there is a define_expand, a define_insn
5339 ; with a '#' template, and a define_split (with C code). The idea is
5340 ; to allow constant folding with the template of the define_insn,
5341 ; then to have the insns split later (between sched1 and final).
5343 (define_expand "floatsidf2"
5344 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5345 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5348 (clobber (match_dup 4))
5349 (clobber (match_dup 5))
5350 (clobber (match_dup 6))])]
5353 if (TARGET_LFIWAX && TARGET_FCFID)
5355 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5358 else if (TARGET_FCFID)
5360 rtx dreg = operands[1];
5362 dreg = force_reg (SImode, dreg);
5363 dreg = convert_to_mode (DImode, dreg, false);
5364 emit_insn (gen_floatdidf2 (operands[0], dreg));
5368 if (!REG_P (operands[1]))
5369 operands[1] = force_reg (SImode, operands[1]);
5370 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5371 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5372 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5373 operands[5] = gen_reg_rtx (DFmode);
5374 operands[6] = gen_reg_rtx (SImode);
5377 (define_insn_and_split "*floatsidf2_internal"
5378 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5379 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5380 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5381 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5382 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5383 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5384 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5385 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5390 rtx lowword, highword;
5391 gcc_assert (MEM_P (operands[4]));
5392 highword = adjust_address (operands[4], SImode, 0);
5393 lowword = adjust_address (operands[4], SImode, 4);
5394 if (! WORDS_BIG_ENDIAN)
5395 std::swap (lowword, highword);
5397 emit_insn (gen_xorsi3 (operands[6], operands[1],
5398 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5399 emit_move_insn (lowword, operands[6]);
5400 emit_move_insn (highword, operands[2]);
5401 emit_move_insn (operands[5], operands[4]);
5402 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5405 [(set_attr "length" "24")
5406 (set_attr "type" "fp")])
5408 ;; If we don't have a direct conversion to single precision, don't enable this
5409 ;; conversion for 32-bit without fast math, because we don't have the insn to
5410 ;; generate the fixup swizzle to avoid double rounding problems.
5411 (define_expand "floatunssisf2"
5412 [(set (match_operand:SF 0 "gpc_reg_operand")
5413 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5415 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5417 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5419 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5421 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5426 rtx dreg = operands[1];
5428 dreg = force_reg (SImode, dreg);
5429 dreg = convert_to_mode (DImode, dreg, true);
5430 emit_insn (gen_floatdisf2 (operands[0], dreg));
5435 (define_expand "floatunssidf2"
5436 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5437 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5440 (clobber (match_dup 4))
5441 (clobber (match_dup 5))])]
5444 if (TARGET_LFIWZX && TARGET_FCFID)
5446 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5449 else if (TARGET_FCFID)
5451 rtx dreg = operands[1];
5453 dreg = force_reg (SImode, dreg);
5454 dreg = convert_to_mode (DImode, dreg, true);
5455 emit_insn (gen_floatdidf2 (operands[0], dreg));
5459 if (!REG_P (operands[1]))
5460 operands[1] = force_reg (SImode, operands[1]);
5461 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5462 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5463 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5464 operands[5] = gen_reg_rtx (DFmode);
5467 (define_insn_and_split "*floatunssidf2_internal"
5468 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5469 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5470 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5471 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5472 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5473 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5474 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5475 && !(TARGET_FCFID && TARGET_POWERPC64)"
5480 rtx lowword, highword;
5481 gcc_assert (MEM_P (operands[4]));
5482 highword = adjust_address (operands[4], SImode, 0);
5483 lowword = adjust_address (operands[4], SImode, 4);
5484 if (! WORDS_BIG_ENDIAN)
5485 std::swap (lowword, highword);
5487 emit_move_insn (lowword, operands[1]);
5488 emit_move_insn (highword, operands[2]);
5489 emit_move_insn (operands[5], operands[4]);
5490 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5493 [(set_attr "length" "20")
5494 (set_attr "type" "fp")])
5496 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5497 ;; vector registers. These insns favor doing the sign/zero extension in
5498 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5499 ;; extension and then a direct move.
5501 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5502 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5504 (match_operand:QHI 1 "input_operand")))
5505 (clobber (match_scratch:DI 2))
5506 (clobber (match_scratch:DI 3))
5507 (clobber (match_scratch:<QHI:MODE> 4))])]
5508 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5510 if (MEM_P (operands[1]))
5511 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5514 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5515 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5517 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5518 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5519 (clobber (match_scratch:DI 3 "=X,r,X"))
5520 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5521 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5523 "&& reload_completed"
5526 rtx result = operands[0];
5527 rtx input = operands[1];
5528 rtx di = operands[2];
5532 rtx tmp = operands[3];
5533 if (altivec_register_operand (input, <QHI:MODE>mode))
5534 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5535 else if (GET_CODE (tmp) == SCRATCH)
5536 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5539 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5540 emit_move_insn (di, tmp);
5545 rtx tmp = operands[4];
5546 emit_move_insn (tmp, input);
5547 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5550 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5554 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5555 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5556 (unsigned_float:FP_ISA3
5557 (match_operand:QHI 1 "input_operand")))
5558 (clobber (match_scratch:DI 2))
5559 (clobber (match_scratch:DI 3))])]
5560 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5562 if (MEM_P (operands[1]))
5563 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5566 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5567 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5568 (unsigned_float:FP_ISA3
5569 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5570 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5571 (clobber (match_scratch:DI 3 "=X,r,X"))]
5572 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5574 "&& reload_completed"
5577 rtx result = operands[0];
5578 rtx input = operands[1];
5579 rtx di = operands[2];
5581 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5582 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5585 rtx tmp = operands[3];
5586 if (GET_CODE (tmp) == SCRATCH)
5587 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5590 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5591 emit_move_insn (di, tmp);
5595 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5599 (define_expand "fix_trunc<mode>si2"
5600 [(set (match_operand:SI 0 "gpc_reg_operand")
5601 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5604 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5606 rtx src = force_reg (<MODE>mode, operands[1]);
5609 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5612 rtx tmp = gen_reg_rtx (DImode);
5613 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5614 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5621 ; Like the convert to float patterns, this insn must be split before
5622 ; register allocation so that it can allocate the memory slot if it
5624 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5625 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5626 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5627 (clobber (match_scratch:DI 2 "=d"))]
5628 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5629 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5634 rtx dest = operands[0];
5635 rtx src = operands[1];
5636 rtx tmp = operands[2];
5638 if (GET_CODE (tmp) == SCRATCH)
5639 tmp = gen_reg_rtx (DImode);
5641 emit_insn (gen_fctiwz_<mode> (tmp, src));
5644 dest = rs6000_force_indexed_or_indirect_mem (dest);
5645 emit_insn (gen_stfiwx (dest, tmp));
5648 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5650 dest = gen_lowpart (DImode, dest);
5651 emit_move_insn (dest, tmp);
5656 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5657 emit_insn (gen_stfiwx (stack, tmp));
5658 emit_move_insn (dest, stack);
5662 [(set_attr "length" "12")
5663 (set_attr "type" "fp")])
5665 (define_insn_and_split "fix_trunc<mode>si2_internal"
5666 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5667 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5668 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5669 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5671 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5677 gcc_assert (MEM_P (operands[3]));
5678 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5680 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5681 emit_move_insn (operands[3], operands[2]);
5682 emit_move_insn (operands[0], lowword);
5685 [(set_attr "length" "16")
5686 (set_attr "type" "fp")])
5688 (define_expand "fix_trunc<mode>di2"
5689 [(set (match_operand:DI 0 "gpc_reg_operand")
5690 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5691 "TARGET_HARD_FLOAT && TARGET_FCFID"
5694 (define_insn "*fix_trunc<mode>di2_fctidz"
5695 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5696 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5697 "TARGET_HARD_FLOAT && TARGET_FCFID"
5701 [(set_attr "type" "fp")])
5703 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5704 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5705 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5706 ;; values can go in VSX registers. Keeping the direct move part through
5707 ;; register allocation prevents the register allocator from doing a direct move
5708 ;; of the SImode value to a GPR, and then a store/load.
5709 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5710 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5711 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5712 (clobber (match_scratch:SI 2 "=X,X,wi"))]
5713 "TARGET_DIRECT_MOVE"
5716 xscvdp<su>xws %x0,%x1
5718 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5720 (any_fix:SI (match_dup 1)))
5724 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5726 [(set_attr "length" "4,4,8")
5727 (set_attr "type" "fp")])
5729 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5730 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5731 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5732 "TARGET_DIRECT_MOVE"
5735 xscvdp<su>xws %x0,%x1"
5736 [(set_attr "type" "fp")])
5738 ;; Keep the convert and store together through register allocation to prevent
5739 ;; the register allocator from getting clever and doing a direct move to a GPR
5740 ;; and then store for reg+offset stores.
5741 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5742 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5743 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5744 (clobber (match_scratch:SI 2 "=wa"))]
5745 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5747 "&& reload_completed"
5749 (any_fix:SI (match_dup 1)))
5753 operands[3] = (<QHSI:MODE>mode == SImode
5755 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5758 (define_expand "fixuns_trunc<mode>si2"
5759 [(set (match_operand:SI 0 "gpc_reg_operand")
5760 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5761 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5763 if (!TARGET_P8_VECTOR)
5765 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5770 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5771 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5772 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5773 (clobber (match_scratch:DI 2 "=d"))]
5774 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5775 && TARGET_STFIWX && can_create_pseudo_p ()
5776 && !TARGET_P8_VECTOR"
5781 rtx dest = operands[0];
5782 rtx src = operands[1];
5783 rtx tmp = operands[2];
5785 if (GET_CODE (tmp) == SCRATCH)
5786 tmp = gen_reg_rtx (DImode);
5788 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5791 dest = rs6000_force_indexed_or_indirect_mem (dest);
5792 emit_insn (gen_stfiwx (dest, tmp));
5795 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5797 dest = gen_lowpart (DImode, dest);
5798 emit_move_insn (dest, tmp);
5803 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5804 emit_insn (gen_stfiwx (stack, tmp));
5805 emit_move_insn (dest, stack);
5809 [(set_attr "length" "12")
5810 (set_attr "type" "fp")])
5812 (define_insn "fixuns_trunc<mode>di2"
5813 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5814 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5815 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5819 [(set_attr "type" "fp")])
5821 (define_insn "rs6000_mtfsb0"
5822 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5826 [(set_attr "type" "fp")])
5828 (define_insn "rs6000_mtfsb1"
5829 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5833 [(set_attr "type" "fp")])
5835 (define_insn "rs6000_mffscrn"
5836 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5837 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5841 [(set_attr "type" "fp")])
5843 (define_insn "rs6000_mffscdrn"
5844 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5845 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5846 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5849 [(set_attr "type" "fp")])
5851 (define_expand "rs6000_set_fpscr_rn"
5852 [(match_operand:DI 0 "reg_or_cint_operand")]
5855 rtx tmp_df = gen_reg_rtx (DFmode);
5857 /* The floating point rounding control bits are FPSCR[62:63]. Put the
5858 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
5861 rtx src_df = force_reg (DImode, operands[0]);
5862 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5863 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5867 if (CONST_INT_P (operands[0]))
5869 if ((INTVAL (operands[0]) & 0x1) == 0x1)
5870 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5872 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5874 if ((INTVAL (operands[0]) & 0x2) == 0x2)
5875 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5877 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5881 rtx tmp_rn = gen_reg_rtx (DImode);
5882 rtx tmp_di = gen_reg_rtx (DImode);
5884 /* Extract new RN mode from operand. */
5885 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5887 /* Insert new RN mode into FSCPR. */
5888 emit_insn (gen_rs6000_mffs (tmp_df));
5889 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5890 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5891 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5893 /* Need to write to field k=15. The fields are [0:15]. Hence with
5894 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
5895 8-bit field[0:7]. Need to set the bit that corresponds to the
5896 value of i that you want [0:7]. */
5897 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5898 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5903 (define_expand "rs6000_set_fpscr_drn"
5904 [(match_operand:DI 0 "gpc_reg_operand")]
5907 rtx tmp_df = gen_reg_rtx (DFmode);
5909 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5910 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
5913 rtx src_df = gen_reg_rtx (DFmode);
5915 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5916 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5917 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
5921 rtx tmp_rn = gen_reg_rtx (DImode);
5922 rtx tmp_di = gen_reg_rtx (DImode);
5924 /* Extract new DRN mode from operand. */
5925 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
5926 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
5928 /* Insert new RN mode into FSCPR. */
5929 emit_insn (gen_rs6000_mffs (tmp_df));
5930 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5931 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
5932 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5934 /* Need to write to field 7. The fields are [0:15]. The equation to
5935 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
5936 i to 0x1 to get field 7 where i selects the field. */
5937 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5938 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
5943 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5944 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5945 ;; because the first makes it clear that operand 0 is not live
5946 ;; before the instruction.
5947 (define_insn "fctiwz_<mode>"
5948 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5950 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5956 [(set_attr "type" "fp")])
5958 (define_insn "fctiwuz_<mode>"
5959 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5960 (unspec:DI [(unsigned_fix:SI
5961 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5963 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5967 [(set_attr "type" "fp")])
5969 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5970 ;; since the friz instruction does not truncate the value if the floating
5971 ;; point value is < LONG_MIN or > LONG_MAX.
5972 (define_insn "*friz"
5973 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5974 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5975 "TARGET_HARD_FLOAT && TARGET_FPRND
5976 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5980 [(set_attr "type" "fp")])
5982 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5983 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5984 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5985 ;; extend it, store it back on the stack from the GPR, load it back into the
5986 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5987 ;; disable using store and load to sign/zero extend the value.
5988 (define_insn_and_split "*round32<mode>2_fprs"
5989 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5991 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5992 (clobber (match_scratch:DI 2 "=d"))
5993 (clobber (match_scratch:DI 3 "=d"))]
5995 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5996 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6001 rtx dest = operands[0];
6002 rtx src = operands[1];
6003 rtx tmp1 = operands[2];
6004 rtx tmp2 = operands[3];
6005 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6007 if (GET_CODE (tmp1) == SCRATCH)
6008 tmp1 = gen_reg_rtx (DImode);
6009 if (GET_CODE (tmp2) == SCRATCH)
6010 tmp2 = gen_reg_rtx (DImode);
6012 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6013 emit_insn (gen_stfiwx (stack, tmp1));
6014 emit_insn (gen_lfiwax (tmp2, stack));
6015 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6018 [(set_attr "type" "fpload")
6019 (set_attr "length" "16")])
6021 (define_insn_and_split "*roundu32<mode>2_fprs"
6022 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6023 (unsigned_float:SFDF
6024 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6025 (clobber (match_scratch:DI 2 "=d"))
6026 (clobber (match_scratch:DI 3 "=d"))]
6028 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6029 && can_create_pseudo_p ()"
6034 rtx dest = operands[0];
6035 rtx src = operands[1];
6036 rtx tmp1 = operands[2];
6037 rtx tmp2 = operands[3];
6038 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6040 if (GET_CODE (tmp1) == SCRATCH)
6041 tmp1 = gen_reg_rtx (DImode);
6042 if (GET_CODE (tmp2) == SCRATCH)
6043 tmp2 = gen_reg_rtx (DImode);
6045 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6046 emit_insn (gen_stfiwx (stack, tmp1));
6047 emit_insn (gen_lfiwzx (tmp2, stack));
6048 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6051 [(set_attr "type" "fpload")
6052 (set_attr "length" "16")])
6054 ;; No VSX equivalent to fctid
6055 (define_insn "lrint<mode>di2"
6056 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6057 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6059 "TARGET_HARD_FLOAT && TARGET_FPRND"
6061 [(set_attr "type" "fp")])
6063 (define_insn "btrunc<mode>2"
6064 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6065 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6067 "TARGET_HARD_FLOAT && TARGET_FPRND"
6071 [(set_attr "type" "fp")])
6073 (define_insn "ceil<mode>2"
6074 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6075 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6077 "TARGET_HARD_FLOAT && TARGET_FPRND"
6081 [(set_attr "type" "fp")])
6083 (define_insn "floor<mode>2"
6084 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6085 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6087 "TARGET_HARD_FLOAT && TARGET_FPRND"
6091 [(set_attr "type" "fp")])
6093 ;; No VSX equivalent to frin
6094 (define_insn "round<mode>2"
6095 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6096 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6098 "TARGET_HARD_FLOAT && TARGET_FPRND"
6100 [(set_attr "type" "fp")])
6102 (define_insn "*xsrdpi<mode>2"
6103 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6104 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6106 "TARGET_HARD_FLOAT && TARGET_VSX"
6108 [(set_attr "type" "fp")])
6110 (define_expand "lround<mode>di2"
6112 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6114 (set (match_operand:DI 0 "gpc_reg_operand")
6115 (unspec:DI [(match_dup 2)]
6117 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6119 operands[2] = gen_reg_rtx (<MODE>mode);
6122 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6123 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6124 ; is only generated for Power8 or later.
6125 (define_insn "stfiwx"
6126 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6127 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6133 [(set_attr "type" "fpstore")])
6135 ;; If we don't have a direct conversion to single precision, don't enable this
6136 ;; conversion for 32-bit without fast math, because we don't have the insn to
6137 ;; generate the fixup swizzle to avoid double rounding problems.
6138 (define_expand "floatsisf2"
6139 [(set (match_operand:SF 0 "gpc_reg_operand")
6140 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6142 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6144 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6146 if (TARGET_FCFIDS && TARGET_LFIWAX)
6148 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6151 else if (TARGET_FCFID && TARGET_LFIWAX)
6153 rtx dfreg = gen_reg_rtx (DFmode);
6154 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6155 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6160 rtx dreg = operands[1];
6162 dreg = force_reg (SImode, dreg);
6163 dreg = convert_to_mode (DImode, dreg, false);
6164 emit_insn (gen_floatdisf2 (operands[0], dreg));
6169 (define_insn "floatdidf2"
6170 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6171 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6172 "TARGET_FCFID && TARGET_HARD_FLOAT"
6176 [(set_attr "type" "fp")])
6178 ; Allow the combiner to merge source memory operands to the conversion so that
6179 ; the optimizer/register allocator doesn't try to load the value too early in a
6180 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6181 ; hit. We will split after reload to avoid the trip through the GPRs
6183 (define_insn_and_split "*floatdidf2_mem"
6184 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6185 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6186 (clobber (match_scratch:DI 2 "=d,wi"))]
6187 "TARGET_HARD_FLOAT && TARGET_FCFID"
6189 "&& reload_completed"
6190 [(set (match_dup 2) (match_dup 1))
6191 (set (match_dup 0) (float:DF (match_dup 2)))]
6193 [(set_attr "length" "8")
6194 (set_attr "type" "fpload")])
6196 (define_expand "floatunsdidf2"
6197 [(set (match_operand:DF 0 "gpc_reg_operand")
6199 (match_operand:DI 1 "gpc_reg_operand")))]
6200 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6203 (define_insn "*floatunsdidf2_fcfidu"
6204 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6205 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6206 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6210 [(set_attr "type" "fp")])
6212 (define_insn_and_split "*floatunsdidf2_mem"
6213 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6214 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6215 (clobber (match_scratch:DI 2 "=d,wi"))]
6216 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6218 "&& reload_completed"
6219 [(set (match_dup 2) (match_dup 1))
6220 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6222 [(set_attr "length" "8")
6223 (set_attr "type" "fpload")])
6225 (define_expand "floatdisf2"
6226 [(set (match_operand:SF 0 "gpc_reg_operand")
6227 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6228 "TARGET_FCFID && TARGET_HARD_FLOAT
6229 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6233 rtx val = operands[1];
6234 if (!flag_unsafe_math_optimizations)
6236 rtx label = gen_label_rtx ();
6237 val = gen_reg_rtx (DImode);
6238 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6241 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6246 (define_insn "floatdisf2_fcfids"
6247 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6248 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6249 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6253 [(set_attr "type" "fp")])
6255 (define_insn_and_split "*floatdisf2_mem"
6256 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6257 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6258 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6259 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6261 "&& reload_completed"
6264 emit_move_insn (operands[2], operands[1]);
6265 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6268 [(set_attr "length" "8")])
6270 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6271 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6272 ;; from double rounding.
6273 ;; Instead of creating a new cpu type for two FP operations, just use fp
6274 (define_insn_and_split "floatdisf2_internal1"
6275 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6276 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6277 (clobber (match_scratch:DF 2 "=d"))]
6278 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6280 "&& reload_completed"
6282 (float:DF (match_dup 1)))
6284 (float_truncate:SF (match_dup 2)))]
6286 [(set_attr "length" "8")
6287 (set_attr "type" "fp")])
6289 ;; Twiddles bits to avoid double rounding.
6290 ;; Bits that might be truncated when converting to DFmode are replaced
6291 ;; by a bit that won't be lost at that stage, but is below the SFmode
6292 ;; rounding position.
6293 (define_expand "floatdisf2_internal2"
6294 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6296 (clobber (reg:DI CA_REGNO))])
6297 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6299 (set (match_dup 3) (plus:DI (match_dup 3)
6301 (set (match_dup 0) (plus:DI (match_dup 0)
6303 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6305 (set (match_dup 0) (ior:DI (match_dup 0)
6307 (set (match_dup 0) (and:DI (match_dup 0)
6309 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6310 (label_ref (match_operand:DI 2 ""))
6312 (set (match_dup 0) (match_dup 1))]
6313 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6315 operands[3] = gen_reg_rtx (DImode);
6316 operands[4] = gen_reg_rtx (CCUNSmode);
6319 (define_expand "floatunsdisf2"
6320 [(set (match_operand:SF 0 "gpc_reg_operand")
6321 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6322 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6325 (define_insn "floatunsdisf2_fcfidus"
6326 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6327 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6328 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6332 [(set_attr "type" "fp")])
6334 (define_insn_and_split "*floatunsdisf2_mem"
6335 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6336 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6337 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6338 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6340 "&& reload_completed"
6343 emit_move_insn (operands[2], operands[1]);
6344 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6347 [(set_attr "length" "8")
6348 (set_attr "type" "fpload")])
6350 ;; Define the TImode operations that can be done in a small number
6351 ;; of instructions. The & constraints are to prevent the register
6352 ;; allocator from allocating registers that overlap with the inputs
6353 ;; (for example, having an input in 7,8 and an output in 6,7). We
6354 ;; also allow for the output being the same as one of the inputs.
6356 (define_expand "addti3"
6357 [(set (match_operand:TI 0 "gpc_reg_operand")
6358 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6359 (match_operand:TI 2 "reg_or_short_operand")))]
6362 rtx lo0 = gen_lowpart (DImode, operands[0]);
6363 rtx lo1 = gen_lowpart (DImode, operands[1]);
6364 rtx lo2 = gen_lowpart (DImode, operands[2]);
6365 rtx hi0 = gen_highpart (DImode, operands[0]);
6366 rtx hi1 = gen_highpart (DImode, operands[1]);
6367 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6369 if (!reg_or_short_operand (lo2, DImode))
6370 lo2 = force_reg (DImode, lo2);
6371 if (!adde_operand (hi2, DImode))
6372 hi2 = force_reg (DImode, hi2);
6374 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6375 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6379 (define_expand "subti3"
6380 [(set (match_operand:TI 0 "gpc_reg_operand")
6381 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6382 (match_operand:TI 2 "gpc_reg_operand")))]
6385 rtx lo0 = gen_lowpart (DImode, operands[0]);
6386 rtx lo1 = gen_lowpart (DImode, operands[1]);
6387 rtx lo2 = gen_lowpart (DImode, operands[2]);
6388 rtx hi0 = gen_highpart (DImode, operands[0]);
6389 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6390 rtx hi2 = gen_highpart (DImode, operands[2]);
6392 if (!reg_or_short_operand (lo1, DImode))
6393 lo1 = force_reg (DImode, lo1);
6394 if (!adde_operand (hi1, DImode))
6395 hi1 = force_reg (DImode, hi1);
6397 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6398 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6402 ;; 128-bit logical operations expanders
6404 (define_expand "and<mode>3"
6405 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6406 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6407 (match_operand:BOOL_128 2 "vlogical_operand")))]
6411 (define_expand "ior<mode>3"
6412 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6413 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6414 (match_operand:BOOL_128 2 "vlogical_operand")))]
6418 (define_expand "xor<mode>3"
6419 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6420 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6421 (match_operand:BOOL_128 2 "vlogical_operand")))]
6425 (define_expand "one_cmpl<mode>2"
6426 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6427 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6431 (define_expand "nor<mode>3"
6432 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6434 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6435 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6439 (define_expand "andc<mode>3"
6440 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6442 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6443 (match_operand:BOOL_128 1 "vlogical_operand")))]
6447 ;; Power8 vector logical instructions.
6448 (define_expand "eqv<mode>3"
6449 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6451 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6452 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6453 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6456 ;; Rewrite nand into canonical form
6457 (define_expand "nand<mode>3"
6458 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6460 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6461 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6462 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6465 ;; The canonical form is to have the negated element first, so we need to
6466 ;; reverse arguments.
6467 (define_expand "orc<mode>3"
6468 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6470 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6471 (match_operand:BOOL_128 1 "vlogical_operand")))]
6472 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6475 ;; 128-bit logical operations insns and split operations
6476 (define_insn_and_split "*and<mode>3_internal"
6477 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6479 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6480 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6483 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6484 return "xxland %x0,%x1,%x2";
6486 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6487 return "vand %0,%1,%2";
6491 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6494 rs6000_split_logical (operands, AND, false, false, false);
6499 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6500 (const_string "veclogical")
6501 (const_string "integer")))
6502 (set (attr "length")
6504 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6507 (match_test "TARGET_POWERPC64")
6509 (const_string "16"))))])
6512 (define_insn_and_split "*bool<mode>3_internal"
6513 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6514 (match_operator:BOOL_128 3 "boolean_or_operator"
6515 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6516 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6519 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6520 return "xxl%q3 %x0,%x1,%x2";
6522 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6523 return "v%q3 %0,%1,%2";
6527 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6530 rs6000_split_logical (operands, GET_CODE (operands[3]), false, 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"))))])
6548 (define_insn_and_split "*boolc<mode>3_internal1"
6549 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6550 (match_operator:BOOL_128 3 "boolean_operator"
6552 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6553 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6554 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6556 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6557 return "xxl%q3 %x0,%x1,%x2";
6559 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6560 return "v%q3 %0,%1,%2";
6564 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6565 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6568 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6573 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6574 (const_string "veclogical")
6575 (const_string "integer")))
6576 (set (attr "length")
6578 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6581 (match_test "TARGET_POWERPC64")
6583 (const_string "16"))))])
6585 (define_insn_and_split "*boolc<mode>3_internal2"
6586 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6587 (match_operator:TI2 3 "boolean_operator"
6589 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6590 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6591 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6593 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6596 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6599 [(set_attr "type" "integer")
6600 (set (attr "length")
6602 (match_test "TARGET_POWERPC64")
6604 (const_string "16")))])
6607 (define_insn_and_split "*boolcc<mode>3_internal1"
6608 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6609 (match_operator:BOOL_128 3 "boolean_operator"
6611 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6613 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6614 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6616 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6617 return "xxl%q3 %x0,%x1,%x2";
6619 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6620 return "v%q3 %0,%1,%2";
6624 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6625 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6628 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6633 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6634 (const_string "veclogical")
6635 (const_string "integer")))
6636 (set (attr "length")
6638 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6641 (match_test "TARGET_POWERPC64")
6643 (const_string "16"))))])
6645 (define_insn_and_split "*boolcc<mode>3_internal2"
6646 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6647 (match_operator:TI2 3 "boolean_operator"
6649 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6651 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6652 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6654 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6657 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6660 [(set_attr "type" "integer")
6661 (set (attr "length")
6663 (match_test "TARGET_POWERPC64")
6665 (const_string "16")))])
6669 (define_insn_and_split "*eqv<mode>3_internal1"
6670 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6673 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6674 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6677 if (vsx_register_operand (operands[0], <MODE>mode))
6678 return "xxleqv %x0,%x1,%x2";
6682 "TARGET_P8_VECTOR && reload_completed
6683 && int_reg_operand (operands[0], <MODE>mode)"
6686 rs6000_split_logical (operands, XOR, true, false, false);
6691 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6692 (const_string "veclogical")
6693 (const_string "integer")))
6694 (set (attr "length")
6696 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6699 (match_test "TARGET_POWERPC64")
6701 (const_string "16"))))])
6703 (define_insn_and_split "*eqv<mode>3_internal2"
6704 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6707 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6708 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6711 "reload_completed && !TARGET_P8_VECTOR"
6714 rs6000_split_logical (operands, XOR, true, false, false);
6717 [(set_attr "type" "integer")
6718 (set (attr "length")
6720 (match_test "TARGET_POWERPC64")
6722 (const_string "16")))])
6724 ;; 128-bit one's complement
6725 (define_insn_and_split "*one_cmpl<mode>3_internal"
6726 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6728 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6731 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6732 return "xxlnor %x0,%x1,%x1";
6734 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6735 return "vnor %0,%1,%1";
6739 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6742 rs6000_split_logical (operands, NOT, false, false, false);
6747 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6748 (const_string "veclogical")
6749 (const_string "integer")))
6750 (set (attr "length")
6752 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6755 (match_test "TARGET_POWERPC64")
6757 (const_string "16"))))])
6760 ;; Now define ways of moving data around.
6762 ;; Set up a register with a value from the GOT table
6764 (define_expand "movsi_got"
6765 [(set (match_operand:SI 0 "gpc_reg_operand")
6766 (unspec:SI [(match_operand:SI 1 "got_operand")
6767 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6768 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6770 if (GET_CODE (operands[1]) == CONST)
6772 rtx offset = const0_rtx;
6773 HOST_WIDE_INT value;
6775 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6776 value = INTVAL (offset);
6779 rtx tmp = (!can_create_pseudo_p ()
6781 : gen_reg_rtx (Pmode));
6782 emit_insn (gen_movsi_got (tmp, operands[1]));
6783 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6788 operands[2] = rs6000_got_register (operands[1]);
6791 (define_insn "*movsi_got_internal"
6792 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6793 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6794 (match_operand:SI 2 "gpc_reg_operand" "b")]
6796 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6797 "lwz %0,%a1@got(%2)"
6798 [(set_attr "type" "load")])
6800 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6801 ;; didn't get allocated to a hard register.
6803 [(set (match_operand:SI 0 "gpc_reg_operand")
6804 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6805 (match_operand:SI 2 "memory_operand")]
6807 "DEFAULT_ABI == ABI_V4
6809 && reload_completed"
6810 [(set (match_dup 0) (match_dup 2))
6811 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6815 ;; For SI, we special-case integers that can't be loaded in one insn. We
6816 ;; do the load 16-bits at a time. We could do this by loading from memory,
6817 ;; and this is even supposed to be faster, but it is simpler not to get
6818 ;; integers in the TOC.
6819 (define_insn "movsi_low"
6820 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6821 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6822 (match_operand 2 "" ""))))]
6823 "TARGET_MACHO && ! TARGET_64BIT"
6824 "lwz %0,lo16(%2)(%1)"
6825 [(set_attr "type" "load")])
6827 ;; MR LA LWZ LFIWZX LXSIWZX
6828 ;; STW STFIWX STXSIWX LI LIS
6829 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6830 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6832 (define_insn "*movsi_internal1"
6833 [(set (match_operand:SI 0 "nonimmediate_operand"
6834 "=r, r, r, ?*wI, ?*wH,
6836 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6837 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6840 (match_operand:SI 1 "input_operand"
6847 "gpc_reg_operand (operands[0], SImode)
6848 || gpc_reg_operand (operands[1], SImode)"
6874 "*, *, load, fpload, fpload,
6875 store, fpstore, fpstore, *, *,
6876 *, veclogical, vecsimple, vecsimple, vecsimple,
6877 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6887 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6888 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6890 ;; Because SF values are actually stored as DF values within the vector
6891 ;; registers, we need to convert the value to the vector SF format when
6892 ;; we need to use the bits in a union or similar cases. We only need
6893 ;; to do this transformation when the value is a vector register. Loads,
6894 ;; stores, and transfers within GPRs are assumed to be safe.
6896 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6897 ;; no alternatives, because the call is created as part of secondary_reload,
6898 ;; and operand #2's register class is used to allocate the temporary register.
6899 ;; This function is called before reload, and it creates the temporary as
6902 ;; MR LWZ LFIWZX LXSIWZX STW
6903 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6906 (define_insn_and_split "movsi_from_sf"
6907 [(set (match_operand:SI 0 "nonimmediate_operand"
6908 "=r, r, ?*wI, ?*wH, m,
6909 m, wY, Z, r, ?*wIwH,
6912 (unspec:SI [(match_operand:SF 1 "input_operand"
6914 f, wb, wu, wIwH, wIwH,
6918 (clobber (match_scratch:V4SF 2
6923 "TARGET_NO_SF_SUBREG
6924 && (register_operand (operands[0], SImode)
6925 || register_operand (operands[1], SFmode))"
6938 "&& reload_completed
6939 && int_reg_operand (operands[0], SImode)
6940 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6943 rtx op0 = operands[0];
6944 rtx op1 = operands[1];
6945 rtx op2 = operands[2];
6946 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6947 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6949 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6950 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6954 "*, load, fpload, fpload, store,
6955 fpstore, fpstore, fpstore, mftgpr, fp,
6963 ;; movsi_from_sf with zero extension
6965 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6968 (define_insn_and_split "*movdi_from_sf_zero_ext"
6969 [(set (match_operand:DI 0 "gpc_reg_operand"
6970 "=r, r, ?*wI, ?*wH, r,
6974 (unspec:SI [(match_operand:SF 1 "input_operand"
6977 UNSPEC_SI_FROM_SF)))
6979 (clobber (match_scratch:V4SF 2
6983 "TARGET_DIRECT_MOVE_64BIT
6984 && (register_operand (operands[0], DImode)
6985 || register_operand (operands[1], SImode))"
6994 "&& reload_completed
6995 && register_operand (operands[0], DImode)
6996 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6999 rtx op0 = operands[0];
7000 rtx op1 = operands[1];
7001 rtx op2 = operands[2];
7002 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7004 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7005 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7009 "*, load, fpload, fpload, two,
7016 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7017 ;; moving it to SImode. We can do a SFmode store without having to do the
7018 ;; conversion explicitly. If we are doing a register->register conversion, use
7019 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
7020 ;; input will not fit in a SFmode, and the later assumes the value has already
7022 (define_insn "*movsi_from_df"
7023 [(set (match_operand:SI 0 "nonimmediate_operand" "=wa,m,wY,Z")
7024 (unspec:SI [(float_truncate:SF
7025 (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
7026 UNSPEC_SI_FROM_SF))]
7028 "TARGET_NO_SF_SUBREG"
7034 [(set_attr "type" "fp,fpstore,fpstore,fpstore")])
7036 ;; Split a load of a large constant into the appropriate two-insn
7040 [(set (match_operand:SI 0 "gpc_reg_operand")
7041 (match_operand:SI 1 "const_int_operand"))]
7042 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7043 && (INTVAL (operands[1]) & 0xffff) != 0"
7047 (ior:SI (match_dup 0)
7050 if (rs6000_emit_set_const (operands[0], operands[1]))
7056 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7058 [(set (match_operand:DI 0 "altivec_register_operand")
7059 (match_operand:DI 1 "xxspltib_constant_split"))]
7060 "TARGET_P9_VECTOR && reload_completed"
7063 rtx op0 = operands[0];
7064 rtx op1 = operands[1];
7065 int r = REGNO (op0);
7066 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7068 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7069 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7073 (define_insn "*mov<mode>_internal2"
7074 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7075 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7077 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7083 [(set_attr "type" "cmp,logical,cmp")
7084 (set_attr "dot" "yes")
7085 (set_attr "length" "4,4,8")])
7088 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7089 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7091 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7093 [(set (match_dup 0) (match_dup 1))
7095 (compare:CC (match_dup 0)
7099 (define_expand "mov<mode>"
7100 [(set (match_operand:INT 0 "general_operand")
7101 (match_operand:INT 1 "any_operand"))]
7104 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7108 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7109 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7110 ;; MTVSRWZ MF%1 MT%1 NOP
7111 (define_insn "*mov<mode>_internal"
7112 [(set (match_operand:QHI 0 "nonimmediate_operand"
7113 "=r, r, ?*wJwK, m, Z, r,
7114 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7115 ?*wJwK, r, *c*l, *h")
7117 (match_operand:QHI 1 "input_operand"
7118 "r, m, Z, r, wJwK, i,
7119 wJwK, O, wM, wB, wS, ?*wJwK,
7122 "gpc_reg_operand (operands[0], <MODE>mode)
7123 || gpc_reg_operand (operands[1], <MODE>mode)"
7142 "*, load, fpload, store, fpstore, *,
7143 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7144 mffgpr, mfjmpr, mtjmpr, *")
7152 ;; Here is how to move condition codes around. When we store CC data in
7153 ;; an integer register or memory, we store just the high-order 4 bits.
7154 ;; This lets us not shift in the most common case of CR0.
7155 (define_expand "movcc"
7156 [(set (match_operand:CC 0 "nonimmediate_operand")
7157 (match_operand:CC 1 "nonimmediate_operand"))]
7161 (define_insn "*movcc_internal1"
7162 [(set (match_operand:CC 0 "nonimmediate_operand"
7163 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7164 (match_operand:CC 1 "general_operand"
7165 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7166 "register_operand (operands[0], CCmode)
7167 || register_operand (operands[1], CCmode)"
7171 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7174 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7181 [(set_attr_alternative "type"
7182 [(const_string "cr_logical")
7183 (const_string "mtcr")
7184 (const_string "mtcr")
7185 (const_string "cr_logical")
7186 (if_then_else (match_test "TARGET_MFCRF")
7187 (const_string "mfcrf") (const_string "mfcr"))
7188 (if_then_else (match_test "TARGET_MFCRF")
7189 (const_string "mfcrf") (const_string "mfcr"))
7190 (const_string "integer")
7191 (const_string "integer")
7192 (const_string "mfjmpr")
7193 (const_string "mtjmpr")
7194 (const_string "load")
7195 (const_string "store")])
7196 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7198 ;; For floating-point, we normally deal with the floating-point registers
7199 ;; unless -msoft-float is used. The sole exception is that parameter passing
7200 ;; can produce floating-point values in fixed-point registers. Unless the
7201 ;; value is a simple constant or already in memory, we deal with this by
7202 ;; allocating memory and copying the value explicitly via that memory location.
7204 ;; Move 32-bit binary/decimal floating point
7205 (define_expand "mov<mode>"
7206 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7207 (match_operand:FMOVE32 1 "any_operand"))]
7210 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7215 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7216 (match_operand:FMOVE32 1 "const_double_operand"))]
7218 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7219 || (GET_CODE (operands[0]) == SUBREG
7220 && GET_CODE (SUBREG_REG (operands[0])) == REG
7221 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7222 [(set (match_dup 2) (match_dup 3))]
7226 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7228 if (! TARGET_POWERPC64)
7229 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7231 operands[2] = gen_lowpart (SImode, operands[0]);
7233 operands[3] = gen_int_mode (l, SImode);
7236 ;; Originally, we tried to keep movsf and movsd common, but the differences
7237 ;; addressing was making it rather difficult to hide with mode attributes. In
7238 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7239 ;; before the VSX stores meant that the register allocator would tend to do a
7240 ;; direct move to the GPR (which involves conversion from scalar to
7241 ;; vector/memory formats) to save values in the traditional Altivec registers,
7242 ;; while SDmode had problems on power6 if the GPR store was not first due to
7243 ;; the power6 not having an integer store operation.
7245 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7246 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7247 ;; MR MT<x> MF<x> NOP
7249 (define_insn "movsf_hardfloat"
7250 [(set (match_operand:SF 0 "nonimmediate_operand"
7251 "=!r, f, wb, wu, m, wY,
7252 Z, m, ww, !r, f, ww,
7254 (match_operand:SF 1 "input_operand"
7255 "m, m, wY, Z, f, wb,
7258 "(register_operand (operands[0], SFmode)
7259 || register_operand (operands[1], SFmode))
7260 && TARGET_HARD_FLOAT
7261 && (TARGET_ALLOW_SF_SUBREG
7262 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7275 xscpsgndp %x0,%x1,%x1
7281 "load, fpload, fpload, fpload, fpstore, fpstore,
7282 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7283 *, mtjmpr, mfjmpr, *")])
7285 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7286 ;; FMR MR MT%0 MF%1 NOP
7287 (define_insn "movsd_hardfloat"
7288 [(set (match_operand:SD 0 "nonimmediate_operand"
7289 "=!r, wz, m, Z, ?wh, ?r,
7290 f, !r, *c*l, !r, *h")
7291 (match_operand:SD 1 "input_operand"
7292 "m, Z, r, wx, r, wh,
7294 "(register_operand (operands[0], SDmode)
7295 || register_operand (operands[1], SDmode))
7296 && TARGET_HARD_FLOAT"
7310 "load, fpload, store, fpstore, mffgpr, mftgpr,
7311 fpsimple, *, mtjmpr, mfjmpr, *")])
7313 ;; MR MT%0 MF%0 LWZ STW LI
7314 ;; LIS G-const. F/n-const NOP
7315 (define_insn "*mov<mode>_softfloat"
7316 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7317 "=r, *c*l, r, r, m, r,
7320 (match_operand:FMOVE32 1 "input_operand"
7324 "(gpc_reg_operand (operands[0], <MODE>mode)
7325 || gpc_reg_operand (operands[1], <MODE>mode))
7326 && TARGET_SOFT_FLOAT"
7339 "*, mtjmpr, mfjmpr, load, store, *,
7346 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7347 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7349 ;; Because SF values are actually stored as DF values within the vector
7350 ;; registers, we need to convert the value to the vector SF format when
7351 ;; we need to use the bits in a union or similar cases. We only need
7352 ;; to do this transformation when the value is a vector register. Loads,
7353 ;; stores, and transfers within GPRs are assumed to be safe.
7355 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7356 ;; no alternatives, because the call is created as part of secondary_reload,
7357 ;; and operand #2's register class is used to allocate the temporary register.
7358 ;; This function is called before reload, and it creates the temporary as
7361 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7362 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7363 (define_insn_and_split "movsf_from_si"
7364 [(set (match_operand:SF 0 "nonimmediate_operand"
7365 "=!r, f, wb, wu, m, Z,
7368 (unspec:SF [(match_operand:SI 1 "input_operand"
7373 (clobber (match_scratch:DI 2
7377 "TARGET_NO_SF_SUBREG
7378 && (register_operand (operands[0], SFmode)
7379 || register_operand (operands[1], SImode))"
7392 "&& reload_completed
7393 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7394 && int_reg_operand_not_pseudo (operands[1], SImode)"
7397 rtx op0 = operands[0];
7398 rtx op1 = operands[1];
7399 rtx op2 = operands[2];
7400 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7402 /* Move SF value to upper 32-bits for xscvspdpn. */
7403 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7404 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7405 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7412 "load, fpload, fpload, fpload, store, fpstore,
7413 fpstore, vecfloat, mffgpr, *")])
7416 ;; Move 64-bit binary/decimal floating point
7417 (define_expand "mov<mode>"
7418 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7419 (match_operand:FMOVE64 1 "any_operand"))]
7422 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7427 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7428 (match_operand:FMOVE64 1 "const_int_operand"))]
7429 "! TARGET_POWERPC64 && reload_completed
7430 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7431 || (GET_CODE (operands[0]) == SUBREG
7432 && GET_CODE (SUBREG_REG (operands[0])) == REG
7433 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7434 [(set (match_dup 2) (match_dup 4))
7435 (set (match_dup 3) (match_dup 1))]
7437 int endian = (WORDS_BIG_ENDIAN == 0);
7438 HOST_WIDE_INT value = INTVAL (operands[1]);
7440 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7441 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7442 operands[4] = GEN_INT (value >> 32);
7443 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7447 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7448 (match_operand:FMOVE64 1 "const_double_operand"))]
7449 "! TARGET_POWERPC64 && reload_completed
7450 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7451 || (GET_CODE (operands[0]) == SUBREG
7452 && GET_CODE (SUBREG_REG (operands[0])) == REG
7453 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7454 [(set (match_dup 2) (match_dup 4))
7455 (set (match_dup 3) (match_dup 5))]
7457 int endian = (WORDS_BIG_ENDIAN == 0);
7460 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7462 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7463 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7464 operands[4] = gen_int_mode (l[endian], SImode);
7465 operands[5] = gen_int_mode (l[1 - endian], SImode);
7469 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7470 (match_operand:FMOVE64 1 "const_double_operand"))]
7471 "TARGET_POWERPC64 && reload_completed
7472 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7473 || (GET_CODE (operands[0]) == SUBREG
7474 && GET_CODE (SUBREG_REG (operands[0])) == REG
7475 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7476 [(set (match_dup 2) (match_dup 3))]
7478 int endian = (WORDS_BIG_ENDIAN == 0);
7482 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7484 operands[2] = gen_lowpart (DImode, operands[0]);
7485 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7486 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7487 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7489 operands[3] = gen_int_mode (val, DImode);
7492 ;; Don't have reload use general registers to load a constant. It is
7493 ;; less efficient than loading the constant into an FP register, since
7494 ;; it will probably be used there.
7496 ;; The move constraints are ordered to prefer floating point registers before
7497 ;; general purpose registers to avoid doing a store and a load to get the value
7498 ;; into a floating point register when it is needed for a floating point
7499 ;; operation. Prefer traditional floating point registers over VSX registers,
7500 ;; since the D-form version of the memory instructions does not need a GPR for
7501 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7504 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7505 ;; except for 0.0 which can be created on VSX with an xor instruction.
7507 ;; STFD LFD FMR LXSD STXSD
7508 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7512 (define_insn "*mov<mode>_hardfloat32"
7513 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7514 "=m, d, d, <f64_p9>, wY,
7515 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7518 (match_operand:FMOVE64 1 "input_operand"
7519 "d, m, d, wY, <f64_p9>,
7520 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7523 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7524 && (gpc_reg_operand (operands[0], <MODE>mode)
7525 || gpc_reg_operand (operands[1], <MODE>mode))"
7541 "fpstore, fpload, fpsimple, fpload, fpstore,
7542 fpload, fpstore, veclogical, veclogical, two,
7545 (set_attr "size" "64")
7551 ;; STW LWZ MR G-const H-const F-const
7553 (define_insn "*mov<mode>_softfloat32"
7554 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7555 "=Y, r, r, r, r, r")
7557 (match_operand:FMOVE64 1 "input_operand"
7558 "r, Y, r, G, H, F"))]
7561 && (gpc_reg_operand (operands[0], <MODE>mode)
7562 || gpc_reg_operand (operands[1], <MODE>mode))"
7565 "store, load, two, *, *, *")
7568 "8, 8, 8, 8, 12, 16")])
7570 ; ld/std require word-aligned displacements -> 'Y' constraint.
7571 ; List Y->r and r->Y before r->r for reload.
7573 ;; STFD LFD FMR LXSD STXSD
7574 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7575 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7576 ;; NOP MFTGPR MFFGPR MFVSRD MTVSRD
7578 (define_insn "*mov<mode>_hardfloat64"
7579 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7580 "=m, d, d, <f64_p9>, wY,
7581 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7582 YZ, r, !r, *c*l, !r,
7583 *h, r, wg, r, <f64_dm>")
7585 (match_operand:FMOVE64 1 "input_operand"
7586 "d, m, d, wY, <f64_p9>,
7587 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7589 0, wg, r, <f64_dm>, r"))]
7591 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7592 && (gpc_reg_operand (operands[0], <MODE>mode)
7593 || gpc_reg_operand (operands[1], <MODE>mode))"
7616 "fpstore, fpload, fpsimple, fpload, fpstore,
7617 fpload, fpstore, veclogical, veclogical, integer,
7618 store, load, *, mtjmpr, mfjmpr,
7619 *, mftgpr, mffgpr, mftgpr, mffgpr")
7621 (set_attr "size" "64")
7622 (set_attr "length" "4")])
7624 ;; STD LD MR MT<SPR> MF<SPR> G-const
7625 ;; H-const F-const Special
7627 (define_insn "*mov<mode>_softfloat64"
7628 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7629 "=Y, r, r, *c*l, r, r,
7632 (match_operand:FMOVE64 1 "input_operand"
7636 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7637 && (gpc_reg_operand (operands[0], <MODE>mode)
7638 || gpc_reg_operand (operands[1], <MODE>mode))"
7650 "store, load, *, mtjmpr, mfjmpr, *,
7657 (define_expand "mov<mode>"
7658 [(set (match_operand:FMOVE128 0 "general_operand")
7659 (match_operand:FMOVE128 1 "any_operand"))]
7662 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7666 ;; It's important to list Y->r and r->Y before r->r because otherwise
7667 ;; reload, given m->r, will try to pick r->r and reload it, which
7668 ;; doesn't make progress.
7670 ;; We can't split little endian direct moves of TDmode, because the words are
7671 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7672 ;; problematical. Don't allow direct move for this case.
7674 (define_insn_and_split "*mov<mode>_64bit_dm"
7675 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7676 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7677 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7678 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7679 && (gpc_reg_operand (operands[0], <MODE>mode)
7680 || gpc_reg_operand (operands[1], <MODE>mode))"
7682 "&& reload_completed"
7684 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7685 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7687 (define_insn_and_split "*movtd_64bit_nodm"
7688 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7689 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7690 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7691 && (gpc_reg_operand (operands[0], TDmode)
7692 || gpc_reg_operand (operands[1], TDmode))"
7694 "&& reload_completed"
7696 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7697 [(set_attr "length" "8,8,8,12,12,8")])
7699 (define_insn_and_split "*mov<mode>_32bit"
7700 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7701 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7702 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7703 && (FLOAT128_2REG_P (<MODE>mode)
7704 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7705 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7706 && (gpc_reg_operand (operands[0], <MODE>mode)
7707 || gpc_reg_operand (operands[1], <MODE>mode))"
7709 "&& reload_completed"
7711 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7712 [(set_attr "length" "8,8,8,8,20,20,16")])
7714 (define_insn_and_split "*mov<mode>_softfloat"
7715 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7716 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7718 && (gpc_reg_operand (operands[0], <MODE>mode)
7719 || gpc_reg_operand (operands[1], <MODE>mode))"
7721 "&& reload_completed"
7723 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7724 [(set_attr_alternative "length"
7725 [(if_then_else (match_test "TARGET_POWERPC64")
7727 (const_string "16"))
7728 (if_then_else (match_test "TARGET_POWERPC64")
7730 (const_string "16"))
7731 (if_then_else (match_test "TARGET_POWERPC64")
7733 (const_string "32"))
7734 (if_then_else (match_test "TARGET_POWERPC64")
7736 (const_string "16"))])])
7738 (define_expand "extenddf<mode>2"
7739 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7740 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7741 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7743 if (FLOAT128_IEEE_P (<MODE>mode))
7744 rs6000_expand_float128_convert (operands[0], operands[1], false);
7745 else if (TARGET_VSX)
7747 if (<MODE>mode == TFmode)
7748 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7749 else if (<MODE>mode == IFmode)
7750 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7756 rtx zero = gen_reg_rtx (DFmode);
7757 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7759 if (<MODE>mode == TFmode)
7760 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7761 else if (<MODE>mode == IFmode)
7762 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7769 ;; Allow memory operands for the source to be created by the combiner.
7770 (define_insn_and_split "extenddf<mode>2_fprs"
7771 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7772 (float_extend:IBM128
7773 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7774 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7775 "!TARGET_VSX && TARGET_HARD_FLOAT
7776 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7778 "&& reload_completed"
7779 [(set (match_dup 3) (match_dup 1))
7780 (set (match_dup 4) (match_dup 2))]
7782 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7783 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7785 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7786 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7789 (define_insn_and_split "extenddf<mode>2_vsx"
7790 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7791 (float_extend:IBM128
7792 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7793 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7795 "&& reload_completed"
7796 [(set (match_dup 2) (match_dup 1))
7797 (set (match_dup 3) (match_dup 4))]
7799 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7800 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7802 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7803 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7804 operands[4] = CONST0_RTX (DFmode);
7807 (define_expand "extendsf<mode>2"
7808 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7809 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7810 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7812 if (FLOAT128_IEEE_P (<MODE>mode))
7813 rs6000_expand_float128_convert (operands[0], operands[1], false);
7816 rtx tmp = gen_reg_rtx (DFmode);
7817 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7818 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7823 (define_expand "trunc<mode>df2"
7824 [(set (match_operand:DF 0 "gpc_reg_operand")
7825 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7826 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7828 if (FLOAT128_IEEE_P (<MODE>mode))
7830 rs6000_expand_float128_convert (operands[0], operands[1], false);
7835 (define_insn_and_split "trunc<mode>df2_internal1"
7836 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7838 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7839 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7840 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7844 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7847 emit_note (NOTE_INSN_DELETED);
7850 [(set_attr "type" "fpsimple")])
7852 (define_insn "trunc<mode>df2_internal2"
7853 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7854 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7855 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7856 && TARGET_LONG_DOUBLE_128"
7858 [(set_attr "type" "fp")])
7860 (define_expand "trunc<mode>sf2"
7861 [(set (match_operand:SF 0 "gpc_reg_operand")
7862 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7863 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7865 if (FLOAT128_IEEE_P (<MODE>mode))
7866 rs6000_expand_float128_convert (operands[0], operands[1], false);
7869 rtx tmp = gen_reg_rtx (DFmode);
7870 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7871 emit_insn (gen_truncdfsf2 (operands[0], tmp));
7876 (define_expand "floatsi<mode>2"
7877 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7878 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7879 (clobber (match_scratch:DI 2))])]
7880 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7882 rtx op0 = operands[0];
7883 rtx op1 = operands[1];
7885 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7887 else if (FLOAT128_IEEE_P (<MODE>mode))
7889 rs6000_expand_float128_convert (op0, op1, false);
7894 rtx tmp = gen_reg_rtx (DFmode);
7895 expand_float (tmp, op1, false);
7896 if (<MODE>mode == TFmode)
7897 emit_insn (gen_extenddftf2 (op0, tmp));
7898 else if (<MODE>mode == IFmode)
7899 emit_insn (gen_extenddfif2 (op0, tmp));
7906 ; fadd, but rounding towards zero.
7907 ; This is probably not the optimal code sequence.
7908 (define_insn "fix_trunc_helper<mode>"
7909 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7910 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7911 UNSPEC_FIX_TRUNC_TF))
7912 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7913 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7914 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7915 [(set_attr "type" "fp")
7916 (set_attr "length" "20")])
7918 (define_expand "fix_trunc<mode>si2"
7919 [(set (match_operand:SI 0 "gpc_reg_operand")
7920 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7921 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7923 rtx op0 = operands[0];
7924 rtx op1 = operands[1];
7926 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7930 if (FLOAT128_IEEE_P (<MODE>mode))
7931 rs6000_expand_float128_convert (op0, op1, false);
7932 else if (<MODE>mode == TFmode)
7933 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7934 else if (<MODE>mode == IFmode)
7935 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7942 (define_expand "fix_trunc<mode>si2_fprs"
7943 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7944 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7945 (clobber (match_dup 2))
7946 (clobber (match_dup 3))
7947 (clobber (match_dup 4))
7948 (clobber (match_dup 5))])]
7949 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7951 operands[2] = gen_reg_rtx (DFmode);
7952 operands[3] = gen_reg_rtx (DFmode);
7953 operands[4] = gen_reg_rtx (DImode);
7954 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7957 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7958 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7959 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7960 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7961 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7962 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7963 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7964 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7970 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7973 gcc_assert (MEM_P (operands[5]));
7974 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7976 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7977 emit_move_insn (operands[5], operands[4]);
7978 emit_move_insn (operands[0], lowword);
7982 (define_expand "fix_trunc<mode>di2"
7983 [(set (match_operand:DI 0 "gpc_reg_operand")
7984 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7985 "TARGET_FLOAT128_TYPE"
7987 if (!TARGET_FLOAT128_HW)
7989 rs6000_expand_float128_convert (operands[0], operands[1], false);
7994 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7995 [(set (match_operand:SDI 0 "gpc_reg_operand")
7996 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7997 "TARGET_FLOAT128_TYPE"
7999 rs6000_expand_float128_convert (operands[0], operands[1], true);
8003 (define_expand "floatdi<mode>2"
8004 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8005 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8006 "TARGET_FLOAT128_TYPE"
8008 if (!TARGET_FLOAT128_HW)
8010 rs6000_expand_float128_convert (operands[0], operands[1], false);
8015 (define_expand "floatunsdi<IEEE128:mode>2"
8016 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8017 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8018 "TARGET_FLOAT128_TYPE"
8020 if (!TARGET_FLOAT128_HW)
8022 rs6000_expand_float128_convert (operands[0], operands[1], true);
8027 (define_expand "floatuns<IEEE128:mode>2"
8028 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8029 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8030 "TARGET_FLOAT128_TYPE"
8032 rtx op0 = operands[0];
8033 rtx op1 = operands[1];
8035 if (TARGET_FLOAT128_HW)
8036 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8038 rs6000_expand_float128_convert (op0, op1, true);
8042 (define_expand "neg<mode>2"
8043 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8044 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8045 "FLOAT128_IEEE_P (<MODE>mode)
8046 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8048 if (FLOAT128_IEEE_P (<MODE>mode))
8050 if (TARGET_FLOAT128_HW)
8052 if (<MODE>mode == TFmode)
8053 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
8054 else if (<MODE>mode == KFmode)
8055 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
8059 else if (TARGET_FLOAT128_TYPE)
8061 if (<MODE>mode == TFmode)
8062 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
8063 else if (<MODE>mode == KFmode)
8064 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
8070 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8071 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8073 operands[1], <MODE>mode);
8075 if (target && !rtx_equal_p (target, operands[0]))
8076 emit_move_insn (operands[0], target);
8082 (define_insn "neg<mode>2_internal"
8083 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8084 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8085 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8087 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8088 return "fneg %L0,%L1\;fneg %0,%1";
8090 return "fneg %0,%1\;fneg %L0,%L1";
8092 [(set_attr "type" "fpsimple")
8093 (set_attr "length" "8")])
8095 (define_expand "abs<mode>2"
8096 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8097 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8098 "FLOAT128_IEEE_P (<MODE>mode)
8099 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8103 if (FLOAT128_IEEE_P (<MODE>mode))
8105 if (TARGET_FLOAT128_HW)
8107 if (<MODE>mode == TFmode)
8108 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8109 else if (<MODE>mode == KFmode)
8110 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8115 else if (TARGET_FLOAT128_TYPE)
8117 if (<MODE>mode == TFmode)
8118 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8119 else if (<MODE>mode == KFmode)
8120 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8129 label = gen_label_rtx ();
8130 if (<MODE>mode == TFmode)
8131 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8132 else if (<MODE>mode == IFmode)
8133 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8140 (define_expand "abs<mode>2_internal"
8141 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8142 (match_operand:IBM128 1 "gpc_reg_operand"))
8143 (set (match_dup 3) (match_dup 5))
8144 (set (match_dup 5) (abs:DF (match_dup 5)))
8145 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8146 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8147 (label_ref (match_operand 2 ""))
8149 (set (match_dup 6) (neg:DF (match_dup 6)))]
8150 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8152 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8153 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8154 operands[3] = gen_reg_rtx (DFmode);
8155 operands[4] = gen_reg_rtx (CCFPmode);
8156 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8157 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8161 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8164 (define_expand "ieee_128bit_negative_zero"
8165 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8166 "TARGET_FLOAT128_TYPE"
8168 rtvec v = rtvec_alloc (16);
8171 for (i = 0; i < 16; i++)
8172 RTVEC_ELT (v, i) = const0_rtx;
8174 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8175 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8177 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8181 ;; IEEE 128-bit negate
8183 ;; We have 2 insns here for negate and absolute value. The first uses
8184 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8185 ;; insns, and second insn after the first split pass loads up the bit to
8186 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8187 ;; neg/abs to create the constant just once.
8189 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8190 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8191 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8192 (clobber (match_scratch:V16QI 2 "=v"))]
8193 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8196 [(parallel [(set (match_dup 0)
8197 (neg:IEEE128 (match_dup 1)))
8198 (use (match_dup 2))])]
8200 if (GET_CODE (operands[2]) == SCRATCH)
8201 operands[2] = gen_reg_rtx (V16QImode);
8203 operands[3] = gen_reg_rtx (V16QImode);
8204 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8206 [(set_attr "length" "8")
8207 (set_attr "type" "vecsimple")])
8209 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8210 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8211 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8212 (use (match_operand:V16QI 2 "register_operand" "v"))]
8213 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8214 "xxlxor %x0,%x1,%x2"
8215 [(set_attr "type" "veclogical")])
8217 ;; IEEE 128-bit absolute value
8218 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8219 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8220 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8221 (clobber (match_scratch:V16QI 2 "=v"))]
8222 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8225 [(parallel [(set (match_dup 0)
8226 (abs:IEEE128 (match_dup 1)))
8227 (use (match_dup 2))])]
8229 if (GET_CODE (operands[2]) == SCRATCH)
8230 operands[2] = gen_reg_rtx (V16QImode);
8232 operands[3] = gen_reg_rtx (V16QImode);
8233 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8235 [(set_attr "length" "8")
8236 (set_attr "type" "vecsimple")])
8238 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8239 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8240 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8241 (use (match_operand:V16QI 2 "register_operand" "v"))]
8242 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8243 "xxlandc %x0,%x1,%x2"
8244 [(set_attr "type" "veclogical")])
8246 ;; IEEE 128-bit negative absolute value
8247 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8248 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8251 (match_operand:IEEE128 1 "register_operand" "wa"))))
8252 (clobber (match_scratch:V16QI 2 "=v"))]
8253 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8254 && FLOAT128_IEEE_P (<MODE>mode)"
8257 [(parallel [(set (match_dup 0)
8258 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8259 (use (match_dup 2))])]
8261 if (GET_CODE (operands[2]) == SCRATCH)
8262 operands[2] = gen_reg_rtx (V16QImode);
8264 operands[3] = gen_reg_rtx (V16QImode);
8265 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8267 [(set_attr "length" "8")
8268 (set_attr "type" "vecsimple")])
8270 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8271 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8274 (match_operand:IEEE128 1 "register_operand" "wa"))))
8275 (use (match_operand:V16QI 2 "register_operand" "v"))]
8276 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8278 [(set_attr "type" "veclogical")])
8280 ;; Float128 conversion functions. These expand to library function calls.
8281 ;; We use expand to convert from IBM double double to IEEE 128-bit
8282 ;; and trunc for the opposite.
8283 (define_expand "extendiftf2"
8284 [(set (match_operand:TF 0 "gpc_reg_operand")
8285 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8286 "TARGET_FLOAT128_TYPE"
8288 rs6000_expand_float128_convert (operands[0], operands[1], false);
8292 (define_expand "extendifkf2"
8293 [(set (match_operand:KF 0 "gpc_reg_operand")
8294 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8295 "TARGET_FLOAT128_TYPE"
8297 rs6000_expand_float128_convert (operands[0], operands[1], false);
8301 (define_expand "extendtfkf2"
8302 [(set (match_operand:KF 0 "gpc_reg_operand")
8303 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8304 "TARGET_FLOAT128_TYPE"
8306 rs6000_expand_float128_convert (operands[0], operands[1], false);
8310 (define_expand "extendtfif2"
8311 [(set (match_operand:IF 0 "gpc_reg_operand")
8312 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8313 "TARGET_FLOAT128_TYPE"
8315 rs6000_expand_float128_convert (operands[0], operands[1], false);
8319 (define_expand "trunciftf2"
8320 [(set (match_operand:TF 0 "gpc_reg_operand")
8321 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8322 "TARGET_FLOAT128_TYPE"
8324 rs6000_expand_float128_convert (operands[0], operands[1], false);
8328 (define_expand "truncifkf2"
8329 [(set (match_operand:KF 0 "gpc_reg_operand")
8330 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8331 "TARGET_FLOAT128_TYPE"
8333 rs6000_expand_float128_convert (operands[0], operands[1], false);
8337 (define_expand "trunckftf2"
8338 [(set (match_operand:TF 0 "gpc_reg_operand")
8339 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8340 "TARGET_FLOAT128_TYPE"
8342 rs6000_expand_float128_convert (operands[0], operands[1], false);
8346 (define_expand "trunctfif2"
8347 [(set (match_operand:IF 0 "gpc_reg_operand")
8348 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8349 "TARGET_FLOAT128_TYPE"
8351 rs6000_expand_float128_convert (operands[0], operands[1], false);
8355 (define_insn_and_split "*extend<mode>tf2_internal"
8356 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8358 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8359 "TARGET_FLOAT128_TYPE
8360 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8362 "&& reload_completed"
8363 [(set (match_dup 0) (match_dup 2))]
8365 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8368 (define_insn_and_split "*extendtf<mode>2_internal"
8369 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8371 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8372 "TARGET_FLOAT128_TYPE
8373 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8375 "&& reload_completed"
8376 [(set (match_dup 0) (match_dup 2))]
8378 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8382 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8383 ;; must have 3 arguments, and scratch register constraint must be a single
8386 ;; Reload patterns to support gpr load/store with misaligned mem.
8387 ;; and multiple gpr load/store at offset >= 0xfffc
8388 (define_expand "reload_<mode>_store"
8389 [(parallel [(match_operand 0 "memory_operand" "=m")
8390 (match_operand 1 "gpc_reg_operand" "r")
8391 (match_operand:GPR 2 "register_operand" "=&b")])]
8394 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8398 (define_expand "reload_<mode>_load"
8399 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8400 (match_operand 1 "memory_operand" "m")
8401 (match_operand:GPR 2 "register_operand" "=b")])]
8404 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8409 ;; Reload patterns for various types using the vector registers. We may need
8410 ;; an additional base register to convert the reg+offset addressing to reg+reg
8411 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8412 ;; index register for gpr registers.
8413 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8414 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8415 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8416 (match_operand:P 2 "register_operand" "=b")])]
8419 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8423 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8424 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8425 (match_operand:RELOAD 1 "memory_operand" "m")
8426 (match_operand:P 2 "register_operand" "=b")])]
8429 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8434 ;; Reload sometimes tries to move the address to a GPR, and can generate
8435 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8436 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8438 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8439 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8440 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8441 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8443 "TARGET_ALTIVEC && reload_completed"
8445 "&& reload_completed"
8447 (plus:P (match_dup 1)
8450 (and:P (match_dup 0)
8453 ;; Power8 merge instructions to allow direct move to/from floating point
8454 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8455 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8456 ;; value, since it is allocated in reload and not all of the flow information
8457 ;; is setup for it. We have two patterns to do the two moves between gprs and
8458 ;; fprs. There isn't a dependancy between the two, but we could potentially
8459 ;; schedule other instructions between the two instructions.
8461 (define_insn "p8_fmrgow_<mode>"
8462 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8464 (match_operand:DF 1 "register_operand" "d")
8465 (match_operand:DF 2 "register_operand" "d")]
8466 UNSPEC_P8V_FMRGOW))]
8467 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8469 [(set_attr "type" "fpsimple")])
8471 (define_insn "p8_mtvsrwz"
8472 [(set (match_operand:DF 0 "register_operand" "=d")
8473 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8474 UNSPEC_P8V_MTVSRWZ))]
8475 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8477 [(set_attr "type" "mftgpr")])
8479 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8480 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8481 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8482 UNSPEC_P8V_RELOAD_FROM_GPR))
8483 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8484 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8486 "&& reload_completed"
8489 rtx dest = operands[0];
8490 rtx src = operands[1];
8491 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8492 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8493 rtx gpr_hi_reg = gen_highpart (SImode, src);
8494 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8496 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8497 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8498 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8501 [(set_attr "length" "12")
8502 (set_attr "type" "three")])
8504 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8505 (define_insn "p8_mtvsrd_df"
8506 [(set (match_operand:DF 0 "register_operand" "=wa")
8507 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8508 UNSPEC_P8V_MTVSRD))]
8509 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8511 [(set_attr "type" "mftgpr")])
8513 (define_insn "p8_xxpermdi_<mode>"
8514 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8515 (unspec:FMOVE128_GPR [
8516 (match_operand:DF 1 "register_operand" "wa")
8517 (match_operand:DF 2 "register_operand" "wa")]
8518 UNSPEC_P8V_XXPERMDI))]
8519 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8520 "xxpermdi %x0,%x1,%x2,0"
8521 [(set_attr "type" "vecperm")])
8523 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8524 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8525 (unspec:FMOVE128_GPR
8526 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8527 UNSPEC_P8V_RELOAD_FROM_GPR))
8528 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8529 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8531 "&& reload_completed"
8534 rtx dest = operands[0];
8535 rtx src = operands[1];
8536 /* You might think that we could use op0 as one temp and a DF clobber
8537 as op2, but you'd be wrong. Secondary reload move patterns don't
8538 check for overlap of the clobber and the destination. */
8539 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8540 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8541 rtx gpr_hi_reg = gen_highpart (DImode, src);
8542 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8544 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8545 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8546 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8549 [(set_attr "length" "12")
8550 (set_attr "type" "three")])
8553 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8554 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8556 && (int_reg_operand (operands[0], <MODE>mode)
8557 || int_reg_operand (operands[1], <MODE>mode))
8558 && (!TARGET_DIRECT_MOVE_128
8559 || (!vsx_register_operand (operands[0], <MODE>mode)
8560 && !vsx_register_operand (operands[1], <MODE>mode)))"
8562 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8564 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8565 ;; type is stored internally as double precision in the VSX registers, we have
8566 ;; to convert it from the vector format.
8567 (define_insn "p8_mtvsrd_sf"
8568 [(set (match_operand:SF 0 "register_operand" "=wa")
8569 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8570 UNSPEC_P8V_MTVSRD))]
8571 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8573 [(set_attr "type" "mftgpr")])
8575 (define_insn_and_split "reload_vsx_from_gprsf"
8576 [(set (match_operand:SF 0 "register_operand" "=wa")
8577 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8578 UNSPEC_P8V_RELOAD_FROM_GPR))
8579 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8580 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8582 "&& reload_completed"
8585 rtx op0 = operands[0];
8586 rtx op1 = operands[1];
8587 rtx op2 = operands[2];
8588 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8590 /* Move SF value to upper 32-bits for xscvspdpn. */
8591 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8592 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8593 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8596 [(set_attr "length" "8")
8597 (set_attr "type" "two")])
8599 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8600 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8601 ;; and then doing a move of that.
8602 (define_insn "p8_mfvsrd_3_<mode>"
8603 [(set (match_operand:DF 0 "register_operand" "=r")
8604 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8605 UNSPEC_P8V_RELOAD_FROM_VSX))]
8606 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8608 [(set_attr "type" "mftgpr")])
8610 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8611 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8612 (unspec:FMOVE128_GPR
8613 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8614 UNSPEC_P8V_RELOAD_FROM_VSX))
8615 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8616 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8618 "&& reload_completed"
8621 rtx dest = operands[0];
8622 rtx src = operands[1];
8623 rtx tmp = operands[2];
8624 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8625 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8627 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8628 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8629 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8632 [(set_attr "length" "12")
8633 (set_attr "type" "three")])
8635 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8636 ;; type is stored internally as double precision, we have to convert it to the
8639 (define_insn_and_split "reload_gpr_from_vsxsf"
8640 [(set (match_operand:SF 0 "register_operand" "=r")
8641 (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8642 UNSPEC_P8V_RELOAD_FROM_VSX))
8643 (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8644 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8646 "&& reload_completed"
8649 rtx op0 = operands[0];
8650 rtx op1 = operands[1];
8651 rtx op2 = operands[2];
8652 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8653 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8655 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8656 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8659 [(set_attr "length" "8")
8660 (set_attr "type" "two")])
8663 ;; Next come the multi-word integer load and store and the load and store
8666 ;; List r->r after r->Y, otherwise reload will try to reload a
8667 ;; non-offsettable address by using r->r which won't make progress.
8668 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8669 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8671 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8672 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8673 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8676 (define_insn "*movdi_internal32"
8677 [(set (match_operand:DI 0 "nonimmediate_operand"
8678 "=Y, r, r, m, ^d, ^d,
8679 r, wY, Z, ^wb, $wv, ^wi,
8680 *wo, *wo, *wv, *wi, *wi, *wv,
8683 (match_operand:DI 1 "input_operand"
8684 "r, Y, r, ^d, m, ^d,
8685 IJKnF, ^wb, $wv, wY, Z, ^wi,
8686 Oj, wM, OjwM, Oj, wM, wS,
8690 && (gpc_reg_operand (operands[0], DImode)
8691 || gpc_reg_operand (operands[1], DImode))"
8713 "store, load, *, fpstore, fpload, fpsimple,
8714 *, fpstore, fpstore, fpload, fpload, veclogical,
8715 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8717 (set_attr "size" "64")
8725 [(set (match_operand:DI 0 "gpc_reg_operand")
8726 (match_operand:DI 1 "const_int_operand"))]
8727 "! TARGET_POWERPC64 && reload_completed
8728 && gpr_or_gpr_p (operands[0], operands[1])
8729 && !direct_move_p (operands[0], operands[1])"
8730 [(set (match_dup 2) (match_dup 4))
8731 (set (match_dup 3) (match_dup 1))]
8733 HOST_WIDE_INT value = INTVAL (operands[1]);
8734 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8736 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8738 operands[4] = GEN_INT (value >> 32);
8739 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8743 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8744 (match_operand:DIFD 1 "input_operand"))]
8745 "reload_completed && !TARGET_POWERPC64
8746 && gpr_or_gpr_p (operands[0], operands[1])
8747 && !direct_move_p (operands[0], operands[1])"
8749 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8751 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8752 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8753 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8754 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8755 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8756 (define_insn "*movdi_internal64"
8757 [(set (match_operand:DI 0 "nonimmediate_operand"
8758 "=YZ, r, r, r, r, r,
8759 m, ^d, ^d, wY, Z, $wb,
8760 $wv, ^wi, *wo, *wo, *wv, *wi,
8761 *wi, *wv, *wv, r, *h, *h,
8762 ?*r, ?*wg, ?*r, ?*wj")
8764 (match_operand:DI 1 "input_operand"
8765 "r, YZ, r, I, L, nF,
8766 ^d, m, ^d, ^wb, $wv, wY,
8767 Z, ^wi, Oj, wM, OjwM, Oj,
8768 wM, wS, wB, *h, r, 0,
8772 && (gpc_reg_operand (operands[0], DImode)
8773 || gpc_reg_operand (operands[1], DImode))"
8804 "store, load, *, *, *, *,
8805 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8806 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8807 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8808 mftgpr, mffgpr, mftgpr, mffgpr")
8810 (set_attr "size" "64")
8818 ; Some DImode loads are best done as a load of -1 followed by a mask
8821 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8822 (match_operand:DI 1 "const_int_operand"))]
8824 && num_insns_constant (operands[1], DImode) > 1
8825 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8826 && rs6000_is_valid_and_mask (operands[1], DImode)"
8830 (and:DI (match_dup 0)
8834 ;; Split a load of a large constant into the appropriate five-instruction
8835 ;; sequence. Handle anything in a constant number of insns.
8836 ;; When non-easy constants can go in the TOC, this should use
8837 ;; easy_fp_constant predicate.
8839 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8840 (match_operand:DI 1 "const_int_operand"))]
8841 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8842 [(set (match_dup 0) (match_dup 2))
8843 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8845 if (rs6000_emit_set_const (operands[0], operands[1]))
8852 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8853 (match_operand:DI 1 "const_scalar_int_operand"))]
8854 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8855 [(set (match_dup 0) (match_dup 2))
8856 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8858 if (rs6000_emit_set_const (operands[0], operands[1]))
8865 [(set (match_operand:DI 0 "altivec_register_operand")
8866 (match_operand:DI 1 "s5bit_cint_operand"))]
8867 "TARGET_VSX && reload_completed"
8870 rtx op0 = operands[0];
8871 rtx op1 = operands[1];
8872 int r = REGNO (op0);
8873 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8875 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8876 if (op1 != const0_rtx && op1 != constm1_rtx)
8878 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8879 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8884 ;; Split integer constants that can be loaded with XXSPLTIB and a
8885 ;; sign extend operation.
8887 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8888 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8889 "TARGET_P9_VECTOR && reload_completed"
8892 rtx op0 = operands[0];
8893 rtx op1 = operands[1];
8894 int r = REGNO (op0);
8895 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8897 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8898 if (<MODE>mode == DImode)
8899 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8900 else if (<MODE>mode == SImode)
8901 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8902 else if (<MODE>mode == HImode)
8904 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8905 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8911 ;; TImode/PTImode is similar, except that we usually want to compute the
8912 ;; address into a register and use lsi/stsi (the exception is during reload).
8914 (define_insn "*mov<mode>_string"
8915 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8916 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8918 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8919 && (gpc_reg_operand (operands[0], <MODE>mode)
8920 || gpc_reg_operand (operands[1], <MODE>mode))"
8922 [(set_attr "type" "store,store,load,load,*,*")
8923 (set_attr "update" "yes")
8924 (set_attr "indexed" "yes")
8925 (set_attr "cell_micro" "conditional")])
8927 (define_insn "*mov<mode>_ppc64"
8928 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8929 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8930 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8931 && (gpc_reg_operand (operands[0], <MODE>mode)
8932 || gpc_reg_operand (operands[1], <MODE>mode)))"
8934 return rs6000_output_move_128bit (operands);
8936 [(set_attr "type" "store,store,load,load,*,*")
8937 (set_attr "length" "8")])
8940 [(set (match_operand:TI2 0 "int_reg_operand")
8941 (match_operand:TI2 1 "const_scalar_int_operand"))]
8943 && (VECTOR_MEM_NONE_P (<MODE>mode)
8944 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8945 [(set (match_dup 2) (match_dup 4))
8946 (set (match_dup 3) (match_dup 5))]
8948 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8950 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8952 if (CONST_WIDE_INT_P (operands[1]))
8954 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8955 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8957 else if (CONST_INT_P (operands[1]))
8959 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8960 operands[5] = operands[1];
8967 [(set (match_operand:TI2 0 "nonimmediate_operand")
8968 (match_operand:TI2 1 "input_operand"))]
8970 && gpr_or_gpr_p (operands[0], operands[1])
8971 && !direct_move_p (operands[0], operands[1])
8972 && !quad_load_store_p (operands[0], operands[1])"
8974 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8976 (define_expand "setmemsi"
8977 [(parallel [(set (match_operand:BLK 0 "")
8978 (match_operand 2 "const_int_operand"))
8979 (use (match_operand:SI 1 ""))
8980 (use (match_operand:SI 3 ""))])]
8983 /* If value to set is not zero, use the library routine. */
8984 if (operands[2] != const0_rtx)
8987 if (expand_block_clear (operands))
8993 ;; String compare N insn.
8994 ;; Argument 0 is the target (result)
8995 ;; Argument 1 is the destination
8996 ;; Argument 2 is the source
8997 ;; Argument 3 is the length
8998 ;; Argument 4 is the alignment
9000 (define_expand "cmpstrnsi"
9001 [(parallel [(set (match_operand:SI 0)
9002 (compare:SI (match_operand:BLK 1)
9003 (match_operand:BLK 2)))
9004 (use (match_operand:SI 3))
9005 (use (match_operand:SI 4))])]
9006 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9008 if (optimize_insn_for_size_p ())
9011 if (expand_strn_compare (operands, 0))
9017 ;; String compare insn.
9018 ;; Argument 0 is the target (result)
9019 ;; Argument 1 is the destination
9020 ;; Argument 2 is the source
9021 ;; Argument 3 is the alignment
9023 (define_expand "cmpstrsi"
9024 [(parallel [(set (match_operand:SI 0)
9025 (compare:SI (match_operand:BLK 1)
9026 (match_operand:BLK 2)))
9027 (use (match_operand:SI 3))])]
9028 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9030 if (optimize_insn_for_size_p ())
9033 if (expand_strn_compare (operands, 1))
9039 ;; Block compare insn.
9040 ;; Argument 0 is the target (result)
9041 ;; Argument 1 is the destination
9042 ;; Argument 2 is the source
9043 ;; Argument 3 is the length
9044 ;; Argument 4 is the alignment
9046 (define_expand "cmpmemsi"
9047 [(parallel [(set (match_operand:SI 0)
9048 (compare:SI (match_operand:BLK 1)
9049 (match_operand:BLK 2)))
9050 (use (match_operand:SI 3))
9051 (use (match_operand:SI 4))])]
9054 if (expand_block_compare (operands))
9060 ;; String/block move insn.
9061 ;; Argument 0 is the destination
9062 ;; Argument 1 is the source
9063 ;; Argument 2 is the length
9064 ;; Argument 3 is the alignment
9066 (define_expand "movmemsi"
9067 [(parallel [(set (match_operand:BLK 0 "")
9068 (match_operand:BLK 1 ""))
9069 (use (match_operand:SI 2 ""))
9070 (use (match_operand:SI 3 ""))])]
9073 if (expand_block_move (operands))
9079 ;; Define insns that do load or store with update. Some of these we can
9080 ;; get by using pre-decrement or pre-increment, but the hardware can also
9081 ;; do cases where the increment is not the size of the object.
9083 ;; In all these cases, we use operands 0 and 1 for the register being
9084 ;; incremented because those are the operands that local-alloc will
9085 ;; tie and these are the pair most likely to be tieable (and the ones
9086 ;; that will benefit the most).
9088 (define_insn "*movdi_update1"
9089 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9090 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9091 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9092 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9093 (plus:DI (match_dup 1) (match_dup 2)))]
9094 "TARGET_POWERPC64 && TARGET_UPDATE
9095 && (!avoiding_indexed_address_p (DImode)
9096 || !gpc_reg_operand (operands[2], DImode))"
9100 [(set_attr "type" "load")
9101 (set_attr "update" "yes")
9102 (set_attr "indexed" "yes,no")])
9104 (define_insn "movdi_<mode>_update"
9105 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9106 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9107 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9108 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9109 (plus:P (match_dup 1) (match_dup 2)))]
9110 "TARGET_POWERPC64 && TARGET_UPDATE
9111 && (!avoiding_indexed_address_p (Pmode)
9112 || !gpc_reg_operand (operands[2], Pmode)
9113 || (REG_P (operands[0])
9114 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9118 [(set_attr "type" "store")
9119 (set_attr "update" "yes")
9120 (set_attr "indexed" "yes,no")])
9122 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9123 ;; needed for stack allocation, even if the user passes -mno-update.
9124 (define_insn "movdi_<mode>_update_stack"
9125 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9126 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9127 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9128 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9129 (plus:P (match_dup 1) (match_dup 2)))]
9134 [(set_attr "type" "store")
9135 (set_attr "update" "yes")
9136 (set_attr "indexed" "yes,no")])
9138 (define_insn "*movsi_update1"
9139 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9140 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9141 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9142 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9143 (plus:SI (match_dup 1) (match_dup 2)))]
9145 && (!avoiding_indexed_address_p (SImode)
9146 || !gpc_reg_operand (operands[2], SImode))"
9150 [(set_attr "type" "load")
9151 (set_attr "update" "yes")
9152 (set_attr "indexed" "yes,no")])
9154 (define_insn "*movsi_update2"
9155 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9157 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9158 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9159 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9160 (plus:DI (match_dup 1) (match_dup 2)))]
9161 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9163 [(set_attr "type" "load")
9164 (set_attr "sign_extend" "yes")
9165 (set_attr "update" "yes")
9166 (set_attr "indexed" "yes")])
9168 (define_insn "movsi_update"
9169 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9170 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9171 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9172 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9173 (plus:SI (match_dup 1) (match_dup 2)))]
9175 && (!avoiding_indexed_address_p (SImode)
9176 || !gpc_reg_operand (operands[2], SImode)
9177 || (REG_P (operands[0])
9178 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9182 [(set_attr "type" "store")
9183 (set_attr "update" "yes")
9184 (set_attr "indexed" "yes,no")])
9186 ;; This is an unconditional pattern; needed for stack allocation, even
9187 ;; if the user passes -mno-update.
9188 (define_insn "movsi_update_stack"
9189 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9190 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9191 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9192 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9193 (plus:SI (match_dup 1) (match_dup 2)))]
9198 [(set_attr "type" "store")
9199 (set_attr "update" "yes")
9200 (set_attr "indexed" "yes,no")])
9202 (define_insn "*movhi_update1"
9203 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9204 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9205 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9206 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9207 (plus:SI (match_dup 1) (match_dup 2)))]
9209 && (!avoiding_indexed_address_p (SImode)
9210 || !gpc_reg_operand (operands[2], SImode))"
9214 [(set_attr "type" "load")
9215 (set_attr "update" "yes")
9216 (set_attr "indexed" "yes,no")])
9218 (define_insn "*movhi_update2"
9219 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9221 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9222 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9223 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9224 (plus:SI (match_dup 1) (match_dup 2)))]
9226 && (!avoiding_indexed_address_p (SImode)
9227 || !gpc_reg_operand (operands[2], SImode))"
9231 [(set_attr "type" "load")
9232 (set_attr "update" "yes")
9233 (set_attr "indexed" "yes,no")])
9235 (define_insn "*movhi_update3"
9236 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9238 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9239 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9240 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9241 (plus:SI (match_dup 1) (match_dup 2)))]
9243 && !(avoiding_indexed_address_p (SImode)
9244 && gpc_reg_operand (operands[2], SImode))"
9248 [(set_attr "type" "load")
9249 (set_attr "sign_extend" "yes")
9250 (set_attr "update" "yes")
9251 (set_attr "indexed" "yes,no")])
9253 (define_insn "*movhi_update4"
9254 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9255 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9256 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9257 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9258 (plus:SI (match_dup 1) (match_dup 2)))]
9260 && (!avoiding_indexed_address_p (SImode)
9261 || !gpc_reg_operand (operands[2], SImode))"
9265 [(set_attr "type" "store")
9266 (set_attr "update" "yes")
9267 (set_attr "indexed" "yes,no")])
9269 (define_insn "*movqi_update1"
9270 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9271 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9272 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9273 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9274 (plus:SI (match_dup 1) (match_dup 2)))]
9276 && (!avoiding_indexed_address_p (SImode)
9277 || !gpc_reg_operand (operands[2], SImode))"
9281 [(set_attr "type" "load")
9282 (set_attr "update" "yes")
9283 (set_attr "indexed" "yes,no")])
9285 (define_insn "*movqi_update2"
9286 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9288 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9289 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9290 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9291 (plus:SI (match_dup 1) (match_dup 2)))]
9293 && (!avoiding_indexed_address_p (SImode)
9294 || !gpc_reg_operand (operands[2], SImode))"
9298 [(set_attr "type" "load")
9299 (set_attr "update" "yes")
9300 (set_attr "indexed" "yes,no")])
9302 (define_insn "*movqi_update3"
9303 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9304 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9305 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9306 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9307 (plus:SI (match_dup 1) (match_dup 2)))]
9309 && (!avoiding_indexed_address_p (SImode)
9310 || !gpc_reg_operand (operands[2], SImode))"
9314 [(set_attr "type" "store")
9315 (set_attr "update" "yes")
9316 (set_attr "indexed" "yes,no")])
9318 (define_insn "*movsf_update1"
9319 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9320 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9321 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9322 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9323 (plus:SI (match_dup 1) (match_dup 2)))]
9324 "TARGET_HARD_FLOAT && TARGET_UPDATE
9325 && (!avoiding_indexed_address_p (SImode)
9326 || !gpc_reg_operand (operands[2], SImode))"
9330 [(set_attr "type" "fpload")
9331 (set_attr "update" "yes")
9332 (set_attr "indexed" "yes,no")])
9334 (define_insn "*movsf_update2"
9335 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9336 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9337 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9338 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9339 (plus:SI (match_dup 1) (match_dup 2)))]
9340 "TARGET_HARD_FLOAT && TARGET_UPDATE
9341 && (!avoiding_indexed_address_p (SImode)
9342 || !gpc_reg_operand (operands[2], SImode))"
9346 [(set_attr "type" "fpstore")
9347 (set_attr "update" "yes")
9348 (set_attr "indexed" "yes,no")])
9350 (define_insn "*movsf_update3"
9351 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9352 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9353 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9354 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9355 (plus:SI (match_dup 1) (match_dup 2)))]
9356 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9357 && (!avoiding_indexed_address_p (SImode)
9358 || !gpc_reg_operand (operands[2], SImode))"
9362 [(set_attr "type" "load")
9363 (set_attr "update" "yes")
9364 (set_attr "indexed" "yes,no")])
9366 (define_insn "*movsf_update4"
9367 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9368 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9369 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9370 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9371 (plus:SI (match_dup 1) (match_dup 2)))]
9372 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9373 && (!avoiding_indexed_address_p (SImode)
9374 || !gpc_reg_operand (operands[2], SImode))"
9378 [(set_attr "type" "store")
9379 (set_attr "update" "yes")
9380 (set_attr "indexed" "yes,no")])
9382 (define_insn "*movdf_update1"
9383 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9384 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9385 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9386 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9387 (plus:SI (match_dup 1) (match_dup 2)))]
9388 "TARGET_HARD_FLOAT && TARGET_UPDATE
9389 && (!avoiding_indexed_address_p (SImode)
9390 || !gpc_reg_operand (operands[2], SImode))"
9394 [(set_attr "type" "fpload")
9395 (set_attr "update" "yes")
9396 (set_attr "indexed" "yes,no")
9397 (set_attr "size" "64")])
9399 (define_insn "*movdf_update2"
9400 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9401 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9402 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9403 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9404 (plus:SI (match_dup 1) (match_dup 2)))]
9405 "TARGET_HARD_FLOAT && TARGET_UPDATE
9406 && (!avoiding_indexed_address_p (SImode)
9407 || !gpc_reg_operand (operands[2], SImode))"
9411 [(set_attr "type" "fpstore")
9412 (set_attr "update" "yes")
9413 (set_attr "indexed" "yes,no")])
9416 ;; After inserting conditional returns we can sometimes have
9417 ;; unnecessary register moves. Unfortunately we cannot have a
9418 ;; modeless peephole here, because some single SImode sets have early
9419 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9420 ;; sequences, using get_attr_length here will smash the operands
9421 ;; array. Neither is there an early_cobbler_p predicate.
9422 ;; Also this optimization interferes with scalars going into
9423 ;; altivec registers (the code does reloading through the FPRs).
9425 [(set (match_operand:DF 0 "gpc_reg_operand")
9426 (match_operand:DF 1 "any_operand"))
9427 (set (match_operand:DF 2 "gpc_reg_operand")
9430 && peep2_reg_dead_p (2, operands[0])"
9431 [(set (match_dup 2) (match_dup 1))])
9434 [(set (match_operand:SF 0 "gpc_reg_operand")
9435 (match_operand:SF 1 "any_operand"))
9436 (set (match_operand:SF 2 "gpc_reg_operand")
9439 && peep2_reg_dead_p (2, operands[0])"
9440 [(set (match_dup 2) (match_dup 1))])
9445 (define_insn "*tls_gdld_nomark<bits>"
9446 [(match_parallel 3 ""
9447 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9448 (call (mem:SI (match_operand:P 1))
9449 (match_operand:P 2 "unspec_tls")))
9451 "HAVE_AS_TLS && !TARGET_TLS_MARKERS && DEFAULT_ABI != ABI_DARWIN"
9454 op[0] = operands[0];
9455 op[1] = XVECEXP (operands[2], 0, 0);
9456 if (XINT (operands[2], 1) == UNSPEC_TLSGD)
9458 op[2] = XVECEXP (operands[2], 0, 1);
9459 if (TARGET_CMODEL != CMODEL_SMALL)
9460 output_asm_insn ("addis %0,%2,%1@got@tlsgd@ha\;"
9461 "addi %0,%0,%1@got@tlsgd@l", op);
9463 output_asm_insn ("addi %0,%2,%1@got@tlsgd", op);
9467 if (TARGET_CMODEL != CMODEL_SMALL)
9468 output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\;"
9469 "addi %0,%0,%&@got@tlsld@l", op);
9471 output_asm_insn ("addi %0,%1,%&@got@tlsld", op);
9473 return rs6000_call_template (operands, 1);
9475 [(set_attr "type" "two")
9476 (set (attr "length")
9477 (cond [(match_test "TARGET_CMODEL != CMODEL_SMALL")
9479 (match_test "DEFAULT_ABI != ABI_V4")
9483 (define_insn_and_split "*tls_gd<bits>"
9484 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9485 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9486 (match_operand:P 2 "gpc_reg_operand" "b")]
9488 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9489 "addi %0,%2,%1@got@tlsgd"
9490 "&& TARGET_CMODEL != CMODEL_SMALL"
9493 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9495 (lo_sum:P (match_dup 3)
9496 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9498 operands[3] = gen_reg_rtx (<MODE>mode);
9500 [(set (attr "length")
9501 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9505 (define_insn "*tls_gd_high<bits>"
9506 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9508 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9509 (match_operand:P 2 "gpc_reg_operand" "b")]
9511 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9512 "addis %0,%2,%1@got@tlsgd@ha")
9514 (define_insn "*tls_gd_low<bits>"
9515 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9516 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9517 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9518 (match_operand:P 3 "gpc_reg_operand" "b")]
9520 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9521 "addi %0,%1,%2@got@tlsgd@l")
9523 (define_insn_and_split "*tls_ld<bits>"
9524 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9525 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9527 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9528 "addi %0,%1,%&@got@tlsld"
9529 "&& TARGET_CMODEL != CMODEL_SMALL"
9532 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9534 (lo_sum:P (match_dup 2)
9535 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9537 operands[2] = gen_reg_rtx (<MODE>mode);
9539 [(set (attr "length")
9540 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9544 (define_insn "*tls_ld_high<bits>"
9545 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9547 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9549 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9550 "addis %0,%1,%&@got@tlsld@ha")
9552 (define_insn "*tls_ld_low<bits>"
9553 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9554 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9555 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9557 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9558 "addi %0,%1,%&@got@tlsld@l")
9560 (define_insn "tls_dtprel_<bits>"
9561 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9562 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9563 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9566 "addi %0,%1,%2@dtprel")
9568 (define_insn "tls_dtprel_ha_<bits>"
9569 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9570 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9571 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9572 UNSPEC_TLSDTPRELHA))]
9574 "addis %0,%1,%2@dtprel@ha")
9576 (define_insn "tls_dtprel_lo_<bits>"
9577 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9578 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9579 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9580 UNSPEC_TLSDTPRELLO))]
9582 "addi %0,%1,%2@dtprel@l")
9584 (define_insn_and_split "tls_got_dtprel_<bits>"
9585 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9586 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9587 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9588 UNSPEC_TLSGOTDTPREL))]
9590 "<ptrload> %0,%2@got@dtprel(%1)"
9591 "&& TARGET_CMODEL != CMODEL_SMALL"
9594 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9596 (lo_sum:P (match_dup 3)
9597 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9599 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9601 [(set (attr "length")
9602 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9606 (define_insn "*tls_got_dtprel_high<bits>"
9607 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9609 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9610 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9611 UNSPEC_TLSGOTDTPREL)))]
9612 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9613 "addis %0,%1,%2@got@dtprel@ha")
9615 (define_insn "*tls_got_dtprel_low<bits>"
9616 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9617 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9618 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9619 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9620 UNSPEC_TLSGOTDTPREL)))]
9621 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9622 "<ptrload> %0,%2@got@dtprel@l(%1)")
9624 (define_insn "tls_tprel_<bits>"
9625 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9626 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9627 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9630 "addi %0,%1,%2@tprel")
9632 (define_insn "tls_tprel_ha_<bits>"
9633 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9634 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9635 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9636 UNSPEC_TLSTPRELHA))]
9638 "addis %0,%1,%2@tprel@ha")
9640 (define_insn "tls_tprel_lo_<bits>"
9641 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9642 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9643 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9644 UNSPEC_TLSTPRELLO))]
9646 "addi %0,%1,%2@tprel@l")
9648 ;; "b" output constraint here and on tls_tls input to support linker tls
9649 ;; optimization. The linker may edit the instructions emitted by a
9650 ;; tls_got_tprel/tls_tls pair to addis,addi.
9651 (define_insn_and_split "tls_got_tprel_<bits>"
9652 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9653 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9654 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9655 UNSPEC_TLSGOTTPREL))]
9657 "<ptrload> %0,%2@got@tprel(%1)"
9658 "&& TARGET_CMODEL != CMODEL_SMALL"
9661 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9663 (lo_sum:P (match_dup 3)
9664 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9666 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9668 [(set (attr "length")
9669 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9673 (define_insn "*tls_got_tprel_high<bits>"
9674 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9676 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9677 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9678 UNSPEC_TLSGOTTPREL)))]
9679 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9680 "addis %0,%1,%2@got@tprel@ha")
9682 (define_insn "*tls_got_tprel_low<bits>"
9683 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9684 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9685 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9686 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9687 UNSPEC_TLSGOTTPREL)))]
9688 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9689 "<ptrload> %0,%2@got@tprel@l(%1)")
9691 (define_insn "tls_tls_<bits>"
9692 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9693 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9694 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9696 "TARGET_ELF && HAVE_AS_TLS"
9699 (define_expand "tls_get_tpointer"
9700 [(set (match_operand:SI 0 "gpc_reg_operand")
9701 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9702 "TARGET_XCOFF && HAVE_AS_TLS"
9704 emit_insn (gen_tls_get_tpointer_internal ());
9705 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9709 (define_insn "tls_get_tpointer_internal"
9711 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9712 (clobber (reg:SI LR_REGNO))]
9713 "TARGET_XCOFF && HAVE_AS_TLS"
9714 "bla __get_tpointer")
9716 (define_expand "tls_get_addr<mode>"
9717 [(set (match_operand:P 0 "gpc_reg_operand")
9718 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9719 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9720 "TARGET_XCOFF && HAVE_AS_TLS"
9722 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9723 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9724 emit_insn (gen_tls_get_addr_internal<mode> ());
9725 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9729 (define_insn "tls_get_addr_internal<mode>"
9731 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9735 (clobber (reg:P 11))
9736 (clobber (reg:CC CR0_REGNO))
9737 (clobber (reg:P LR_REGNO))]
9738 "TARGET_XCOFF && HAVE_AS_TLS"
9739 "bla __tls_get_addr")
9741 ;; Next come insns related to the calling sequence.
9743 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9744 ;; We move the back-chain and decrement the stack pointer.
9746 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9747 ;; constant alloca, using that predicate will force the generic code to put
9748 ;; the constant size into a register before calling the expander.
9750 ;; As a result the expander would not have the constant size information
9751 ;; in those cases and would have to generate less efficient code.
9753 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9754 ;; the constant size. The value is forced into a register if necessary.
9756 (define_expand "allocate_stack"
9757 [(set (match_operand 0 "gpc_reg_operand")
9758 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9760 (minus (reg 1) (match_dup 1)))]
9763 rtx chain = gen_reg_rtx (Pmode);
9764 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9766 rtx insn, par, set, mem;
9768 /* By allowing reg_or_cint_operand as the predicate we can get
9769 better code for stack-clash-protection because we do not lose
9770 size information. But the rest of the code expects the operand
9771 to be reg_or_short_operand. If it isn't, then force it into
9773 rtx orig_op1 = operands[1];
9774 if (!reg_or_short_operand (operands[1], Pmode))
9775 operands[1] = force_reg (Pmode, operands[1]);
9777 emit_move_insn (chain, stack_bot);
9779 /* Check stack bounds if necessary. */
9780 if (crtl->limit_stack)
9783 available = expand_binop (Pmode, sub_optab,
9784 stack_pointer_rtx, stack_limit_rtx,
9785 NULL_RTX, 1, OPTAB_WIDEN);
9786 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9789 /* Allocate and probe if requested.
9790 This may look similar to the loop we use for prologue allocations,
9791 but it is critically different. For the former we know the loop
9792 will iterate, but do not know that generally here. The former
9793 uses that knowledge to rotate the loop. Combining them would be
9794 possible with some performance cost. */
9795 if (flag_stack_clash_protection)
9797 rtx rounded_size, last_addr, residual;
9798 HOST_WIDE_INT probe_interval;
9799 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9800 &residual, &probe_interval,
9803 /* We do occasionally get in here with constant sizes, we might
9804 as well do a reasonable job when we obviously can. */
9805 if (rounded_size != const0_rtx)
9807 rtx loop_lab, end_loop;
9808 bool rotated = CONST_INT_P (rounded_size);
9809 rtx update = GEN_INT (-probe_interval);
9810 if (probe_interval > 32768)
9811 update = force_reg (Pmode, update);
9813 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9814 last_addr, rotated);
9816 if (Pmode == SImode)
9817 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9821 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9824 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9825 last_addr, rotated);
9828 /* Now handle residuals. We just have to set operands[1] correctly
9829 and let the rest of the expander run. */
9830 operands[1] = residual;
9833 if (!(CONST_INT_P (operands[1])
9834 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9836 operands[1] = force_reg (Pmode, operands[1]);
9837 neg_op0 = gen_reg_rtx (Pmode);
9839 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9841 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9844 neg_op0 = GEN_INT (-INTVAL (operands[1]));
9846 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9847 : gen_movdi_di_update_stack))
9848 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9850 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9851 it now and set the alias set/attributes. The above gen_*_update
9852 calls will generate a PARALLEL with the MEM set being the first
9854 par = PATTERN (insn);
9855 gcc_assert (GET_CODE (par) == PARALLEL);
9856 set = XVECEXP (par, 0, 0);
9857 gcc_assert (GET_CODE (set) == SET);
9858 mem = SET_DEST (set);
9859 gcc_assert (MEM_P (mem));
9860 MEM_NOTRAP_P (mem) = 1;
9861 set_mem_alias_set (mem, get_frame_alias_set ());
9863 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9867 ;; These patterns say how to save and restore the stack pointer. We need not
9868 ;; save the stack pointer at function level since we are careful to
9869 ;; preserve the backchain. At block level, we have to restore the backchain
9870 ;; when we restore the stack pointer.
9872 ;; For nonlocal gotos, we must save both the stack pointer and its
9873 ;; backchain and restore both. Note that in the nonlocal case, the
9874 ;; save area is a memory location.
9876 (define_expand "save_stack_function"
9877 [(match_operand 0 "any_operand")
9878 (match_operand 1 "any_operand")]
9882 (define_expand "restore_stack_function"
9883 [(match_operand 0 "any_operand")
9884 (match_operand 1 "any_operand")]
9888 ;; Adjust stack pointer (op0) to a new value (op1).
9889 ;; First copy old stack backchain to new location, and ensure that the
9890 ;; scheduler won't reorder the sp assignment before the backchain write.
9891 (define_expand "restore_stack_block"
9892 [(set (match_dup 2) (match_dup 3))
9893 (set (match_dup 4) (match_dup 2))
9895 (set (match_operand 0 "register_operand")
9896 (match_operand 1 "register_operand"))]
9901 operands[1] = force_reg (Pmode, operands[1]);
9902 operands[2] = gen_reg_rtx (Pmode);
9903 operands[3] = gen_frame_mem (Pmode, operands[0]);
9904 operands[4] = gen_frame_mem (Pmode, operands[1]);
9905 p = rtvec_alloc (1);
9906 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9908 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9911 (define_expand "save_stack_nonlocal"
9912 [(set (match_dup 3) (match_dup 4))
9913 (set (match_operand 0 "memory_operand") (match_dup 3))
9914 (set (match_dup 2) (match_operand 1 "register_operand"))]
9917 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9919 /* Copy the backchain to the first word, sp to the second. */
9920 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9921 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9922 operands[3] = gen_reg_rtx (Pmode);
9923 operands[4] = gen_frame_mem (Pmode, operands[1]);
9926 (define_expand "restore_stack_nonlocal"
9927 [(set (match_dup 2) (match_operand 1 "memory_operand"))
9928 (set (match_dup 3) (match_dup 4))
9929 (set (match_dup 5) (match_dup 2))
9931 (set (match_operand 0 "register_operand") (match_dup 3))]
9934 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9937 /* Restore the backchain from the first word, sp from the second. */
9938 operands[2] = gen_reg_rtx (Pmode);
9939 operands[3] = gen_reg_rtx (Pmode);
9940 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9941 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9942 operands[5] = gen_frame_mem (Pmode, operands[3]);
9943 p = rtvec_alloc (1);
9944 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9946 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9949 ;; TOC register handling.
9951 ;; Code to initialize the TOC register...
9953 (define_insn "load_toc_aix_si"
9954 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9955 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9957 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9960 extern int need_toc_init;
9962 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9963 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9964 operands[2] = gen_rtx_REG (Pmode, 2);
9965 return "lwz %0,%1(%2)";
9967 [(set_attr "type" "load")
9968 (set_attr "update" "no")
9969 (set_attr "indexed" "no")])
9971 (define_insn "load_toc_aix_di"
9972 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9973 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9975 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9978 extern int need_toc_init;
9980 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9981 !TARGET_ELF || !TARGET_MINIMAL_TOC);
9983 strcat (buf, "@toc");
9984 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9985 operands[2] = gen_rtx_REG (Pmode, 2);
9986 return "ld %0,%1(%2)";
9988 [(set_attr "type" "load")
9989 (set_attr "update" "no")
9990 (set_attr "indexed" "no")])
9992 (define_insn "load_toc_v4_pic_si"
9993 [(set (reg:SI LR_REGNO)
9994 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9995 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9996 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9997 [(set_attr "type" "branch")])
9999 (define_expand "load_toc_v4_PIC_1"
10000 [(parallel [(set (reg:SI LR_REGNO)
10001 (match_operand:SI 0 "immediate_operand" "s"))
10002 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10003 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10004 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10007 (define_insn "load_toc_v4_PIC_1_normal"
10008 [(set (reg:SI LR_REGNO)
10009 (match_operand:SI 0 "immediate_operand" "s"))
10010 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10011 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10012 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10013 "bcl 20,31,%0\n%0:"
10014 [(set_attr "type" "branch")
10015 (set_attr "cannot_copy" "yes")])
10017 (define_insn "load_toc_v4_PIC_1_476"
10018 [(set (reg:SI LR_REGNO)
10019 (match_operand:SI 0 "immediate_operand" "s"))
10020 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10021 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10022 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10025 static char templ[32];
10027 get_ppc476_thunk_name (name);
10028 sprintf (templ, "bl %s\n%%0:", name);
10031 [(set_attr "type" "branch")
10032 (set_attr "cannot_copy" "yes")])
10034 (define_expand "load_toc_v4_PIC_1b"
10035 [(parallel [(set (reg:SI LR_REGNO)
10036 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10037 (label_ref (match_operand 1 ""))]
10040 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10043 (define_insn "load_toc_v4_PIC_1b_normal"
10044 [(set (reg:SI LR_REGNO)
10045 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10046 (label_ref (match_operand 1 "" ""))]
10049 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10050 "bcl 20,31,$+8\;.long %0-$"
10051 [(set_attr "type" "branch")
10052 (set_attr "length" "8")])
10054 (define_insn "load_toc_v4_PIC_1b_476"
10055 [(set (reg:SI LR_REGNO)
10056 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10057 (label_ref (match_operand 1 "" ""))]
10060 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10063 static char templ[32];
10065 get_ppc476_thunk_name (name);
10066 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10069 [(set_attr "type" "branch")
10070 (set_attr "length" "16")])
10072 (define_insn "load_toc_v4_PIC_2"
10073 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10075 (match_operand:SI 1 "gpc_reg_operand" "b")
10077 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10078 (match_operand:SI 3 "immediate_operand" "s"))))))]
10079 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10081 [(set_attr "type" "load")])
10083 (define_insn "load_toc_v4_PIC_3b"
10084 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10086 (match_operand:SI 1 "gpc_reg_operand" "b")
10089 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10090 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10091 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10092 "addis %0,%1,%2-%3@ha")
10094 (define_insn "load_toc_v4_PIC_3c"
10095 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10097 (match_operand:SI 1 "gpc_reg_operand" "b")
10099 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10100 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10101 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10102 "addi %0,%1,%2-%3@l")
10104 ;; If the TOC is shared over a translation unit, as happens with all
10105 ;; the kinds of PIC that we support, we need to restore the TOC
10106 ;; pointer only when jumping over units of translation.
10107 ;; On Darwin, we need to reload the picbase.
10109 (define_expand "builtin_setjmp_receiver"
10110 [(use (label_ref (match_operand 0 "")))]
10111 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10112 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10113 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10116 if (DEFAULT_ABI == ABI_DARWIN)
10118 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10119 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10123 crtl->uses_pic_offset_table = 1;
10124 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10125 CODE_LABEL_NUMBER (operands[0]));
10126 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10128 emit_insn (gen_load_macho_picbase (tmplabrtx));
10129 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10130 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10134 rs6000_emit_load_toc_table (FALSE);
10138 ;; Largetoc support
10139 (define_insn "*largetoc_high"
10140 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10142 (unspec [(match_operand:DI 1 "" "")
10143 (match_operand:DI 2 "gpc_reg_operand" "b")]
10145 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10146 "addis %0,%2,%1@toc@ha")
10148 (define_insn "*largetoc_high_aix<mode>"
10149 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10151 (unspec [(match_operand:P 1 "" "")
10152 (match_operand:P 2 "gpc_reg_operand" "b")]
10154 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10155 "addis %0,%1@u(%2)")
10157 (define_insn "*largetoc_high_plus"
10158 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10161 (unspec [(match_operand:DI 1 "" "")
10162 (match_operand:DI 2 "gpc_reg_operand" "b")]
10164 (match_operand:DI 3 "add_cint_operand" "n"))))]
10165 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10166 "addis %0,%2,%1+%3@toc@ha")
10168 (define_insn "*largetoc_high_plus_aix<mode>"
10169 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10172 (unspec [(match_operand:P 1 "" "")
10173 (match_operand:P 2 "gpc_reg_operand" "b")]
10175 (match_operand:P 3 "add_cint_operand" "n"))))]
10176 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10177 "addis %0,%1+%3@u(%2)")
10179 (define_insn "*largetoc_low"
10180 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10181 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10182 (match_operand:DI 2 "" "")))]
10183 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10186 (define_insn "*largetoc_low_aix<mode>"
10187 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10188 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10189 (match_operand:P 2 "" "")))]
10190 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10193 (define_insn_and_split "*tocref<mode>"
10194 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10195 (match_operand:P 1 "small_toc_ref" "R"))]
10198 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10199 [(set (match_dup 0) (high:P (match_dup 1)))
10200 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10202 ;; Elf specific ways of loading addresses for non-PIC code.
10203 ;; The output of this could be r0, but we make a very strong
10204 ;; preference for a base register because it will usually
10205 ;; be needed there.
10206 (define_insn "elf_high"
10207 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10208 (high:SI (match_operand 1 "" "")))]
10209 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10212 (define_insn "elf_low"
10213 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10214 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10215 (match_operand 2 "" "")))]
10216 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10219 (define_insn "*pltseq_tocsave_<mode>"
10220 [(set (match_operand:P 0 "memory_operand" "=m")
10221 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10222 (match_operand:P 2 "symbol_ref_operand" "s")
10223 (match_operand:P 3 "" "")]
10225 "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10226 && DEFAULT_ABI == ABI_ELFv2"
10228 return rs6000_pltseq_template (operands, 0);
10231 (define_insn "*pltseq_plt16_ha_<mode>"
10232 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10233 (unspec:P [(match_operand:P 1 "" "")
10234 (match_operand:P 2 "symbol_ref_operand" "s")
10235 (match_operand:P 3 "" "")]
10237 "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10238 && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
10240 return rs6000_pltseq_template (operands, 1);
10243 (define_insn "*pltseq_plt16_lo_<mode>"
10244 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10245 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10246 (match_operand:P 2 "symbol_ref_operand" "s")
10247 (match_operand:P 3 "" "")]
10249 "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10250 && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
10252 return rs6000_pltseq_template (operands, 2);
10254 [(set_attr "type" "load")])
10256 (define_insn "*pltseq_mtctr_<mode>"
10257 [(set (match_operand:P 0 "register_operand" "=c")
10258 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10259 (match_operand:P 2 "symbol_ref_operand" "s")
10260 (match_operand:P 3 "" "")]
10262 "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10263 && (DEFAULT_ABI == ABI_ELFv2 || DEFAULT_ABI == ABI_V4)"
10265 return rs6000_pltseq_template (operands, 3);
10268 ;; Call and call_value insns
10269 (define_expand "call"
10270 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10271 (match_operand 1 ""))
10272 (use (match_operand 2 ""))
10273 (clobber (reg:SI LR_REGNO))])]
10277 if (MACHOPIC_INDIRECT)
10278 operands[0] = machopic_indirect_call_target (operands[0]);
10281 gcc_assert (GET_CODE (operands[0]) == MEM);
10283 operands[0] = XEXP (operands[0], 0);
10285 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10287 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10291 if (DEFAULT_ABI == ABI_V4)
10293 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10297 if (GET_CODE (operands[0]) != SYMBOL_REF)
10298 operands[0] = force_reg (Pmode, operands[0]);
10301 (define_expand "call_value"
10302 [(parallel [(set (match_operand 0 "")
10303 (call (mem:SI (match_operand 1 "address_operand"))
10304 (match_operand 2 "")))
10305 (use (match_operand 3 ""))
10306 (clobber (reg:SI LR_REGNO))])]
10310 if (MACHOPIC_INDIRECT)
10311 operands[1] = machopic_indirect_call_target (operands[1]);
10314 gcc_assert (GET_CODE (operands[1]) == MEM);
10316 operands[1] = XEXP (operands[1], 0);
10318 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10320 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10324 if (DEFAULT_ABI == ABI_V4)
10326 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10330 if (GET_CODE (operands[1]) != SYMBOL_REF)
10331 operands[1] = force_reg (Pmode, operands[1]);
10334 ;; Call to function in current module. No TOC pointer reload needed.
10335 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10336 ;; either the function was not prototyped, or it was prototyped as a
10337 ;; variable argument function. It is > 0 if FP registers were passed
10338 ;; and < 0 if they were not.
10340 (define_insn "*call_local32"
10341 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10343 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10344 (clobber (reg:SI LR_REGNO))]
10345 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10347 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10348 output_asm_insn ("crxor 6,6,6", operands);
10350 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10351 output_asm_insn ("creqv 6,6,6", operands);
10353 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10355 [(set_attr "type" "branch")
10356 (set_attr "length" "4,8")])
10358 (define_insn "*call_local64"
10359 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10361 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10362 (clobber (reg:SI LR_REGNO))]
10363 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10365 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10366 output_asm_insn ("crxor 6,6,6", operands);
10368 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10369 output_asm_insn ("creqv 6,6,6", operands);
10371 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10373 [(set_attr "type" "branch")
10374 (set_attr "length" "4,8")])
10376 (define_insn "*call_value_local32"
10377 [(set (match_operand 0 "" "")
10378 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10379 (match_operand 2)))
10380 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10381 (clobber (reg:SI LR_REGNO))]
10382 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10384 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10385 output_asm_insn ("crxor 6,6,6", operands);
10387 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10388 output_asm_insn ("creqv 6,6,6", operands);
10390 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10392 [(set_attr "type" "branch")
10393 (set_attr "length" "4,8")])
10396 (define_insn "*call_value_local64"
10397 [(set (match_operand 0 "" "")
10398 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10399 (match_operand 2)))
10400 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10401 (clobber (reg:SI LR_REGNO))]
10402 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10404 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10405 output_asm_insn ("crxor 6,6,6", operands);
10407 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10408 output_asm_insn ("creqv 6,6,6", operands);
10410 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10412 [(set_attr "type" "branch")
10413 (set_attr "length" "4,8")])
10416 ;; A function pointer under System V is just a normal pointer
10417 ;; operands[0] is the function pointer
10418 ;; operands[1] is the tls call arg
10419 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10420 ;; which indicates how to set cr1
10422 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10423 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10425 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10426 (clobber (reg:SI LR_REGNO))]
10427 "DEFAULT_ABI == ABI_V4
10428 || DEFAULT_ABI == ABI_DARWIN"
10430 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10431 output_asm_insn ("crxor 6,6,6", operands);
10433 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10434 output_asm_insn ("creqv 6,6,6", operands);
10436 return rs6000_indirect_call_template (operands, 0);
10438 [(set_attr "type" "jmpreg")
10439 (set (attr "length")
10440 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10441 (match_test "which_alternative != 1"))
10442 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10443 (const_string "12")
10444 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10445 (match_test "which_alternative != 1"))
10446 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10447 (const_string "8")]
10448 (const_string "4")))])
10450 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10451 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10453 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10454 (clobber (reg:SI LR_REGNO))]
10455 "(DEFAULT_ABI == ABI_DARWIN
10456 || (DEFAULT_ABI == ABI_V4
10457 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10459 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10460 output_asm_insn ("crxor 6,6,6", operands);
10462 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10463 output_asm_insn ("creqv 6,6,6", operands);
10466 return macho_call_template (insn, operands, 0, 2);
10468 return rs6000_call_template (operands, 0);
10471 "DEFAULT_ABI == ABI_V4
10472 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10473 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10474 [(parallel [(call (mem:SI (match_dup 0))
10476 (use (match_dup 2))
10477 (use (match_dup 3))
10478 (clobber (reg:SI LR_REGNO))])]
10480 operands[3] = pic_offset_table_rtx;
10482 [(set_attr "type" "branch,branch")
10483 (set_attr "length" "4,8")])
10485 (define_insn "*call_nonlocal_sysv_secure<mode>"
10486 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10488 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10489 (use (match_operand:SI 3 "register_operand" "r,r"))
10490 (clobber (reg:SI LR_REGNO))]
10491 "(DEFAULT_ABI == ABI_V4
10492 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10493 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10495 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10496 output_asm_insn ("crxor 6,6,6", operands);
10498 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10499 output_asm_insn ("creqv 6,6,6", operands);
10501 return rs6000_call_template (operands, 0);
10503 [(set_attr "type" "branch,branch")
10504 (set_attr "length" "4,8")])
10506 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10507 [(set (match_operand 0 "" "")
10508 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10509 (match_operand 2)))
10510 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10511 (clobber (reg:SI LR_REGNO))]
10512 "DEFAULT_ABI == ABI_V4
10513 || DEFAULT_ABI == ABI_DARWIN"
10515 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10516 output_asm_insn ("crxor 6,6,6", operands);
10518 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10519 output_asm_insn ("creqv 6,6,6", operands);
10521 return rs6000_indirect_call_template (operands, 1);
10523 [(set_attr "type" "jmpreg")
10524 (set (attr "length")
10525 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10526 (match_test "which_alternative != 1"))
10527 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10528 (const_string "12")
10529 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10530 (match_test "which_alternative != 1"))
10531 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10532 (const_string "8")]
10533 (const_string "4")))])
10535 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10536 [(set (match_operand 0 "" "")
10537 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10538 (match_operand 2)))
10539 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10540 (clobber (reg:SI LR_REGNO))]
10541 "(DEFAULT_ABI == ABI_DARWIN
10542 || (DEFAULT_ABI == ABI_V4
10543 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10545 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10546 output_asm_insn ("crxor 6,6,6", operands);
10548 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10549 output_asm_insn ("creqv 6,6,6", operands);
10552 return macho_call_template (insn, operands, 1, 3);
10554 return rs6000_call_template (operands, 1);
10557 "DEFAULT_ABI == ABI_V4
10558 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10559 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10560 [(parallel [(set (match_dup 0)
10561 (call (mem:SI (match_dup 1))
10563 (use (match_dup 3))
10564 (use (match_dup 4))
10565 (clobber (reg:SI LR_REGNO))])]
10567 operands[4] = pic_offset_table_rtx;
10569 [(set_attr "type" "branch,branch")
10570 (set_attr "length" "4,8")])
10572 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10573 [(set (match_operand 0 "" "")
10574 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10575 (match_operand 2)))
10576 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10577 (use (match_operand:SI 4 "register_operand" "r,r"))
10578 (clobber (reg:SI LR_REGNO))]
10579 "(DEFAULT_ABI == ABI_V4
10580 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10581 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10583 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10584 output_asm_insn ("crxor 6,6,6", operands);
10586 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10587 output_asm_insn ("creqv 6,6,6", operands);
10589 return rs6000_call_template (operands, 1);
10591 [(set_attr "type" "branch,branch")
10592 (set_attr "length" "4,8")])
10595 ;; Call to AIX abi function in the same module.
10597 (define_insn "*call_local_aix<mode>"
10598 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10600 (clobber (reg:P LR_REGNO))]
10601 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10603 [(set_attr "type" "branch")])
10605 (define_insn "*call_value_local_aix<mode>"
10606 [(set (match_operand 0 "" "")
10607 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10608 (match_operand 2)))
10609 (clobber (reg:P LR_REGNO))]
10610 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10612 [(set_attr "type" "branch")])
10614 ;; Call to AIX abi function which may be in another module.
10615 ;; Restore the TOC pointer (r2) after the call.
10617 (define_insn "*call_nonlocal_aix<mode>"
10618 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10620 (clobber (reg:P LR_REGNO))]
10621 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10623 return rs6000_call_template (operands, 0);
10625 [(set_attr "type" "branch")
10626 (set_attr "length" "8")])
10628 (define_insn "*call_value_nonlocal_aix<mode>"
10629 [(set (match_operand 0 "" "")
10630 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10631 (match_operand 2)))
10632 (clobber (reg:P LR_REGNO))]
10633 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10635 return rs6000_call_template (operands, 1);
10637 [(set_attr "type" "branch")
10638 (set_attr "length" "8")])
10640 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10641 ;; Operand0 is the addresss of the function to call
10642 ;; Operand2 is the location in the function descriptor to load r2 from
10643 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10645 (define_insn "*call_indirect_aix<mode>"
10646 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10648 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10649 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10650 (clobber (reg:P LR_REGNO))]
10651 "DEFAULT_ABI == ABI_AIX"
10653 return rs6000_indirect_call_template (operands, 0);
10655 [(set_attr "type" "jmpreg")
10656 (set (attr "length")
10657 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10658 (match_test "which_alternative != 1"))
10659 (const_string "16")
10660 (const_string "12")))])
10662 (define_insn "*call_value_indirect_aix<mode>"
10663 [(set (match_operand 0 "" "")
10664 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10665 (match_operand 2)))
10666 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10667 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10668 (clobber (reg:P LR_REGNO))]
10669 "DEFAULT_ABI == ABI_AIX"
10671 return rs6000_indirect_call_template (operands, 1);
10673 [(set_attr "type" "jmpreg")
10674 (set (attr "length")
10675 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10676 (match_test "which_alternative != 1"))
10677 (const_string "16")
10678 (const_string "12")))])
10680 ;; Call to indirect functions with the ELFv2 ABI.
10681 ;; Operand0 is the addresss of the function to call
10682 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10684 (define_insn "*call_indirect_elfv2<mode>"
10685 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10687 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10688 (clobber (reg:P LR_REGNO))]
10689 "DEFAULT_ABI == ABI_ELFv2"
10691 return rs6000_indirect_call_template (operands, 0);
10693 [(set_attr "type" "jmpreg")
10694 (set (attr "length")
10695 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10696 (match_test "which_alternative != 1"))
10697 (const_string "12")
10698 (const_string "8")))])
10700 (define_insn "*call_value_indirect_elfv2<mode>"
10701 [(set (match_operand 0 "" "")
10702 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10703 (match_operand 2)))
10704 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10705 (clobber (reg:P LR_REGNO))]
10706 "DEFAULT_ABI == ABI_ELFv2"
10708 return rs6000_indirect_call_template (operands, 1);
10710 [(set_attr "type" "jmpreg")
10711 (set (attr "length")
10712 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10713 (match_test "which_alternative != 1"))
10714 (const_string "12")
10715 (const_string "8")))])
10717 ;; Call subroutine returning any type.
10718 (define_expand "untyped_call"
10719 [(parallel [(call (match_operand 0 "")
10721 (match_operand 1 "")
10722 (match_operand 2 "")])]
10727 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10729 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10731 rtx set = XVECEXP (operands[2], 0, i);
10732 emit_move_insn (SET_DEST (set), SET_SRC (set));
10735 /* The optimizer does not know that the call sets the function value
10736 registers we stored in the result block. We avoid problems by
10737 claiming that all hard registers are used and clobbered at this
10739 emit_insn (gen_blockage ());
10744 ;; sibling call patterns
10745 (define_expand "sibcall"
10746 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10747 (match_operand 1 ""))
10748 (use (match_operand 2 ""))
10753 if (MACHOPIC_INDIRECT)
10754 operands[0] = machopic_indirect_call_target (operands[0]);
10757 gcc_assert (GET_CODE (operands[0]) == MEM);
10758 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10760 operands[0] = XEXP (operands[0], 0);
10762 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10764 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10768 if (DEFAULT_ABI == ABI_V4)
10770 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10775 (define_expand "sibcall_value"
10776 [(parallel [(set (match_operand 0 "register_operand")
10777 (call (mem:SI (match_operand 1 "address_operand"))
10778 (match_operand 2 "")))
10779 (use (match_operand 3 ""))
10784 if (MACHOPIC_INDIRECT)
10785 operands[1] = machopic_indirect_call_target (operands[1]);
10788 gcc_assert (GET_CODE (operands[1]) == MEM);
10789 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10791 operands[1] = XEXP (operands[1], 0);
10793 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10795 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10799 if (DEFAULT_ABI == ABI_V4)
10801 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10806 (define_insn "*sibcall_local32"
10807 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10809 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10811 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10813 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10814 output_asm_insn ("crxor 6,6,6", operands);
10816 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10817 output_asm_insn ("creqv 6,6,6", operands);
10819 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10821 [(set_attr "type" "branch")
10822 (set_attr "length" "4,8")])
10824 (define_insn "*sibcall_local64"
10825 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10827 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10829 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10831 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10832 output_asm_insn ("crxor 6,6,6", operands);
10834 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10835 output_asm_insn ("creqv 6,6,6", operands);
10837 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10839 [(set_attr "type" "branch")
10840 (set_attr "length" "4,8")])
10842 (define_insn "*sibcall_value_local32"
10843 [(set (match_operand 0 "" "")
10844 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10845 (match_operand 2)))
10846 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10848 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10850 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10851 output_asm_insn ("crxor 6,6,6", operands);
10853 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10854 output_asm_insn ("creqv 6,6,6", operands);
10856 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10858 [(set_attr "type" "branch")
10859 (set_attr "length" "4,8")])
10861 (define_insn "*sibcall_value_local64"
10862 [(set (match_operand 0 "" "")
10863 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10864 (match_operand 2)))
10865 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10867 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10869 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10870 output_asm_insn ("crxor 6,6,6", operands);
10872 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10873 output_asm_insn ("creqv 6,6,6", operands);
10875 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10877 [(set_attr "type" "branch")
10878 (set_attr "length" "4,8")])
10880 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10881 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10883 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10885 "DEFAULT_ABI == ABI_V4
10886 || DEFAULT_ABI == ABI_DARWIN"
10888 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10889 output_asm_insn ("crxor 6,6,6", operands);
10891 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10892 output_asm_insn ("creqv 6,6,6", operands);
10894 return rs6000_indirect_sibcall_template (operands, 0);
10896 [(set_attr "type" "jmpreg")
10897 (set (attr "length")
10898 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10899 (match_test "which_alternative != 1"))
10900 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10901 (const_string "12")
10902 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10903 (match_test "which_alternative != 1"))
10904 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10905 (const_string "8")]
10906 (const_string "4")))])
10908 (define_insn "*sibcall_nonlocal_sysv<mode>"
10909 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10911 (use (match_operand 2 "immediate_operand" "O,n"))
10913 "(DEFAULT_ABI == ABI_DARWIN
10914 || DEFAULT_ABI == ABI_V4)
10915 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10917 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10918 output_asm_insn ("crxor 6,6,6", operands);
10920 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10921 output_asm_insn ("creqv 6,6,6", operands);
10923 return rs6000_sibcall_template (operands, 0);
10925 [(set_attr "type" "branch")
10926 (set_attr "length" "4,8")])
10928 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
10929 [(set (match_operand 0 "" "")
10930 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10931 (match_operand 2)))
10932 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10934 "DEFAULT_ABI == ABI_V4
10935 || DEFAULT_ABI == ABI_DARWIN"
10937 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10938 output_asm_insn ("crxor 6,6,6", operands);
10940 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10941 output_asm_insn ("creqv 6,6,6", operands);
10943 return rs6000_indirect_sibcall_template (operands, 1);
10945 [(set_attr "type" "jmpreg")
10946 (set (attr "length")
10947 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10948 (match_test "which_alternative != 1"))
10949 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10950 (const_string "12")
10951 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10952 (match_test "which_alternative != 1"))
10953 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10954 (const_string "8")]
10955 (const_string "4")))])
10957 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10958 [(set (match_operand 0 "" "")
10959 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10960 (match_operand 2)))
10961 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10963 "(DEFAULT_ABI == ABI_DARWIN
10964 || DEFAULT_ABI == ABI_V4)
10965 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10967 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10968 output_asm_insn ("crxor 6,6,6", operands);
10970 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10971 output_asm_insn ("creqv 6,6,6", operands);
10973 return rs6000_sibcall_template (operands, 1);
10975 [(set_attr "type" "branch")
10976 (set_attr "length" "4,8")])
10978 ;; AIX ABI sibling call patterns.
10980 (define_insn "*sibcall_aix<mode>"
10981 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10984 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10986 if (which_alternative == 0)
10987 return rs6000_sibcall_template (operands, 0);
10991 [(set_attr "type" "branch")])
10993 (define_insn "*sibcall_value_aix<mode>"
10994 [(set (match_operand 0 "" "")
10995 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10996 (match_operand 2)))
10998 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11000 if (which_alternative == 0)
11001 return rs6000_sibcall_template (operands, 1);
11005 [(set_attr "type" "branch")])
11007 (define_expand "sibcall_epilogue"
11008 [(use (const_int 0))]
11011 if (!TARGET_SCHED_PROLOG)
11012 emit_insn (gen_blockage ());
11013 rs6000_emit_epilogue (TRUE);
11017 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11018 ;; all of memory. This blocks insns from being moved across this point.
11020 (define_insn "blockage"
11021 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11024 [(set_attr "length" "0")])
11026 (define_expand "probe_stack_address"
11027 [(use (match_operand 0 "address_operand"))]
11030 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11031 MEM_VOLATILE_P (operands[0]) = 1;
11034 emit_insn (gen_probe_stack_di (operands[0]));
11036 emit_insn (gen_probe_stack_si (operands[0]));
11040 (define_insn "probe_stack_<mode>"
11041 [(set (match_operand:P 0 "memory_operand" "=m")
11042 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11045 operands[1] = gen_rtx_REG (Pmode, 0);
11046 return "st<wd>%U0%X0 %1,%0";
11048 [(set_attr "type" "store")
11049 (set (attr "update")
11050 (if_then_else (match_operand 0 "update_address_mem")
11051 (const_string "yes")
11052 (const_string "no")))
11053 (set (attr "indexed")
11054 (if_then_else (match_operand 0 "indexed_address_mem")
11055 (const_string "yes")
11056 (const_string "no")))])
11058 (define_insn "probe_stack_range<P:mode>"
11059 [(set (match_operand:P 0 "register_operand" "=&r")
11060 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11061 (match_operand:P 2 "register_operand" "r")
11062 (match_operand:P 3 "register_operand" "r")]
11063 UNSPECV_PROBE_STACK_RANGE))]
11065 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11066 [(set_attr "type" "three")])
11068 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11069 ;; signed & unsigned, and one type of branch.
11071 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11072 ;; insns, and branches.
11074 (define_expand "cbranch<mode>4"
11075 [(use (match_operator 0 "comparison_operator"
11076 [(match_operand:GPR 1 "gpc_reg_operand")
11077 (match_operand:GPR 2 "reg_or_short_operand")]))
11078 (use (match_operand 3))]
11081 /* Take care of the possibility that operands[2] might be negative but
11082 this might be a logical operation. That insn doesn't exist. */
11083 if (GET_CODE (operands[2]) == CONST_INT
11084 && INTVAL (operands[2]) < 0)
11086 operands[2] = force_reg (<MODE>mode, operands[2]);
11087 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11088 GET_MODE (operands[0]),
11089 operands[1], operands[2]);
11092 rs6000_emit_cbranch (<MODE>mode, operands);
11096 (define_expand "cbranch<mode>4"
11097 [(use (match_operator 0 "comparison_operator"
11098 [(match_operand:FP 1 "gpc_reg_operand")
11099 (match_operand:FP 2 "gpc_reg_operand")]))
11100 (use (match_operand 3))]
11103 rs6000_emit_cbranch (<MODE>mode, operands);
11107 (define_expand "cstore<mode>4_signed"
11108 [(use (match_operator 1 "signed_comparison_operator"
11109 [(match_operand:P 2 "gpc_reg_operand")
11110 (match_operand:P 3 "gpc_reg_operand")]))
11111 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11114 enum rtx_code cond_code = GET_CODE (operands[1]);
11116 rtx op0 = operands[0];
11117 rtx op1 = operands[2];
11118 rtx op2 = operands[3];
11120 if (cond_code == GE || cond_code == LT)
11122 cond_code = swap_condition (cond_code);
11123 std::swap (op1, op2);
11126 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11127 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11128 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11130 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11131 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11132 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11134 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11136 if (cond_code == LE)
11137 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11140 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11141 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11142 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11148 (define_expand "cstore<mode>4_unsigned"
11149 [(use (match_operator 1 "unsigned_comparison_operator"
11150 [(match_operand:P 2 "gpc_reg_operand")
11151 (match_operand:P 3 "reg_or_short_operand")]))
11152 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11155 enum rtx_code cond_code = GET_CODE (operands[1]);
11157 rtx op0 = operands[0];
11158 rtx op1 = operands[2];
11159 rtx op2 = operands[3];
11161 if (cond_code == GEU || cond_code == LTU)
11163 cond_code = swap_condition (cond_code);
11164 std::swap (op1, op2);
11167 if (!gpc_reg_operand (op1, <MODE>mode))
11168 op1 = force_reg (<MODE>mode, op1);
11169 if (!reg_or_short_operand (op2, <MODE>mode))
11170 op2 = force_reg (<MODE>mode, op2);
11172 rtx tmp = gen_reg_rtx (<MODE>mode);
11173 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11175 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11176 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11178 if (cond_code == LEU)
11179 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11181 emit_insn (gen_neg<mode>2 (op0, tmp2));
11186 (define_expand "cstore_si_as_di"
11187 [(use (match_operator 1 "unsigned_comparison_operator"
11188 [(match_operand:SI 2 "gpc_reg_operand")
11189 (match_operand:SI 3 "reg_or_short_operand")]))
11190 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11193 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11194 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11196 operands[2] = force_reg (SImode, operands[2]);
11197 operands[3] = force_reg (SImode, operands[3]);
11198 rtx op1 = gen_reg_rtx (DImode);
11199 rtx op2 = gen_reg_rtx (DImode);
11200 convert_move (op1, operands[2], uns_flag);
11201 convert_move (op2, operands[3], uns_flag);
11203 if (cond_code == GT || cond_code == LE)
11205 cond_code = swap_condition (cond_code);
11206 std::swap (op1, op2);
11209 rtx tmp = gen_reg_rtx (DImode);
11210 rtx tmp2 = gen_reg_rtx (DImode);
11211 emit_insn (gen_subdi3 (tmp, op1, op2));
11212 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11218 gcc_unreachable ();
11223 tmp3 = gen_reg_rtx (DImode);
11224 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11228 convert_move (operands[0], tmp3, 1);
11233 (define_expand "cstore<mode>4_signed_imm"
11234 [(use (match_operator 1 "signed_comparison_operator"
11235 [(match_operand:GPR 2 "gpc_reg_operand")
11236 (match_operand:GPR 3 "immediate_operand")]))
11237 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11240 bool invert = false;
11242 enum rtx_code cond_code = GET_CODE (operands[1]);
11244 rtx op0 = operands[0];
11245 rtx op1 = operands[2];
11246 HOST_WIDE_INT val = INTVAL (operands[3]);
11248 if (cond_code == GE || cond_code == GT)
11250 cond_code = reverse_condition (cond_code);
11254 if (cond_code == LE)
11257 rtx tmp = gen_reg_rtx (<MODE>mode);
11258 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11259 rtx x = gen_reg_rtx (<MODE>mode);
11261 emit_insn (gen_and<mode>3 (x, op1, tmp));
11263 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11267 rtx tmp = gen_reg_rtx (<MODE>mode);
11268 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11272 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11273 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11278 (define_expand "cstore<mode>4_unsigned_imm"
11279 [(use (match_operator 1 "unsigned_comparison_operator"
11280 [(match_operand:GPR 2 "gpc_reg_operand")
11281 (match_operand:GPR 3 "immediate_operand")]))
11282 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11285 bool invert = false;
11287 enum rtx_code cond_code = GET_CODE (operands[1]);
11289 rtx op0 = operands[0];
11290 rtx op1 = operands[2];
11291 HOST_WIDE_INT val = INTVAL (operands[3]);
11293 if (cond_code == GEU || cond_code == GTU)
11295 cond_code = reverse_condition (cond_code);
11299 if (cond_code == LEU)
11302 rtx tmp = gen_reg_rtx (<MODE>mode);
11303 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11304 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11305 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11306 rtx x = gen_reg_rtx (<MODE>mode);
11308 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11310 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11314 rtx tmp = gen_reg_rtx (<MODE>mode);
11315 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11319 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11320 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11325 (define_expand "cstore<mode>4"
11326 [(use (match_operator 1 "comparison_operator"
11327 [(match_operand:GPR 2 "gpc_reg_operand")
11328 (match_operand:GPR 3 "reg_or_short_operand")]))
11329 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11332 /* Expanding EQ and NE directly to some machine instructions does not help
11333 but does hurt combine. So don't. */
11334 if (GET_CODE (operands[1]) == EQ)
11335 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11336 else if (<MODE>mode == Pmode
11337 && GET_CODE (operands[1]) == NE)
11338 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11339 else if (GET_CODE (operands[1]) == NE)
11341 rtx tmp = gen_reg_rtx (<MODE>mode);
11342 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11343 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11346 /* If ISEL is fast, expand to it. */
11347 else if (TARGET_ISEL)
11348 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11350 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11351 etc. combinations magically work out just right. */
11352 else if (<MODE>mode == Pmode
11353 && unsigned_comparison_operator (operands[1], VOIDmode))
11354 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11355 operands[2], operands[3]));
11357 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11358 else if (<MODE>mode == SImode && Pmode == DImode)
11359 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11360 operands[2], operands[3]));
11362 /* For signed comparisons against a constant, we can do some simple
11364 else if (signed_comparison_operator (operands[1], VOIDmode)
11365 && CONST_INT_P (operands[3]))
11366 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11367 operands[2], operands[3]));
11369 /* And similarly for unsigned comparisons. */
11370 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11371 && CONST_INT_P (operands[3]))
11372 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11373 operands[2], operands[3]));
11375 /* We also do not want to use mfcr for signed comparisons. */
11376 else if (<MODE>mode == Pmode
11377 && signed_comparison_operator (operands[1], VOIDmode))
11378 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11379 operands[2], operands[3]));
11381 /* Everything else, use the mfcr brute force. */
11383 rs6000_emit_sCOND (<MODE>mode, operands);
11388 (define_expand "cstore<mode>4"
11389 [(use (match_operator 1 "comparison_operator"
11390 [(match_operand:FP 2 "gpc_reg_operand")
11391 (match_operand:FP 3 "gpc_reg_operand")]))
11392 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11395 rs6000_emit_sCOND (<MODE>mode, operands);
11400 (define_expand "stack_protect_set"
11401 [(match_operand 0 "memory_operand")
11402 (match_operand 1 "memory_operand")]
11405 if (rs6000_stack_protector_guard == SSP_TLS)
11407 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11408 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11409 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11410 operands[1] = gen_rtx_MEM (Pmode, addr);
11414 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11416 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11421 (define_insn "stack_protect_setsi"
11422 [(set (match_operand:SI 0 "memory_operand" "=m")
11423 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11424 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11426 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11427 [(set_attr "type" "three")
11428 (set_attr "length" "12")])
11430 (define_insn "stack_protect_setdi"
11431 [(set (match_operand:DI 0 "memory_operand" "=Y")
11432 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11433 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11435 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11436 [(set_attr "type" "three")
11437 (set_attr "length" "12")])
11439 (define_expand "stack_protect_test"
11440 [(match_operand 0 "memory_operand")
11441 (match_operand 1 "memory_operand")
11442 (match_operand 2 "")]
11445 rtx guard = operands[1];
11447 if (rs6000_stack_protector_guard == SSP_TLS)
11449 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11450 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11451 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11452 guard = gen_rtx_MEM (Pmode, addr);
11455 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11456 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11457 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11458 emit_jump_insn (jump);
11463 (define_insn "stack_protect_testsi"
11464 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11465 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11466 (match_operand:SI 2 "memory_operand" "m,m")]
11468 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11469 (clobber (match_scratch:SI 3 "=&r,&r"))]
11472 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11473 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11474 [(set_attr "length" "16,20")])
11476 (define_insn "stack_protect_testdi"
11477 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11478 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11479 (match_operand:DI 2 "memory_operand" "Y,Y")]
11481 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11482 (clobber (match_scratch:DI 3 "=&r,&r"))]
11485 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11486 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11487 [(set_attr "length" "16,20")])
11490 ;; Here are the actual compare insns.
11491 (define_insn "*cmp<mode>_signed"
11492 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11493 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11494 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11496 "cmp<wd>%I2 %0,%1,%2"
11497 [(set_attr "type" "cmp")])
11499 (define_insn "*cmp<mode>_unsigned"
11500 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11501 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11502 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11504 "cmpl<wd>%I2 %0,%1,%2"
11505 [(set_attr "type" "cmp")])
11507 ;; If we are comparing a register for equality with a large constant,
11508 ;; we can do this with an XOR followed by a compare. But this is profitable
11509 ;; only if the large constant is only used for the comparison (and in this
11510 ;; case we already have a register to reuse as scratch).
11512 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11513 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11516 [(set (match_operand:SI 0 "register_operand")
11517 (match_operand:SI 1 "logical_const_operand"))
11518 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11520 (match_operand:SI 2 "logical_const_operand")]))
11521 (set (match_operand:CC 4 "cc_reg_operand")
11522 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11525 (if_then_else (match_operator 6 "equality_operator"
11526 [(match_dup 4) (const_int 0)])
11527 (match_operand 7 "")
11528 (match_operand 8 "")))]
11529 "peep2_reg_dead_p (3, operands[0])
11530 && peep2_reg_dead_p (4, operands[4])
11531 && REGNO (operands[0]) != REGNO (operands[5])"
11532 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11533 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11534 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11537 /* Get the constant we are comparing against, and see what it looks like
11538 when sign-extended from 16 to 32 bits. Then see what constant we could
11539 XOR with SEXTC to get the sign-extended value. */
11540 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11542 operands[1], operands[2]);
11543 HOST_WIDE_INT c = INTVAL (cnst);
11544 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11545 HOST_WIDE_INT xorv = c ^ sextc;
11547 operands[9] = GEN_INT (xorv);
11548 operands[10] = GEN_INT (sextc);
11551 ;; Only need to compare second words if first words equal
11552 (define_insn "*cmp<mode>_internal1"
11553 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11554 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11555 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11556 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11557 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11558 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11559 [(set_attr "type" "fpcompare")
11560 (set_attr "length" "12")])
11562 (define_insn_and_split "*cmp<mode>_internal2"
11563 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11564 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11565 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11566 (clobber (match_scratch:DF 3 "=d"))
11567 (clobber (match_scratch:DF 4 "=d"))
11568 (clobber (match_scratch:DF 5 "=d"))
11569 (clobber (match_scratch:DF 6 "=d"))
11570 (clobber (match_scratch:DF 7 "=d"))
11571 (clobber (match_scratch:DF 8 "=d"))
11572 (clobber (match_scratch:DF 9 "=d"))
11573 (clobber (match_scratch:DF 10 "=d"))
11574 (clobber (match_scratch:GPR 11 "=b"))]
11575 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11576 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11578 "&& reload_completed"
11579 [(set (match_dup 3) (match_dup 14))
11580 (set (match_dup 4) (match_dup 15))
11581 (set (match_dup 9) (abs:DF (match_dup 5)))
11582 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11583 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11584 (label_ref (match_dup 12))
11586 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11587 (set (pc) (label_ref (match_dup 13)))
11589 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11590 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11591 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11592 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11595 REAL_VALUE_TYPE rv;
11596 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11597 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11599 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11600 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11601 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11602 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11603 operands[12] = gen_label_rtx ();
11604 operands[13] = gen_label_rtx ();
11606 operands[14] = force_const_mem (DFmode,
11607 const_double_from_real_value (rv, DFmode));
11608 operands[15] = force_const_mem (DFmode,
11609 const_double_from_real_value (dconst0,
11614 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11615 operands[14] = gen_const_mem (DFmode, tocref);
11616 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11617 operands[15] = gen_const_mem (DFmode, tocref);
11618 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11619 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11623 ;; Now we have the scc insns. We can do some combinations because of the
11624 ;; way the machine works.
11626 ;; Note that this is probably faster if we can put an insn between the
11627 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11628 ;; cases the insns below which don't use an intermediate CR field will
11629 ;; be used instead.
11631 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11632 (match_operator:GPR 1 "scc_comparison_operator"
11633 [(match_operand 2 "cc_reg_operand" "y")
11636 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11637 [(set (attr "type")
11638 (cond [(match_test "TARGET_MFCRF")
11639 (const_string "mfcrf")
11641 (const_string "mfcr")))
11642 (set_attr "length" "8")])
11644 (define_insn_and_split ""
11645 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11646 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11647 [(match_operand 2 "cc_reg_operand" "y,y")
11650 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11651 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11654 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11656 "&& reload_completed"
11657 [(set (match_dup 3)
11658 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11660 (compare:CC (match_dup 3)
11663 [(set_attr "type" "shift")
11664 (set_attr "dot" "yes")
11665 (set_attr "length" "8,16")])
11668 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11669 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11670 [(match_operand 2 "cc_reg_operand" "y")
11672 (match_operand:SI 3 "const_int_operand" "n")))]
11675 int is_bit = ccr_bit (operands[1], 1);
11676 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11679 if (is_bit >= put_bit)
11680 count = is_bit - put_bit;
11682 count = 32 - (put_bit - is_bit);
11684 operands[4] = GEN_INT (count);
11685 operands[5] = GEN_INT (put_bit);
11687 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11689 [(set (attr "type")
11690 (cond [(match_test "TARGET_MFCRF")
11691 (const_string "mfcrf")
11693 (const_string "mfcr")))
11694 (set_attr "length" "8")])
11697 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11699 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11700 [(match_operand 2 "cc_reg_operand" "y,y")
11702 (match_operand:SI 3 "const_int_operand" "n,n"))
11704 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11705 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11709 int is_bit = ccr_bit (operands[1], 1);
11710 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11713 /* Force split for non-cc0 compare. */
11714 if (which_alternative == 1)
11717 if (is_bit >= put_bit)
11718 count = is_bit - put_bit;
11720 count = 32 - (put_bit - is_bit);
11722 operands[5] = GEN_INT (count);
11723 operands[6] = GEN_INT (put_bit);
11725 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11727 [(set_attr "type" "shift")
11728 (set_attr "dot" "yes")
11729 (set_attr "length" "8,16")])
11732 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11734 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11735 [(match_operand 2 "cc_reg_operand")
11737 (match_operand:SI 3 "const_int_operand"))
11739 (set (match_operand:SI 4 "gpc_reg_operand")
11740 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11743 [(set (match_dup 4)
11744 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11747 (compare:CC (match_dup 4)
11752 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11753 (define_code_attr UNS [(eq "CC")
11755 (lt "CC") (ltu "CCUNS")
11756 (gt "CC") (gtu "CCUNS")
11757 (le "CC") (leu "CCUNS")
11758 (ge "CC") (geu "CCUNS")])
11759 (define_code_attr UNSu_ [(eq "")
11764 (ge "") (geu "u_")])
11765 (define_code_attr UNSIK [(eq "I")
11770 (ge "I") (geu "K")])
11772 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11773 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11774 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11775 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11776 (clobber (match_scratch:GPR 3 "=r"))
11777 (clobber (match_scratch:GPR 4 "=r"))
11778 (clobber (match_scratch:<UNS> 5 "=y"))]
11780 && !(<CODE> == EQ && operands[2] == const0_rtx)
11781 && !(<CODE> == NE && operands[2] == const0_rtx
11782 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11787 rtx_code code = <CODE>;
11788 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11790 HOST_WIDE_INT val = INTVAL (operands[2]);
11791 if (code == LT && val != -0x8000)
11796 if (code == GT && val != 0x7fff)
11801 if (code == LTU && val != 0)
11806 if (code == GTU && val != 0xffff)
11811 operands[2] = GEN_INT (val);
11814 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11815 operands[3] = const0_rtx;
11818 if (GET_CODE (operands[3]) == SCRATCH)
11819 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11820 emit_move_insn (operands[3], const0_rtx);
11823 if (GET_CODE (operands[4]) == SCRATCH)
11824 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11825 emit_move_insn (operands[4], const1_rtx);
11827 if (GET_CODE (operands[5]) == SCRATCH)
11828 operands[5] = gen_reg_rtx (<UNS>mode);
11830 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11831 emit_insn (gen_rtx_SET (operands[5], c1));
11833 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11834 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11835 emit_move_insn (operands[0], x);
11839 [(set (attr "cost")
11840 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11842 || <CODE> == LE || <CODE> == GE
11843 || <CODE> == LEU || <CODE> == GEU")
11845 (const_string "10")))])
11847 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11850 (define_expand "eq<mode>3"
11852 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11853 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11854 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11855 (clobber (match_scratch:GPR 3 "=r"))
11856 (clobber (match_scratch:GPR 4 "=r"))])]
11859 if (TARGET_ISEL && operands[2] != const0_rtx)
11861 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11867 (define_insn_and_split "*eq<mode>3"
11868 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11869 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11870 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11871 (clobber (match_scratch:GPR 3 "=r"))
11872 (clobber (match_scratch:GPR 4 "=r"))]
11873 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11876 [(set (match_dup 4)
11877 (clz:GPR (match_dup 3)))
11879 (lshiftrt:GPR (match_dup 4)
11882 operands[3] = rs6000_emit_eqne (<MODE>mode,
11883 operands[1], operands[2], operands[3]);
11885 if (GET_CODE (operands[4]) == SCRATCH)
11886 operands[4] = gen_reg_rtx (<MODE>mode);
11888 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11890 [(set (attr "length")
11891 (if_then_else (match_test "operands[2] == const0_rtx")
11893 (const_string "12")))])
11895 (define_expand "ne<mode>3"
11897 (set (match_operand:P 0 "gpc_reg_operand" "=r")
11898 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11899 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11900 (clobber (match_scratch:P 3 "=r"))
11901 (clobber (match_scratch:P 4 "=r"))
11902 (clobber (reg:P CA_REGNO))])]
11905 if (TARGET_ISEL && operands[2] != const0_rtx)
11907 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11913 (define_insn_and_split "*ne<mode>3"
11914 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11915 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11916 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11917 (clobber (match_scratch:P 3 "=r"))
11918 (clobber (match_scratch:P 4 "=r"))
11919 (clobber (reg:P CA_REGNO))]
11920 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11923 [(parallel [(set (match_dup 4)
11924 (plus:P (match_dup 3)
11926 (set (reg:P CA_REGNO)
11927 (ne:P (match_dup 3)
11929 (parallel [(set (match_dup 0)
11930 (plus:P (plus:P (not:P (match_dup 4))
11933 (clobber (reg:P CA_REGNO))])]
11935 operands[3] = rs6000_emit_eqne (<MODE>mode,
11936 operands[1], operands[2], operands[3]);
11938 if (GET_CODE (operands[4]) == SCRATCH)
11939 operands[4] = gen_reg_rtx (<MODE>mode);
11941 [(set (attr "length")
11942 (if_then_else (match_test "operands[2] == const0_rtx")
11944 (const_string "12")))])
11946 (define_insn_and_split "*neg_eq_<mode>"
11947 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11948 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11949 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11950 (clobber (match_scratch:P 3 "=r"))
11951 (clobber (match_scratch:P 4 "=r"))
11952 (clobber (reg:P CA_REGNO))]
11956 [(parallel [(set (match_dup 4)
11957 (plus:P (match_dup 3)
11959 (set (reg:P CA_REGNO)
11960 (ne:P (match_dup 3)
11962 (parallel [(set (match_dup 0)
11963 (plus:P (reg:P CA_REGNO)
11965 (clobber (reg:P CA_REGNO))])]
11967 operands[3] = rs6000_emit_eqne (<MODE>mode,
11968 operands[1], operands[2], operands[3]);
11970 if (GET_CODE (operands[4]) == SCRATCH)
11971 operands[4] = gen_reg_rtx (<MODE>mode);
11973 [(set (attr "length")
11974 (if_then_else (match_test "operands[2] == const0_rtx")
11976 (const_string "12")))])
11978 (define_insn_and_split "*neg_ne_<mode>"
11979 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11980 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11981 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11982 (clobber (match_scratch:P 3 "=r"))
11983 (clobber (match_scratch:P 4 "=r"))
11984 (clobber (reg:P CA_REGNO))]
11988 [(parallel [(set (match_dup 4)
11989 (neg:P (match_dup 3)))
11990 (set (reg:P CA_REGNO)
11991 (eq:P (match_dup 3)
11993 (parallel [(set (match_dup 0)
11994 (plus:P (reg:P CA_REGNO)
11996 (clobber (reg:P CA_REGNO))])]
11998 operands[3] = rs6000_emit_eqne (<MODE>mode,
11999 operands[1], operands[2], operands[3]);
12001 if (GET_CODE (operands[4]) == SCRATCH)
12002 operands[4] = gen_reg_rtx (<MODE>mode);
12004 [(set (attr "length")
12005 (if_then_else (match_test "operands[2] == const0_rtx")
12007 (const_string "12")))])
12009 (define_insn_and_split "*plus_eq_<mode>"
12010 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12011 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12012 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12013 (match_operand:P 3 "gpc_reg_operand" "r")))
12014 (clobber (match_scratch:P 4 "=r"))
12015 (clobber (match_scratch:P 5 "=r"))
12016 (clobber (reg:P CA_REGNO))]
12020 [(parallel [(set (match_dup 5)
12021 (neg:P (match_dup 4)))
12022 (set (reg:P CA_REGNO)
12023 (eq:P (match_dup 4)
12025 (parallel [(set (match_dup 0)
12026 (plus:P (match_dup 3)
12028 (clobber (reg:P CA_REGNO))])]
12030 operands[4] = rs6000_emit_eqne (<MODE>mode,
12031 operands[1], operands[2], operands[4]);
12033 if (GET_CODE (operands[5]) == SCRATCH)
12034 operands[5] = gen_reg_rtx (<MODE>mode);
12036 [(set (attr "length")
12037 (if_then_else (match_test "operands[2] == const0_rtx")
12039 (const_string "12")))])
12041 (define_insn_and_split "*plus_ne_<mode>"
12042 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12043 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12044 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12045 (match_operand:P 3 "gpc_reg_operand" "r")))
12046 (clobber (match_scratch:P 4 "=r"))
12047 (clobber (match_scratch:P 5 "=r"))
12048 (clobber (reg:P CA_REGNO))]
12052 [(parallel [(set (match_dup 5)
12053 (plus:P (match_dup 4)
12055 (set (reg:P CA_REGNO)
12056 (ne:P (match_dup 4)
12058 (parallel [(set (match_dup 0)
12059 (plus:P (match_dup 3)
12061 (clobber (reg:P CA_REGNO))])]
12063 operands[4] = rs6000_emit_eqne (<MODE>mode,
12064 operands[1], operands[2], operands[4]);
12066 if (GET_CODE (operands[5]) == SCRATCH)
12067 operands[5] = gen_reg_rtx (<MODE>mode);
12069 [(set (attr "length")
12070 (if_then_else (match_test "operands[2] == const0_rtx")
12072 (const_string "12")))])
12074 (define_insn_and_split "*minus_eq_<mode>"
12075 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12076 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12077 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12078 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12079 (clobber (match_scratch:P 4 "=r"))
12080 (clobber (match_scratch:P 5 "=r"))
12081 (clobber (reg:P CA_REGNO))]
12085 [(parallel [(set (match_dup 5)
12086 (plus:P (match_dup 4)
12088 (set (reg:P CA_REGNO)
12089 (ne:P (match_dup 4)
12091 (parallel [(set (match_dup 0)
12092 (plus:P (plus:P (match_dup 3)
12095 (clobber (reg:P CA_REGNO))])]
12097 operands[4] = rs6000_emit_eqne (<MODE>mode,
12098 operands[1], operands[2], operands[4]);
12100 if (GET_CODE (operands[5]) == SCRATCH)
12101 operands[5] = gen_reg_rtx (<MODE>mode);
12103 [(set (attr "length")
12104 (if_then_else (match_test "operands[2] == const0_rtx")
12106 (const_string "12")))])
12108 (define_insn_and_split "*minus_ne_<mode>"
12109 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12110 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12111 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12112 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12113 (clobber (match_scratch:P 4 "=r"))
12114 (clobber (match_scratch:P 5 "=r"))
12115 (clobber (reg:P CA_REGNO))]
12119 [(parallel [(set (match_dup 5)
12120 (neg:P (match_dup 4)))
12121 (set (reg:P CA_REGNO)
12122 (eq:P (match_dup 4)
12124 (parallel [(set (match_dup 0)
12125 (plus:P (plus:P (match_dup 3)
12128 (clobber (reg:P CA_REGNO))])]
12130 operands[4] = rs6000_emit_eqne (<MODE>mode,
12131 operands[1], operands[2], operands[4]);
12133 if (GET_CODE (operands[5]) == SCRATCH)
12134 operands[5] = gen_reg_rtx (<MODE>mode);
12136 [(set (attr "length")
12137 (if_then_else (match_test "operands[2] == const0_rtx")
12139 (const_string "12")))])
12141 (define_insn_and_split "*eqsi3_ext<mode>"
12142 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12143 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12144 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12145 (clobber (match_scratch:SI 3 "=r"))
12146 (clobber (match_scratch:SI 4 "=r"))]
12150 [(set (match_dup 4)
12151 (clz:SI (match_dup 3)))
12154 (lshiftrt:SI (match_dup 4)
12157 operands[3] = rs6000_emit_eqne (SImode,
12158 operands[1], operands[2], operands[3]);
12160 if (GET_CODE (operands[4]) == SCRATCH)
12161 operands[4] = gen_reg_rtx (SImode);
12163 [(set (attr "length")
12164 (if_then_else (match_test "operands[2] == const0_rtx")
12166 (const_string "12")))])
12168 (define_insn_and_split "*nesi3_ext<mode>"
12169 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12170 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12171 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12172 (clobber (match_scratch:SI 3 "=r"))
12173 (clobber (match_scratch:SI 4 "=r"))
12174 (clobber (match_scratch:EXTSI 5 "=r"))]
12178 [(set (match_dup 4)
12179 (clz:SI (match_dup 3)))
12182 (lshiftrt:SI (match_dup 4)
12185 (xor:EXTSI (match_dup 5)
12188 operands[3] = rs6000_emit_eqne (SImode,
12189 operands[1], operands[2], operands[3]);
12191 if (GET_CODE (operands[4]) == SCRATCH)
12192 operands[4] = gen_reg_rtx (SImode);
12193 if (GET_CODE (operands[5]) == SCRATCH)
12194 operands[5] = gen_reg_rtx (<MODE>mode);
12196 [(set (attr "length")
12197 (if_then_else (match_test "operands[2] == const0_rtx")
12198 (const_string "12")
12199 (const_string "16")))])
12201 ;; Conditional branches.
12202 ;; These either are a single bc insn, or a bc around a b.
12204 (define_insn "*cbranch"
12206 (if_then_else (match_operator 1 "branch_comparison_operator"
12207 [(match_operand 2 "cc_reg_operand" "y")
12209 (label_ref (match_operand 0))
12213 return output_cbranch (operands[1], "%l0", 0, insn);
12215 [(set_attr "type" "branch")
12216 (set (attr "length")
12217 (if_then_else (and (ge (minus (match_dup 0) (pc))
12218 (const_int -32768))
12219 (lt (minus (match_dup 0) (pc))
12220 (const_int 32764)))
12224 ;; Conditional return.
12225 (define_insn "*creturn"
12227 (if_then_else (match_operator 0 "branch_comparison_operator"
12228 [(match_operand 1 "cc_reg_operand" "y")
12234 return output_cbranch (operands[0], NULL, 0, insn);
12236 [(set_attr "type" "jmpreg")])
12238 ;; Logic on condition register values.
12240 ; This pattern matches things like
12241 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12242 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12244 ; which are generated by the branch logic.
12245 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12247 (define_insn "cceq_ior_compare"
12248 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12249 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12250 [(match_operator:SI 2
12251 "branch_positive_comparison_operator"
12253 "cc_reg_operand" "y,y")
12255 (match_operator:SI 4
12256 "branch_positive_comparison_operator"
12258 "cc_reg_operand" "0,y")
12262 "cr%q1 %E0,%j2,%j4"
12263 [(set_attr "type" "cr_logical")
12264 (set_attr "cr_logical_3op" "no,yes")])
12266 ; Why is the constant -1 here, but 1 in the previous pattern?
12267 ; Because ~1 has all but the low bit set.
12268 (define_insn "cceq_ior_compare_complement"
12269 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12270 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12271 [(not:SI (match_operator:SI 2
12272 "branch_positive_comparison_operator"
12274 "cc_reg_operand" "y,y")
12276 (match_operator:SI 4
12277 "branch_positive_comparison_operator"
12279 "cc_reg_operand" "0,y")
12283 "cr%q1 %E0,%j2,%j4"
12284 [(set_attr "type" "cr_logical")
12285 (set_attr "cr_logical_3op" "no,yes")])
12287 (define_insn "*cceq_rev_compare"
12288 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12289 (compare:CCEQ (match_operator:SI 1
12290 "branch_positive_comparison_operator"
12292 "cc_reg_operand" "0,y")
12297 [(set_attr "type" "cr_logical")
12298 (set_attr "cr_logical_3op" "no,yes")])
12300 ;; If we are comparing the result of two comparisons, this can be done
12301 ;; using creqv or crxor.
12303 (define_insn_and_split ""
12304 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12305 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12306 [(match_operand 2 "cc_reg_operand" "y")
12308 (match_operator 3 "branch_comparison_operator"
12309 [(match_operand 4 "cc_reg_operand" "y")
12314 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12317 int positive_1, positive_2;
12319 positive_1 = branch_positive_comparison_operator (operands[1],
12320 GET_MODE (operands[1]));
12321 positive_2 = branch_positive_comparison_operator (operands[3],
12322 GET_MODE (operands[3]));
12325 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12326 GET_CODE (operands[1])),
12328 operands[2], const0_rtx);
12329 else if (GET_MODE (operands[1]) != SImode)
12330 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12331 operands[2], const0_rtx);
12334 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12335 GET_CODE (operands[3])),
12337 operands[4], const0_rtx);
12338 else if (GET_MODE (operands[3]) != SImode)
12339 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12340 operands[4], const0_rtx);
12342 if (positive_1 == positive_2)
12344 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12345 operands[5] = constm1_rtx;
12349 operands[5] = const1_rtx;
12353 ;; Unconditional branch and return.
12355 (define_insn "jump"
12357 (label_ref (match_operand 0)))]
12360 [(set_attr "type" "branch")])
12362 (define_insn "<return_str>return"
12366 [(set_attr "type" "jmpreg")])
12368 (define_expand "indirect_jump"
12369 [(set (pc) (match_operand 0 "register_operand"))]
12372 if (!rs6000_speculate_indirect_jumps) {
12373 rtx ccreg = gen_reg_rtx (CCmode);
12374 if (Pmode == DImode)
12375 emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12377 emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12382 (define_insn "*indirect_jump<mode>"
12384 (match_operand:P 0 "register_operand" "c,*l"))]
12385 "rs6000_speculate_indirect_jumps"
12387 [(set_attr "type" "jmpreg")])
12389 (define_insn "indirect_jump<mode>_nospec"
12390 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12391 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12392 "!rs6000_speculate_indirect_jumps"
12393 "crset %E1\;beq%T0- %1\;b $"
12394 [(set_attr "type" "jmpreg")
12395 (set_attr "length" "12")])
12397 ;; Table jump for switch statements:
12398 (define_expand "tablejump"
12399 [(use (match_operand 0))
12400 (use (label_ref (match_operand 1)))]
12403 if (rs6000_speculate_indirect_jumps)
12406 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12408 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12412 rtx ccreg = gen_reg_rtx (CCmode);
12415 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12417 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12418 emit_jump_insn (jump);
12423 (define_expand "tablejumpsi"
12424 [(set (match_dup 3)
12425 (plus:SI (match_operand:SI 0)
12427 (parallel [(set (pc)
12429 (use (label_ref (match_operand 1)))])]
12430 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12432 operands[0] = force_reg (SImode, operands[0]);
12433 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12434 operands[3] = gen_reg_rtx (SImode);
12437 (define_expand "tablejumpsi_nospec"
12438 [(set (match_dup 4)
12439 (plus:SI (match_operand:SI 0)
12441 (parallel [(set (pc)
12443 (use (label_ref (match_operand 1)))
12444 (clobber (match_operand 2))])]
12445 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12447 operands[0] = force_reg (SImode, operands[0]);
12448 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12449 operands[4] = gen_reg_rtx (SImode);
12452 (define_expand "tablejumpdi"
12453 [(set (match_dup 4)
12454 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12456 (plus:DI (match_dup 4)
12458 (parallel [(set (pc)
12460 (use (label_ref (match_operand 1)))])]
12461 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12463 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12464 operands[3] = gen_reg_rtx (DImode);
12465 operands[4] = gen_reg_rtx (DImode);
12468 (define_expand "tablejumpdi_nospec"
12469 [(set (match_dup 5)
12470 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12472 (plus:DI (match_dup 5)
12474 (parallel [(set (pc)
12476 (use (label_ref (match_operand 1)))
12477 (clobber (match_operand 2))])]
12478 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12480 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12481 operands[4] = gen_reg_rtx (DImode);
12482 operands[5] = gen_reg_rtx (DImode);
12485 (define_insn "*tablejump<mode>_internal1"
12487 (match_operand:P 0 "register_operand" "c,*l"))
12488 (use (label_ref (match_operand 1)))]
12489 "rs6000_speculate_indirect_jumps"
12491 [(set_attr "type" "jmpreg")])
12493 (define_insn "*tablejump<mode>_internal1_nospec"
12495 (match_operand:P 0 "register_operand" "c,*l"))
12496 (use (label_ref (match_operand 1)))
12497 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12498 "!rs6000_speculate_indirect_jumps"
12499 "crset %E2\;beq%T0- %2\;b $"
12500 [(set_attr "type" "jmpreg")
12501 (set_attr "length" "12")])
12504 [(unspec [(const_int 0)] UNSPEC_NOP)]
12508 (define_insn "group_ending_nop"
12509 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12512 if (rs6000_tune == PROCESSOR_POWER6)
12513 return "ori 1,1,0";
12514 return "ori 2,2,0";
12517 (define_insn "speculation_barrier"
12518 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12522 ;; Define the subtract-one-and-jump insns, starting with the template
12523 ;; so loop.c knows what to generate.
12525 (define_expand "doloop_end"
12526 [(use (match_operand 0)) ; loop pseudo
12527 (use (match_operand 1))] ; label
12532 if (GET_MODE (operands[0]) != DImode)
12534 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12538 if (GET_MODE (operands[0]) != SImode)
12540 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12545 (define_expand "ctr<mode>"
12546 [(parallel [(set (pc)
12547 (if_then_else (ne (match_operand:P 0 "register_operand")
12549 (label_ref (match_operand 1))
12552 (plus:P (match_dup 0)
12554 (clobber (match_scratch:CC 2))
12555 (clobber (match_scratch:P 3))])]
12559 ;; We need to be able to do this for any operand, including MEM, or we
12560 ;; will cause reload to blow up since we don't allow output reloads on
12562 ;; For the length attribute to be calculated correctly, the
12563 ;; label MUST be operand 0.
12564 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12565 ;; the ctr<mode> insns.
12567 (define_code_iterator eqne [eq ne])
12568 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12569 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12571 (define_insn "<bd>_<mode>"
12573 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12575 (label_ref (match_operand 0))
12577 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12578 (plus:P (match_dup 1)
12580 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12581 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12584 if (which_alternative != 0)
12586 else if (get_attr_length (insn) == 4)
12589 return "<bd_neg> $+8\;b %l0";
12591 [(set_attr "type" "branch")
12592 (set_attr_alternative "length"
12593 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12594 (const_int -32768))
12595 (lt (minus (match_dup 0) (pc))
12596 (const_int 32764)))
12599 (const_string "16")
12600 (const_string "20")
12601 (const_string "20")])])
12603 ;; Now the splitter if we could not allocate the CTR register
12606 (if_then_else (match_operator 2 "comparison_operator"
12607 [(match_operand:P 1 "gpc_reg_operand")
12610 (match_operand 6)))
12611 (set (match_operand:P 0 "nonimmediate_operand")
12612 (plus:P (match_dup 1)
12614 (clobber (match_scratch:CC 3))
12615 (clobber (match_scratch:P 4))]
12618 (if_then_else (match_dup 7)
12622 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12624 emit_insn (gen_rtx_SET (operands[3],
12625 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12626 if (gpc_reg_operand (operands[0], <MODE>mode))
12627 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12630 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12631 emit_move_insn (operands[0], operands[4]);
12633 /* No DONE so branch comes from the pattern. */
12636 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12637 ;; Note that in the case of long branches we have to decompose this into
12638 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12639 ;; and the CR bit, which means there is no way to conveniently invert the
12640 ;; comparison as is done with plain bdnz/bdz.
12642 (define_insn "<bd>tf_<mode>"
12646 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12648 (match_operator 3 "branch_comparison_operator"
12649 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12651 (label_ref (match_operand 0))
12653 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12654 (plus:P (match_dup 1)
12656 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12657 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12658 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12661 if (which_alternative != 0)
12663 else if (get_attr_length (insn) == 4)
12665 if (branch_positive_comparison_operator (operands[3],
12666 GET_MODE (operands[3])))
12667 return "<bd>t %j3,%l0";
12669 return "<bd>f %j3,%l0";
12673 static char seq[96];
12674 char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12675 sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12679 [(set_attr "type" "branch")
12680 (set_attr_alternative "length"
12681 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12682 (const_int -32768))
12683 (lt (minus (match_dup 0) (pc))
12684 (const_int 32764)))
12687 (const_string "16")
12688 (const_string "20")
12689 (const_string "20")])])
12691 ;; Now the splitter if we could not allocate the CTR register
12696 (match_operator 1 "comparison_operator"
12697 [(match_operand:P 0 "gpc_reg_operand")
12699 (match_operator 3 "branch_comparison_operator"
12700 [(match_operand 2 "cc_reg_operand")
12703 (match_operand 5)))
12704 (set (match_operand:P 6 "int_reg_operand")
12705 (plus:P (match_dup 0)
12707 (clobber (match_scratch:P 7))
12708 (clobber (match_scratch:CC 8))
12709 (clobber (match_scratch:CCEQ 9))]
12713 rtx ctr = operands[0];
12714 rtx ctrcmp = operands[1];
12715 rtx ccin = operands[2];
12716 rtx cccmp = operands[3];
12717 rtx dst1 = operands[4];
12718 rtx dst2 = operands[5];
12719 rtx ctrout = operands[6];
12720 rtx ctrtmp = operands[7];
12721 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12722 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12724 cmpcode = reverse_condition (cmpcode);
12725 /* Generate crand/crandc here. */
12726 emit_insn (gen_rtx_SET (operands[8],
12727 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12728 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12730 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12732 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12733 operands[8], cccmp, ccin));
12735 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12736 operands[8], cccmp, ccin));
12737 if (gpc_reg_operand (operands[0], <MODE>mode))
12738 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12741 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12742 emit_move_insn (ctrout, ctrtmp);
12744 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12745 emit_jump_insn (gen_rtx_SET (pc_rtx,
12746 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12752 (define_insn "trap"
12753 [(trap_if (const_int 1) (const_int 0))]
12756 [(set_attr "type" "trap")])
12758 (define_expand "ctrap<mode>4"
12759 [(trap_if (match_operator 0 "ordered_comparison_operator"
12760 [(match_operand:GPR 1 "register_operand")
12761 (match_operand:GPR 2 "reg_or_short_operand")])
12762 (match_operand 3 "zero_constant" ""))]
12767 [(trap_if (match_operator 0 "ordered_comparison_operator"
12768 [(match_operand:GPR 1 "register_operand" "r")
12769 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12772 "t<wd>%V0%I2 %1,%2"
12773 [(set_attr "type" "trap")])
12775 ;; Insns related to generating the function prologue and epilogue.
12777 (define_expand "prologue"
12778 [(use (const_int 0))]
12781 rs6000_emit_prologue ();
12782 if (!TARGET_SCHED_PROLOG)
12783 emit_insn (gen_blockage ());
12787 (define_insn "*movesi_from_cr_one"
12788 [(match_parallel 0 "mfcr_operation"
12789 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12790 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12791 (match_operand 3 "immediate_operand" "n")]
12792 UNSPEC_MOVESI_FROM_CR))])]
12797 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12799 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12800 operands[4] = GEN_INT (mask);
12801 output_asm_insn ("mfcr %1,%4", operands);
12805 [(set_attr "type" "mfcrf")])
12807 ;; Don't include the volatile CRs since their values are not used wrt CR save
12808 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12809 ;; prologue past an insn (early exit test) that defines a register used in the
12811 (define_insn "prologue_movesi_from_cr"
12812 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12813 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12814 (reg:CC CR4_REGNO)]
12815 UNSPEC_MOVESI_FROM_CR))]
12818 [(set_attr "type" "mfcr")])
12820 (define_insn "*crsave"
12821 [(match_parallel 0 "crsave_operation"
12822 [(set (match_operand:SI 1 "memory_operand" "=m")
12823 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12826 [(set_attr "type" "store")])
12828 (define_insn "*stmw"
12829 [(match_parallel 0 "stmw_operation"
12830 [(set (match_operand:SI 1 "memory_operand" "=m")
12831 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12834 [(set_attr "type" "store")
12835 (set_attr "update" "yes")
12836 (set_attr "indexed" "yes")])
12838 ; The following comment applies to:
12842 ; return_and_restore_gpregs*
12843 ; return_and_restore_fpregs*
12844 ; return_and_restore_fpregs_aix*
12846 ; The out-of-line save / restore functions expects one input argument.
12847 ; Since those are not standard call_insn's, we must avoid using
12848 ; MATCH_OPERAND for that argument. That way the register rename
12849 ; optimization will not try to rename this register.
12850 ; Each pattern is repeated for each possible register number used in
12851 ; various ABIs (r11, r1, and for some functions r12)
12853 (define_insn "*save_gpregs_<mode>_r11"
12854 [(match_parallel 0 "any_parallel_operand"
12855 [(clobber (reg:P LR_REGNO))
12856 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12858 (set (match_operand:P 2 "memory_operand" "=m")
12859 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12862 [(set_attr "type" "branch")])
12864 (define_insn "*save_gpregs_<mode>_r12"
12865 [(match_parallel 0 "any_parallel_operand"
12866 [(clobber (reg:P LR_REGNO))
12867 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12869 (set (match_operand:P 2 "memory_operand" "=m")
12870 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12873 [(set_attr "type" "branch")])
12875 (define_insn "*save_gpregs_<mode>_r1"
12876 [(match_parallel 0 "any_parallel_operand"
12877 [(clobber (reg:P LR_REGNO))
12878 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12880 (set (match_operand:P 2 "memory_operand" "=m")
12881 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12884 [(set_attr "type" "branch")])
12886 (define_insn "*save_fpregs_<mode>_r11"
12887 [(match_parallel 0 "any_parallel_operand"
12888 [(clobber (reg:P LR_REGNO))
12889 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12891 (set (match_operand:DF 2 "memory_operand" "=m")
12892 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12895 [(set_attr "type" "branch")])
12897 (define_insn "*save_fpregs_<mode>_r12"
12898 [(match_parallel 0 "any_parallel_operand"
12899 [(clobber (reg:P LR_REGNO))
12900 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12902 (set (match_operand:DF 2 "memory_operand" "=m")
12903 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12906 [(set_attr "type" "branch")])
12908 (define_insn "*save_fpregs_<mode>_r1"
12909 [(match_parallel 0 "any_parallel_operand"
12910 [(clobber (reg:P LR_REGNO))
12911 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12913 (set (match_operand:DF 2 "memory_operand" "=m")
12914 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12917 [(set_attr "type" "branch")])
12919 ; This is to explain that changes to the stack pointer should
12920 ; not be moved over loads from or stores to stack memory.
12921 (define_insn "stack_tie"
12922 [(match_parallel 0 "tie_operand"
12923 [(set (mem:BLK (reg 1)) (const_int 0))])]
12926 [(set_attr "length" "0")])
12928 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12929 ; stay behind all restores from the stack, it cannot be reordered to before
12930 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
12931 (define_insn "stack_restore_tie"
12932 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12933 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12934 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12935 (set (mem:BLK (scratch)) (const_int 0))]
12940 [(set_attr "type" "*,add")])
12942 (define_expand "epilogue"
12943 [(use (const_int 0))]
12946 if (!TARGET_SCHED_PROLOG)
12947 emit_insn (gen_blockage ());
12948 rs6000_emit_epilogue (FALSE);
12952 ; On some processors, doing the mtcrf one CC register at a time is
12953 ; faster (like on the 604e). On others, doing them all at once is
12954 ; faster; for instance, on the 601 and 750.
12956 (define_expand "movsi_to_cr_one"
12957 [(set (match_operand:CC 0 "cc_reg_operand")
12958 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
12959 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12961 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12963 (define_insn "*movsi_to_cr"
12964 [(match_parallel 0 "mtcrf_operation"
12965 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12966 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12967 (match_operand 3 "immediate_operand" "n")]
12968 UNSPEC_MOVESI_TO_CR))])]
12973 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12974 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12975 operands[4] = GEN_INT (mask);
12976 return "mtcrf %4,%2";
12978 [(set_attr "type" "mtcr")])
12980 (define_insn "*mtcrfsi"
12981 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12982 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12983 (match_operand 2 "immediate_operand" "n")]
12984 UNSPEC_MOVESI_TO_CR))]
12985 "GET_CODE (operands[0]) == REG
12986 && CR_REGNO_P (REGNO (operands[0]))
12987 && GET_CODE (operands[2]) == CONST_INT
12988 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12990 [(set_attr "type" "mtcr")])
12992 ; The load-multiple instructions have similar properties.
12993 ; Note that "load_multiple" is a name known to the machine-independent
12994 ; code that actually corresponds to the PowerPC load-string.
12996 (define_insn "*lmw"
12997 [(match_parallel 0 "lmw_operation"
12998 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12999 (match_operand:SI 2 "memory_operand" "m"))])]
13002 [(set_attr "type" "load")
13003 (set_attr "update" "yes")
13004 (set_attr "indexed" "yes")
13005 (set_attr "cell_micro" "always")])
13007 ; FIXME: "any_parallel_operand" is a bit flexible...
13009 ; The following comment applies to:
13013 ; return_and_restore_gpregs*
13014 ; return_and_restore_fpregs*
13015 ; return_and_restore_fpregs_aix*
13017 ; The out-of-line save / restore functions expects one input argument.
13018 ; Since those are not standard call_insn's, we must avoid using
13019 ; MATCH_OPERAND for that argument. That way the register rename
13020 ; optimization will not try to rename this register.
13021 ; Each pattern is repeated for each possible register number used in
13022 ; various ABIs (r11, r1, and for some functions r12)
13024 (define_insn "*restore_gpregs_<mode>_r11"
13025 [(match_parallel 0 "any_parallel_operand"
13026 [(clobber (reg:P LR_REGNO))
13027 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13029 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13030 (match_operand:P 3 "memory_operand" "m"))])]
13033 [(set_attr "type" "branch")])
13035 (define_insn "*restore_gpregs_<mode>_r12"
13036 [(match_parallel 0 "any_parallel_operand"
13037 [(clobber (reg:P LR_REGNO))
13038 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13040 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13041 (match_operand:P 3 "memory_operand" "m"))])]
13044 [(set_attr "type" "branch")])
13046 (define_insn "*restore_gpregs_<mode>_r1"
13047 [(match_parallel 0 "any_parallel_operand"
13048 [(clobber (reg:P LR_REGNO))
13049 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13051 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13052 (match_operand:P 3 "memory_operand" "m"))])]
13055 [(set_attr "type" "branch")])
13057 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13058 [(match_parallel 0 "any_parallel_operand"
13060 (clobber (reg:P LR_REGNO))
13061 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13063 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13064 (match_operand:P 3 "memory_operand" "m"))])]
13067 [(set_attr "type" "branch")])
13069 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13070 [(match_parallel 0 "any_parallel_operand"
13072 (clobber (reg:P LR_REGNO))
13073 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13075 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13076 (match_operand:P 3 "memory_operand" "m"))])]
13079 [(set_attr "type" "branch")])
13081 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13082 [(match_parallel 0 "any_parallel_operand"
13084 (clobber (reg:P LR_REGNO))
13085 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13087 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13088 (match_operand:P 3 "memory_operand" "m"))])]
13091 [(set_attr "type" "branch")])
13093 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13094 [(match_parallel 0 "any_parallel_operand"
13096 (clobber (reg:P LR_REGNO))
13097 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13099 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13100 (match_operand:DF 3 "memory_operand" "m"))])]
13103 [(set_attr "type" "branch")])
13105 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13106 [(match_parallel 0 "any_parallel_operand"
13108 (clobber (reg:P LR_REGNO))
13109 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13111 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13112 (match_operand:DF 3 "memory_operand" "m"))])]
13115 [(set_attr "type" "branch")])
13117 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13118 [(match_parallel 0 "any_parallel_operand"
13120 (clobber (reg:P LR_REGNO))
13121 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13123 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13124 (match_operand:DF 3 "memory_operand" "m"))])]
13127 [(set_attr "type" "branch")])
13129 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13130 [(match_parallel 0 "any_parallel_operand"
13132 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13134 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13135 (match_operand:DF 3 "memory_operand" "m"))])]
13138 [(set_attr "type" "branch")])
13140 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13141 [(match_parallel 0 "any_parallel_operand"
13143 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13145 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13146 (match_operand:DF 3 "memory_operand" "m"))])]
13149 [(set_attr "type" "branch")])
13151 ; This is used in compiling the unwind routines.
13152 (define_expand "eh_return"
13153 [(use (match_operand 0 "general_operand"))]
13157 emit_insn (gen_eh_set_lr_si (operands[0]));
13159 emit_insn (gen_eh_set_lr_di (operands[0]));
13163 ; We can't expand this before we know where the link register is stored.
13164 (define_insn "eh_set_lr_<mode>"
13165 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13167 (clobber (match_scratch:P 1 "=&b"))]
13172 [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13173 (clobber (match_scratch 1))]
13177 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13181 (define_insn "prefetch"
13182 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13183 (match_operand:SI 1 "const_int_operand" "n")
13184 (match_operand:SI 2 "const_int_operand" "n"))]
13189 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13190 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13191 The AIX assembler does not support the three operand form of dcbt
13192 and dcbtst on Power 7 (-mpwr7). */
13193 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13195 if (REG_P (operands[0]))
13197 if (INTVAL (operands[1]) == 0)
13198 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13200 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13204 if (INTVAL (operands[1]) == 0)
13205 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13207 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13210 [(set_attr "type" "load")])
13212 ;; Handle -fsplit-stack.
13214 (define_expand "split_stack_prologue"
13218 rs6000_expand_split_stack_prologue ();
13222 (define_expand "load_split_stack_limit"
13223 [(set (match_operand 0)
13224 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13227 emit_insn (gen_rtx_SET (operands[0],
13228 gen_rtx_UNSPEC (Pmode,
13229 gen_rtvec (1, const0_rtx),
13230 UNSPEC_STACK_CHECK)));
13234 (define_insn "load_split_stack_limit_di"
13235 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13236 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13238 "ld %0,-0x7040(13)"
13239 [(set_attr "type" "load")
13240 (set_attr "update" "no")
13241 (set_attr "indexed" "no")])
13243 (define_insn "load_split_stack_limit_si"
13244 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13245 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13247 "lwz %0,-0x7020(2)"
13248 [(set_attr "type" "load")
13249 (set_attr "update" "no")
13250 (set_attr "indexed" "no")])
13252 ;; A return instruction which the middle-end doesn't see.
13253 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13254 ;; after the call to __morestack.
13255 (define_insn "split_stack_return"
13256 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13259 [(set_attr "type" "jmpreg")])
13261 ;; If there are operand 0 bytes available on the stack, jump to
13263 (define_expand "split_stack_space_check"
13264 [(set (match_dup 2)
13265 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13267 (minus (reg STACK_POINTER_REGNUM)
13268 (match_operand 0)))
13269 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13270 (set (pc) (if_then_else
13271 (geu (match_dup 4) (const_int 0))
13272 (label_ref (match_operand 1))
13276 rs6000_split_stack_space_check (operands[0], operands[1]);
13280 (define_insn "bpermd_<mode>"
13281 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13282 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13283 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13286 [(set_attr "type" "popcnt")])
13289 ;; Builtin fma support. Handle
13290 ;; Note that the conditions for expansion are in the FMA_F iterator.
13292 (define_expand "fma<mode>4"
13293 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13295 (match_operand:FMA_F 1 "gpc_reg_operand")
13296 (match_operand:FMA_F 2 "gpc_reg_operand")
13297 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13301 (define_insn "*fma<mode>4_fpr"
13302 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13304 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13305 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13306 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13307 "TARGET_HARD_FLOAT"
13309 fmadd<Ftrad> %0,%1,%2,%3
13310 xsmadda<Fvsx> %x0,%x1,%x2
13311 xsmaddm<Fvsx> %x0,%x1,%x3"
13312 [(set_attr "type" "fp")])
13314 ; Altivec only has fma and nfms.
13315 (define_expand "fms<mode>4"
13316 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13318 (match_operand:FMA_F 1 "gpc_reg_operand")
13319 (match_operand:FMA_F 2 "gpc_reg_operand")
13320 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13321 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13324 (define_insn "*fms<mode>4_fpr"
13325 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13327 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13328 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13329 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13330 "TARGET_HARD_FLOAT"
13332 fmsub<Ftrad> %0,%1,%2,%3
13333 xsmsuba<Fvsx> %x0,%x1,%x2
13334 xsmsubm<Fvsx> %x0,%x1,%x3"
13335 [(set_attr "type" "fp")])
13337 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13338 (define_expand "fnma<mode>4"
13339 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13342 (match_operand:FMA_F 1 "gpc_reg_operand")
13343 (match_operand:FMA_F 2 "gpc_reg_operand")
13344 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13345 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13348 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13349 (define_expand "fnms<mode>4"
13350 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13353 (match_operand:FMA_F 1 "gpc_reg_operand")
13354 (match_operand:FMA_F 2 "gpc_reg_operand")
13355 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13356 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13359 ; Not an official optab name, but used from builtins.
13360 (define_expand "nfma<mode>4"
13361 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13364 (match_operand:FMA_F 1 "gpc_reg_operand")
13365 (match_operand:FMA_F 2 "gpc_reg_operand")
13366 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13367 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13370 (define_insn "*nfma<mode>4_fpr"
13371 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13374 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13375 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13376 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13377 "TARGET_HARD_FLOAT"
13379 fnmadd<Ftrad> %0,%1,%2,%3
13380 xsnmadda<Fvsx> %x0,%x1,%x2
13381 xsnmaddm<Fvsx> %x0,%x1,%x3"
13382 [(set_attr "type" "fp")])
13384 ; Not an official optab name, but used from builtins.
13385 (define_expand "nfms<mode>4"
13386 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13389 (match_operand:FMA_F 1 "gpc_reg_operand")
13390 (match_operand:FMA_F 2 "gpc_reg_operand")
13391 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13395 (define_insn "*nfmssf4_fpr"
13396 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13399 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13400 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13402 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13403 "TARGET_HARD_FLOAT"
13405 fnmsub<Ftrad> %0,%1,%2,%3
13406 xsnmsuba<Fvsx> %x0,%x1,%x2
13407 xsnmsubm<Fvsx> %x0,%x1,%x3"
13408 [(set_attr "type" "fp")])
13411 (define_expand "rs6000_get_timebase"
13412 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13415 if (TARGET_POWERPC64)
13416 emit_insn (gen_rs6000_mftb_di (operands[0]));
13418 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13422 (define_insn "rs6000_get_timebase_ppc32"
13423 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13424 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13425 (clobber (match_scratch:SI 1 "=r"))
13426 (clobber (match_scratch:CC 2 "=y"))]
13427 "!TARGET_POWERPC64"
13429 if (WORDS_BIG_ENDIAN)
13432 return "mfspr %0,269\;"
13440 return "mftbu %0\;"
13449 return "mfspr %L0,269\;"
13457 return "mftbu %L0\;"
13464 [(set_attr "length" "20")])
13466 (define_insn "rs6000_mftb_<mode>"
13467 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13468 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13472 return "mfspr %0,268";
13478 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13479 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13480 (define_insn "rs6000_mffsl_hw"
13481 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13482 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13483 "TARGET_HARD_FLOAT"
13486 (define_expand "rs6000_mffsl"
13487 [(set (match_operand:DF 0 "gpc_reg_operand")
13488 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13489 "TARGET_HARD_FLOAT"
13491 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13492 otherwise fall back to the older mffs instruction to emulate the mffsl
13495 if (!TARGET_P9_MISC)
13497 rtx tmp_di = gen_reg_rtx (DImode);
13498 rtx tmp_df = gen_reg_rtx (DFmode);
13500 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13501 instruction using the mffs instruction and masking off the bits
13502 the mmsl instruciton actually reads. */
13503 emit_insn (gen_rs6000_mffs (tmp_df));
13504 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13505 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13507 operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13511 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13515 (define_insn "rs6000_mffs"
13516 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13517 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13518 "TARGET_HARD_FLOAT"
13521 (define_insn "rs6000_mtfsf"
13522 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13523 (match_operand:DF 1 "gpc_reg_operand" "d")]
13525 "TARGET_HARD_FLOAT"
13528 (define_insn "rs6000_mtfsf_hi"
13529 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13530 (match_operand:DF 1 "gpc_reg_operand" "d")]
13532 "TARGET_HARD_FLOAT"
13536 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13537 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13538 ;; register that is being loaded. The fused ops must be physically adjacent.
13540 ;; On Power8 GPR loads, we try to use the register that is being load. The
13541 ;; peephole2 then gathers any other fused possibilities that it can find after
13542 ;; register allocation. If power9 fusion is selected, we also fuse floating
13543 ;; point loads/stores.
13545 ;; Find cases where the addis that feeds into a load instruction is either used
13546 ;; once or is the same as the target register, and replace it with the fusion
13550 [(set (match_operand:P 0 "base_reg_operand")
13551 (match_operand:P 1 "fusion_gpr_addis"))
13552 (set (match_operand:INT1 2 "base_reg_operand")
13553 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13555 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13559 expand_fusion_gpr_load (operands);
13563 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13566 (define_insn "*fusion_gpr_load_<mode>"
13567 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13568 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13569 UNSPEC_FUSION_GPR))]
13572 return emit_fusion_gpr_load (operands[0], operands[1]);
13574 [(set_attr "type" "load")
13575 (set_attr "length" "8")])
13578 ;; Optimize cases where we want to do a D-form load (register+offset) on
13579 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13584 ;; and we change this to:
13589 [(match_scratch:P 0 "b")
13590 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13591 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13592 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13594 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13595 [(set (match_dup 0)
13600 rtx tmp_reg = operands[0];
13601 rtx mem = operands[2];
13602 rtx addr = XEXP (mem, 0);
13603 rtx add_op0, add_op1, new_addr;
13605 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13606 add_op0 = XEXP (addr, 0);
13607 add_op1 = XEXP (addr, 1);
13608 gcc_assert (REG_P (add_op0));
13609 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13611 operands[4] = add_op1;
13612 operands[5] = change_address (mem, <MODE>mode, new_addr);
13615 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13616 ;; Altivec register, and the register allocator has generated:
13620 ;; and we change this to:
13625 [(match_scratch:P 0 "b")
13626 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13627 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13628 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13630 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13631 [(set (match_dup 0)
13636 rtx tmp_reg = operands[0];
13637 rtx mem = operands[3];
13638 rtx addr = XEXP (mem, 0);
13639 rtx add_op0, add_op1, new_addr;
13641 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13642 add_op0 = XEXP (addr, 0);
13643 add_op1 = XEXP (addr, 1);
13644 gcc_assert (REG_P (add_op0));
13645 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13647 operands[4] = add_op1;
13648 operands[5] = change_address (mem, <MODE>mode, new_addr);
13652 ;; Miscellaneous ISA 2.06 (power7) instructions
13653 (define_insn "addg6s"
13654 [(set (match_operand:SI 0 "register_operand" "=r")
13655 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13656 (match_operand:SI 2 "register_operand" "r")]
13660 [(set_attr "type" "integer")])
13662 (define_insn "cdtbcd"
13663 [(set (match_operand:SI 0 "register_operand" "=r")
13664 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13668 [(set_attr "type" "integer")])
13670 (define_insn "cbcdtd"
13671 [(set (match_operand:SI 0 "register_operand" "=r")
13672 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13676 [(set_attr "type" "integer")])
13678 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13681 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13682 (UNSPEC_DIVEU "eu")])
13684 (define_insn "div<div_extend>_<mode>"
13685 [(set (match_operand:GPR 0 "register_operand" "=r")
13686 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13687 (match_operand:GPR 2 "register_operand" "r")]
13688 UNSPEC_DIV_EXTEND))]
13690 "div<wd><div_extend> %0,%1,%2"
13691 [(set_attr "type" "div")
13692 (set_attr "size" "<bits>")])
13695 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13697 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13698 (define_mode_attr FP128_64 [(TF "DF")
13703 (define_expand "unpack<mode>"
13704 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13706 [(match_operand:FMOVE128 1 "register_operand")
13707 (match_operand:QI 2 "const_0_to_1_operand")]
13708 UNSPEC_UNPACK_128BIT))]
13709 "FLOAT128_2REG_P (<MODE>mode)"
13712 (define_insn_and_split "unpack<mode>_dm"
13713 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13715 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13716 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13717 UNSPEC_UNPACK_128BIT))]
13718 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13720 "&& reload_completed"
13721 [(set (match_dup 0) (match_dup 3))]
13723 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13725 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13727 emit_note (NOTE_INSN_DELETED);
13731 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13733 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13735 (define_insn_and_split "unpack<mode>_nodm"
13736 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13738 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13739 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13740 UNSPEC_UNPACK_128BIT))]
13741 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13743 "&& reload_completed"
13744 [(set (match_dup 0) (match_dup 3))]
13746 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13748 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13750 emit_note (NOTE_INSN_DELETED);
13754 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13756 [(set_attr "type" "fp,fpstore")])
13758 (define_insn_and_split "pack<mode>"
13759 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13761 [(match_operand:<FP128_64> 1 "register_operand" "d")
13762 (match_operand:<FP128_64> 2 "register_operand" "d")]
13763 UNSPEC_PACK_128BIT))]
13764 "FLOAT128_2REG_P (<MODE>mode)"
13766 "&& reload_completed"
13767 [(set (match_dup 3) (match_dup 1))
13768 (set (match_dup 4) (match_dup 2))]
13770 unsigned dest_hi = REGNO (operands[0]);
13771 unsigned dest_lo = dest_hi + 1;
13773 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13774 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13776 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13777 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13779 [(set_attr "type" "fp")
13780 (set_attr "length" "8")])
13782 (define_insn "unpack<mode>"
13783 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13784 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13785 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13786 UNSPEC_UNPACK_128BIT))]
13787 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13789 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13790 return ASM_COMMENT_START " xxpermdi to same register";
13792 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13793 return "xxpermdi %x0,%x1,%x1,%3";
13795 [(set_attr "type" "vecperm")])
13797 (define_insn "pack<mode>"
13798 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13799 (unspec:FMOVE128_VSX
13800 [(match_operand:DI 1 "register_operand" "wa")
13801 (match_operand:DI 2 "register_operand" "wa")]
13802 UNSPEC_PACK_128BIT))]
13804 "xxpermdi %x0,%x1,%x2,0"
13805 [(set_attr "type" "vecperm")])
13809 ;; ISA 2.08 IEEE 128-bit floating point support.
13811 (define_insn "add<mode>3"
13812 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13814 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13815 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13816 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13818 [(set_attr "type" "vecfloat")
13819 (set_attr "size" "128")])
13821 (define_insn "sub<mode>3"
13822 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13824 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13825 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13826 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13828 [(set_attr "type" "vecfloat")
13829 (set_attr "size" "128")])
13831 (define_insn "mul<mode>3"
13832 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13834 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13835 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13836 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13838 [(set_attr "type" "qmul")
13839 (set_attr "size" "128")])
13841 (define_insn "div<mode>3"
13842 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13844 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13845 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13846 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13848 [(set_attr "type" "vecdiv")
13849 (set_attr "size" "128")])
13851 (define_insn "sqrt<mode>2"
13852 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13854 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13855 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13857 [(set_attr "type" "vecdiv")
13858 (set_attr "size" "128")])
13860 (define_expand "copysign<mode>3"
13861 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13862 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13863 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13864 "FLOAT128_IEEE_P (<MODE>mode)"
13866 if (TARGET_FLOAT128_HW)
13867 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13870 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13875 (define_insn "copysign<mode>3_hard"
13876 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13878 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13879 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13881 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13882 "xscpsgnqp %0,%2,%1"
13883 [(set_attr "type" "vecmove")
13884 (set_attr "size" "128")])
13886 (define_insn "copysign<mode>3_soft"
13887 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13889 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13890 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13892 (clobber (match_scratch:IEEE128 3 "=&v"))]
13893 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13894 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13895 [(set_attr "type" "veccomplex")
13896 (set_attr "length" "8")])
13898 (define_insn "neg<mode>2_hw"
13899 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13901 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13902 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13904 [(set_attr "type" "vecmove")
13905 (set_attr "size" "128")])
13908 (define_insn "abs<mode>2_hw"
13909 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13911 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13912 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13914 [(set_attr "type" "vecmove")
13915 (set_attr "size" "128")])
13918 (define_insn "*nabs<mode>2_hw"
13919 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13922 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13923 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13925 [(set_attr "type" "vecmove")
13926 (set_attr "size" "128")])
13928 ;; Initially don't worry about doing fusion
13929 (define_insn "fma<mode>4_hw"
13930 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13932 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13933 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13934 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13935 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13936 "xsmaddqp %0,%1,%2"
13937 [(set_attr "type" "qmul")
13938 (set_attr "size" "128")])
13940 (define_insn "*fms<mode>4_hw"
13941 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13943 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13944 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13946 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13947 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13948 "xsmsubqp %0,%1,%2"
13949 [(set_attr "type" "qmul")
13950 (set_attr "size" "128")])
13952 (define_insn "*nfma<mode>4_hw"
13953 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13956 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13957 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13958 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13959 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13960 "xsnmaddqp %0,%1,%2"
13961 [(set_attr "type" "qmul")
13962 (set_attr "size" "128")])
13964 (define_insn "*nfms<mode>4_hw"
13965 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13968 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13969 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13971 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13972 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13973 "xsnmsubqp %0,%1,%2"
13974 [(set_attr "type" "qmul")
13975 (set_attr "size" "128")])
13977 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13978 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13979 (float_extend:IEEE128
13980 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13981 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13983 [(set_attr "type" "vecfloat")
13984 (set_attr "size" "128")])
13986 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13987 ;; point is a simple copy.
13988 (define_insn_and_split "extendkftf2"
13989 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13990 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13991 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13995 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13998 emit_note (NOTE_INSN_DELETED);
14001 [(set_attr "type" "*,veclogical")
14002 (set_attr "length" "0,4")])
14004 (define_insn_and_split "trunctfkf2"
14005 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14006 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14007 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14011 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14014 emit_note (NOTE_INSN_DELETED);
14017 [(set_attr "type" "*,veclogical")
14018 (set_attr "length" "0,4")])
14020 (define_insn "trunc<mode>df2_hw"
14021 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14023 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14024 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14026 [(set_attr "type" "vecfloat")
14027 (set_attr "size" "128")])
14029 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14030 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14032 (define_insn_and_split "trunc<mode>sf2_hw"
14033 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14035 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14036 (clobber (match_scratch:DF 2 "=v"))]
14037 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14040 [(set (match_dup 2)
14041 (unspec:DF [(match_dup 1)]
14042 UNSPEC_TRUNC_ROUND_TO_ODD))
14044 (float_truncate:SF (match_dup 2)))]
14046 if (GET_CODE (operands[2]) == SCRATCH)
14047 operands[2] = gen_reg_rtx (DFmode);
14049 [(set_attr "type" "vecfloat")
14050 (set_attr "length" "8")])
14052 ;; Conversion between IEEE 128-bit and integer types
14054 ;; The fix function for DImode and SImode was declared earlier as a
14055 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14056 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14057 ;; unless we have the IEEE 128-bit hardware.
14059 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14060 ;; to provide a GPR target that used direct move and a conversion in the GPR
14061 ;; which works around QImode/HImode not being allowed in vector registers in
14062 ;; ISA 2.07 (power8).
14063 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14064 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14065 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14066 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14067 "xscvqp<su><wd>z %0,%1"
14068 [(set_attr "type" "vecfloat")
14069 (set_attr "size" "128")])
14071 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14072 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14074 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14075 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14076 "xscvqp<su>wz %0,%1"
14077 [(set_attr "type" "vecfloat")
14078 (set_attr "size" "128")])
14080 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14081 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14082 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14083 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14085 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14086 (clobber (match_scratch:QHSI 2 "=v"))]
14087 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14089 "&& reload_completed"
14090 [(set (match_dup 2)
14091 (any_fix:QHSI (match_dup 1)))
14095 (define_insn "float_<mode>di2_hw"
14096 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14097 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14098 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14100 [(set_attr "type" "vecfloat")
14101 (set_attr "size" "128")])
14103 (define_insn_and_split "float_<mode>si2_hw"
14104 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14105 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14106 (clobber (match_scratch:DI 2 "=v"))]
14107 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14110 [(set (match_dup 2)
14111 (sign_extend:DI (match_dup 1)))
14113 (float:IEEE128 (match_dup 2)))]
14115 if (GET_CODE (operands[2]) == SCRATCH)
14116 operands[2] = gen_reg_rtx (DImode);
14118 if (MEM_P (operands[1]))
14119 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14122 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14123 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14124 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14125 (clobber (match_scratch:DI 2 "=X,r,X"))]
14126 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14128 "&& reload_completed"
14131 rtx dest = operands[0];
14132 rtx src = operands[1];
14133 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14135 if (altivec_register_operand (src, <QHI:MODE>mode))
14136 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14137 else if (int_reg_operand (src, <QHI:MODE>mode))
14139 rtx ext_di = operands[2];
14140 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14141 emit_move_insn (dest_di, ext_di);
14143 else if (MEM_P (src))
14145 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14146 emit_move_insn (dest_qhi, src);
14147 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14150 gcc_unreachable ();
14152 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14155 [(set_attr "length" "8,12,12")
14156 (set_attr "type" "vecfloat")
14157 (set_attr "size" "128")])
14159 (define_insn "floatuns_<mode>di2_hw"
14160 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14161 (unsigned_float:IEEE128
14162 (match_operand:DI 1 "altivec_register_operand" "v")))]
14163 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14165 [(set_attr "type" "vecfloat")
14166 (set_attr "size" "128")])
14168 (define_insn_and_split "floatuns_<mode>si2_hw"
14169 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14170 (unsigned_float:IEEE128
14171 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14172 (clobber (match_scratch:DI 2 "=v"))]
14173 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14176 [(set (match_dup 2)
14177 (zero_extend:DI (match_dup 1)))
14179 (float:IEEE128 (match_dup 2)))]
14181 if (GET_CODE (operands[2]) == SCRATCH)
14182 operands[2] = gen_reg_rtx (DImode);
14184 if (MEM_P (operands[1]))
14185 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14188 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14189 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14190 (unsigned_float:IEEE128
14191 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14192 (clobber (match_scratch:DI 2 "=X,r,X"))]
14193 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14195 "&& reload_completed"
14198 rtx dest = operands[0];
14199 rtx src = operands[1];
14200 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14202 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14203 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14204 else if (int_reg_operand (src, <QHI:MODE>mode))
14206 rtx ext_di = operands[2];
14207 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14208 emit_move_insn (dest_di, ext_di);
14211 gcc_unreachable ();
14213 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14216 [(set_attr "length" "8,12,8")
14217 (set_attr "type" "vecfloat")
14218 (set_attr "size" "128")])
14220 ;; IEEE 128-bit round to integer built-in functions
14221 (define_insn "floor<mode>2"
14222 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14224 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14226 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14228 [(set_attr "type" "vecfloat")
14229 (set_attr "size" "128")])
14231 (define_insn "ceil<mode>2"
14232 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14234 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14236 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14238 [(set_attr "type" "vecfloat")
14239 (set_attr "size" "128")])
14241 (define_insn "btrunc<mode>2"
14242 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14244 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14246 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14248 [(set_attr "type" "vecfloat")
14249 (set_attr "size" "128")])
14251 (define_insn "round<mode>2"
14252 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14254 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14256 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14258 [(set_attr "type" "vecfloat")
14259 (set_attr "size" "128")])
14261 ;; IEEE 128-bit instructions with round to odd semantics
14262 (define_insn "add<mode>3_odd"
14263 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14265 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14266 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14267 UNSPEC_ADD_ROUND_TO_ODD))]
14268 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14269 "xsaddqpo %0,%1,%2"
14270 [(set_attr "type" "vecfloat")
14271 (set_attr "size" "128")])
14273 (define_insn "sub<mode>3_odd"
14274 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14276 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14277 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14278 UNSPEC_SUB_ROUND_TO_ODD))]
14279 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14280 "xssubqpo %0,%1,%2"
14281 [(set_attr "type" "vecfloat")
14282 (set_attr "size" "128")])
14284 (define_insn "mul<mode>3_odd"
14285 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14287 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14288 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14289 UNSPEC_MUL_ROUND_TO_ODD))]
14290 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14291 "xsmulqpo %0,%1,%2"
14292 [(set_attr "type" "qmul")
14293 (set_attr "size" "128")])
14295 (define_insn "div<mode>3_odd"
14296 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14298 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14299 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14300 UNSPEC_DIV_ROUND_TO_ODD))]
14301 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14302 "xsdivqpo %0,%1,%2"
14303 [(set_attr "type" "vecdiv")
14304 (set_attr "size" "128")])
14306 (define_insn "sqrt<mode>2_odd"
14307 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14309 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14310 UNSPEC_SQRT_ROUND_TO_ODD))]
14311 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14313 [(set_attr "type" "vecdiv")
14314 (set_attr "size" "128")])
14316 (define_insn "fma<mode>4_odd"
14317 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14319 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14320 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14321 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14322 UNSPEC_FMA_ROUND_TO_ODD))]
14323 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14324 "xsmaddqpo %0,%1,%2"
14325 [(set_attr "type" "qmul")
14326 (set_attr "size" "128")])
14328 (define_insn "*fms<mode>4_odd"
14329 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14331 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14332 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14334 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14335 UNSPEC_FMA_ROUND_TO_ODD))]
14336 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14337 "xsmsubqpo %0,%1,%2"
14338 [(set_attr "type" "qmul")
14339 (set_attr "size" "128")])
14341 (define_insn "*nfma<mode>4_odd"
14342 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14345 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14346 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14347 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14348 UNSPEC_FMA_ROUND_TO_ODD)))]
14349 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14350 "xsnmaddqpo %0,%1,%2"
14351 [(set_attr "type" "qmul")
14352 (set_attr "size" "128")])
14354 (define_insn "*nfms<mode>4_odd"
14355 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14358 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14359 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14361 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14362 UNSPEC_FMA_ROUND_TO_ODD)))]
14363 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14364 "xsnmsubqpo %0,%1,%2"
14365 [(set_attr "type" "qmul")
14366 (set_attr "size" "128")])
14368 (define_insn "trunc<mode>df2_odd"
14369 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14370 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14371 UNSPEC_TRUNC_ROUND_TO_ODD))]
14372 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14374 [(set_attr "type" "vecfloat")
14375 (set_attr "size" "128")])
14377 ;; IEEE 128-bit comparisons
14378 (define_insn "*cmp<mode>_hw"
14379 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14380 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14381 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14382 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14383 "xscmpuqp %0,%1,%2"
14384 [(set_attr "type" "veccmp")
14385 (set_attr "size" "128")])
14389 (include "sync.md")
14390 (include "vector.md")
14392 (include "altivec.md")
14394 (include "crypto.md")