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
152 ;; UNSPEC_VOLATILE usage
155 (define_c_enum "unspecv"
157 UNSPECV_LL ; load-locked
158 UNSPECV_SC ; store-conditional
159 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
160 UNSPECV_EH_RR ; eh_reg_restore
161 UNSPECV_ISYNC ; isync instruction
162 UNSPECV_MFTB ; move from time base
163 UNSPECV_NLGR ; non-local goto receiver
164 UNSPECV_MFFS ; Move from FPSCR
165 UNSPECV_MFFSL ; Move from FPSCR light instruction version
166 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
167 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
168 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
169 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
170 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
171 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
172 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
173 UNSPECV_SPEC_BARRIER ; Speculation barrier
177 ;; Define an insn type attribute. This is used in function unit delay
181 add,logical,shift,insert,
183 exts,cntlz,popcnt,isel,
184 load,store,fpload,fpstore,vecload,vecstore,
186 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
187 cr_logical,mfcr,mfcrf,mtcr,
188 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
189 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
190 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
191 veclogical,veccmpfx,vecexts,vecmove,
193 (const_string "integer"))
195 ;; What data size does this instruction work on?
196 ;; This is used for insert, mul and others as necessary.
197 (define_attr "size" "8,16,32,64,128" (const_string "32"))
199 ;; What is the insn_cost for this insn? The target hook can still override
200 ;; this. For optimizing for size the "length" attribute is used instead.
201 (define_attr "cost" "" (const_int 0))
203 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
204 ;; This is used for add, logical, shift, exts, mul.
205 (define_attr "dot" "no,yes" (const_string "no"))
207 ;; Does this instruction sign-extend its result?
208 ;; This is used for load insns.
209 (define_attr "sign_extend" "no,yes" (const_string "no"))
211 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
212 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
214 ;; Does this instruction use indexed (that is, reg+reg) addressing?
215 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
216 ;; it is automatically set based on that. If a load or store instruction
217 ;; has fewer than two operands it needs to set this attribute manually
218 ;; or the compiler will crash.
219 (define_attr "indexed" "no,yes"
220 (if_then_else (ior (match_operand 0 "indexed_address_mem")
221 (match_operand 1 "indexed_address_mem"))
223 (const_string "no")))
225 ;; Does this instruction use update addressing?
226 ;; This is used for load and store insns. See the comments for "indexed".
227 (define_attr "update" "no,yes"
228 (if_then_else (ior (match_operand 0 "update_address_mem")
229 (match_operand 1 "update_address_mem"))
231 (const_string "no")))
233 ;; Is this instruction using operands[2] as shift amount, and can that be a
235 ;; This is used for shift insns.
236 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
238 ;; Is this instruction using a shift amount from a register?
239 ;; This is used for shift insns.
240 (define_attr "var_shift" "no,yes"
241 (if_then_else (and (eq_attr "type" "shift")
242 (eq_attr "maybe_var_shift" "yes"))
243 (if_then_else (match_operand 2 "gpc_reg_operand")
246 (const_string "no")))
248 ;; Is copying of this instruction disallowed?
249 (define_attr "cannot_copy" "no,yes" (const_string "no"))
251 ;; Length of the instruction (in bytes).
252 (define_attr "length" "" (const_int 4))
254 ;; Processor type -- this attribute must exactly match the processor_type
255 ;; enumeration in rs6000-opts.h.
257 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
258 ppc750,ppc7400,ppc7450,
259 ppc403,ppc405,ppc440,ppc476,
260 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
261 power4,power5,power6,power7,power8,power9,
262 rs64a,mpccore,cell,ppca2,titan"
263 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
266 ;; If this instruction is microcoded on the CELL processor
267 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
268 (define_attr "cell_micro" "not,conditional,always"
269 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
270 (eq_attr "dot" "yes"))
271 (and (eq_attr "type" "load")
272 (eq_attr "sign_extend" "yes"))
273 (and (eq_attr "type" "shift")
274 (eq_attr "var_shift" "yes")))
275 (const_string "always")
276 (const_string "not")))
278 (automata_option "ndfa")
291 (include "e300c2c3.md")
292 (include "e500mc.md")
293 (include "e500mc64.md")
296 (include "power4.md")
297 (include "power5.md")
298 (include "power6.md")
299 (include "power7.md")
300 (include "power8.md")
301 (include "power9.md")
306 (include "predicates.md")
307 (include "constraints.md")
309 (include "darwin.md")
314 ; This mode iterator allows :GPR to be used to indicate the allowable size
315 ; of whole values in GPRs.
316 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
318 ; And again, for patterns that need two (potentially) different integer modes.
319 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
321 ; Any supported integer mode.
322 (define_mode_iterator INT [QI HI SI DI TI PTI])
324 ; Any supported integer mode that fits in one register.
325 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
327 ; Integer modes supported in VSX registers with ISA 3.0 instructions
328 (define_mode_iterator INT_ISA3 [QI HI SI DI])
330 ; Everything we can extend QImode to.
331 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
333 ; Everything we can extend HImode to.
334 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
336 ; Everything we can extend SImode to.
337 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
339 ; QImode or HImode for small integer moves and small atomic ops
340 (define_mode_iterator QHI [QI HI])
342 ; QImode, HImode, SImode for fused ops only for GPR loads
343 (define_mode_iterator QHSI [QI HI SI])
345 ; HImode or SImode for sign extended fusion ops
346 (define_mode_iterator HSI [HI SI])
348 ; SImode or DImode, even if DImode doesn't fit in GPRs.
349 (define_mode_iterator SDI [SI DI])
351 ; The size of a pointer. Also, the size of the value that a record-condition
352 ; (one with a '.') will compare; and the size used for arithmetic carries.
353 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
355 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
356 ; PTImode is GPR only)
357 (define_mode_iterator TI2 [TI PTI])
359 ; Any hardware-supported floating-point mode
360 (define_mode_iterator FP [
361 (SF "TARGET_HARD_FLOAT")
362 (DF "TARGET_HARD_FLOAT")
363 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
364 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
365 (KF "TARGET_FLOAT128_TYPE")
369 ; Any fma capable floating-point mode.
370 (define_mode_iterator FMA_F [
371 (SF "TARGET_HARD_FLOAT")
372 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
373 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
374 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
375 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
376 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
379 ; Floating point move iterators to combine binary and decimal moves
380 (define_mode_iterator FMOVE32 [SF SD])
381 (define_mode_iterator FMOVE64 [DF DD])
382 (define_mode_iterator FMOVE64X [DI DF DD])
383 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
384 (IF "FLOAT128_IBM_P (IFmode)")
385 (TD "TARGET_HARD_FLOAT")])
387 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
388 (IF "FLOAT128_2REG_P (IFmode)")
389 (TD "TARGET_HARD_FLOAT")])
391 ; Iterators for 128 bit types for direct move
392 (define_mode_iterator FMOVE128_GPR [TI
400 (KF "FLOAT128_VECTOR_P (KFmode)")
401 (TF "FLOAT128_VECTOR_P (TFmode)")])
403 ; Iterator for 128-bit VSX types for pack/unpack
404 (define_mode_iterator FMOVE128_VSX [V1TI KF])
406 ; Iterators for converting to/from TFmode
407 (define_mode_iterator IFKF [IF KF])
409 ; Constraints for moving IF/KFmode.
410 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
412 ; Whether a floating point move is ok, don't allow SD without hardware FP
413 (define_mode_attr fmove_ok [(SF "")
415 (SD "TARGET_HARD_FLOAT")
418 ; Convert REAL_VALUE to the appropriate bits
419 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
420 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
421 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
422 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
424 ; Whether 0.0 has an all-zero bit pattern
425 (define_mode_attr zero_fp [(SF "j")
434 ; Definitions for 64-bit VSX
435 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
437 ; Definitions for 64-bit direct move
438 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
440 ; Definitions for 64-bit use of altivec registers
441 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
443 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
444 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
446 ; These modes do not fit in integer registers in 32-bit mode.
447 (define_mode_iterator DIFD [DI DF DD])
449 ; Iterator for reciprocal estimate instructions
450 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
452 ; Iterator for just SF/DF
453 (define_mode_iterator SFDF [SF DF])
455 ; Like SFDF, but a different name to match conditional move where the
456 ; comparison operands may be a different mode than the input operands.
457 (define_mode_iterator SFDF2 [SF DF])
459 ; Iterator for 128-bit floating point that uses the IBM double-double format
460 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
461 (TF "FLOAT128_IBM_P (TFmode)")])
463 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
464 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
465 (TF "FLOAT128_IEEE_P (TFmode)")])
467 ; Iterator for 128-bit floating point
468 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
469 (IF "TARGET_FLOAT128_TYPE")
470 (TF "TARGET_LONG_DOUBLE_128")])
472 ; Iterator for signbit on 64-bit machines with direct move
473 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
474 (TF "FLOAT128_VECTOR_P (TFmode)")])
476 ; Iterator for ISA 3.0 supported floating point types
477 (define_mode_iterator FP_ISA3 [SF DF])
479 ; SF/DF suffix for traditional floating instructions
480 (define_mode_attr Ftrad [(SF "s") (DF "")])
482 ; SF/DF suffix for VSX instructions
483 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
485 ; SF/DF constraint for arithmetic on traditional floating point registers
486 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
488 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
489 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
490 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
492 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
494 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
495 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
496 ; instructions added in ISA 2.07 (power8)
497 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
499 ; SF/DF constraint for arithmetic on altivec registers
500 (define_mode_attr Fa [(SF "wu") (DF "wv")])
502 ; s/d suffix for things like sdiv/ddiv
503 (define_mode_attr Fs [(SF "s") (DF "d")])
506 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
507 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
509 ; Conditional returns.
510 (define_code_iterator any_return [return simple_return])
511 (define_code_attr return_pred [(return "direct_return ()")
512 (simple_return "1")])
513 (define_code_attr return_str [(return "") (simple_return "simple_")])
516 (define_code_iterator iorxor [ior xor])
517 (define_code_iterator and_ior_xor [and ior xor])
519 ; Signed/unsigned variants of ops.
520 (define_code_iterator any_extend [sign_extend zero_extend])
521 (define_code_iterator any_fix [fix unsigned_fix])
522 (define_code_iterator any_float [float unsigned_float])
524 (define_code_attr u [(sign_extend "")
529 (define_code_attr su [(sign_extend "s")
534 (unsigned_float "u")])
536 (define_code_attr az [(sign_extend "a")
541 (unsigned_float "z")])
543 (define_code_attr uns [(fix "")
546 (unsigned_float "uns")])
548 ; Various instructions that come in SI and DI forms.
549 ; A generic w/d attribute, for things like cmpw/cmpd.
550 (define_mode_attr wd [(QI "b")
561 ;; How many bits in this mode?
562 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
565 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
567 ;; Bitmask for shift instructions
568 (define_mode_attr hH [(SI "h") (DI "H")])
570 ;; A mode twice the size of the given mode
571 (define_mode_attr dmode [(SI "di") (DI "ti")])
572 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
574 ;; Suffix for reload patterns
575 (define_mode_attr ptrsize [(SI "32bit")
578 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
579 (DI "TARGET_64BIT")])
581 (define_mode_attr mptrsize [(SI "si")
584 (define_mode_attr ptrload [(SI "lwz")
587 (define_mode_attr ptrm [(SI "m")
590 (define_mode_attr rreg [(SF "f")
597 (define_mode_attr rreg2 [(SF "f")
600 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
601 (DF "TARGET_FCFID")])
603 ;; Mode iterator for logical operations on 128-bit types
604 (define_mode_iterator BOOL_128 [TI
606 (V16QI "TARGET_ALTIVEC")
607 (V8HI "TARGET_ALTIVEC")
608 (V4SI "TARGET_ALTIVEC")
609 (V4SF "TARGET_ALTIVEC")
610 (V2DI "TARGET_ALTIVEC")
611 (V2DF "TARGET_ALTIVEC")
612 (V1TI "TARGET_ALTIVEC")])
614 ;; For the GPRs we use 3 constraints for register outputs, two that are the
615 ;; same as the output register, and a third where the output register is an
616 ;; early clobber, so we don't have to deal with register overlaps. For the
617 ;; vector types, we prefer to use the vector registers. For TI mode, allow
620 ;; Mode attribute for boolean operation register constraints for output
621 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
623 (V16QI "wa,v,&?r,?r,?r")
624 (V8HI "wa,v,&?r,?r,?r")
625 (V4SI "wa,v,&?r,?r,?r")
626 (V4SF "wa,v,&?r,?r,?r")
627 (V2DI "wa,v,&?r,?r,?r")
628 (V2DF "wa,v,&?r,?r,?r")
629 (V1TI "wa,v,&?r,?r,?r")])
631 ;; Mode attribute for boolean operation register constraints for operand1
632 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
640 (V1TI "wa,v,r,0,r")])
642 ;; Mode attribute for boolean operation register constraints for operand2
643 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
651 (V1TI "wa,v,r,r,0")])
653 ;; Mode attribute for boolean operation register constraints for operand1
654 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
655 ;; is used for operand1 or operand2
656 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
664 (V1TI "wa,v,r,0,0")])
666 ;; Reload iterator for creating the function to allocate a base register to
667 ;; supplement addressing modes.
668 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
669 SF SD SI DF DD DI TI PTI KF IF TF])
671 ;; Iterate over smin, smax
672 (define_code_iterator fp_minmax [smin smax])
674 (define_code_attr minmax [(smin "min")
677 (define_code_attr SMINMAX [(smin "SMIN")
680 ;; Iterator to optimize the following cases:
681 ;; D-form load to FPR register & move to Altivec register
682 ;; Move Altivec register to FPR register and store
683 (define_mode_iterator ALTIVEC_DFORM [DF
684 (SF "TARGET_P8_VECTOR")
685 (DI "TARGET_POWERPC64")])
688 ;; Start with fixed-point load and store insns. Here we put only the more
689 ;; complex forms. Basic data transfer is done later.
691 (define_insn "zero_extendqi<mode>2"
692 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
693 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
700 [(set_attr "type" "load,shift,fpload,vecperm")])
702 (define_insn_and_split "*zero_extendqi<mode>2_dot"
703 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
704 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
706 (clobber (match_scratch:EXTQI 0 "=r,r"))]
711 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
713 (zero_extend:EXTQI (match_dup 1)))
715 (compare:CC (match_dup 0)
718 [(set_attr "type" "logical")
719 (set_attr "dot" "yes")
720 (set_attr "length" "4,8")])
722 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
723 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
724 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
726 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
727 (zero_extend:EXTQI (match_dup 1)))]
732 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
734 (zero_extend:EXTQI (match_dup 1)))
736 (compare:CC (match_dup 0)
739 [(set_attr "type" "logical")
740 (set_attr "dot" "yes")
741 (set_attr "length" "4,8")])
744 (define_insn "zero_extendhi<mode>2"
745 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
746 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
750 rlwinm %0,%1,0,0xffff
753 [(set_attr "type" "load,shift,fpload,vecperm")])
755 (define_insn_and_split "*zero_extendhi<mode>2_dot"
756 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
757 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
759 (clobber (match_scratch:EXTHI 0 "=r,r"))]
764 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
766 (zero_extend:EXTHI (match_dup 1)))
768 (compare:CC (match_dup 0)
771 [(set_attr "type" "logical")
772 (set_attr "dot" "yes")
773 (set_attr "length" "4,8")])
775 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
776 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
777 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
779 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
780 (zero_extend:EXTHI (match_dup 1)))]
785 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
787 (zero_extend:EXTHI (match_dup 1)))
789 (compare:CC (match_dup 0)
792 [(set_attr "type" "logical")
793 (set_attr "dot" "yes")
794 (set_attr "length" "4,8")])
797 (define_insn "zero_extendsi<mode>2"
798 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
799 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
808 xxextractuw %x0,%x1,4"
809 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
811 (define_insn_and_split "*zero_extendsi<mode>2_dot"
812 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
813 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
815 (clobber (match_scratch:EXTSI 0 "=r,r"))]
820 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
822 (zero_extend:DI (match_dup 1)))
824 (compare:CC (match_dup 0)
827 [(set_attr "type" "shift")
828 (set_attr "dot" "yes")
829 (set_attr "length" "4,8")])
831 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
832 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
833 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
835 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
836 (zero_extend:EXTSI (match_dup 1)))]
841 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
843 (zero_extend:EXTSI (match_dup 1)))
845 (compare:CC (match_dup 0)
848 [(set_attr "type" "shift")
849 (set_attr "dot" "yes")
850 (set_attr "length" "4,8")])
853 (define_insn "extendqi<mode>2"
854 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
855 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
860 [(set_attr "type" "exts,vecperm")])
862 (define_insn_and_split "*extendqi<mode>2_dot"
863 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
864 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
866 (clobber (match_scratch:EXTQI 0 "=r,r"))]
871 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
873 (sign_extend:EXTQI (match_dup 1)))
875 (compare:CC (match_dup 0)
878 [(set_attr "type" "exts")
879 (set_attr "dot" "yes")
880 (set_attr "length" "4,8")])
882 (define_insn_and_split "*extendqi<mode>2_dot2"
883 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
884 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
886 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
887 (sign_extend:EXTQI (match_dup 1)))]
892 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
894 (sign_extend:EXTQI (match_dup 1)))
896 (compare:CC (match_dup 0)
899 [(set_attr "type" "exts")
900 (set_attr "dot" "yes")
901 (set_attr "length" "4,8")])
904 (define_expand "extendhi<mode>2"
905 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
906 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
910 (define_insn "*extendhi<mode>2"
911 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
912 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
919 [(set_attr "type" "load,exts,fpload,vecperm")
920 (set_attr "sign_extend" "yes")
921 (set_attr "length" "4,4,8,4")])
924 [(set (match_operand:EXTHI 0 "altivec_register_operand")
926 (match_operand:HI 1 "indexed_or_indirect_operand")))]
927 "TARGET_P9_VECTOR && reload_completed"
931 (sign_extend:EXTHI (match_dup 2)))]
933 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
936 (define_insn_and_split "*extendhi<mode>2_dot"
937 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
938 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
940 (clobber (match_scratch:EXTHI 0 "=r,r"))]
945 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
947 (sign_extend:EXTHI (match_dup 1)))
949 (compare:CC (match_dup 0)
952 [(set_attr "type" "exts")
953 (set_attr "dot" "yes")
954 (set_attr "length" "4,8")])
956 (define_insn_and_split "*extendhi<mode>2_dot2"
957 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
958 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
960 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
961 (sign_extend:EXTHI (match_dup 1)))]
966 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
968 (sign_extend:EXTHI (match_dup 1)))
970 (compare:CC (match_dup 0)
973 [(set_attr "type" "exts")
974 (set_attr "dot" "yes")
975 (set_attr "length" "4,8")])
978 (define_insn "extendsi<mode>2"
979 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
980 "=r, r, wl, wu, wj, wK, wH, wr")
982 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
983 "YZ, r, Z, Z, r, wK, wH, ?wIwH")))]
994 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
995 (set_attr "sign_extend" "yes")
996 (set_attr "length" "4,4,4,4,4,4,8,8")])
999 [(set (match_operand:EXTSI 0 "int_reg_operand")
1000 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1001 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1005 (sign_extend:DI (match_dup 2)))]
1007 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1011 [(set (match_operand:DI 0 "altivec_register_operand")
1012 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1013 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1016 rtx dest = operands[0];
1017 rtx src = operands[1];
1018 int dest_regno = REGNO (dest);
1019 int src_regno = REGNO (src);
1020 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1021 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1023 if (BYTES_BIG_ENDIAN)
1025 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1026 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1030 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1031 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1036 (define_insn_and_split "*extendsi<mode>2_dot"
1037 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1038 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1040 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1045 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1047 (sign_extend:EXTSI (match_dup 1)))
1049 (compare:CC (match_dup 0)
1052 [(set_attr "type" "exts")
1053 (set_attr "dot" "yes")
1054 (set_attr "length" "4,8")])
1056 (define_insn_and_split "*extendsi<mode>2_dot2"
1057 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1058 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1060 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1061 (sign_extend:EXTSI (match_dup 1)))]
1066 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1068 (sign_extend:EXTSI (match_dup 1)))
1070 (compare:CC (match_dup 0)
1073 [(set_attr "type" "exts")
1074 (set_attr "dot" "yes")
1075 (set_attr "length" "4,8")])
1077 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1079 (define_insn "*macchwc"
1080 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1081 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1082 (match_operand:SI 2 "gpc_reg_operand" "r")
1085 (match_operand:HI 1 "gpc_reg_operand" "r")))
1086 (match_operand:SI 4 "gpc_reg_operand" "0"))
1088 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1089 (plus:SI (mult:SI (ashiftrt:SI
1097 [(set_attr "type" "halfmul")])
1099 (define_insn "*macchw"
1100 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1101 (plus:SI (mult:SI (ashiftrt:SI
1102 (match_operand:SI 2 "gpc_reg_operand" "r")
1105 (match_operand:HI 1 "gpc_reg_operand" "r")))
1106 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1109 [(set_attr "type" "halfmul")])
1111 (define_insn "*macchwuc"
1112 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1113 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1114 (match_operand:SI 2 "gpc_reg_operand" "r")
1117 (match_operand:HI 1 "gpc_reg_operand" "r")))
1118 (match_operand:SI 4 "gpc_reg_operand" "0"))
1120 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1121 (plus:SI (mult:SI (lshiftrt:SI
1129 [(set_attr "type" "halfmul")])
1131 (define_insn "*macchwu"
1132 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1133 (plus:SI (mult:SI (lshiftrt:SI
1134 (match_operand:SI 2 "gpc_reg_operand" "r")
1137 (match_operand:HI 1 "gpc_reg_operand" "r")))
1138 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1141 [(set_attr "type" "halfmul")])
1143 (define_insn "*machhwc"
1144 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1145 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1146 (match_operand:SI 1 "gpc_reg_operand" "%r")
1149 (match_operand:SI 2 "gpc_reg_operand" "r")
1151 (match_operand:SI 4 "gpc_reg_operand" "0"))
1153 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1154 (plus:SI (mult:SI (ashiftrt:SI
1163 [(set_attr "type" "halfmul")])
1165 (define_insn "*machhw"
1166 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1167 (plus:SI (mult:SI (ashiftrt:SI
1168 (match_operand:SI 1 "gpc_reg_operand" "%r")
1171 (match_operand:SI 2 "gpc_reg_operand" "r")
1173 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1176 [(set_attr "type" "halfmul")])
1178 (define_insn "*machhwuc"
1179 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1180 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1181 (match_operand:SI 1 "gpc_reg_operand" "%r")
1184 (match_operand:SI 2 "gpc_reg_operand" "r")
1186 (match_operand:SI 4 "gpc_reg_operand" "0"))
1188 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1189 (plus:SI (mult:SI (lshiftrt:SI
1198 [(set_attr "type" "halfmul")])
1200 (define_insn "*machhwu"
1201 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1202 (plus:SI (mult:SI (lshiftrt:SI
1203 (match_operand:SI 1 "gpc_reg_operand" "%r")
1206 (match_operand:SI 2 "gpc_reg_operand" "r")
1208 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1211 [(set_attr "type" "halfmul")])
1213 (define_insn "*maclhwc"
1214 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1215 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1216 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1218 (match_operand:HI 2 "gpc_reg_operand" "r")))
1219 (match_operand:SI 4 "gpc_reg_operand" "0"))
1221 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1222 (plus:SI (mult:SI (sign_extend:SI
1229 [(set_attr "type" "halfmul")])
1231 (define_insn "*maclhw"
1232 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1233 (plus:SI (mult:SI (sign_extend:SI
1234 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1236 (match_operand:HI 2 "gpc_reg_operand" "r")))
1237 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1240 [(set_attr "type" "halfmul")])
1242 (define_insn "*maclhwuc"
1243 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1244 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1245 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1247 (match_operand:HI 2 "gpc_reg_operand" "r")))
1248 (match_operand:SI 4 "gpc_reg_operand" "0"))
1250 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1251 (plus:SI (mult:SI (zero_extend:SI
1258 [(set_attr "type" "halfmul")])
1260 (define_insn "*maclhwu"
1261 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1262 (plus:SI (mult:SI (zero_extend:SI
1263 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1265 (match_operand:HI 2 "gpc_reg_operand" "r")))
1266 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1269 [(set_attr "type" "halfmul")])
1271 (define_insn "*nmacchwc"
1272 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1273 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1274 (mult:SI (ashiftrt:SI
1275 (match_operand:SI 2 "gpc_reg_operand" "r")
1278 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1280 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1281 (minus:SI (match_dup 4)
1282 (mult:SI (ashiftrt:SI
1289 [(set_attr "type" "halfmul")])
1291 (define_insn "*nmacchw"
1292 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1293 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1294 (mult:SI (ashiftrt:SI
1295 (match_operand:SI 2 "gpc_reg_operand" "r")
1298 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1301 [(set_attr "type" "halfmul")])
1303 (define_insn "*nmachhwc"
1304 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1305 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1306 (mult:SI (ashiftrt:SI
1307 (match_operand:SI 1 "gpc_reg_operand" "%r")
1310 (match_operand:SI 2 "gpc_reg_operand" "r")
1313 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1314 (minus:SI (match_dup 4)
1315 (mult:SI (ashiftrt:SI
1323 [(set_attr "type" "halfmul")])
1325 (define_insn "*nmachhw"
1326 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1327 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1328 (mult:SI (ashiftrt:SI
1329 (match_operand:SI 1 "gpc_reg_operand" "%r")
1332 (match_operand:SI 2 "gpc_reg_operand" "r")
1336 [(set_attr "type" "halfmul")])
1338 (define_insn "*nmaclhwc"
1339 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1340 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1341 (mult:SI (sign_extend:SI
1342 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1344 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1346 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347 (minus:SI (match_dup 4)
1348 (mult:SI (sign_extend:SI
1354 [(set_attr "type" "halfmul")])
1356 (define_insn "*nmaclhw"
1357 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1358 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1359 (mult:SI (sign_extend:SI
1360 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1362 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1365 [(set_attr "type" "halfmul")])
1367 (define_insn "*mulchwc"
1368 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1369 (compare:CC (mult:SI (ashiftrt:SI
1370 (match_operand:SI 2 "gpc_reg_operand" "r")
1373 (match_operand:HI 1 "gpc_reg_operand" "r")))
1375 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1376 (mult:SI (ashiftrt:SI
1383 [(set_attr "type" "halfmul")])
1385 (define_insn "*mulchw"
1386 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1387 (mult:SI (ashiftrt:SI
1388 (match_operand:SI 2 "gpc_reg_operand" "r")
1391 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1394 [(set_attr "type" "halfmul")])
1396 (define_insn "*mulchwuc"
1397 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1398 (compare:CC (mult:SI (lshiftrt:SI
1399 (match_operand:SI 2 "gpc_reg_operand" "r")
1402 (match_operand:HI 1 "gpc_reg_operand" "r")))
1404 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1405 (mult:SI (lshiftrt:SI
1412 [(set_attr "type" "halfmul")])
1414 (define_insn "*mulchwu"
1415 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1416 (mult:SI (lshiftrt:SI
1417 (match_operand:SI 2 "gpc_reg_operand" "r")
1420 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1423 [(set_attr "type" "halfmul")])
1425 (define_insn "*mulhhwc"
1426 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1427 (compare:CC (mult:SI (ashiftrt:SI
1428 (match_operand:SI 1 "gpc_reg_operand" "%r")
1431 (match_operand:SI 2 "gpc_reg_operand" "r")
1434 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1435 (mult:SI (ashiftrt:SI
1443 [(set_attr "type" "halfmul")])
1445 (define_insn "*mulhhw"
1446 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1447 (mult:SI (ashiftrt:SI
1448 (match_operand:SI 1 "gpc_reg_operand" "%r")
1451 (match_operand:SI 2 "gpc_reg_operand" "r")
1455 [(set_attr "type" "halfmul")])
1457 (define_insn "*mulhhwuc"
1458 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1459 (compare:CC (mult:SI (lshiftrt:SI
1460 (match_operand:SI 1 "gpc_reg_operand" "%r")
1463 (match_operand:SI 2 "gpc_reg_operand" "r")
1466 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1467 (mult:SI (lshiftrt:SI
1475 [(set_attr "type" "halfmul")])
1477 (define_insn "*mulhhwu"
1478 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1479 (mult:SI (lshiftrt:SI
1480 (match_operand:SI 1 "gpc_reg_operand" "%r")
1483 (match_operand:SI 2 "gpc_reg_operand" "r")
1487 [(set_attr "type" "halfmul")])
1489 (define_insn "*mullhwc"
1490 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1491 (compare:CC (mult:SI (sign_extend:SI
1492 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1494 (match_operand:HI 2 "gpc_reg_operand" "r")))
1496 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1497 (mult:SI (sign_extend:SI
1503 [(set_attr "type" "halfmul")])
1505 (define_insn "*mullhw"
1506 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1507 (mult:SI (sign_extend:SI
1508 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1510 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1513 [(set_attr "type" "halfmul")])
1515 (define_insn "*mullhwuc"
1516 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1517 (compare:CC (mult:SI (zero_extend:SI
1518 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1520 (match_operand:HI 2 "gpc_reg_operand" "r")))
1522 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1523 (mult:SI (zero_extend:SI
1529 [(set_attr "type" "halfmul")])
1531 (define_insn "*mullhwu"
1532 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1533 (mult:SI (zero_extend:SI
1534 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1536 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1539 [(set_attr "type" "halfmul")])
1541 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1542 (define_insn "dlmzb"
1543 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1544 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1545 (match_operand:SI 2 "gpc_reg_operand" "r")]
1547 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1548 (unspec:SI [(match_dup 1)
1554 (define_expand "strlensi"
1555 [(set (match_operand:SI 0 "gpc_reg_operand")
1556 (unspec:SI [(match_operand:BLK 1 "general_operand")
1557 (match_operand:QI 2 "const_int_operand")
1558 (match_operand 3 "const_int_operand")]
1559 UNSPEC_DLMZB_STRLEN))
1560 (clobber (match_scratch:CC 4))]
1561 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1563 rtx result = operands[0];
1564 rtx src = operands[1];
1565 rtx search_char = operands[2];
1566 rtx align = operands[3];
1567 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1568 rtx loop_label, end_label, mem, cr0, cond;
1569 if (search_char != const0_rtx
1570 || GET_CODE (align) != CONST_INT
1571 || INTVAL (align) < 8)
1573 word1 = gen_reg_rtx (SImode);
1574 word2 = gen_reg_rtx (SImode);
1575 scratch_dlmzb = gen_reg_rtx (SImode);
1576 scratch_string = gen_reg_rtx (Pmode);
1577 loop_label = gen_label_rtx ();
1578 end_label = gen_label_rtx ();
1579 addr = force_reg (Pmode, XEXP (src, 0));
1580 emit_move_insn (scratch_string, addr);
1581 emit_label (loop_label);
1582 mem = change_address (src, SImode, scratch_string);
1583 emit_move_insn (word1, mem);
1584 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1585 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1586 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1587 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1588 emit_jump_insn (gen_rtx_SET (pc_rtx,
1589 gen_rtx_IF_THEN_ELSE (VOIDmode,
1595 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1596 emit_jump_insn (gen_rtx_SET (pc_rtx,
1597 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1599 emit_label (end_label);
1600 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1601 emit_insn (gen_subsi3 (result, scratch_string, addr));
1602 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1606 ;; Fixed-point arithmetic insns.
1608 (define_expand "add<mode>3"
1609 [(set (match_operand:SDI 0 "gpc_reg_operand")
1610 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1611 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1614 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1616 rtx lo0 = gen_lowpart (SImode, operands[0]);
1617 rtx lo1 = gen_lowpart (SImode, operands[1]);
1618 rtx lo2 = gen_lowpart (SImode, operands[2]);
1619 rtx hi0 = gen_highpart (SImode, operands[0]);
1620 rtx hi1 = gen_highpart (SImode, operands[1]);
1621 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1623 if (!reg_or_short_operand (lo2, SImode))
1624 lo2 = force_reg (SImode, lo2);
1625 if (!adde_operand (hi2, SImode))
1626 hi2 = force_reg (SImode, hi2);
1628 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1629 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1633 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1635 rtx tmp = ((!can_create_pseudo_p ()
1636 || rtx_equal_p (operands[0], operands[1]))
1637 ? operands[0] : gen_reg_rtx (<MODE>mode));
1639 /* Adding a constant to r0 is not a valid insn, so use a different
1640 strategy in that case. */
1641 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1643 if (operands[0] == operands[1])
1645 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1646 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1650 HOST_WIDE_INT val = INTVAL (operands[2]);
1651 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1652 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1654 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1657 /* The ordering here is important for the prolog expander.
1658 When space is allocated from the stack, adding 'low' first may
1659 produce a temporary deallocation (which would be bad). */
1660 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1661 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1666 (define_insn "*add<mode>3"
1667 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1668 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1669 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1675 [(set_attr "type" "add")])
1677 (define_insn "*addsi3_high"
1678 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1679 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1680 (high:SI (match_operand 2 "" ""))))]
1681 "TARGET_MACHO && !TARGET_64BIT"
1682 "addis %0,%1,ha16(%2)"
1683 [(set_attr "type" "add")])
1685 (define_insn_and_split "*add<mode>3_dot"
1686 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1687 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1688 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1690 (clobber (match_scratch:GPR 0 "=r,r"))]
1691 "<MODE>mode == Pmode"
1695 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1697 (plus:GPR (match_dup 1)
1700 (compare:CC (match_dup 0)
1703 [(set_attr "type" "add")
1704 (set_attr "dot" "yes")
1705 (set_attr "length" "4,8")])
1707 (define_insn_and_split "*add<mode>3_dot2"
1708 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1709 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1710 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1712 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1713 (plus:GPR (match_dup 1)
1715 "<MODE>mode == Pmode"
1719 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1721 (plus:GPR (match_dup 1)
1724 (compare:CC (match_dup 0)
1727 [(set_attr "type" "add")
1728 (set_attr "dot" "yes")
1729 (set_attr "length" "4,8")])
1731 (define_insn_and_split "*add<mode>3_imm_dot"
1732 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1733 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1734 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1736 (clobber (match_scratch:GPR 0 "=r,r"))
1737 (clobber (reg:GPR CA_REGNO))]
1738 "<MODE>mode == Pmode"
1742 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1744 (plus:GPR (match_dup 1)
1747 (compare:CC (match_dup 0)
1750 [(set_attr "type" "add")
1751 (set_attr "dot" "yes")
1752 (set_attr "length" "4,8")])
1754 (define_insn_and_split "*add<mode>3_imm_dot2"
1755 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1756 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1757 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1759 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1760 (plus:GPR (match_dup 1)
1762 (clobber (reg:GPR CA_REGNO))]
1763 "<MODE>mode == Pmode"
1767 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1769 (plus:GPR (match_dup 1)
1772 (compare:CC (match_dup 0)
1775 [(set_attr "type" "add")
1776 (set_attr "dot" "yes")
1777 (set_attr "length" "4,8")])
1779 ;; Split an add that we can't do in one insn into two insns, each of which
1780 ;; does one 16-bit part. This is used by combine. Note that the low-order
1781 ;; add should be last in case the result gets used in an address.
1784 [(set (match_operand:GPR 0 "gpc_reg_operand")
1785 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1786 (match_operand:GPR 2 "non_add_cint_operand")))]
1788 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1789 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1791 HOST_WIDE_INT val = INTVAL (operands[2]);
1792 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1793 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1795 operands[4] = GEN_INT (low);
1796 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1797 operands[3] = GEN_INT (rest);
1798 else if (can_create_pseudo_p ())
1800 operands[3] = gen_reg_rtx (DImode);
1801 emit_move_insn (operands[3], operands[2]);
1802 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1810 (define_insn "add<mode>3_carry"
1811 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1812 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1813 (match_operand:P 2 "reg_or_short_operand" "rI")))
1814 (set (reg:P CA_REGNO)
1815 (ltu:P (plus:P (match_dup 1)
1820 [(set_attr "type" "add")])
1822 (define_insn "*add<mode>3_imm_carry_pos"
1823 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1824 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1825 (match_operand:P 2 "short_cint_operand" "n")))
1826 (set (reg:P CA_REGNO)
1827 (geu:P (match_dup 1)
1828 (match_operand:P 3 "const_int_operand" "n")))]
1829 "INTVAL (operands[2]) > 0
1830 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1832 [(set_attr "type" "add")])
1834 (define_insn "*add<mode>3_imm_carry_0"
1835 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1836 (match_operand:P 1 "gpc_reg_operand" "r"))
1837 (set (reg:P CA_REGNO)
1841 [(set_attr "type" "add")])
1843 (define_insn "*add<mode>3_imm_carry_m1"
1844 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1845 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1847 (set (reg:P CA_REGNO)
1852 [(set_attr "type" "add")])
1854 (define_insn "*add<mode>3_imm_carry_neg"
1855 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1856 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1857 (match_operand:P 2 "short_cint_operand" "n")))
1858 (set (reg:P CA_REGNO)
1859 (gtu:P (match_dup 1)
1860 (match_operand:P 3 "const_int_operand" "n")))]
1861 "INTVAL (operands[2]) < 0
1862 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1864 [(set_attr "type" "add")])
1867 (define_expand "add<mode>3_carry_in"
1869 (set (match_operand:GPR 0 "gpc_reg_operand")
1870 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1871 (match_operand:GPR 2 "adde_operand"))
1872 (reg:GPR CA_REGNO)))
1873 (clobber (reg:GPR CA_REGNO))])]
1876 if (operands[2] == const0_rtx)
1878 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1881 if (operands[2] == constm1_rtx)
1883 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1888 (define_insn "*add<mode>3_carry_in_internal"
1889 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1890 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1891 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1892 (reg:GPR CA_REGNO)))
1893 (clobber (reg:GPR CA_REGNO))]
1896 [(set_attr "type" "add")])
1898 (define_insn "*add<mode>3_carry_in_internal2"
1899 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1900 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1902 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1903 (clobber (reg:GPR CA_REGNO))]
1906 [(set_attr "type" "add")])
1908 (define_insn "add<mode>3_carry_in_0"
1909 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1910 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1911 (reg:GPR CA_REGNO)))
1912 (clobber (reg:GPR CA_REGNO))]
1915 [(set_attr "type" "add")])
1917 (define_insn "add<mode>3_carry_in_m1"
1918 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1919 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1922 (clobber (reg:GPR CA_REGNO))]
1925 [(set_attr "type" "add")])
1928 (define_expand "one_cmpl<mode>2"
1929 [(set (match_operand:SDI 0 "gpc_reg_operand")
1930 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1933 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1935 rs6000_split_logical (operands, NOT, false, false, false);
1940 (define_insn "*one_cmpl<mode>2"
1941 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1942 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1946 (define_insn_and_split "*one_cmpl<mode>2_dot"
1947 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1948 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1950 (clobber (match_scratch:GPR 0 "=r,r"))]
1951 "<MODE>mode == Pmode"
1955 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1957 (not:GPR (match_dup 1)))
1959 (compare:CC (match_dup 0)
1962 [(set_attr "type" "logical")
1963 (set_attr "dot" "yes")
1964 (set_attr "length" "4,8")])
1966 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1967 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1968 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1970 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1971 (not:GPR (match_dup 1)))]
1972 "<MODE>mode == Pmode"
1976 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1978 (not:GPR (match_dup 1)))
1980 (compare:CC (match_dup 0)
1983 [(set_attr "type" "logical")
1984 (set_attr "dot" "yes")
1985 (set_attr "length" "4,8")])
1988 (define_expand "sub<mode>3"
1989 [(set (match_operand:SDI 0 "gpc_reg_operand")
1990 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
1991 (match_operand:SDI 2 "gpc_reg_operand")))]
1994 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1996 rtx lo0 = gen_lowpart (SImode, operands[0]);
1997 rtx lo1 = gen_lowpart (SImode, operands[1]);
1998 rtx lo2 = gen_lowpart (SImode, operands[2]);
1999 rtx hi0 = gen_highpart (SImode, operands[0]);
2000 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2001 rtx hi2 = gen_highpart (SImode, operands[2]);
2003 if (!reg_or_short_operand (lo1, SImode))
2004 lo1 = force_reg (SImode, lo1);
2005 if (!adde_operand (hi1, SImode))
2006 hi1 = force_reg (SImode, hi1);
2008 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2009 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2013 if (short_cint_operand (operands[1], <MODE>mode))
2015 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2020 (define_insn "*subf<mode>3"
2021 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2022 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2023 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2026 [(set_attr "type" "add")])
2028 (define_insn_and_split "*subf<mode>3_dot"
2029 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2030 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2031 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2033 (clobber (match_scratch:GPR 0 "=r,r"))]
2034 "<MODE>mode == Pmode"
2038 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2040 (minus:GPR (match_dup 2)
2043 (compare:CC (match_dup 0)
2046 [(set_attr "type" "add")
2047 (set_attr "dot" "yes")
2048 (set_attr "length" "4,8")])
2050 (define_insn_and_split "*subf<mode>3_dot2"
2051 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2052 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2053 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2055 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2056 (minus:GPR (match_dup 2)
2058 "<MODE>mode == Pmode"
2062 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2064 (minus:GPR (match_dup 2)
2067 (compare:CC (match_dup 0)
2070 [(set_attr "type" "add")
2071 (set_attr "dot" "yes")
2072 (set_attr "length" "4,8")])
2074 (define_insn "subf<mode>3_imm"
2075 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2076 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2077 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2078 (clobber (reg:GPR CA_REGNO))]
2081 [(set_attr "type" "add")])
2083 (define_insn_and_split "subf<mode>3_carry_dot2"
2084 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2085 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2086 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2088 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2089 (minus:P (match_dup 2)
2091 (set (reg:P CA_REGNO)
2092 (leu:P (match_dup 1)
2094 "<MODE>mode == Pmode"
2098 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2099 [(parallel [(set (match_dup 0)
2100 (minus:P (match_dup 2)
2102 (set (reg:P CA_REGNO)
2103 (leu:P (match_dup 1)
2106 (compare:CC (match_dup 0)
2109 [(set_attr "type" "add")
2110 (set_attr "dot" "yes")
2111 (set_attr "length" "4,8")])
2113 (define_insn "subf<mode>3_carry"
2114 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2115 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2116 (match_operand:P 1 "gpc_reg_operand" "r")))
2117 (set (reg:P CA_REGNO)
2118 (leu:P (match_dup 1)
2122 [(set_attr "type" "add")])
2124 (define_insn "*subf<mode>3_imm_carry_0"
2125 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2126 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2127 (set (reg:P CA_REGNO)
2132 [(set_attr "type" "add")])
2134 (define_insn "*subf<mode>3_imm_carry_m1"
2135 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2136 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2137 (set (reg:P CA_REGNO)
2141 [(set_attr "type" "add")])
2144 (define_expand "subf<mode>3_carry_in"
2146 (set (match_operand:GPR 0 "gpc_reg_operand")
2147 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2149 (match_operand:GPR 2 "adde_operand")))
2150 (clobber (reg:GPR CA_REGNO))])]
2153 if (operands[2] == const0_rtx)
2155 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2158 if (operands[2] == constm1_rtx)
2160 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2165 (define_insn "*subf<mode>3_carry_in_internal"
2166 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2167 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2169 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2170 (clobber (reg:GPR CA_REGNO))]
2173 [(set_attr "type" "add")])
2175 (define_insn "subf<mode>3_carry_in_0"
2176 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2177 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2178 (reg:GPR CA_REGNO)))
2179 (clobber (reg:GPR CA_REGNO))]
2182 [(set_attr "type" "add")])
2184 (define_insn "subf<mode>3_carry_in_m1"
2185 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2186 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2187 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2189 (clobber (reg:GPR CA_REGNO))]
2192 [(set_attr "type" "add")])
2194 (define_insn "subf<mode>3_carry_in_xx"
2195 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2196 (plus:GPR (reg:GPR CA_REGNO)
2198 (clobber (reg:GPR CA_REGNO))]
2201 [(set_attr "type" "add")])
2204 (define_insn "neg<mode>2"
2205 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2206 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2209 [(set_attr "type" "add")])
2211 (define_insn_and_split "*neg<mode>2_dot"
2212 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2213 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2215 (clobber (match_scratch:GPR 0 "=r,r"))]
2216 "<MODE>mode == Pmode"
2220 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2222 (neg:GPR (match_dup 1)))
2224 (compare:CC (match_dup 0)
2227 [(set_attr "type" "add")
2228 (set_attr "dot" "yes")
2229 (set_attr "length" "4,8")])
2231 (define_insn_and_split "*neg<mode>2_dot2"
2232 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2233 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2235 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2236 (neg:GPR (match_dup 1)))]
2237 "<MODE>mode == Pmode"
2241 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2243 (neg:GPR (match_dup 1)))
2245 (compare:CC (match_dup 0)
2248 [(set_attr "type" "add")
2249 (set_attr "dot" "yes")
2250 (set_attr "length" "4,8")])
2253 (define_insn "clz<mode>2"
2254 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2255 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2258 [(set_attr "type" "cntlz")])
2260 (define_expand "ctz<mode>2"
2261 [(set (match_operand:GPR 0 "gpc_reg_operand")
2262 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2267 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2271 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2272 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2273 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2277 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2278 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2279 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2280 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2284 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2285 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2286 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2287 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2293 (define_insn "ctz<mode>2_hw"
2294 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2295 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2298 [(set_attr "type" "cntlz")])
2300 (define_expand "ffs<mode>2"
2301 [(set (match_operand:GPR 0 "gpc_reg_operand")
2302 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2305 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2306 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2307 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2308 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2309 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2310 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2311 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2316 (define_expand "popcount<mode>2"
2317 [(set (match_operand:GPR 0 "gpc_reg_operand")
2318 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2319 "TARGET_POPCNTB || TARGET_POPCNTD"
2321 rs6000_emit_popcount (operands[0], operands[1]);
2325 (define_insn "popcntb<mode>2"
2326 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2327 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2331 [(set_attr "type" "popcnt")])
2333 (define_insn "popcntd<mode>2"
2334 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2335 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2338 [(set_attr "type" "popcnt")])
2341 (define_expand "parity<mode>2"
2342 [(set (match_operand:GPR 0 "gpc_reg_operand")
2343 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2346 rs6000_emit_parity (operands[0], operands[1]);
2350 (define_insn "parity<mode>2_cmpb"
2351 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2352 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2353 "TARGET_CMPB && TARGET_POPCNTB"
2355 [(set_attr "type" "popcnt")])
2357 (define_insn "cmpb<mode>3"
2358 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2359 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2360 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2363 [(set_attr "type" "cmp")])
2365 ;; Since the hardware zeros the upper part of the register, save generating the
2366 ;; AND immediate if we are converting to unsigned
2367 (define_insn "*bswap<mode>2_extenddi"
2368 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2370 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2373 [(set_attr "type" "load")])
2375 (define_insn "*bswaphi2_extendsi"
2376 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2378 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2381 [(set_attr "type" "load")])
2383 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2384 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2385 ;; load with byte swap, which can be slower than doing it in the registers. It
2386 ;; also prevents certain failures with the RELOAD register allocator.
2388 (define_expand "bswap<mode>2"
2389 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2390 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2393 rtx dest = operands[0];
2394 rtx src = operands[1];
2396 if (!REG_P (dest) && !REG_P (src))
2397 src = force_reg (<MODE>mode, src);
2401 src = rs6000_force_indexed_or_indirect_mem (src);
2402 emit_insn (gen_bswap<mode>2_load (dest, src));
2404 else if (MEM_P (dest))
2406 dest = rs6000_force_indexed_or_indirect_mem (dest);
2407 emit_insn (gen_bswap<mode>2_store (dest, src));
2410 emit_insn (gen_bswap<mode>2_reg (dest, src));
2414 (define_insn "bswap<mode>2_load"
2415 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2416 (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2419 [(set_attr "type" "load")])
2421 (define_insn "bswap<mode>2_store"
2422 [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2423 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2426 [(set_attr "type" "store")])
2428 (define_insn_and_split "bswaphi2_reg"
2429 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2431 (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2432 (clobber (match_scratch:SI 2 "=&r,X"))]
2437 "reload_completed && int_reg_operand (operands[0], HImode)"
2439 (and:SI (lshiftrt:SI (match_dup 4)
2443 (and:SI (ashift:SI (match_dup 4)
2445 (const_int 65280))) ;; 0xff00
2447 (ior:SI (match_dup 3)
2450 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2451 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2453 [(set_attr "length" "12,4")
2454 (set_attr "type" "*,vecperm")])
2456 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2457 ;; zero_extract insns do not change for -mlittle.
2458 (define_insn_and_split "bswapsi2_reg"
2459 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2461 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2466 "reload_completed && int_reg_operand (operands[0], SImode)"
2467 [(set (match_dup 0) ; DABC
2468 (rotate:SI (match_dup 1)
2470 (set (match_dup 0) ; DCBC
2471 (ior:SI (and:SI (ashift:SI (match_dup 1)
2473 (const_int 16711680))
2474 (and:SI (match_dup 0)
2475 (const_int -16711681))))
2476 (set (match_dup 0) ; DCBA
2477 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2480 (and:SI (match_dup 0)
2481 (const_int -256))))]
2483 [(set_attr "length" "12,4")
2484 (set_attr "type" "*,vecperm")])
2486 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2487 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2490 (define_expand "bswapdi2"
2491 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2493 (match_operand:DI 1 "reg_or_mem_operand")))
2494 (clobber (match_scratch:DI 2))
2495 (clobber (match_scratch:DI 3))])]
2498 rtx dest = operands[0];
2499 rtx src = operands[1];
2501 if (!REG_P (dest) && !REG_P (src))
2502 operands[1] = src = force_reg (DImode, src);
2504 if (TARGET_POWERPC64 && TARGET_LDBRX)
2508 src = rs6000_force_indexed_or_indirect_mem (src);
2509 emit_insn (gen_bswapdi2_load (dest, src));
2511 else if (MEM_P (dest))
2513 dest = rs6000_force_indexed_or_indirect_mem (dest);
2514 emit_insn (gen_bswapdi2_store (dest, src));
2516 else if (TARGET_P9_VECTOR)
2517 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2519 emit_insn (gen_bswapdi2_reg (dest, src));
2523 if (!TARGET_POWERPC64)
2525 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2526 that uses 64-bit registers needs the same scratch registers as 64-bit
2528 emit_insn (gen_bswapdi2_32bit (dest, src));
2533 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2534 (define_insn "bswapdi2_load"
2535 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2536 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2537 "TARGET_POWERPC64 && TARGET_LDBRX"
2539 [(set_attr "type" "load")])
2541 (define_insn "bswapdi2_store"
2542 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2543 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2544 "TARGET_POWERPC64 && TARGET_LDBRX"
2546 [(set_attr "type" "store")])
2548 (define_insn "bswapdi2_xxbrd"
2549 [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2550 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2553 [(set_attr "type" "vecperm")])
2555 (define_insn "bswapdi2_reg"
2556 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2557 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2558 (clobber (match_scratch:DI 2 "=&r"))
2559 (clobber (match_scratch:DI 3 "=&r"))]
2560 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2562 [(set_attr "length" "36")])
2564 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2565 (define_insn "*bswapdi2_64bit"
2566 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2567 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2568 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2569 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2570 "TARGET_POWERPC64 && !TARGET_LDBRX
2571 && (REG_P (operands[0]) || REG_P (operands[1]))
2572 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2573 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2575 [(set_attr "length" "16,12,36")])
2578 [(set (match_operand:DI 0 "gpc_reg_operand")
2579 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2580 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2581 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2582 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2585 rtx dest = operands[0];
2586 rtx src = operands[1];
2587 rtx op2 = operands[2];
2588 rtx op3 = operands[3];
2589 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2590 BYTES_BIG_ENDIAN ? 4 : 0);
2591 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2592 BYTES_BIG_ENDIAN ? 4 : 0);
2598 addr1 = XEXP (src, 0);
2599 if (GET_CODE (addr1) == PLUS)
2601 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2602 if (TARGET_AVOID_XFORM)
2604 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2608 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2610 else if (TARGET_AVOID_XFORM)
2612 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2617 emit_move_insn (op2, GEN_INT (4));
2618 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2621 word1 = change_address (src, SImode, addr1);
2622 word2 = change_address (src, SImode, addr2);
2624 if (BYTES_BIG_ENDIAN)
2626 emit_insn (gen_bswapsi2 (op3_32, word2));
2627 emit_insn (gen_bswapsi2 (dest_32, word1));
2631 emit_insn (gen_bswapsi2 (op3_32, word1));
2632 emit_insn (gen_bswapsi2 (dest_32, word2));
2635 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2636 emit_insn (gen_iordi3 (dest, dest, op3));
2641 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2642 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2643 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2644 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2645 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2648 rtx dest = operands[0];
2649 rtx src = operands[1];
2650 rtx op2 = operands[2];
2651 rtx op3 = operands[3];
2652 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2653 BYTES_BIG_ENDIAN ? 4 : 0);
2654 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2655 BYTES_BIG_ENDIAN ? 4 : 0);
2661 addr1 = XEXP (dest, 0);
2662 if (GET_CODE (addr1) == PLUS)
2664 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2665 if (TARGET_AVOID_XFORM)
2667 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2671 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2673 else if (TARGET_AVOID_XFORM)
2675 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2680 emit_move_insn (op2, GEN_INT (4));
2681 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2684 word1 = change_address (dest, SImode, addr1);
2685 word2 = change_address (dest, SImode, addr2);
2687 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2689 if (BYTES_BIG_ENDIAN)
2691 emit_insn (gen_bswapsi2 (word1, src_si));
2692 emit_insn (gen_bswapsi2 (word2, op3_si));
2696 emit_insn (gen_bswapsi2 (word2, src_si));
2697 emit_insn (gen_bswapsi2 (word1, op3_si));
2703 [(set (match_operand:DI 0 "gpc_reg_operand")
2704 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2705 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2706 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2707 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2710 rtx dest = operands[0];
2711 rtx src = operands[1];
2712 rtx op2 = operands[2];
2713 rtx op3 = operands[3];
2714 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2715 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2716 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2717 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2718 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2720 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2721 emit_insn (gen_bswapsi2 (dest_si, src_si));
2722 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2723 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2724 emit_insn (gen_iordi3 (dest, dest, op3));
2728 (define_insn "bswapdi2_32bit"
2729 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2730 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2731 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2732 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2734 [(set_attr "length" "16,12,36")])
2737 [(set (match_operand:DI 0 "gpc_reg_operand")
2738 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2739 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2740 "!TARGET_POWERPC64 && reload_completed"
2743 rtx dest = operands[0];
2744 rtx src = operands[1];
2745 rtx op2 = operands[2];
2746 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2747 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2753 addr1 = XEXP (src, 0);
2754 if (GET_CODE (addr1) == PLUS)
2756 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2757 if (TARGET_AVOID_XFORM
2758 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2760 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2764 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2766 else if (TARGET_AVOID_XFORM
2767 || REGNO (addr1) == REGNO (dest2))
2769 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2774 emit_move_insn (op2, GEN_INT (4));
2775 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2778 word1 = change_address (src, SImode, addr1);
2779 word2 = change_address (src, SImode, addr2);
2781 emit_insn (gen_bswapsi2 (dest2, word1));
2782 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2783 thus allowing us to omit an early clobber on the output. */
2784 emit_insn (gen_bswapsi2 (dest1, word2));
2789 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2790 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2791 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2792 "!TARGET_POWERPC64 && reload_completed"
2795 rtx dest = operands[0];
2796 rtx src = operands[1];
2797 rtx op2 = operands[2];
2798 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2799 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2805 addr1 = XEXP (dest, 0);
2806 if (GET_CODE (addr1) == PLUS)
2808 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2809 if (TARGET_AVOID_XFORM)
2811 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2815 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2817 else if (TARGET_AVOID_XFORM)
2819 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2824 emit_move_insn (op2, GEN_INT (4));
2825 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2828 word1 = change_address (dest, SImode, addr1);
2829 word2 = change_address (dest, SImode, addr2);
2831 emit_insn (gen_bswapsi2 (word2, src1));
2832 emit_insn (gen_bswapsi2 (word1, src2));
2837 [(set (match_operand:DI 0 "gpc_reg_operand")
2838 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2839 (clobber (match_operand:SI 2 ""))]
2840 "!TARGET_POWERPC64 && reload_completed"
2843 rtx dest = operands[0];
2844 rtx src = operands[1];
2845 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2846 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2847 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2848 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2850 emit_insn (gen_bswapsi2 (dest1, src2));
2851 emit_insn (gen_bswapsi2 (dest2, src1));
2856 (define_insn "mul<mode>3"
2857 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2858 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2859 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2864 [(set_attr "type" "mul")
2866 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2868 (match_operand:GPR 2 "short_cint_operand")
2869 (const_string "16")]
2870 (const_string "<bits>")))])
2872 (define_insn_and_split "*mul<mode>3_dot"
2873 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2874 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2875 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2877 (clobber (match_scratch:GPR 0 "=r,r"))]
2878 "<MODE>mode == Pmode"
2882 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2884 (mult:GPR (match_dup 1)
2887 (compare:CC (match_dup 0)
2890 [(set_attr "type" "mul")
2891 (set_attr "size" "<bits>")
2892 (set_attr "dot" "yes")
2893 (set_attr "length" "4,8")])
2895 (define_insn_and_split "*mul<mode>3_dot2"
2896 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2897 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2898 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2900 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2901 (mult:GPR (match_dup 1)
2903 "<MODE>mode == Pmode"
2907 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2909 (mult:GPR (match_dup 1)
2912 (compare:CC (match_dup 0)
2915 [(set_attr "type" "mul")
2916 (set_attr "size" "<bits>")
2917 (set_attr "dot" "yes")
2918 (set_attr "length" "4,8")])
2921 (define_expand "<su>mul<mode>3_highpart"
2922 [(set (match_operand:GPR 0 "gpc_reg_operand")
2924 (mult:<DMODE> (any_extend:<DMODE>
2925 (match_operand:GPR 1 "gpc_reg_operand"))
2927 (match_operand:GPR 2 "gpc_reg_operand")))
2931 if (<MODE>mode == SImode && TARGET_POWERPC64)
2933 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2938 if (!WORDS_BIG_ENDIAN)
2940 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2946 (define_insn "*<su>mul<mode>3_highpart"
2947 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2949 (mult:<DMODE> (any_extend:<DMODE>
2950 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2952 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2954 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2955 "mulh<wd><u> %0,%1,%2"
2956 [(set_attr "type" "mul")
2957 (set_attr "size" "<bits>")])
2959 (define_insn "<su>mulsi3_highpart_le"
2960 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2962 (mult:DI (any_extend:DI
2963 (match_operand:SI 1 "gpc_reg_operand" "r"))
2965 (match_operand:SI 2 "gpc_reg_operand" "r")))
2967 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2969 [(set_attr "type" "mul")])
2971 (define_insn "<su>muldi3_highpart_le"
2972 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2974 (mult:TI (any_extend:TI
2975 (match_operand:DI 1 "gpc_reg_operand" "r"))
2977 (match_operand:DI 2 "gpc_reg_operand" "r")))
2979 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2981 [(set_attr "type" "mul")
2982 (set_attr "size" "64")])
2984 (define_insn "<su>mulsi3_highpart_64"
2985 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2988 (mult:DI (any_extend:DI
2989 (match_operand:SI 1 "gpc_reg_operand" "r"))
2991 (match_operand:SI 2 "gpc_reg_operand" "r")))
2995 [(set_attr "type" "mul")])
2997 (define_expand "<u>mul<mode><dmode>3"
2998 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2999 (mult:<DMODE> (any_extend:<DMODE>
3000 (match_operand:GPR 1 "gpc_reg_operand"))
3002 (match_operand:GPR 2 "gpc_reg_operand"))))]
3003 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3005 rtx l = gen_reg_rtx (<MODE>mode);
3006 rtx h = gen_reg_rtx (<MODE>mode);
3007 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3008 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3009 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3010 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3014 (define_insn "*maddld4"
3015 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3016 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3017 (match_operand:DI 2 "gpc_reg_operand" "r"))
3018 (match_operand:DI 3 "gpc_reg_operand" "r")))]
3020 "maddld %0,%1,%2,%3"
3021 [(set_attr "type" "mul")])
3023 (define_insn "udiv<mode>3"
3024 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3025 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3026 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3029 [(set_attr "type" "div")
3030 (set_attr "size" "<bits>")])
3033 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3034 ;; modulus. If it isn't a power of two, force operands into register and do
3036 (define_expand "div<mode>3"
3037 [(set (match_operand:GPR 0 "gpc_reg_operand")
3038 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3039 (match_operand:GPR 2 "reg_or_cint_operand")))]
3042 if (CONST_INT_P (operands[2])
3043 && INTVAL (operands[2]) > 0
3044 && exact_log2 (INTVAL (operands[2])) >= 0)
3046 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3050 operands[2] = force_reg (<MODE>mode, operands[2]);
3053 (define_insn "*div<mode>3"
3054 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3055 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3056 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3059 [(set_attr "type" "div")
3060 (set_attr "size" "<bits>")])
3062 (define_insn "div<mode>3_sra"
3063 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3064 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3065 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3066 (clobber (reg:GPR CA_REGNO))]
3068 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3069 [(set_attr "type" "two")
3070 (set_attr "length" "8")])
3072 (define_insn_and_split "*div<mode>3_sra_dot"
3073 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3074 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3075 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3077 (clobber (match_scratch:GPR 0 "=r,r"))
3078 (clobber (reg:GPR CA_REGNO))]
3079 "<MODE>mode == Pmode"
3081 sra<wd>i %0,%1,%p2\;addze. %0,%0
3083 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3084 [(parallel [(set (match_dup 0)
3085 (div:GPR (match_dup 1)
3087 (clobber (reg:GPR CA_REGNO))])
3089 (compare:CC (match_dup 0)
3092 [(set_attr "type" "two")
3093 (set_attr "length" "8,12")
3094 (set_attr "cell_micro" "not")])
3096 (define_insn_and_split "*div<mode>3_sra_dot2"
3097 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3098 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3099 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3101 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3102 (div:GPR (match_dup 1)
3104 (clobber (reg:GPR CA_REGNO))]
3105 "<MODE>mode == Pmode"
3107 sra<wd>i %0,%1,%p2\;addze. %0,%0
3109 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3110 [(parallel [(set (match_dup 0)
3111 (div:GPR (match_dup 1)
3113 (clobber (reg:GPR CA_REGNO))])
3115 (compare:CC (match_dup 0)
3118 [(set_attr "type" "two")
3119 (set_attr "length" "8,12")
3120 (set_attr "cell_micro" "not")])
3122 (define_expand "mod<mode>3"
3123 [(set (match_operand:GPR 0 "gpc_reg_operand")
3124 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3125 (match_operand:GPR 2 "reg_or_cint_operand")))]
3132 if (GET_CODE (operands[2]) != CONST_INT
3133 || INTVAL (operands[2]) <= 0
3134 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3139 operands[2] = force_reg (<MODE>mode, operands[2]);
3143 temp1 = gen_reg_rtx (<MODE>mode);
3144 temp2 = gen_reg_rtx (<MODE>mode);
3146 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3147 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3148 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3153 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3154 ;; mod, prefer putting the result of mod into a different register
3155 (define_insn "*mod<mode>3"
3156 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3157 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3158 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3161 [(set_attr "type" "div")
3162 (set_attr "size" "<bits>")])
3165 (define_insn "umod<mode>3"
3166 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3167 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3168 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3171 [(set_attr "type" "div")
3172 (set_attr "size" "<bits>")])
3174 ;; On machines with modulo support, do a combined div/mod the old fashioned
3175 ;; method, since the multiply/subtract is faster than doing the mod instruction
3179 [(set (match_operand:GPR 0 "gpc_reg_operand")
3180 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3181 (match_operand:GPR 2 "gpc_reg_operand")))
3182 (set (match_operand:GPR 3 "gpc_reg_operand")
3183 (mod:GPR (match_dup 1)
3186 && ! reg_mentioned_p (operands[0], operands[1])
3187 && ! reg_mentioned_p (operands[0], operands[2])
3188 && ! reg_mentioned_p (operands[3], operands[1])
3189 && ! reg_mentioned_p (operands[3], operands[2])"
3191 (div:GPR (match_dup 1)
3194 (mult:GPR (match_dup 0)
3197 (minus:GPR (match_dup 1)
3201 [(set (match_operand:GPR 0 "gpc_reg_operand")
3202 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3203 (match_operand:GPR 2 "gpc_reg_operand")))
3204 (set (match_operand:GPR 3 "gpc_reg_operand")
3205 (umod:GPR (match_dup 1)
3208 && ! reg_mentioned_p (operands[0], operands[1])
3209 && ! reg_mentioned_p (operands[0], operands[2])
3210 && ! reg_mentioned_p (operands[3], operands[1])
3211 && ! reg_mentioned_p (operands[3], operands[2])"
3213 (udiv:GPR (match_dup 1)
3216 (mult:GPR (match_dup 0)
3219 (minus:GPR (match_dup 1)
3223 ;; Logical instructions
3224 ;; The logical instructions are mostly combined by using match_operator,
3225 ;; but the plain AND insns are somewhat different because there is no
3226 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3227 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3229 (define_expand "and<mode>3"
3230 [(set (match_operand:SDI 0 "gpc_reg_operand")
3231 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3232 (match_operand:SDI 2 "reg_or_cint_operand")))]
3235 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3237 rs6000_split_logical (operands, AND, false, false, false);
3241 if (CONST_INT_P (operands[2]))
3243 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3245 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3249 if (logical_const_operand (operands[2], <MODE>mode))
3251 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3255 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3257 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3261 operands[2] = force_reg (<MODE>mode, operands[2]);
3266 (define_insn "and<mode>3_imm"
3267 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3268 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3269 (match_operand:GPR 2 "logical_const_operand" "n")))
3270 (clobber (match_scratch:CC 3 "=x"))]
3271 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3272 "andi%e2. %0,%1,%u2"
3273 [(set_attr "type" "logical")
3274 (set_attr "dot" "yes")])
3276 (define_insn_and_split "*and<mode>3_imm_dot"
3277 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3278 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3279 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3281 (clobber (match_scratch:GPR 0 "=r,r"))
3282 (clobber (match_scratch:CC 4 "=X,x"))]
3283 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3284 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3288 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3289 [(parallel [(set (match_dup 0)
3290 (and:GPR (match_dup 1)
3292 (clobber (match_dup 4))])
3294 (compare:CC (match_dup 0)
3297 [(set_attr "type" "logical")
3298 (set_attr "dot" "yes")
3299 (set_attr "length" "4,8")])
3301 (define_insn_and_split "*and<mode>3_imm_dot2"
3302 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3303 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3304 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3306 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3307 (and:GPR (match_dup 1)
3309 (clobber (match_scratch:CC 4 "=X,x"))]
3310 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3311 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3315 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3316 [(parallel [(set (match_dup 0)
3317 (and:GPR (match_dup 1)
3319 (clobber (match_dup 4))])
3321 (compare:CC (match_dup 0)
3324 [(set_attr "type" "logical")
3325 (set_attr "dot" "yes")
3326 (set_attr "length" "4,8")])
3328 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3329 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3330 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3331 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3333 (clobber (match_scratch:GPR 0 "=r,r"))]
3334 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3335 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3339 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3341 (and:GPR (match_dup 1)
3344 (compare:CC (match_dup 0)
3347 [(set_attr "type" "logical")
3348 (set_attr "dot" "yes")
3349 (set_attr "length" "4,8")])
3351 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3352 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3353 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3354 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3356 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3357 (and:GPR (match_dup 1)
3359 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3360 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3364 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3366 (and:GPR (match_dup 1)
3369 (compare:CC (match_dup 0)
3372 [(set_attr "type" "logical")
3373 (set_attr "dot" "yes")
3374 (set_attr "length" "4,8")])
3376 (define_insn "*and<mode>3_imm_dot_shifted"
3377 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3380 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3381 (match_operand:SI 4 "const_int_operand" "n"))
3382 (match_operand:GPR 2 "const_int_operand" "n"))
3384 (clobber (match_scratch:GPR 0 "=r"))]
3385 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3386 << INTVAL (operands[4])),
3388 && (<MODE>mode == Pmode
3389 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3391 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3392 return "andi%e2. %0,%1,%u2";
3394 [(set_attr "type" "logical")
3395 (set_attr "dot" "yes")])
3398 (define_insn "and<mode>3_mask"
3399 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3400 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3401 (match_operand:GPR 2 "const_int_operand" "n")))]
3402 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3404 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3406 [(set_attr "type" "shift")])
3408 (define_insn_and_split "*and<mode>3_mask_dot"
3409 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3410 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3411 (match_operand:GPR 2 "const_int_operand" "n,n"))
3413 (clobber (match_scratch:GPR 0 "=r,r"))]
3414 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3415 && !logical_const_operand (operands[2], <MODE>mode)
3416 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3418 if (which_alternative == 0)
3419 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3423 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3425 (and:GPR (match_dup 1)
3428 (compare:CC (match_dup 0)
3431 [(set_attr "type" "shift")
3432 (set_attr "dot" "yes")
3433 (set_attr "length" "4,8")])
3435 (define_insn_and_split "*and<mode>3_mask_dot2"
3436 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3437 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3438 (match_operand:GPR 2 "const_int_operand" "n,n"))
3440 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3441 (and:GPR (match_dup 1)
3443 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3444 && !logical_const_operand (operands[2], <MODE>mode)
3445 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3447 if (which_alternative == 0)
3448 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3452 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3454 (and:GPR (match_dup 1)
3457 (compare:CC (match_dup 0)
3460 [(set_attr "type" "shift")
3461 (set_attr "dot" "yes")
3462 (set_attr "length" "4,8")])
3465 (define_insn_and_split "*and<mode>3_2insn"
3466 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3467 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3468 (match_operand:GPR 2 "const_int_operand" "n")))]
3469 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3470 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3471 || logical_const_operand (operands[2], <MODE>mode))"
3476 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3479 [(set_attr "type" "shift")
3480 (set_attr "length" "8")])
3482 (define_insn_and_split "*and<mode>3_2insn_dot"
3483 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3484 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3485 (match_operand:GPR 2 "const_int_operand" "n,n"))
3487 (clobber (match_scratch:GPR 0 "=r,r"))]
3488 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3489 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3490 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3491 || logical_const_operand (operands[2], <MODE>mode))"
3493 "&& reload_completed"
3496 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3499 [(set_attr "type" "shift")
3500 (set_attr "dot" "yes")
3501 (set_attr "length" "8,12")])
3503 (define_insn_and_split "*and<mode>3_2insn_dot2"
3504 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3505 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3506 (match_operand:GPR 2 "const_int_operand" "n,n"))
3508 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3509 (and:GPR (match_dup 1)
3511 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3512 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3513 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3514 || logical_const_operand (operands[2], <MODE>mode))"
3516 "&& reload_completed"
3519 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3522 [(set_attr "type" "shift")
3523 (set_attr "dot" "yes")
3524 (set_attr "length" "8,12")])
3527 (define_expand "<code><mode>3"
3528 [(set (match_operand:SDI 0 "gpc_reg_operand")
3529 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3530 (match_operand:SDI 2 "reg_or_cint_operand")))]
3533 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3535 rs6000_split_logical (operands, <CODE>, false, false, false);
3539 if (non_logical_cint_operand (operands[2], <MODE>mode))
3541 rtx tmp = ((!can_create_pseudo_p ()
3542 || rtx_equal_p (operands[0], operands[1]))
3543 ? operands[0] : gen_reg_rtx (<MODE>mode));
3545 HOST_WIDE_INT value = INTVAL (operands[2]);
3546 HOST_WIDE_INT lo = value & 0xffff;
3547 HOST_WIDE_INT hi = value - lo;
3549 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3550 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3554 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3555 operands[2] = force_reg (<MODE>mode, operands[2]);
3559 [(set (match_operand:GPR 0 "gpc_reg_operand")
3560 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3561 (match_operand:GPR 2 "non_logical_cint_operand")))]
3564 (iorxor:GPR (match_dup 1)
3567 (iorxor:GPR (match_dup 3)
3570 operands[3] = ((!can_create_pseudo_p ()
3571 || rtx_equal_p (operands[0], operands[1]))
3572 ? operands[0] : gen_reg_rtx (<MODE>mode));
3574 HOST_WIDE_INT value = INTVAL (operands[2]);
3575 HOST_WIDE_INT lo = value & 0xffff;
3576 HOST_WIDE_INT hi = value - lo;
3578 operands[4] = GEN_INT (hi);
3579 operands[5] = GEN_INT (lo);
3582 (define_insn "*bool<mode>3_imm"
3583 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3584 (match_operator:GPR 3 "boolean_or_operator"
3585 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3586 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3589 [(set_attr "type" "logical")])
3591 (define_insn "*bool<mode>3"
3592 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3593 (match_operator:GPR 3 "boolean_operator"
3594 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3595 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3598 [(set_attr "type" "logical")])
3600 (define_insn_and_split "*bool<mode>3_dot"
3601 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3602 (compare:CC (match_operator:GPR 3 "boolean_operator"
3603 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3604 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3606 (clobber (match_scratch:GPR 0 "=r,r"))]
3607 "<MODE>mode == Pmode"
3611 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3615 (compare:CC (match_dup 0)
3618 [(set_attr "type" "logical")
3619 (set_attr "dot" "yes")
3620 (set_attr "length" "4,8")])
3622 (define_insn_and_split "*bool<mode>3_dot2"
3623 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3624 (compare:CC (match_operator:GPR 3 "boolean_operator"
3625 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3626 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3628 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3630 "<MODE>mode == Pmode"
3634 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3638 (compare:CC (match_dup 0)
3641 [(set_attr "type" "logical")
3642 (set_attr "dot" "yes")
3643 (set_attr "length" "4,8")])
3646 (define_insn "*boolc<mode>3"
3647 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3648 (match_operator:GPR 3 "boolean_operator"
3649 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3650 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3653 [(set_attr "type" "logical")])
3655 (define_insn_and_split "*boolc<mode>3_dot"
3656 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3657 (compare:CC (match_operator:GPR 3 "boolean_operator"
3658 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3659 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3661 (clobber (match_scratch:GPR 0 "=r,r"))]
3662 "<MODE>mode == Pmode"
3666 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3670 (compare:CC (match_dup 0)
3673 [(set_attr "type" "logical")
3674 (set_attr "dot" "yes")
3675 (set_attr "length" "4,8")])
3677 (define_insn_and_split "*boolc<mode>3_dot2"
3678 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3679 (compare:CC (match_operator:GPR 3 "boolean_operator"
3680 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3681 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3683 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3685 "<MODE>mode == Pmode"
3689 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3693 (compare:CC (match_dup 0)
3696 [(set_attr "type" "logical")
3697 (set_attr "dot" "yes")
3698 (set_attr "length" "4,8")])
3701 (define_insn "*boolcc<mode>3"
3702 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3703 (match_operator:GPR 3 "boolean_operator"
3704 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3705 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3708 [(set_attr "type" "logical")])
3710 (define_insn_and_split "*boolcc<mode>3_dot"
3711 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3712 (compare:CC (match_operator:GPR 3 "boolean_operator"
3713 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3714 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3716 (clobber (match_scratch:GPR 0 "=r,r"))]
3717 "<MODE>mode == Pmode"
3721 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3725 (compare:CC (match_dup 0)
3728 [(set_attr "type" "logical")
3729 (set_attr "dot" "yes")
3730 (set_attr "length" "4,8")])
3732 (define_insn_and_split "*boolcc<mode>3_dot2"
3733 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3734 (compare:CC (match_operator:GPR 3 "boolean_operator"
3735 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3736 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3738 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3740 "<MODE>mode == Pmode"
3744 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3748 (compare:CC (match_dup 0)
3751 [(set_attr "type" "logical")
3752 (set_attr "dot" "yes")
3753 (set_attr "length" "4,8")])
3756 ;; TODO: Should have dots of this as well.
3757 (define_insn "*eqv<mode>3"
3758 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3759 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3760 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3763 [(set_attr "type" "logical")])
3765 ;; Rotate-and-mask and insert.
3767 (define_insn "*rotl<mode>3_mask"
3768 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3769 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3770 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3771 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3772 (match_operand:GPR 3 "const_int_operand" "n")))]
3773 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3775 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3777 [(set_attr "type" "shift")
3778 (set_attr "maybe_var_shift" "yes")])
3780 (define_insn_and_split "*rotl<mode>3_mask_dot"
3781 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3783 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3784 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3785 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3786 (match_operand:GPR 3 "const_int_operand" "n,n"))
3788 (clobber (match_scratch:GPR 0 "=r,r"))]
3789 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3790 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3792 if (which_alternative == 0)
3793 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3797 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3799 (and:GPR (match_dup 4)
3802 (compare:CC (match_dup 0)
3805 [(set_attr "type" "shift")
3806 (set_attr "maybe_var_shift" "yes")
3807 (set_attr "dot" "yes")
3808 (set_attr "length" "4,8")])
3810 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3811 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3813 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3814 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3815 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3816 (match_operand:GPR 3 "const_int_operand" "n,n"))
3818 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3819 (and:GPR (match_dup 4)
3821 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3822 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3824 if (which_alternative == 0)
3825 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3829 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3831 (and:GPR (match_dup 4)
3834 (compare:CC (match_dup 0)
3837 [(set_attr "type" "shift")
3838 (set_attr "maybe_var_shift" "yes")
3839 (set_attr "dot" "yes")
3840 (set_attr "length" "4,8")])
3842 ; Special case for less-than-0. We can do it with just one machine
3843 ; instruction, but the generic optimizers do not realise it is cheap.
3844 (define_insn "*lt0_<mode>di"
3845 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3846 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3850 [(set_attr "type" "shift")])
3852 (define_insn "*lt0_<mode>si"
3853 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3854 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3857 "rlwinm %0,%1,1,31,31"
3858 [(set_attr "type" "shift")])
3862 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3863 ; both are an AND so are the same precedence).
3864 (define_insn "*rotl<mode>3_insert"
3865 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3867 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3868 (match_operand:SI 2 "const_int_operand" "n")])
3869 (match_operand:GPR 3 "const_int_operand" "n"))
3870 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3871 (match_operand:GPR 6 "const_int_operand" "n"))))]
3872 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3873 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3875 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3877 [(set_attr "type" "insert")])
3878 ; FIXME: this needs an attr "size", so that the scheduler can see the
3879 ; difference between rlwimi and rldimi. We also might want dot forms,
3880 ; but not for rlwimi on POWER4 and similar processors.
3882 (define_insn "*rotl<mode>3_insert_2"
3883 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3884 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3885 (match_operand:GPR 6 "const_int_operand" "n"))
3886 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3887 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3888 (match_operand:SI 2 "const_int_operand" "n")])
3889 (match_operand:GPR 3 "const_int_operand" "n"))))]
3890 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3891 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3893 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3895 [(set_attr "type" "insert")])
3897 ; There are also some forms without one of the ANDs.
3898 (define_insn "*rotl<mode>3_insert_3"
3899 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3900 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3901 (match_operand:GPR 4 "const_int_operand" "n"))
3902 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3903 (match_operand:SI 2 "const_int_operand" "n"))))]
3904 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3906 if (<MODE>mode == SImode)
3907 return "rlwimi %0,%1,%h2,0,31-%h2";
3909 return "rldimi %0,%1,%H2,0";
3911 [(set_attr "type" "insert")])
3913 (define_insn "*rotl<mode>3_insert_4"
3914 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3915 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3916 (match_operand:GPR 4 "const_int_operand" "n"))
3917 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3918 (match_operand:SI 2 "const_int_operand" "n"))))]
3919 "<MODE>mode == SImode &&
3920 GET_MODE_PRECISION (<MODE>mode)
3921 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3923 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3924 - INTVAL (operands[2]));
3925 if (<MODE>mode == SImode)
3926 return "rlwimi %0,%1,%h2,32-%h2,31";
3928 return "rldimi %0,%1,%H2,64-%H2";
3930 [(set_attr "type" "insert")])
3932 (define_insn "*rotlsi3_insert_5"
3933 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3934 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3935 (match_operand:SI 2 "const_int_operand" "n,n"))
3936 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3937 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3938 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3939 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3940 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3944 [(set_attr "type" "insert")])
3946 (define_insn "*rotldi3_insert_6"
3947 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3948 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3949 (match_operand:DI 2 "const_int_operand" "n"))
3950 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3951 (match_operand:DI 4 "const_int_operand" "n"))))]
3952 "exact_log2 (-UINTVAL (operands[2])) > 0
3953 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3955 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3956 return "rldimi %0,%3,0,%5";
3958 [(set_attr "type" "insert")
3959 (set_attr "size" "64")])
3961 (define_insn "*rotldi3_insert_7"
3962 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3963 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3964 (match_operand:DI 4 "const_int_operand" "n"))
3965 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3966 (match_operand:DI 2 "const_int_operand" "n"))))]
3967 "exact_log2 (-UINTVAL (operands[2])) > 0
3968 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3970 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3971 return "rldimi %0,%3,0,%5";
3973 [(set_attr "type" "insert")
3974 (set_attr "size" "64")])
3977 ; This handles the important case of multiple-precision shifts. There is
3978 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3980 [(set (match_operand:GPR 0 "gpc_reg_operand")
3981 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3982 (match_operand:SI 3 "const_int_operand"))
3983 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3984 (match_operand:SI 4 "const_int_operand"))))]
3985 "can_create_pseudo_p ()
3986 && INTVAL (operands[3]) + INTVAL (operands[4])
3987 >= GET_MODE_PRECISION (<MODE>mode)"
3989 (lshiftrt:GPR (match_dup 2)
3992 (ior:GPR (and:GPR (match_dup 5)
3994 (ashift:GPR (match_dup 1)
3997 unsigned HOST_WIDE_INT mask = 1;
3998 mask = (mask << INTVAL (operands[3])) - 1;
3999 operands[5] = gen_reg_rtx (<MODE>mode);
4000 operands[6] = GEN_INT (mask);
4004 [(set (match_operand:GPR 0 "gpc_reg_operand")
4005 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4006 (match_operand:SI 4 "const_int_operand"))
4007 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4008 (match_operand:SI 3 "const_int_operand"))))]
4009 "can_create_pseudo_p ()
4010 && INTVAL (operands[3]) + INTVAL (operands[4])
4011 >= GET_MODE_PRECISION (<MODE>mode)"
4013 (lshiftrt:GPR (match_dup 2)
4016 (ior:GPR (and:GPR (match_dup 5)
4018 (ashift:GPR (match_dup 1)
4021 unsigned HOST_WIDE_INT mask = 1;
4022 mask = (mask << INTVAL (operands[3])) - 1;
4023 operands[5] = gen_reg_rtx (<MODE>mode);
4024 operands[6] = GEN_INT (mask);
4028 ; Another important case is setting some bits to 1; we can do that with
4029 ; an insert instruction, in many cases.
4030 (define_insn_and_split "*ior<mode>_mask"
4031 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4032 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4033 (match_operand:GPR 2 "const_int_operand" "n")))
4034 (clobber (match_scratch:GPR 3 "=r"))]
4035 "!logical_const_operand (operands[2], <MODE>mode)
4036 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4042 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4045 (and:GPR (match_dup 1)
4049 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4050 if (GET_CODE (operands[3]) == SCRATCH)
4051 operands[3] = gen_reg_rtx (<MODE>mode);
4052 operands[4] = GEN_INT (ne);
4053 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4055 [(set_attr "type" "two")
4056 (set_attr "length" "8")])
4059 ; Yet another case is an rldimi with the second value coming from memory.
4060 ; The zero_extend that should become part of the rldimi is merged into the
4061 ; load from memory instead. Split things properly again.
4063 [(set (match_operand:DI 0 "gpc_reg_operand")
4064 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4065 (match_operand:SI 2 "const_int_operand"))
4066 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4067 "INTVAL (operands[2]) == <bits>"
4069 (zero_extend:DI (match_dup 3)))
4071 (ior:DI (and:DI (match_dup 4)
4073 (ashift:DI (match_dup 1)
4076 operands[4] = gen_reg_rtx (DImode);
4077 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4082 [(set (match_operand:SI 0 "gpc_reg_operand")
4083 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4084 (match_operand:SI 2 "const_int_operand"))
4085 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4086 "INTVAL (operands[2]) == <bits>"
4088 (zero_extend:SI (match_dup 3)))
4090 (ior:SI (and:SI (match_dup 4)
4092 (ashift:SI (match_dup 1)
4095 operands[4] = gen_reg_rtx (SImode);
4096 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4100 ;; Now the simple shifts.
4102 (define_insn "rotl<mode>3"
4103 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4104 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4105 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4107 "rotl<wd>%I2 %0,%1,%<hH>2"
4108 [(set_attr "type" "shift")
4109 (set_attr "maybe_var_shift" "yes")])
4111 (define_insn "*rotlsi3_64"
4112 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4114 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4115 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4117 "rotlw%I2 %0,%1,%h2"
4118 [(set_attr "type" "shift")
4119 (set_attr "maybe_var_shift" "yes")])
4121 (define_insn_and_split "*rotl<mode>3_dot"
4122 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4123 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4124 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4126 (clobber (match_scratch:GPR 0 "=r,r"))]
4127 "<MODE>mode == Pmode"
4129 rotl<wd>%I2. %0,%1,%<hH>2
4131 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4133 (rotate:GPR (match_dup 1)
4136 (compare:CC (match_dup 0)
4139 [(set_attr "type" "shift")
4140 (set_attr "maybe_var_shift" "yes")
4141 (set_attr "dot" "yes")
4142 (set_attr "length" "4,8")])
4144 (define_insn_and_split "*rotl<mode>3_dot2"
4145 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4146 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4147 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4149 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4150 (rotate:GPR (match_dup 1)
4152 "<MODE>mode == Pmode"
4154 rotl<wd>%I2. %0,%1,%<hH>2
4156 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4158 (rotate:GPR (match_dup 1)
4161 (compare:CC (match_dup 0)
4164 [(set_attr "type" "shift")
4165 (set_attr "maybe_var_shift" "yes")
4166 (set_attr "dot" "yes")
4167 (set_attr "length" "4,8")])
4170 (define_insn "ashl<mode>3"
4171 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4172 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4173 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4175 "sl<wd>%I2 %0,%1,%<hH>2"
4176 [(set_attr "type" "shift")
4177 (set_attr "maybe_var_shift" "yes")])
4179 (define_insn "*ashlsi3_64"
4180 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4182 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4183 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4186 [(set_attr "type" "shift")
4187 (set_attr "maybe_var_shift" "yes")])
4189 (define_insn_and_split "*ashl<mode>3_dot"
4190 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4191 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4192 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4194 (clobber (match_scratch:GPR 0 "=r,r"))]
4195 "<MODE>mode == Pmode"
4197 sl<wd>%I2. %0,%1,%<hH>2
4199 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4201 (ashift:GPR (match_dup 1)
4204 (compare:CC (match_dup 0)
4207 [(set_attr "type" "shift")
4208 (set_attr "maybe_var_shift" "yes")
4209 (set_attr "dot" "yes")
4210 (set_attr "length" "4,8")])
4212 (define_insn_and_split "*ashl<mode>3_dot2"
4213 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4214 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4215 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4217 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4218 (ashift:GPR (match_dup 1)
4220 "<MODE>mode == Pmode"
4222 sl<wd>%I2. %0,%1,%<hH>2
4224 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4226 (ashift:GPR (match_dup 1)
4229 (compare:CC (match_dup 0)
4232 [(set_attr "type" "shift")
4233 (set_attr "maybe_var_shift" "yes")
4234 (set_attr "dot" "yes")
4235 (set_attr "length" "4,8")])
4237 ;; Pretend we have a memory form of extswsli until register allocation is done
4238 ;; so that we use LWZ to load the value from memory, instead of LWA.
4239 (define_insn_and_split "ashdi3_extswsli"
4240 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4242 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4243 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4248 "&& reload_completed && MEM_P (operands[1])"
4252 (ashift:DI (sign_extend:DI (match_dup 3))
4255 operands[3] = gen_lowpart (SImode, operands[0]);
4257 [(set_attr "type" "shift")
4258 (set_attr "maybe_var_shift" "no")])
4261 (define_insn_and_split "ashdi3_extswsli_dot"
4262 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4265 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4266 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4268 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4275 "&& reload_completed
4276 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4277 || memory_operand (operands[1], SImode))"
4280 rtx dest = operands[0];
4281 rtx src = operands[1];
4282 rtx shift = operands[2];
4283 rtx cr = operands[3];
4290 src2 = gen_lowpart (SImode, dest);
4291 emit_move_insn (src2, src);
4294 if (REGNO (cr) == CR0_REGNO)
4296 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4300 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4301 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4304 [(set_attr "type" "shift")
4305 (set_attr "maybe_var_shift" "no")
4306 (set_attr "dot" "yes")
4307 (set_attr "length" "4,8,8,12")])
4309 (define_insn_and_split "ashdi3_extswsli_dot2"
4310 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4313 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4314 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4316 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4317 (ashift:DI (sign_extend:DI (match_dup 1))
4325 "&& reload_completed
4326 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4327 || memory_operand (operands[1], SImode))"
4330 rtx dest = operands[0];
4331 rtx src = operands[1];
4332 rtx shift = operands[2];
4333 rtx cr = operands[3];
4340 src2 = gen_lowpart (SImode, dest);
4341 emit_move_insn (src2, src);
4344 if (REGNO (cr) == CR0_REGNO)
4346 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4350 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4351 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4354 [(set_attr "type" "shift")
4355 (set_attr "maybe_var_shift" "no")
4356 (set_attr "dot" "yes")
4357 (set_attr "length" "4,8,8,12")])
4359 (define_insn "lshr<mode>3"
4360 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4361 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4362 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4364 "sr<wd>%I2 %0,%1,%<hH>2"
4365 [(set_attr "type" "shift")
4366 (set_attr "maybe_var_shift" "yes")])
4368 (define_insn "*lshrsi3_64"
4369 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4371 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4372 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4375 [(set_attr "type" "shift")
4376 (set_attr "maybe_var_shift" "yes")])
4378 (define_insn_and_split "*lshr<mode>3_dot"
4379 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4380 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4381 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4383 (clobber (match_scratch:GPR 0 "=r,r"))]
4384 "<MODE>mode == Pmode"
4386 sr<wd>%I2. %0,%1,%<hH>2
4388 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4390 (lshiftrt:GPR (match_dup 1)
4393 (compare:CC (match_dup 0)
4396 [(set_attr "type" "shift")
4397 (set_attr "maybe_var_shift" "yes")
4398 (set_attr "dot" "yes")
4399 (set_attr "length" "4,8")])
4401 (define_insn_and_split "*lshr<mode>3_dot2"
4402 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4403 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4404 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4406 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4407 (lshiftrt:GPR (match_dup 1)
4409 "<MODE>mode == Pmode"
4411 sr<wd>%I2. %0,%1,%<hH>2
4413 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4415 (lshiftrt:GPR (match_dup 1)
4418 (compare:CC (match_dup 0)
4421 [(set_attr "type" "shift")
4422 (set_attr "maybe_var_shift" "yes")
4423 (set_attr "dot" "yes")
4424 (set_attr "length" "4,8")])
4427 (define_insn "ashr<mode>3"
4428 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4429 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4430 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4431 (clobber (reg:GPR CA_REGNO))]
4433 "sra<wd>%I2 %0,%1,%<hH>2"
4434 [(set_attr "type" "shift")
4435 (set_attr "maybe_var_shift" "yes")])
4437 (define_insn "*ashrsi3_64"
4438 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4440 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4441 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4442 (clobber (reg:SI CA_REGNO))]
4445 [(set_attr "type" "shift")
4446 (set_attr "maybe_var_shift" "yes")])
4448 (define_insn_and_split "*ashr<mode>3_dot"
4449 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4450 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4451 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4453 (clobber (match_scratch:GPR 0 "=r,r"))
4454 (clobber (reg:GPR CA_REGNO))]
4455 "<MODE>mode == Pmode"
4457 sra<wd>%I2. %0,%1,%<hH>2
4459 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4460 [(parallel [(set (match_dup 0)
4461 (ashiftrt:GPR (match_dup 1)
4463 (clobber (reg:GPR CA_REGNO))])
4465 (compare:CC (match_dup 0)
4468 [(set_attr "type" "shift")
4469 (set_attr "maybe_var_shift" "yes")
4470 (set_attr "dot" "yes")
4471 (set_attr "length" "4,8")])
4473 (define_insn_and_split "*ashr<mode>3_dot2"
4474 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4475 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4476 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4478 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4479 (ashiftrt:GPR (match_dup 1)
4481 (clobber (reg:GPR CA_REGNO))]
4482 "<MODE>mode == Pmode"
4484 sra<wd>%I2. %0,%1,%<hH>2
4486 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4487 [(parallel [(set (match_dup 0)
4488 (ashiftrt:GPR (match_dup 1)
4490 (clobber (reg:GPR CA_REGNO))])
4492 (compare:CC (match_dup 0)
4495 [(set_attr "type" "shift")
4496 (set_attr "maybe_var_shift" "yes")
4497 (set_attr "dot" "yes")
4498 (set_attr "length" "4,8")])
4500 ;; Builtins to replace a division to generate FRE reciprocal estimate
4501 ;; instructions and the necessary fixup instructions
4502 (define_expand "recip<mode>3"
4503 [(match_operand:RECIPF 0 "gpc_reg_operand")
4504 (match_operand:RECIPF 1 "gpc_reg_operand")
4505 (match_operand:RECIPF 2 "gpc_reg_operand")]
4506 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4508 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4512 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4513 ;; hardware division. This is only done before register allocation and with
4514 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4515 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4516 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4518 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4519 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4520 (match_operand 2 "gpc_reg_operand")))]
4521 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4522 && can_create_pseudo_p () && flag_finite_math_only
4523 && !flag_trapping_math && flag_reciprocal_math"
4526 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4530 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4531 ;; appropriate fixup.
4532 (define_expand "rsqrt<mode>2"
4533 [(match_operand:RECIPF 0 "gpc_reg_operand")
4534 (match_operand:RECIPF 1 "gpc_reg_operand")]
4535 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4537 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4541 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4542 ;; modes here, and also add in conditional vsx/power8-vector support to access
4543 ;; values in the traditional Altivec registers if the appropriate
4544 ;; -mupper-regs-{df,sf} option is enabled.
4546 (define_expand "abs<mode>2"
4547 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4548 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4552 (define_insn "*abs<mode>2_fpr"
4553 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4554 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4559 [(set_attr "type" "fpsimple")])
4561 (define_insn "*nabs<mode>2_fpr"
4562 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4565 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4570 [(set_attr "type" "fpsimple")])
4572 (define_expand "neg<mode>2"
4573 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4574 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4578 (define_insn "*neg<mode>2_fpr"
4579 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4580 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4585 [(set_attr "type" "fpsimple")])
4587 (define_expand "add<mode>3"
4588 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4589 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4590 (match_operand:SFDF 2 "gpc_reg_operand")))]
4594 (define_insn "*add<mode>3_fpr"
4595 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4596 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4597 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4600 fadd<Ftrad> %0,%1,%2
4601 xsadd<Fvsx> %x0,%x1,%x2"
4602 [(set_attr "type" "fp")])
4604 (define_expand "sub<mode>3"
4605 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4606 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4607 (match_operand:SFDF 2 "gpc_reg_operand")))]
4611 (define_insn "*sub<mode>3_fpr"
4612 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4613 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4614 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4617 fsub<Ftrad> %0,%1,%2
4618 xssub<Fvsx> %x0,%x1,%x2"
4619 [(set_attr "type" "fp")])
4621 (define_expand "mul<mode>3"
4622 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4623 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4624 (match_operand:SFDF 2 "gpc_reg_operand")))]
4628 (define_insn "*mul<mode>3_fpr"
4629 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4630 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4631 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4634 fmul<Ftrad> %0,%1,%2
4635 xsmul<Fvsx> %x0,%x1,%x2"
4636 [(set_attr "type" "dmul")])
4638 (define_expand "div<mode>3"
4639 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4640 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4641 (match_operand:SFDF 2 "gpc_reg_operand")))]
4644 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4645 && can_create_pseudo_p () && flag_finite_math_only
4646 && !flag_trapping_math && flag_reciprocal_math)
4648 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4653 (define_insn "*div<mode>3_fpr"
4654 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4655 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4656 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4659 fdiv<Ftrad> %0,%1,%2
4660 xsdiv<Fvsx> %x0,%x1,%x2"
4661 [(set_attr "type" "<Fs>div")])
4663 (define_insn "*sqrt<mode>2_internal"
4664 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4665 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4666 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4669 xssqrt<Fvsx> %x0,%x1"
4670 [(set_attr "type" "<Fs>sqrt")])
4672 (define_expand "sqrt<mode>2"
4673 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4674 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4675 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4677 if (<MODE>mode == SFmode
4678 && TARGET_RECIP_PRECISION
4679 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4680 && !optimize_function_for_size_p (cfun)
4681 && flag_finite_math_only && !flag_trapping_math
4682 && flag_unsafe_math_optimizations)
4684 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4689 ;; Floating point reciprocal approximation
4690 (define_insn "fre<Fs>"
4691 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4692 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4698 [(set_attr "type" "fp")])
4700 (define_insn "*rsqrt<mode>2"
4701 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4702 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4704 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4706 frsqrte<Ftrad> %0,%1
4707 xsrsqrte<Fvsx> %x0,%x1"
4708 [(set_attr "type" "fp")])
4710 ;; Floating point comparisons
4711 (define_insn "*cmp<mode>_fpr"
4712 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4713 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4714 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4718 xscmpudp %0,%x1,%x2"
4719 [(set_attr "type" "fpcompare")])
4721 ;; Floating point conversions
4722 (define_expand "extendsfdf2"
4723 [(set (match_operand:DF 0 "gpc_reg_operand")
4724 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4727 if (HONOR_SNANS (SFmode))
4728 operands[1] = force_reg (SFmode, operands[1]);
4731 (define_insn_and_split "*extendsfdf2_fpr"
4732 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4733 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4734 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4740 xscpsgndp %x0,%x1,%x1
4743 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4746 emit_note (NOTE_INSN_DELETED);
4749 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4751 (define_insn "*extendsfdf2_snan"
4752 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4753 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4754 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4758 [(set_attr "type" "fp")])
4760 (define_expand "truncdfsf2"
4761 [(set (match_operand:SF 0 "gpc_reg_operand")
4762 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4766 (define_insn "*truncdfsf2_fpr"
4767 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4768 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4773 [(set_attr "type" "fp")])
4775 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4776 ;; builtins.c and optabs.c that are not correct for IBM long double
4777 ;; when little-endian.
4778 (define_expand "signbit<mode>2"
4780 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4782 (subreg:DI (match_dup 2) 0))
4785 (set (match_operand:SI 0 "gpc_reg_operand")
4788 && (!FLOAT128_IEEE_P (<MODE>mode)
4789 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4791 if (FLOAT128_IEEE_P (<MODE>mode))
4793 rtx dest = operands[0];
4794 rtx src = operands[1];
4795 rtx tmp = gen_reg_rtx (DImode);
4796 rtx dest_di = gen_lowpart (DImode, dest);
4798 if (<MODE>mode == KFmode)
4799 emit_insn (gen_signbitkf2_dm (tmp, src));
4800 else if (<MODE>mode == TFmode)
4801 emit_insn (gen_signbittf2_dm (tmp, src));
4805 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4808 operands[2] = gen_reg_rtx (DFmode);
4809 operands[3] = gen_reg_rtx (DImode);
4810 if (TARGET_POWERPC64)
4812 operands[4] = gen_reg_rtx (DImode);
4813 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4814 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4815 WORDS_BIG_ENDIAN ? 4 : 0);
4819 operands[4] = gen_reg_rtx (SImode);
4820 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4821 WORDS_BIG_ENDIAN ? 0 : 4);
4822 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4826 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4827 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4828 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4829 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4831 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4832 ;; split allows the post reload phases to eliminate the move, and do the shift
4833 ;; directly with the register that contains the signbit.
4834 (define_insn_and_split "signbit<mode>2_dm"
4835 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4836 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4838 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4842 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4846 operands[2] = gen_highpart (DImode, operands[1]);
4848 [(set_attr "type" "mftgpr,*")])
4850 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4851 ;; register and then doing a direct move if the value comes from memory. On
4852 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4853 (define_insn_and_split "*signbit<mode>2_dm_mem"
4854 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4855 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4857 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4863 rtx dest = operands[0];
4864 rtx src = operands[1];
4865 rtx addr = XEXP (src, 0);
4867 if (WORDS_BIG_ENDIAN)
4868 operands[2] = adjust_address (src, DImode, 0);
4870 else if (REG_P (addr) || SUBREG_P (addr))
4871 operands[2] = adjust_address (src, DImode, 8);
4873 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4874 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4875 operands[2] = adjust_address (src, DImode, 8);
4879 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4880 emit_insn (gen_rtx_SET (tmp, addr));
4881 operands[2] = change_address (src, DImode,
4882 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4886 (define_expand "copysign<mode>3"
4888 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4890 (neg:SFDF (abs:SFDF (match_dup 1))))
4891 (set (match_operand:SFDF 0 "gpc_reg_operand")
4892 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4897 && ((TARGET_PPC_GFXOPT
4898 && !HONOR_NANS (<MODE>mode)
4899 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4901 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4903 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4905 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4910 operands[3] = gen_reg_rtx (<MODE>mode);
4911 operands[4] = gen_reg_rtx (<MODE>mode);
4912 operands[5] = CONST0_RTX (<MODE>mode);
4915 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4916 ;; compiler from optimizing -0.0
4917 (define_insn "copysign<mode>3_fcpsgn"
4918 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4919 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4920 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4922 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4925 xscpsgndp %x0,%x2,%x1"
4926 [(set_attr "type" "fpsimple")])
4928 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4929 ;; fsel instruction and some auxiliary computations. Then we just have a
4930 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4932 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4933 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4934 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4935 ;; define_splits to make them if made by combine. On VSX machines we have the
4936 ;; min/max instructions.
4938 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4939 ;; to allow either DF/SF to use only traditional registers.
4941 (define_expand "s<minmax><mode>3"
4942 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4943 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4944 (match_operand:SFDF 2 "gpc_reg_operand")))]
4947 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4951 (define_insn "*s<minmax><mode>3_vsx"
4952 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4953 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4954 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4955 "TARGET_VSX && TARGET_HARD_FLOAT"
4957 return (TARGET_P9_MINMAX
4958 ? "xs<minmax>cdp %x0,%x1,%x2"
4959 : "xs<minmax>dp %x0,%x1,%x2");
4961 [(set_attr "type" "fp")])
4963 ;; The conditional move instructions allow us to perform max and min operations
4964 ;; even when we don't have the appropriate max/min instruction using the FSEL
4967 (define_insn_and_split "*s<minmax><mode>3_fpr"
4968 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4969 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4970 (match_operand:SFDF 2 "gpc_reg_operand")))]
4971 "!TARGET_VSX && TARGET_MINMAX"
4976 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4980 (define_expand "mov<mode>cc"
4981 [(set (match_operand:GPR 0 "gpc_reg_operand")
4982 (if_then_else:GPR (match_operand 1 "comparison_operator")
4983 (match_operand:GPR 2 "gpc_reg_operand")
4984 (match_operand:GPR 3 "gpc_reg_operand")))]
4987 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4993 ;; We use the BASE_REGS for the isel input operands because, if rA is
4994 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4995 ;; because we may switch the operands and rB may end up being rA.
4997 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4998 ;; leave out the mode in operand 4 and use one pattern, but reload can
4999 ;; change the mode underneath our feet and then gets confused trying
5000 ;; to reload the value.
5001 (define_insn "isel_signed_<mode>"
5002 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5004 (match_operator 1 "scc_comparison_operator"
5005 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5007 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5008 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5011 [(set_attr "type" "isel")])
5013 (define_insn "isel_unsigned_<mode>"
5014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5016 (match_operator 1 "scc_comparison_operator"
5017 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5019 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5020 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5023 [(set_attr "type" "isel")])
5025 ;; These patterns can be useful for combine; they let combine know that
5026 ;; isel can handle reversed comparisons so long as the operands are
5029 (define_insn "*isel_reversed_signed_<mode>"
5030 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5032 (match_operator 1 "scc_rev_comparison_operator"
5033 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5035 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5036 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5039 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5040 return "isel %0,%3,%2,%j1";
5042 [(set_attr "type" "isel")])
5044 (define_insn "*isel_reversed_unsigned_<mode>"
5045 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5047 (match_operator 1 "scc_rev_comparison_operator"
5048 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5050 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5051 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5054 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5055 return "isel %0,%3,%2,%j1";
5057 [(set_attr "type" "isel")])
5059 ;; Floating point conditional move
5060 (define_expand "mov<mode>cc"
5061 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5062 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5063 (match_operand:SFDF 2 "gpc_reg_operand")
5064 (match_operand:SFDF 3 "gpc_reg_operand")))]
5065 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5067 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5073 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5074 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5076 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5077 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5078 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5079 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5080 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5082 [(set_attr "type" "fp")])
5084 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5085 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5087 (match_operator:CCFP 1 "fpmask_comparison_operator"
5088 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5089 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5090 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5091 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5092 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5097 (if_then_else:V2DI (match_dup 1)
5101 (if_then_else:SFDF (ne (match_dup 6)
5106 if (GET_CODE (operands[6]) == SCRATCH)
5107 operands[6] = gen_reg_rtx (V2DImode);
5109 operands[7] = CONSTM1_RTX (V2DImode);
5110 operands[8] = CONST0_RTX (V2DImode);
5112 [(set_attr "length" "8")
5113 (set_attr "type" "vecperm")])
5115 ;; Handle inverting the fpmask comparisons.
5116 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5117 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5119 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5120 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5121 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5122 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5123 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5124 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5129 (if_then_else:V2DI (match_dup 9)
5133 (if_then_else:SFDF (ne (match_dup 6)
5138 rtx op1 = operands[1];
5139 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5141 if (GET_CODE (operands[6]) == SCRATCH)
5142 operands[6] = gen_reg_rtx (V2DImode);
5144 operands[7] = CONSTM1_RTX (V2DImode);
5145 operands[8] = CONST0_RTX (V2DImode);
5147 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5149 [(set_attr "length" "8")
5150 (set_attr "type" "vecperm")])
5152 (define_insn "*fpmask<mode>"
5153 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5155 (match_operator:CCFP 1 "fpmask_comparison_operator"
5156 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5157 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5158 (match_operand:V2DI 4 "all_ones_constant" "")
5159 (match_operand:V2DI 5 "zero_constant" "")))]
5161 "xscmp%V1dp %x0,%x2,%x3"
5162 [(set_attr "type" "fpcompare")])
5164 (define_insn "*xxsel<mode>"
5165 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5166 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5167 (match_operand:V2DI 2 "zero_constant" ""))
5168 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5169 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5171 "xxsel %x0,%x4,%x3,%x1"
5172 [(set_attr "type" "vecmove")])
5175 ;; Conversions to and from floating-point.
5177 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5178 ; don't want to support putting SImode in FPR registers.
5179 (define_insn "lfiwax"
5180 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5181 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5183 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5189 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5191 ; This split must be run before register allocation because it allocates the
5192 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5193 ; it earlier to allow for the combiner to merge insns together where it might
5194 ; not be needed and also in case the insns are deleted as dead code.
5196 (define_insn_and_split "floatsi<mode>2_lfiwax"
5197 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5198 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5199 (clobber (match_scratch:DI 2 "=wi"))]
5200 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5201 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5206 rtx dest = operands[0];
5207 rtx src = operands[1];
5210 if (!MEM_P (src) && TARGET_POWERPC64
5211 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5212 tmp = convert_to_mode (DImode, src, false);
5216 if (GET_CODE (tmp) == SCRATCH)
5217 tmp = gen_reg_rtx (DImode);
5220 src = rs6000_force_indexed_or_indirect_mem (src);
5221 emit_insn (gen_lfiwax (tmp, src));
5225 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5226 emit_move_insn (stack, src);
5227 emit_insn (gen_lfiwax (tmp, stack));
5230 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5233 [(set_attr "length" "12")
5234 (set_attr "type" "fpload")])
5236 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5237 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5240 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5241 (clobber (match_scratch:DI 2 "=wi"))]
5242 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5247 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5248 if (GET_CODE (operands[2]) == SCRATCH)
5249 operands[2] = gen_reg_rtx (DImode);
5250 if (TARGET_P8_VECTOR)
5251 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5253 emit_insn (gen_lfiwax (operands[2], operands[1]));
5254 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5257 [(set_attr "length" "8")
5258 (set_attr "type" "fpload")])
5260 (define_insn "lfiwzx"
5261 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5262 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5264 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5269 xxextractuw %x0,%x1,4"
5270 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5272 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5273 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5274 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5275 (clobber (match_scratch:DI 2 "=wi"))]
5276 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5281 rtx dest = operands[0];
5282 rtx src = operands[1];
5285 if (!MEM_P (src) && TARGET_POWERPC64
5286 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5287 tmp = convert_to_mode (DImode, src, true);
5291 if (GET_CODE (tmp) == SCRATCH)
5292 tmp = gen_reg_rtx (DImode);
5295 src = rs6000_force_indexed_or_indirect_mem (src);
5296 emit_insn (gen_lfiwzx (tmp, src));
5300 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5301 emit_move_insn (stack, src);
5302 emit_insn (gen_lfiwzx (tmp, stack));
5305 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5308 [(set_attr "length" "12")
5309 (set_attr "type" "fpload")])
5311 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5312 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5313 (unsigned_float:SFDF
5315 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5316 (clobber (match_scratch:DI 2 "=wi"))]
5317 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5322 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5323 if (GET_CODE (operands[2]) == SCRATCH)
5324 operands[2] = gen_reg_rtx (DImode);
5325 if (TARGET_P8_VECTOR)
5326 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5328 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5329 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5332 [(set_attr "length" "8")
5333 (set_attr "type" "fpload")])
5335 ; For each of these conversions, there is a define_expand, a define_insn
5336 ; with a '#' template, and a define_split (with C code). The idea is
5337 ; to allow constant folding with the template of the define_insn,
5338 ; then to have the insns split later (between sched1 and final).
5340 (define_expand "floatsidf2"
5341 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5342 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5345 (clobber (match_dup 4))
5346 (clobber (match_dup 5))
5347 (clobber (match_dup 6))])]
5350 if (TARGET_LFIWAX && TARGET_FCFID)
5352 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5355 else if (TARGET_FCFID)
5357 rtx dreg = operands[1];
5359 dreg = force_reg (SImode, dreg);
5360 dreg = convert_to_mode (DImode, dreg, false);
5361 emit_insn (gen_floatdidf2 (operands[0], dreg));
5365 if (!REG_P (operands[1]))
5366 operands[1] = force_reg (SImode, operands[1]);
5367 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5368 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5369 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5370 operands[5] = gen_reg_rtx (DFmode);
5371 operands[6] = gen_reg_rtx (SImode);
5374 (define_insn_and_split "*floatsidf2_internal"
5375 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5376 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5377 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5378 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5379 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5380 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5381 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5382 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5387 rtx lowword, highword;
5388 gcc_assert (MEM_P (operands[4]));
5389 highword = adjust_address (operands[4], SImode, 0);
5390 lowword = adjust_address (operands[4], SImode, 4);
5391 if (! WORDS_BIG_ENDIAN)
5392 std::swap (lowword, highword);
5394 emit_insn (gen_xorsi3 (operands[6], operands[1],
5395 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5396 emit_move_insn (lowword, operands[6]);
5397 emit_move_insn (highword, operands[2]);
5398 emit_move_insn (operands[5], operands[4]);
5399 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5402 [(set_attr "length" "24")
5403 (set_attr "type" "fp")])
5405 ;; If we don't have a direct conversion to single precision, don't enable this
5406 ;; conversion for 32-bit without fast math, because we don't have the insn to
5407 ;; generate the fixup swizzle to avoid double rounding problems.
5408 (define_expand "floatunssisf2"
5409 [(set (match_operand:SF 0 "gpc_reg_operand")
5410 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5412 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5414 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5416 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5418 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5423 rtx dreg = operands[1];
5425 dreg = force_reg (SImode, dreg);
5426 dreg = convert_to_mode (DImode, dreg, true);
5427 emit_insn (gen_floatdisf2 (operands[0], dreg));
5432 (define_expand "floatunssidf2"
5433 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5434 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5437 (clobber (match_dup 4))
5438 (clobber (match_dup 5))])]
5441 if (TARGET_LFIWZX && TARGET_FCFID)
5443 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5446 else if (TARGET_FCFID)
5448 rtx dreg = operands[1];
5450 dreg = force_reg (SImode, dreg);
5451 dreg = convert_to_mode (DImode, dreg, true);
5452 emit_insn (gen_floatdidf2 (operands[0], dreg));
5456 if (!REG_P (operands[1]))
5457 operands[1] = force_reg (SImode, operands[1]);
5458 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5459 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5460 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5461 operands[5] = gen_reg_rtx (DFmode);
5464 (define_insn_and_split "*floatunssidf2_internal"
5465 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5466 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5467 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5468 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5469 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5470 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5471 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5472 && !(TARGET_FCFID && TARGET_POWERPC64)"
5477 rtx lowword, highword;
5478 gcc_assert (MEM_P (operands[4]));
5479 highword = adjust_address (operands[4], SImode, 0);
5480 lowword = adjust_address (operands[4], SImode, 4);
5481 if (! WORDS_BIG_ENDIAN)
5482 std::swap (lowword, highword);
5484 emit_move_insn (lowword, operands[1]);
5485 emit_move_insn (highword, operands[2]);
5486 emit_move_insn (operands[5], operands[4]);
5487 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5490 [(set_attr "length" "20")
5491 (set_attr "type" "fp")])
5493 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5494 ;; vector registers. These insns favor doing the sign/zero extension in
5495 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5496 ;; extension and then a direct move.
5498 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5499 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5501 (match_operand:QHI 1 "input_operand")))
5502 (clobber (match_scratch:DI 2))
5503 (clobber (match_scratch:DI 3))
5504 (clobber (match_scratch:<QHI:MODE> 4))])]
5505 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5507 if (MEM_P (operands[1]))
5508 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5511 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5512 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5514 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5515 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5516 (clobber (match_scratch:DI 3 "=X,r,X"))
5517 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5518 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5520 "&& reload_completed"
5523 rtx result = operands[0];
5524 rtx input = operands[1];
5525 rtx di = operands[2];
5529 rtx tmp = operands[3];
5530 if (altivec_register_operand (input, <QHI:MODE>mode))
5531 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5532 else if (GET_CODE (tmp) == SCRATCH)
5533 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5536 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5537 emit_move_insn (di, tmp);
5542 rtx tmp = operands[4];
5543 emit_move_insn (tmp, input);
5544 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5547 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5551 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5552 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5553 (unsigned_float:FP_ISA3
5554 (match_operand:QHI 1 "input_operand")))
5555 (clobber (match_scratch:DI 2))
5556 (clobber (match_scratch:DI 3))])]
5557 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5559 if (MEM_P (operands[1]))
5560 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5563 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5564 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5565 (unsigned_float:FP_ISA3
5566 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5567 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5568 (clobber (match_scratch:DI 3 "=X,r,X"))]
5569 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5571 "&& reload_completed"
5574 rtx result = operands[0];
5575 rtx input = operands[1];
5576 rtx di = operands[2];
5578 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5579 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5582 rtx tmp = operands[3];
5583 if (GET_CODE (tmp) == SCRATCH)
5584 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5587 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5588 emit_move_insn (di, tmp);
5592 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5596 (define_expand "fix_trunc<mode>si2"
5597 [(set (match_operand:SI 0 "gpc_reg_operand")
5598 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5601 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5603 rtx src = force_reg (<MODE>mode, operands[1]);
5606 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5609 rtx tmp = gen_reg_rtx (DImode);
5610 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5611 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5618 ; Like the convert to float patterns, this insn must be split before
5619 ; register allocation so that it can allocate the memory slot if it
5621 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5622 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5623 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5624 (clobber (match_scratch:DI 2 "=d"))]
5625 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5626 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5631 rtx dest = operands[0];
5632 rtx src = operands[1];
5633 rtx tmp = operands[2];
5635 if (GET_CODE (tmp) == SCRATCH)
5636 tmp = gen_reg_rtx (DImode);
5638 emit_insn (gen_fctiwz_<mode> (tmp, src));
5641 dest = rs6000_force_indexed_or_indirect_mem (dest);
5642 emit_insn (gen_stfiwx (dest, tmp));
5645 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5647 dest = gen_lowpart (DImode, dest);
5648 emit_move_insn (dest, tmp);
5653 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5654 emit_insn (gen_stfiwx (stack, tmp));
5655 emit_move_insn (dest, stack);
5659 [(set_attr "length" "12")
5660 (set_attr "type" "fp")])
5662 (define_insn_and_split "fix_trunc<mode>si2_internal"
5663 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5664 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5665 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5666 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5668 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5674 gcc_assert (MEM_P (operands[3]));
5675 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5677 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5678 emit_move_insn (operands[3], operands[2]);
5679 emit_move_insn (operands[0], lowword);
5682 [(set_attr "length" "16")
5683 (set_attr "type" "fp")])
5685 (define_expand "fix_trunc<mode>di2"
5686 [(set (match_operand:DI 0 "gpc_reg_operand")
5687 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5688 "TARGET_HARD_FLOAT && TARGET_FCFID"
5691 (define_insn "*fix_trunc<mode>di2_fctidz"
5692 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5693 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5694 "TARGET_HARD_FLOAT && TARGET_FCFID"
5698 [(set_attr "type" "fp")])
5700 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5701 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5702 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5703 ;; values can go in VSX registers. Keeping the direct move part through
5704 ;; register allocation prevents the register allocator from doing a direct move
5705 ;; of the SImode value to a GPR, and then a store/load.
5706 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5707 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5708 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5709 (clobber (match_scratch:SI 2 "=X,X,wi"))]
5710 "TARGET_DIRECT_MOVE"
5713 xscvdp<su>xws %x0,%x1
5715 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5717 (any_fix:SI (match_dup 1)))
5721 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5723 [(set_attr "length" "4,4,8")
5724 (set_attr "type" "fp")])
5726 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5727 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5728 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5729 "TARGET_DIRECT_MOVE"
5732 xscvdp<su>xws %x0,%x1"
5733 [(set_attr "type" "fp")])
5735 ;; Keep the convert and store together through register allocation to prevent
5736 ;; the register allocator from getting clever and doing a direct move to a GPR
5737 ;; and then store for reg+offset stores.
5738 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5739 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5740 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5741 (clobber (match_scratch:SI 2 "=wa"))]
5742 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5744 "&& reload_completed"
5746 (any_fix:SI (match_dup 1)))
5750 operands[3] = (<QHSI:MODE>mode == SImode
5752 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5755 (define_expand "fixuns_trunc<mode>si2"
5756 [(set (match_operand:SI 0 "gpc_reg_operand")
5757 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5758 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5760 if (!TARGET_P8_VECTOR)
5762 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5767 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5768 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5769 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5770 (clobber (match_scratch:DI 2 "=d"))]
5771 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5772 && TARGET_STFIWX && can_create_pseudo_p ()
5773 && !TARGET_P8_VECTOR"
5778 rtx dest = operands[0];
5779 rtx src = operands[1];
5780 rtx tmp = operands[2];
5782 if (GET_CODE (tmp) == SCRATCH)
5783 tmp = gen_reg_rtx (DImode);
5785 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5788 dest = rs6000_force_indexed_or_indirect_mem (dest);
5789 emit_insn (gen_stfiwx (dest, tmp));
5792 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5794 dest = gen_lowpart (DImode, dest);
5795 emit_move_insn (dest, tmp);
5800 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5801 emit_insn (gen_stfiwx (stack, tmp));
5802 emit_move_insn (dest, stack);
5806 [(set_attr "length" "12")
5807 (set_attr "type" "fp")])
5809 (define_insn "fixuns_trunc<mode>di2"
5810 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5811 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5812 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5816 [(set_attr "type" "fp")])
5818 (define_insn "rs6000_mtfsb0"
5819 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5823 [(set_attr "type" "fp")])
5825 (define_insn "rs6000_mtfsb1"
5826 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5830 [(set_attr "type" "fp")])
5832 (define_insn "rs6000_mffscrn"
5833 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5834 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5838 [(set_attr "type" "fp")])
5840 (define_insn "rs6000_mffscdrn"
5841 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5842 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5843 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5846 [(set_attr "type" "fp")])
5848 (define_expand "rs6000_set_fpscr_rn"
5849 [(match_operand:DI 0 "reg_or_cint_operand")]
5852 rtx tmp_df = gen_reg_rtx (DFmode);
5854 /* The floating point rounding control bits are FPSCR[62:63]. Put the
5855 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
5858 rtx src_df = force_reg (DImode, operands[0]);
5859 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5860 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5864 if (CONST_INT_P (operands[0]))
5866 if ((INTVAL (operands[0]) & 0x1) == 0x1)
5867 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5869 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5871 if ((INTVAL (operands[0]) & 0x2) == 0x2)
5872 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5874 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5878 rtx tmp_rn = gen_reg_rtx (DImode);
5879 rtx tmp_di = gen_reg_rtx (DImode);
5881 /* Extract new RN mode from operand. */
5882 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5884 /* Insert new RN mode into FSCPR. */
5885 emit_insn (gen_rs6000_mffs (tmp_df));
5886 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5887 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5888 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5890 /* Need to write to field k=15. The fields are [0:15]. Hence with
5891 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
5892 8-bit field[0:7]. Need to set the bit that corresponds to the
5893 value of i that you want [0:7]. */
5894 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5895 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5900 (define_expand "rs6000_set_fpscr_drn"
5901 [(match_operand:DI 0 "gpc_reg_operand")]
5904 rtx tmp_df = gen_reg_rtx (DFmode);
5906 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5907 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
5910 rtx src_df = gen_reg_rtx (DFmode);
5912 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5913 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5914 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
5918 rtx tmp_rn = gen_reg_rtx (DImode);
5919 rtx tmp_di = gen_reg_rtx (DImode);
5921 /* Extract new DRN mode from operand. */
5922 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
5923 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
5925 /* Insert new RN mode into FSCPR. */
5926 emit_insn (gen_rs6000_mffs (tmp_df));
5927 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5928 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
5929 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5931 /* Need to write to field 7. The fields are [0:15]. The equation to
5932 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
5933 i to 0x1 to get field 7 where i selects the field. */
5934 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5935 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
5940 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5941 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5942 ;; because the first makes it clear that operand 0 is not live
5943 ;; before the instruction.
5944 (define_insn "fctiwz_<mode>"
5945 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5947 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5953 [(set_attr "type" "fp")])
5955 (define_insn "fctiwuz_<mode>"
5956 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5957 (unspec:DI [(unsigned_fix:SI
5958 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5960 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5964 [(set_attr "type" "fp")])
5966 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5967 ;; since the friz instruction does not truncate the value if the floating
5968 ;; point value is < LONG_MIN or > LONG_MAX.
5969 (define_insn "*friz"
5970 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5971 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5972 "TARGET_HARD_FLOAT && TARGET_FPRND
5973 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5977 [(set_attr "type" "fp")])
5979 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5980 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5981 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5982 ;; extend it, store it back on the stack from the GPR, load it back into the
5983 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5984 ;; disable using store and load to sign/zero extend the value.
5985 (define_insn_and_split "*round32<mode>2_fprs"
5986 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5988 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5989 (clobber (match_scratch:DI 2 "=d"))
5990 (clobber (match_scratch:DI 3 "=d"))]
5992 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5993 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5998 rtx dest = operands[0];
5999 rtx src = operands[1];
6000 rtx tmp1 = operands[2];
6001 rtx tmp2 = operands[3];
6002 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6004 if (GET_CODE (tmp1) == SCRATCH)
6005 tmp1 = gen_reg_rtx (DImode);
6006 if (GET_CODE (tmp2) == SCRATCH)
6007 tmp2 = gen_reg_rtx (DImode);
6009 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6010 emit_insn (gen_stfiwx (stack, tmp1));
6011 emit_insn (gen_lfiwax (tmp2, stack));
6012 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6015 [(set_attr "type" "fpload")
6016 (set_attr "length" "16")])
6018 (define_insn_and_split "*roundu32<mode>2_fprs"
6019 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6020 (unsigned_float:SFDF
6021 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6022 (clobber (match_scratch:DI 2 "=d"))
6023 (clobber (match_scratch:DI 3 "=d"))]
6025 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6026 && can_create_pseudo_p ()"
6031 rtx dest = operands[0];
6032 rtx src = operands[1];
6033 rtx tmp1 = operands[2];
6034 rtx tmp2 = operands[3];
6035 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6037 if (GET_CODE (tmp1) == SCRATCH)
6038 tmp1 = gen_reg_rtx (DImode);
6039 if (GET_CODE (tmp2) == SCRATCH)
6040 tmp2 = gen_reg_rtx (DImode);
6042 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6043 emit_insn (gen_stfiwx (stack, tmp1));
6044 emit_insn (gen_lfiwzx (tmp2, stack));
6045 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6048 [(set_attr "type" "fpload")
6049 (set_attr "length" "16")])
6051 ;; No VSX equivalent to fctid
6052 (define_insn "lrint<mode>di2"
6053 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6054 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6056 "TARGET_HARD_FLOAT && TARGET_FPRND"
6058 [(set_attr "type" "fp")])
6060 (define_insn "btrunc<mode>2"
6061 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6062 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6064 "TARGET_HARD_FLOAT && TARGET_FPRND"
6068 [(set_attr "type" "fp")])
6070 (define_insn "ceil<mode>2"
6071 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6072 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6074 "TARGET_HARD_FLOAT && TARGET_FPRND"
6078 [(set_attr "type" "fp")])
6080 (define_insn "floor<mode>2"
6081 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6082 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6084 "TARGET_HARD_FLOAT && TARGET_FPRND"
6088 [(set_attr "type" "fp")])
6090 ;; No VSX equivalent to frin
6091 (define_insn "round<mode>2"
6092 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6093 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6095 "TARGET_HARD_FLOAT && TARGET_FPRND"
6097 [(set_attr "type" "fp")])
6099 (define_insn "*xsrdpi<mode>2"
6100 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6101 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6103 "TARGET_HARD_FLOAT && TARGET_VSX"
6105 [(set_attr "type" "fp")])
6107 (define_expand "lround<mode>di2"
6109 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6111 (set (match_operand:DI 0 "gpc_reg_operand")
6112 (unspec:DI [(match_dup 2)]
6114 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6116 operands[2] = gen_reg_rtx (<MODE>mode);
6119 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6120 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6121 ; is only generated for Power8 or later.
6122 (define_insn "stfiwx"
6123 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6124 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6130 [(set_attr "type" "fpstore")])
6132 ;; If we don't have a direct conversion to single precision, don't enable this
6133 ;; conversion for 32-bit without fast math, because we don't have the insn to
6134 ;; generate the fixup swizzle to avoid double rounding problems.
6135 (define_expand "floatsisf2"
6136 [(set (match_operand:SF 0 "gpc_reg_operand")
6137 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6139 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6141 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6143 if (TARGET_FCFIDS && TARGET_LFIWAX)
6145 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6148 else if (TARGET_FCFID && TARGET_LFIWAX)
6150 rtx dfreg = gen_reg_rtx (DFmode);
6151 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6152 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6157 rtx dreg = operands[1];
6159 dreg = force_reg (SImode, dreg);
6160 dreg = convert_to_mode (DImode, dreg, false);
6161 emit_insn (gen_floatdisf2 (operands[0], dreg));
6166 (define_insn "floatdidf2"
6167 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6168 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6169 "TARGET_FCFID && TARGET_HARD_FLOAT"
6173 [(set_attr "type" "fp")])
6175 ; Allow the combiner to merge source memory operands to the conversion so that
6176 ; the optimizer/register allocator doesn't try to load the value too early in a
6177 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6178 ; hit. We will split after reload to avoid the trip through the GPRs
6180 (define_insn_and_split "*floatdidf2_mem"
6181 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6182 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6183 (clobber (match_scratch:DI 2 "=d,wi"))]
6184 "TARGET_HARD_FLOAT && TARGET_FCFID"
6186 "&& reload_completed"
6187 [(set (match_dup 2) (match_dup 1))
6188 (set (match_dup 0) (float:DF (match_dup 2)))]
6190 [(set_attr "length" "8")
6191 (set_attr "type" "fpload")])
6193 (define_expand "floatunsdidf2"
6194 [(set (match_operand:DF 0 "gpc_reg_operand")
6196 (match_operand:DI 1 "gpc_reg_operand")))]
6197 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6200 (define_insn "*floatunsdidf2_fcfidu"
6201 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6202 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6203 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6207 [(set_attr "type" "fp")])
6209 (define_insn_and_split "*floatunsdidf2_mem"
6210 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6211 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6212 (clobber (match_scratch:DI 2 "=d,wi"))]
6213 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6215 "&& reload_completed"
6216 [(set (match_dup 2) (match_dup 1))
6217 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6219 [(set_attr "length" "8")
6220 (set_attr "type" "fpload")])
6222 (define_expand "floatdisf2"
6223 [(set (match_operand:SF 0 "gpc_reg_operand")
6224 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6225 "TARGET_FCFID && TARGET_HARD_FLOAT
6226 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6230 rtx val = operands[1];
6231 if (!flag_unsafe_math_optimizations)
6233 rtx label = gen_label_rtx ();
6234 val = gen_reg_rtx (DImode);
6235 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6238 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6243 (define_insn "floatdisf2_fcfids"
6244 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6245 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6246 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6250 [(set_attr "type" "fp")])
6252 (define_insn_and_split "*floatdisf2_mem"
6253 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6254 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6255 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6256 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6258 "&& reload_completed"
6261 emit_move_insn (operands[2], operands[1]);
6262 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6265 [(set_attr "length" "8")])
6267 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6268 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6269 ;; from double rounding.
6270 ;; Instead of creating a new cpu type for two FP operations, just use fp
6271 (define_insn_and_split "floatdisf2_internal1"
6272 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6273 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6274 (clobber (match_scratch:DF 2 "=d"))]
6275 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6277 "&& reload_completed"
6279 (float:DF (match_dup 1)))
6281 (float_truncate:SF (match_dup 2)))]
6283 [(set_attr "length" "8")
6284 (set_attr "type" "fp")])
6286 ;; Twiddles bits to avoid double rounding.
6287 ;; Bits that might be truncated when converting to DFmode are replaced
6288 ;; by a bit that won't be lost at that stage, but is below the SFmode
6289 ;; rounding position.
6290 (define_expand "floatdisf2_internal2"
6291 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6293 (clobber (reg:DI CA_REGNO))])
6294 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6296 (set (match_dup 3) (plus:DI (match_dup 3)
6298 (set (match_dup 0) (plus:DI (match_dup 0)
6300 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6302 (set (match_dup 0) (ior:DI (match_dup 0)
6304 (set (match_dup 0) (and:DI (match_dup 0)
6306 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6307 (label_ref (match_operand:DI 2 ""))
6309 (set (match_dup 0) (match_dup 1))]
6310 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6312 operands[3] = gen_reg_rtx (DImode);
6313 operands[4] = gen_reg_rtx (CCUNSmode);
6316 (define_expand "floatunsdisf2"
6317 [(set (match_operand:SF 0 "gpc_reg_operand")
6318 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6319 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6322 (define_insn "floatunsdisf2_fcfidus"
6323 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6324 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6325 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6329 [(set_attr "type" "fp")])
6331 (define_insn_and_split "*floatunsdisf2_mem"
6332 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6333 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6334 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6335 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6337 "&& reload_completed"
6340 emit_move_insn (operands[2], operands[1]);
6341 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6344 [(set_attr "length" "8")
6345 (set_attr "type" "fpload")])
6347 ;; Define the TImode operations that can be done in a small number
6348 ;; of instructions. The & constraints are to prevent the register
6349 ;; allocator from allocating registers that overlap with the inputs
6350 ;; (for example, having an input in 7,8 and an output in 6,7). We
6351 ;; also allow for the output being the same as one of the inputs.
6353 (define_expand "addti3"
6354 [(set (match_operand:TI 0 "gpc_reg_operand")
6355 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6356 (match_operand:TI 2 "reg_or_short_operand")))]
6359 rtx lo0 = gen_lowpart (DImode, operands[0]);
6360 rtx lo1 = gen_lowpart (DImode, operands[1]);
6361 rtx lo2 = gen_lowpart (DImode, operands[2]);
6362 rtx hi0 = gen_highpart (DImode, operands[0]);
6363 rtx hi1 = gen_highpart (DImode, operands[1]);
6364 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6366 if (!reg_or_short_operand (lo2, DImode))
6367 lo2 = force_reg (DImode, lo2);
6368 if (!adde_operand (hi2, DImode))
6369 hi2 = force_reg (DImode, hi2);
6371 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6372 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6376 (define_expand "subti3"
6377 [(set (match_operand:TI 0 "gpc_reg_operand")
6378 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6379 (match_operand:TI 2 "gpc_reg_operand")))]
6382 rtx lo0 = gen_lowpart (DImode, operands[0]);
6383 rtx lo1 = gen_lowpart (DImode, operands[1]);
6384 rtx lo2 = gen_lowpart (DImode, operands[2]);
6385 rtx hi0 = gen_highpart (DImode, operands[0]);
6386 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6387 rtx hi2 = gen_highpart (DImode, operands[2]);
6389 if (!reg_or_short_operand (lo1, DImode))
6390 lo1 = force_reg (DImode, lo1);
6391 if (!adde_operand (hi1, DImode))
6392 hi1 = force_reg (DImode, hi1);
6394 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6395 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6399 ;; 128-bit logical operations expanders
6401 (define_expand "and<mode>3"
6402 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6403 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6404 (match_operand:BOOL_128 2 "vlogical_operand")))]
6408 (define_expand "ior<mode>3"
6409 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6410 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6411 (match_operand:BOOL_128 2 "vlogical_operand")))]
6415 (define_expand "xor<mode>3"
6416 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6417 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6418 (match_operand:BOOL_128 2 "vlogical_operand")))]
6422 (define_expand "one_cmpl<mode>2"
6423 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6424 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6428 (define_expand "nor<mode>3"
6429 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6431 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6432 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6436 (define_expand "andc<mode>3"
6437 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6439 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6440 (match_operand:BOOL_128 1 "vlogical_operand")))]
6444 ;; Power8 vector logical instructions.
6445 (define_expand "eqv<mode>3"
6446 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6448 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6449 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6450 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6453 ;; Rewrite nand into canonical form
6454 (define_expand "nand<mode>3"
6455 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6457 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6458 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6459 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6462 ;; The canonical form is to have the negated element first, so we need to
6463 ;; reverse arguments.
6464 (define_expand "orc<mode>3"
6465 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6467 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6468 (match_operand:BOOL_128 1 "vlogical_operand")))]
6469 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6472 ;; 128-bit logical operations insns and split operations
6473 (define_insn_and_split "*and<mode>3_internal"
6474 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6476 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6477 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6480 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6481 return "xxland %x0,%x1,%x2";
6483 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6484 return "vand %0,%1,%2";
6488 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6491 rs6000_split_logical (operands, AND, false, false, false);
6496 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6497 (const_string "veclogical")
6498 (const_string "integer")))
6499 (set (attr "length")
6501 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6504 (match_test "TARGET_POWERPC64")
6506 (const_string "16"))))])
6509 (define_insn_and_split "*bool<mode>3_internal"
6510 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6511 (match_operator:BOOL_128 3 "boolean_or_operator"
6512 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6513 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6516 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6517 return "xxl%q3 %x0,%x1,%x2";
6519 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6520 return "v%q3 %0,%1,%2";
6524 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6527 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6532 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6533 (const_string "veclogical")
6534 (const_string "integer")))
6535 (set (attr "length")
6537 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6540 (match_test "TARGET_POWERPC64")
6542 (const_string "16"))))])
6545 (define_insn_and_split "*boolc<mode>3_internal1"
6546 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6547 (match_operator:BOOL_128 3 "boolean_operator"
6549 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6550 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6551 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6553 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6554 return "xxl%q3 %x0,%x1,%x2";
6556 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6557 return "v%q3 %0,%1,%2";
6561 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6562 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6565 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6570 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6571 (const_string "veclogical")
6572 (const_string "integer")))
6573 (set (attr "length")
6575 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6578 (match_test "TARGET_POWERPC64")
6580 (const_string "16"))))])
6582 (define_insn_and_split "*boolc<mode>3_internal2"
6583 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6584 (match_operator:TI2 3 "boolean_operator"
6586 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6587 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6588 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6590 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6593 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6596 [(set_attr "type" "integer")
6597 (set (attr "length")
6599 (match_test "TARGET_POWERPC64")
6601 (const_string "16")))])
6604 (define_insn_and_split "*boolcc<mode>3_internal1"
6605 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6606 (match_operator:BOOL_128 3 "boolean_operator"
6608 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6610 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6611 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6613 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6614 return "xxl%q3 %x0,%x1,%x2";
6616 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6617 return "v%q3 %0,%1,%2";
6621 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6622 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6625 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6630 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6631 (const_string "veclogical")
6632 (const_string "integer")))
6633 (set (attr "length")
6635 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6638 (match_test "TARGET_POWERPC64")
6640 (const_string "16"))))])
6642 (define_insn_and_split "*boolcc<mode>3_internal2"
6643 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6644 (match_operator:TI2 3 "boolean_operator"
6646 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6648 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6649 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6651 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6654 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6657 [(set_attr "type" "integer")
6658 (set (attr "length")
6660 (match_test "TARGET_POWERPC64")
6662 (const_string "16")))])
6666 (define_insn_and_split "*eqv<mode>3_internal1"
6667 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6670 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6671 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6674 if (vsx_register_operand (operands[0], <MODE>mode))
6675 return "xxleqv %x0,%x1,%x2";
6679 "TARGET_P8_VECTOR && reload_completed
6680 && int_reg_operand (operands[0], <MODE>mode)"
6683 rs6000_split_logical (operands, XOR, true, false, false);
6688 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6689 (const_string "veclogical")
6690 (const_string "integer")))
6691 (set (attr "length")
6693 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6696 (match_test "TARGET_POWERPC64")
6698 (const_string "16"))))])
6700 (define_insn_and_split "*eqv<mode>3_internal2"
6701 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6704 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6705 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6708 "reload_completed && !TARGET_P8_VECTOR"
6711 rs6000_split_logical (operands, XOR, true, false, false);
6714 [(set_attr "type" "integer")
6715 (set (attr "length")
6717 (match_test "TARGET_POWERPC64")
6719 (const_string "16")))])
6721 ;; 128-bit one's complement
6722 (define_insn_and_split "*one_cmpl<mode>3_internal"
6723 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6725 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6728 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6729 return "xxlnor %x0,%x1,%x1";
6731 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6732 return "vnor %0,%1,%1";
6736 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6739 rs6000_split_logical (operands, NOT, false, false, false);
6744 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6745 (const_string "veclogical")
6746 (const_string "integer")))
6747 (set (attr "length")
6749 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6752 (match_test "TARGET_POWERPC64")
6754 (const_string "16"))))])
6757 ;; Now define ways of moving data around.
6759 ;; Set up a register with a value from the GOT table
6761 (define_expand "movsi_got"
6762 [(set (match_operand:SI 0 "gpc_reg_operand")
6763 (unspec:SI [(match_operand:SI 1 "got_operand")
6764 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6765 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6767 if (GET_CODE (operands[1]) == CONST)
6769 rtx offset = const0_rtx;
6770 HOST_WIDE_INT value;
6772 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6773 value = INTVAL (offset);
6776 rtx tmp = (!can_create_pseudo_p ()
6778 : gen_reg_rtx (Pmode));
6779 emit_insn (gen_movsi_got (tmp, operands[1]));
6780 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6785 operands[2] = rs6000_got_register (operands[1]);
6788 (define_insn "*movsi_got_internal"
6789 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6790 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6791 (match_operand:SI 2 "gpc_reg_operand" "b")]
6793 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6794 "lwz %0,%a1@got(%2)"
6795 [(set_attr "type" "load")])
6797 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6798 ;; didn't get allocated to a hard register.
6800 [(set (match_operand:SI 0 "gpc_reg_operand")
6801 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6802 (match_operand:SI 2 "memory_operand")]
6804 "DEFAULT_ABI == ABI_V4
6806 && reload_completed"
6807 [(set (match_dup 0) (match_dup 2))
6808 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6812 ;; For SI, we special-case integers that can't be loaded in one insn. We
6813 ;; do the load 16-bits at a time. We could do this by loading from memory,
6814 ;; and this is even supposed to be faster, but it is simpler not to get
6815 ;; integers in the TOC.
6816 (define_insn "movsi_low"
6817 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6818 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6819 (match_operand 2 "" ""))))]
6820 "TARGET_MACHO && ! TARGET_64BIT"
6821 "lwz %0,lo16(%2)(%1)"
6822 [(set_attr "type" "load")])
6824 ;; MR LA LWZ LFIWZX LXSIWZX
6825 ;; STW STFIWX STXSIWX LI LIS
6826 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6827 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6829 (define_insn "*movsi_internal1"
6830 [(set (match_operand:SI 0 "nonimmediate_operand"
6831 "=r, r, r, ?*wI, ?*wH,
6833 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6834 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6837 (match_operand:SI 1 "input_operand"
6844 "gpc_reg_operand (operands[0], SImode)
6845 || gpc_reg_operand (operands[1], SImode)"
6871 "*, *, load, fpload, fpload,
6872 store, fpstore, fpstore, *, *,
6873 *, veclogical, vecsimple, vecsimple, vecsimple,
6874 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6884 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6885 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6887 ;; Because SF values are actually stored as DF values within the vector
6888 ;; registers, we need to convert the value to the vector SF format when
6889 ;; we need to use the bits in a union or similar cases. We only need
6890 ;; to do this transformation when the value is a vector register. Loads,
6891 ;; stores, and transfers within GPRs are assumed to be safe.
6893 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6894 ;; no alternatives, because the call is created as part of secondary_reload,
6895 ;; and operand #2's register class is used to allocate the temporary register.
6896 ;; This function is called before reload, and it creates the temporary as
6899 ;; MR LWZ LFIWZX LXSIWZX STW
6900 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6903 (define_insn_and_split "movsi_from_sf"
6904 [(set (match_operand:SI 0 "nonimmediate_operand"
6905 "=r, r, ?*wI, ?*wH, m,
6906 m, wY, Z, r, ?*wIwH,
6909 (unspec:SI [(match_operand:SF 1 "input_operand"
6911 f, wb, wu, wIwH, wIwH,
6915 (clobber (match_scratch:V4SF 2
6920 "TARGET_NO_SF_SUBREG
6921 && (register_operand (operands[0], SImode)
6922 || register_operand (operands[1], SFmode))"
6935 "&& reload_completed
6936 && int_reg_operand (operands[0], SImode)
6937 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6940 rtx op0 = operands[0];
6941 rtx op1 = operands[1];
6942 rtx op2 = operands[2];
6943 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6944 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6946 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6947 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6951 "*, load, fpload, fpload, store,
6952 fpstore, fpstore, fpstore, mftgpr, fp,
6960 ;; movsi_from_sf with zero extension
6962 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6965 (define_insn_and_split "*movdi_from_sf_zero_ext"
6966 [(set (match_operand:DI 0 "gpc_reg_operand"
6967 "=r, r, ?*wI, ?*wH, r,
6971 (unspec:SI [(match_operand:SF 1 "input_operand"
6974 UNSPEC_SI_FROM_SF)))
6976 (clobber (match_scratch:V4SF 2
6980 "TARGET_DIRECT_MOVE_64BIT
6981 && (register_operand (operands[0], DImode)
6982 || register_operand (operands[1], SImode))"
6991 "&& reload_completed
6992 && register_operand (operands[0], DImode)
6993 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6996 rtx op0 = operands[0];
6997 rtx op1 = operands[1];
6998 rtx op2 = operands[2];
6999 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7001 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7002 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7006 "*, load, fpload, fpload, two,
7013 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7014 ;; moving it to SImode. We can do a SFmode store without having to do the
7015 ;; conversion explicitly. If we are doing a register->register conversion, use
7016 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
7017 ;; input will not fit in a SFmode, and the later assumes the value has already
7019 (define_insn "*movsi_from_df"
7020 [(set (match_operand:SI 0 "nonimmediate_operand" "=wa,m,wY,Z")
7021 (unspec:SI [(float_truncate:SF
7022 (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
7023 UNSPEC_SI_FROM_SF))]
7025 "TARGET_NO_SF_SUBREG"
7031 [(set_attr "type" "fp,fpstore,fpstore,fpstore")])
7033 ;; Split a load of a large constant into the appropriate two-insn
7037 [(set (match_operand:SI 0 "gpc_reg_operand")
7038 (match_operand:SI 1 "const_int_operand"))]
7039 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7040 && (INTVAL (operands[1]) & 0xffff) != 0"
7044 (ior:SI (match_dup 0)
7047 if (rs6000_emit_set_const (operands[0], operands[1]))
7053 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7055 [(set (match_operand:DI 0 "altivec_register_operand")
7056 (match_operand:DI 1 "xxspltib_constant_split"))]
7057 "TARGET_P9_VECTOR && reload_completed"
7060 rtx op0 = operands[0];
7061 rtx op1 = operands[1];
7062 int r = REGNO (op0);
7063 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7065 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7066 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7070 (define_insn "*mov<mode>_internal2"
7071 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7072 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7074 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7080 [(set_attr "type" "cmp,logical,cmp")
7081 (set_attr "dot" "yes")
7082 (set_attr "length" "4,4,8")])
7085 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7086 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7088 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7090 [(set (match_dup 0) (match_dup 1))
7092 (compare:CC (match_dup 0)
7096 (define_expand "mov<mode>"
7097 [(set (match_operand:INT 0 "general_operand")
7098 (match_operand:INT 1 "any_operand"))]
7101 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7105 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7106 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7107 ;; MTVSRWZ MF%1 MT%1 NOP
7108 (define_insn "*mov<mode>_internal"
7109 [(set (match_operand:QHI 0 "nonimmediate_operand"
7110 "=r, r, ?*wJwK, m, Z, r,
7111 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7112 ?*wJwK, r, *c*l, *h")
7114 (match_operand:QHI 1 "input_operand"
7115 "r, m, Z, r, wJwK, i,
7116 wJwK, O, wM, wB, wS, ?*wJwK,
7119 "gpc_reg_operand (operands[0], <MODE>mode)
7120 || gpc_reg_operand (operands[1], <MODE>mode)"
7139 "*, load, fpload, store, fpstore, *,
7140 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7141 mffgpr, mfjmpr, mtjmpr, *")
7149 ;; Here is how to move condition codes around. When we store CC data in
7150 ;; an integer register or memory, we store just the high-order 4 bits.
7151 ;; This lets us not shift in the most common case of CR0.
7152 (define_expand "movcc"
7153 [(set (match_operand:CC 0 "nonimmediate_operand")
7154 (match_operand:CC 1 "nonimmediate_operand"))]
7158 (define_insn "*movcc_internal1"
7159 [(set (match_operand:CC 0 "nonimmediate_operand"
7160 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7161 (match_operand:CC 1 "general_operand"
7162 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7163 "register_operand (operands[0], CCmode)
7164 || register_operand (operands[1], CCmode)"
7168 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7171 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7178 [(set_attr_alternative "type"
7179 [(const_string "cr_logical")
7180 (const_string "mtcr")
7181 (const_string "mtcr")
7182 (const_string "cr_logical")
7183 (if_then_else (match_test "TARGET_MFCRF")
7184 (const_string "mfcrf") (const_string "mfcr"))
7185 (if_then_else (match_test "TARGET_MFCRF")
7186 (const_string "mfcrf") (const_string "mfcr"))
7187 (const_string "integer")
7188 (const_string "integer")
7189 (const_string "mfjmpr")
7190 (const_string "mtjmpr")
7191 (const_string "load")
7192 (const_string "store")])
7193 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7195 ;; For floating-point, we normally deal with the floating-point registers
7196 ;; unless -msoft-float is used. The sole exception is that parameter passing
7197 ;; can produce floating-point values in fixed-point registers. Unless the
7198 ;; value is a simple constant or already in memory, we deal with this by
7199 ;; allocating memory and copying the value explicitly via that memory location.
7201 ;; Move 32-bit binary/decimal floating point
7202 (define_expand "mov<mode>"
7203 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7204 (match_operand:FMOVE32 1 "any_operand"))]
7207 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7212 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7213 (match_operand:FMOVE32 1 "const_double_operand"))]
7215 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7216 || (GET_CODE (operands[0]) == SUBREG
7217 && GET_CODE (SUBREG_REG (operands[0])) == REG
7218 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7219 [(set (match_dup 2) (match_dup 3))]
7223 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7225 if (! TARGET_POWERPC64)
7226 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7228 operands[2] = gen_lowpart (SImode, operands[0]);
7230 operands[3] = gen_int_mode (l, SImode);
7233 ;; Originally, we tried to keep movsf and movsd common, but the differences
7234 ;; addressing was making it rather difficult to hide with mode attributes. In
7235 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7236 ;; before the VSX stores meant that the register allocator would tend to do a
7237 ;; direct move to the GPR (which involves conversion from scalar to
7238 ;; vector/memory formats) to save values in the traditional Altivec registers,
7239 ;; while SDmode had problems on power6 if the GPR store was not first due to
7240 ;; the power6 not having an integer store operation.
7242 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7243 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7244 ;; MR MT<x> MF<x> NOP
7246 (define_insn "movsf_hardfloat"
7247 [(set (match_operand:SF 0 "nonimmediate_operand"
7248 "=!r, f, wb, wu, m, wY,
7249 Z, m, ww, !r, f, ww,
7251 (match_operand:SF 1 "input_operand"
7252 "m, m, wY, Z, f, wb,
7255 "(register_operand (operands[0], SFmode)
7256 || register_operand (operands[1], SFmode))
7257 && TARGET_HARD_FLOAT
7258 && (TARGET_ALLOW_SF_SUBREG
7259 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7272 xscpsgndp %x0,%x1,%x1
7278 "load, fpload, fpload, fpload, fpstore, fpstore,
7279 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7280 *, mtjmpr, mfjmpr, *")])
7282 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7283 ;; FMR MR MT%0 MF%1 NOP
7284 (define_insn "movsd_hardfloat"
7285 [(set (match_operand:SD 0 "nonimmediate_operand"
7286 "=!r, wz, m, Z, ?wh, ?r,
7287 f, !r, *c*l, !r, *h")
7288 (match_operand:SD 1 "input_operand"
7289 "m, Z, r, wx, r, wh,
7291 "(register_operand (operands[0], SDmode)
7292 || register_operand (operands[1], SDmode))
7293 && TARGET_HARD_FLOAT"
7307 "load, fpload, store, fpstore, mffgpr, mftgpr,
7308 fpsimple, *, mtjmpr, mfjmpr, *")])
7310 ;; MR MT%0 MF%0 LWZ STW LI
7311 ;; LIS G-const. F/n-const NOP
7312 (define_insn "*mov<mode>_softfloat"
7313 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7314 "=r, *c*l, r, r, m, r,
7317 (match_operand:FMOVE32 1 "input_operand"
7321 "(gpc_reg_operand (operands[0], <MODE>mode)
7322 || gpc_reg_operand (operands[1], <MODE>mode))
7323 && TARGET_SOFT_FLOAT"
7336 "*, mtjmpr, mfjmpr, load, store, *,
7343 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7344 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7346 ;; Because SF values are actually stored as DF values within the vector
7347 ;; registers, we need to convert the value to the vector SF format when
7348 ;; we need to use the bits in a union or similar cases. We only need
7349 ;; to do this transformation when the value is a vector register. Loads,
7350 ;; stores, and transfers within GPRs are assumed to be safe.
7352 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7353 ;; no alternatives, because the call is created as part of secondary_reload,
7354 ;; and operand #2's register class is used to allocate the temporary register.
7355 ;; This function is called before reload, and it creates the temporary as
7358 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7359 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7360 (define_insn_and_split "movsf_from_si"
7361 [(set (match_operand:SF 0 "nonimmediate_operand"
7362 "=!r, f, wb, wu, m, Z,
7365 (unspec:SF [(match_operand:SI 1 "input_operand"
7370 (clobber (match_scratch:DI 2
7374 "TARGET_NO_SF_SUBREG
7375 && (register_operand (operands[0], SFmode)
7376 || register_operand (operands[1], SImode))"
7389 "&& reload_completed
7390 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7391 && int_reg_operand_not_pseudo (operands[1], SImode)"
7394 rtx op0 = operands[0];
7395 rtx op1 = operands[1];
7396 rtx op2 = operands[2];
7397 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7399 /* Move SF value to upper 32-bits for xscvspdpn. */
7400 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7401 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7402 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7409 "load, fpload, fpload, fpload, store, fpstore,
7410 fpstore, vecfloat, mffgpr, *")])
7413 ;; Move 64-bit binary/decimal floating point
7414 (define_expand "mov<mode>"
7415 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7416 (match_operand:FMOVE64 1 "any_operand"))]
7419 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7424 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7425 (match_operand:FMOVE64 1 "const_int_operand"))]
7426 "! TARGET_POWERPC64 && reload_completed
7427 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7428 || (GET_CODE (operands[0]) == SUBREG
7429 && GET_CODE (SUBREG_REG (operands[0])) == REG
7430 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7431 [(set (match_dup 2) (match_dup 4))
7432 (set (match_dup 3) (match_dup 1))]
7434 int endian = (WORDS_BIG_ENDIAN == 0);
7435 HOST_WIDE_INT value = INTVAL (operands[1]);
7437 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7438 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7439 operands[4] = GEN_INT (value >> 32);
7440 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7444 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7445 (match_operand:FMOVE64 1 "const_double_operand"))]
7446 "! TARGET_POWERPC64 && reload_completed
7447 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7448 || (GET_CODE (operands[0]) == SUBREG
7449 && GET_CODE (SUBREG_REG (operands[0])) == REG
7450 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7451 [(set (match_dup 2) (match_dup 4))
7452 (set (match_dup 3) (match_dup 5))]
7454 int endian = (WORDS_BIG_ENDIAN == 0);
7457 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7459 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7460 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7461 operands[4] = gen_int_mode (l[endian], SImode);
7462 operands[5] = gen_int_mode (l[1 - endian], SImode);
7466 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7467 (match_operand:FMOVE64 1 "const_double_operand"))]
7468 "TARGET_POWERPC64 && reload_completed
7469 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7470 || (GET_CODE (operands[0]) == SUBREG
7471 && GET_CODE (SUBREG_REG (operands[0])) == REG
7472 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7473 [(set (match_dup 2) (match_dup 3))]
7475 int endian = (WORDS_BIG_ENDIAN == 0);
7479 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7481 operands[2] = gen_lowpart (DImode, operands[0]);
7482 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7483 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7484 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7486 operands[3] = gen_int_mode (val, DImode);
7489 ;; Don't have reload use general registers to load a constant. It is
7490 ;; less efficient than loading the constant into an FP register, since
7491 ;; it will probably be used there.
7493 ;; The move constraints are ordered to prefer floating point registers before
7494 ;; general purpose registers to avoid doing a store and a load to get the value
7495 ;; into a floating point register when it is needed for a floating point
7496 ;; operation. Prefer traditional floating point registers over VSX registers,
7497 ;; since the D-form version of the memory instructions does not need a GPR for
7498 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7501 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7502 ;; except for 0.0 which can be created on VSX with an xor instruction.
7504 ;; STFD LFD FMR LXSD STXSD
7505 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7509 (define_insn "*mov<mode>_hardfloat32"
7510 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7511 "=m, d, d, <f64_p9>, wY,
7512 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7515 (match_operand:FMOVE64 1 "input_operand"
7516 "d, m, d, wY, <f64_p9>,
7517 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7520 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7521 && (gpc_reg_operand (operands[0], <MODE>mode)
7522 || gpc_reg_operand (operands[1], <MODE>mode))"
7538 "fpstore, fpload, fpsimple, fpload, fpstore,
7539 fpload, fpstore, veclogical, veclogical, two,
7542 (set_attr "size" "64")
7548 ;; STW LWZ MR G-const H-const F-const
7550 (define_insn "*mov<mode>_softfloat32"
7551 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7552 "=Y, r, r, r, r, r")
7554 (match_operand:FMOVE64 1 "input_operand"
7555 "r, Y, r, G, H, F"))]
7558 && (gpc_reg_operand (operands[0], <MODE>mode)
7559 || gpc_reg_operand (operands[1], <MODE>mode))"
7562 "store, load, two, *, *, *")
7565 "8, 8, 8, 8, 12, 16")])
7567 ; ld/std require word-aligned displacements -> 'Y' constraint.
7568 ; List Y->r and r->Y before r->r for reload.
7570 ;; STFD LFD FMR LXSD STXSD
7571 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7572 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7573 ;; NOP MFTGPR MFFGPR MFVSRD MTVSRD
7575 (define_insn "*mov<mode>_hardfloat64"
7576 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7577 "=m, d, d, <f64_p9>, wY,
7578 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7579 YZ, r, !r, *c*l, !r,
7580 *h, r, wg, r, <f64_dm>")
7582 (match_operand:FMOVE64 1 "input_operand"
7583 "d, m, d, wY, <f64_p9>,
7584 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7586 0, wg, r, <f64_dm>, r"))]
7588 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7589 && (gpc_reg_operand (operands[0], <MODE>mode)
7590 || gpc_reg_operand (operands[1], <MODE>mode))"
7613 "fpstore, fpload, fpsimple, fpload, fpstore,
7614 fpload, fpstore, veclogical, veclogical, integer,
7615 store, load, *, mtjmpr, mfjmpr,
7616 *, mftgpr, mffgpr, mftgpr, mffgpr")
7618 (set_attr "size" "64")
7619 (set_attr "length" "4")])
7621 ;; STD LD MR MT<SPR> MF<SPR> G-const
7622 ;; H-const F-const Special
7624 (define_insn "*mov<mode>_softfloat64"
7625 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7626 "=Y, r, r, *c*l, r, r,
7629 (match_operand:FMOVE64 1 "input_operand"
7633 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7634 && (gpc_reg_operand (operands[0], <MODE>mode)
7635 || gpc_reg_operand (operands[1], <MODE>mode))"
7647 "store, load, *, mtjmpr, mfjmpr, *,
7654 (define_expand "mov<mode>"
7655 [(set (match_operand:FMOVE128 0 "general_operand")
7656 (match_operand:FMOVE128 1 "any_operand"))]
7659 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7663 ;; It's important to list Y->r and r->Y before r->r because otherwise
7664 ;; reload, given m->r, will try to pick r->r and reload it, which
7665 ;; doesn't make progress.
7667 ;; We can't split little endian direct moves of TDmode, because the words are
7668 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7669 ;; problematical. Don't allow direct move for this case.
7671 (define_insn_and_split "*mov<mode>_64bit_dm"
7672 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7673 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7674 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7675 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7676 && (gpc_reg_operand (operands[0], <MODE>mode)
7677 || gpc_reg_operand (operands[1], <MODE>mode))"
7679 "&& reload_completed"
7681 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7682 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7684 (define_insn_and_split "*movtd_64bit_nodm"
7685 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7686 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7687 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7688 && (gpc_reg_operand (operands[0], TDmode)
7689 || gpc_reg_operand (operands[1], TDmode))"
7691 "&& reload_completed"
7693 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7694 [(set_attr "length" "8,8,8,12,12,8")])
7696 (define_insn_and_split "*mov<mode>_32bit"
7697 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7698 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7699 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7700 && (FLOAT128_2REG_P (<MODE>mode)
7701 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7702 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7703 && (gpc_reg_operand (operands[0], <MODE>mode)
7704 || gpc_reg_operand (operands[1], <MODE>mode))"
7706 "&& reload_completed"
7708 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7709 [(set_attr "length" "8,8,8,8,20,20,16")])
7711 (define_insn_and_split "*mov<mode>_softfloat"
7712 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7713 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7715 && (gpc_reg_operand (operands[0], <MODE>mode)
7716 || gpc_reg_operand (operands[1], <MODE>mode))"
7718 "&& reload_completed"
7720 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7721 [(set_attr "length" "20,20,16")])
7723 (define_expand "extenddf<mode>2"
7724 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7725 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7726 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7728 if (FLOAT128_IEEE_P (<MODE>mode))
7729 rs6000_expand_float128_convert (operands[0], operands[1], false);
7730 else if (TARGET_VSX)
7732 if (<MODE>mode == TFmode)
7733 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7734 else if (<MODE>mode == IFmode)
7735 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7741 rtx zero = gen_reg_rtx (DFmode);
7742 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7744 if (<MODE>mode == TFmode)
7745 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7746 else if (<MODE>mode == IFmode)
7747 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7754 ;; Allow memory operands for the source to be created by the combiner.
7755 (define_insn_and_split "extenddf<mode>2_fprs"
7756 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7757 (float_extend:IBM128
7758 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7759 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7760 "!TARGET_VSX && TARGET_HARD_FLOAT
7761 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7763 "&& reload_completed"
7764 [(set (match_dup 3) (match_dup 1))
7765 (set (match_dup 4) (match_dup 2))]
7767 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7768 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7770 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7771 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7774 (define_insn_and_split "extenddf<mode>2_vsx"
7775 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7776 (float_extend:IBM128
7777 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7778 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7780 "&& reload_completed"
7781 [(set (match_dup 2) (match_dup 1))
7782 (set (match_dup 3) (match_dup 4))]
7784 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7785 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7787 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7788 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7789 operands[4] = CONST0_RTX (DFmode);
7792 (define_expand "extendsf<mode>2"
7793 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7794 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7795 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7797 if (FLOAT128_IEEE_P (<MODE>mode))
7798 rs6000_expand_float128_convert (operands[0], operands[1], false);
7801 rtx tmp = gen_reg_rtx (DFmode);
7802 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7803 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7808 (define_expand "trunc<mode>df2"
7809 [(set (match_operand:DF 0 "gpc_reg_operand")
7810 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7811 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7813 if (FLOAT128_IEEE_P (<MODE>mode))
7815 rs6000_expand_float128_convert (operands[0], operands[1], false);
7820 (define_insn_and_split "trunc<mode>df2_internal1"
7821 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7823 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7824 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7825 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7829 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7832 emit_note (NOTE_INSN_DELETED);
7835 [(set_attr "type" "fpsimple")])
7837 (define_insn "trunc<mode>df2_internal2"
7838 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7839 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7840 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7841 && TARGET_LONG_DOUBLE_128"
7843 [(set_attr "type" "fp")])
7845 (define_expand "trunc<mode>sf2"
7846 [(set (match_operand:SF 0 "gpc_reg_operand")
7847 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7848 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7850 if (FLOAT128_IEEE_P (<MODE>mode))
7851 rs6000_expand_float128_convert (operands[0], operands[1], false);
7854 rtx tmp = gen_reg_rtx (DFmode);
7855 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7856 emit_insn (gen_truncdfsf2 (operands[0], tmp));
7861 (define_expand "floatsi<mode>2"
7862 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7863 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7864 (clobber (match_scratch:DI 2))])]
7865 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7867 rtx op0 = operands[0];
7868 rtx op1 = operands[1];
7870 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7872 else if (FLOAT128_IEEE_P (<MODE>mode))
7874 rs6000_expand_float128_convert (op0, op1, false);
7879 rtx tmp = gen_reg_rtx (DFmode);
7880 expand_float (tmp, op1, false);
7881 if (<MODE>mode == TFmode)
7882 emit_insn (gen_extenddftf2 (op0, tmp));
7883 else if (<MODE>mode == IFmode)
7884 emit_insn (gen_extenddfif2 (op0, tmp));
7891 ; fadd, but rounding towards zero.
7892 ; This is probably not the optimal code sequence.
7893 (define_insn "fix_trunc_helper<mode>"
7894 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7895 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7896 UNSPEC_FIX_TRUNC_TF))
7897 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7898 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7899 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7900 [(set_attr "type" "fp")
7901 (set_attr "length" "20")])
7903 (define_expand "fix_trunc<mode>si2"
7904 [(set (match_operand:SI 0 "gpc_reg_operand")
7905 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7906 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7908 rtx op0 = operands[0];
7909 rtx op1 = operands[1];
7911 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7915 if (FLOAT128_IEEE_P (<MODE>mode))
7916 rs6000_expand_float128_convert (op0, op1, false);
7917 else if (<MODE>mode == TFmode)
7918 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7919 else if (<MODE>mode == IFmode)
7920 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7927 (define_expand "fix_trunc<mode>si2_fprs"
7928 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7929 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7930 (clobber (match_dup 2))
7931 (clobber (match_dup 3))
7932 (clobber (match_dup 4))
7933 (clobber (match_dup 5))])]
7934 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7936 operands[2] = gen_reg_rtx (DFmode);
7937 operands[3] = gen_reg_rtx (DFmode);
7938 operands[4] = gen_reg_rtx (DImode);
7939 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7942 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7943 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7944 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7945 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7946 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7947 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7948 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7949 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7955 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7958 gcc_assert (MEM_P (operands[5]));
7959 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7961 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7962 emit_move_insn (operands[5], operands[4]);
7963 emit_move_insn (operands[0], lowword);
7967 (define_expand "fix_trunc<mode>di2"
7968 [(set (match_operand:DI 0 "gpc_reg_operand")
7969 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7970 "TARGET_FLOAT128_TYPE"
7972 if (!TARGET_FLOAT128_HW)
7974 rs6000_expand_float128_convert (operands[0], operands[1], false);
7979 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7980 [(set (match_operand:SDI 0 "gpc_reg_operand")
7981 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7982 "TARGET_FLOAT128_TYPE"
7984 rs6000_expand_float128_convert (operands[0], operands[1], true);
7988 (define_expand "floatdi<mode>2"
7989 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7990 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7991 "TARGET_FLOAT128_TYPE"
7993 if (!TARGET_FLOAT128_HW)
7995 rs6000_expand_float128_convert (operands[0], operands[1], false);
8000 (define_expand "floatunsdi<IEEE128:mode>2"
8001 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8002 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8003 "TARGET_FLOAT128_TYPE"
8005 if (!TARGET_FLOAT128_HW)
8007 rs6000_expand_float128_convert (operands[0], operands[1], true);
8012 (define_expand "floatuns<IEEE128:mode>2"
8013 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8014 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8015 "TARGET_FLOAT128_TYPE"
8017 rtx op0 = operands[0];
8018 rtx op1 = operands[1];
8020 if (TARGET_FLOAT128_HW)
8021 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8023 rs6000_expand_float128_convert (op0, op1, true);
8027 (define_expand "neg<mode>2"
8028 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8029 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8030 "FLOAT128_IEEE_P (<MODE>mode)
8031 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8033 if (FLOAT128_IEEE_P (<MODE>mode))
8035 if (TARGET_FLOAT128_HW)
8037 if (<MODE>mode == TFmode)
8038 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
8039 else if (<MODE>mode == KFmode)
8040 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
8044 else if (TARGET_FLOAT128_TYPE)
8046 if (<MODE>mode == TFmode)
8047 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
8048 else if (<MODE>mode == KFmode)
8049 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
8055 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8056 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8058 operands[1], <MODE>mode);
8060 if (target && !rtx_equal_p (target, operands[0]))
8061 emit_move_insn (operands[0], target);
8067 (define_insn "neg<mode>2_internal"
8068 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8069 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8070 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8072 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8073 return "fneg %L0,%L1\;fneg %0,%1";
8075 return "fneg %0,%1\;fneg %L0,%L1";
8077 [(set_attr "type" "fpsimple")
8078 (set_attr "length" "8")])
8080 (define_expand "abs<mode>2"
8081 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8082 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8083 "FLOAT128_IEEE_P (<MODE>mode)
8084 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8088 if (FLOAT128_IEEE_P (<MODE>mode))
8090 if (TARGET_FLOAT128_HW)
8092 if (<MODE>mode == TFmode)
8093 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8094 else if (<MODE>mode == KFmode)
8095 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8100 else if (TARGET_FLOAT128_TYPE)
8102 if (<MODE>mode == TFmode)
8103 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8104 else if (<MODE>mode == KFmode)
8105 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8114 label = gen_label_rtx ();
8115 if (<MODE>mode == TFmode)
8116 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8117 else if (<MODE>mode == IFmode)
8118 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8125 (define_expand "abs<mode>2_internal"
8126 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8127 (match_operand:IBM128 1 "gpc_reg_operand"))
8128 (set (match_dup 3) (match_dup 5))
8129 (set (match_dup 5) (abs:DF (match_dup 5)))
8130 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8131 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8132 (label_ref (match_operand 2 ""))
8134 (set (match_dup 6) (neg:DF (match_dup 6)))]
8135 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8137 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8138 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8139 operands[3] = gen_reg_rtx (DFmode);
8140 operands[4] = gen_reg_rtx (CCFPmode);
8141 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8142 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8146 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8149 (define_expand "ieee_128bit_negative_zero"
8150 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8151 "TARGET_FLOAT128_TYPE"
8153 rtvec v = rtvec_alloc (16);
8156 for (i = 0; i < 16; i++)
8157 RTVEC_ELT (v, i) = const0_rtx;
8159 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8160 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8162 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8166 ;; IEEE 128-bit negate
8168 ;; We have 2 insns here for negate and absolute value. The first uses
8169 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8170 ;; insns, and second insn after the first split pass loads up the bit to
8171 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8172 ;; neg/abs to create the constant just once.
8174 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8175 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8176 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8177 (clobber (match_scratch:V16QI 2 "=v"))]
8178 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8181 [(parallel [(set (match_dup 0)
8182 (neg:IEEE128 (match_dup 1)))
8183 (use (match_dup 2))])]
8185 if (GET_CODE (operands[2]) == SCRATCH)
8186 operands[2] = gen_reg_rtx (V16QImode);
8188 operands[3] = gen_reg_rtx (V16QImode);
8189 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8191 [(set_attr "length" "8")
8192 (set_attr "type" "vecsimple")])
8194 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8195 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8196 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8197 (use (match_operand:V16QI 2 "register_operand" "v"))]
8198 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8199 "xxlxor %x0,%x1,%x2"
8200 [(set_attr "type" "veclogical")])
8202 ;; IEEE 128-bit absolute value
8203 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8204 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8205 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8206 (clobber (match_scratch:V16QI 2 "=v"))]
8207 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8210 [(parallel [(set (match_dup 0)
8211 (abs:IEEE128 (match_dup 1)))
8212 (use (match_dup 2))])]
8214 if (GET_CODE (operands[2]) == SCRATCH)
8215 operands[2] = gen_reg_rtx (V16QImode);
8217 operands[3] = gen_reg_rtx (V16QImode);
8218 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8220 [(set_attr "length" "8")
8221 (set_attr "type" "vecsimple")])
8223 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8224 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8225 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8226 (use (match_operand:V16QI 2 "register_operand" "v"))]
8227 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8228 "xxlandc %x0,%x1,%x2"
8229 [(set_attr "type" "veclogical")])
8231 ;; IEEE 128-bit negative absolute value
8232 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8233 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8236 (match_operand:IEEE128 1 "register_operand" "wa"))))
8237 (clobber (match_scratch:V16QI 2 "=v"))]
8238 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8239 && FLOAT128_IEEE_P (<MODE>mode)"
8242 [(parallel [(set (match_dup 0)
8243 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8244 (use (match_dup 2))])]
8246 if (GET_CODE (operands[2]) == SCRATCH)
8247 operands[2] = gen_reg_rtx (V16QImode);
8249 operands[3] = gen_reg_rtx (V16QImode);
8250 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8252 [(set_attr "length" "8")
8253 (set_attr "type" "vecsimple")])
8255 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8256 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8259 (match_operand:IEEE128 1 "register_operand" "wa"))))
8260 (use (match_operand:V16QI 2 "register_operand" "v"))]
8261 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8263 [(set_attr "type" "veclogical")])
8265 ;; Float128 conversion functions. These expand to library function calls.
8266 ;; We use expand to convert from IBM double double to IEEE 128-bit
8267 ;; and trunc for the opposite.
8268 (define_expand "extendiftf2"
8269 [(set (match_operand:TF 0 "gpc_reg_operand")
8270 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8271 "TARGET_FLOAT128_TYPE"
8273 rs6000_expand_float128_convert (operands[0], operands[1], false);
8277 (define_expand "extendifkf2"
8278 [(set (match_operand:KF 0 "gpc_reg_operand")
8279 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8280 "TARGET_FLOAT128_TYPE"
8282 rs6000_expand_float128_convert (operands[0], operands[1], false);
8286 (define_expand "extendtfkf2"
8287 [(set (match_operand:KF 0 "gpc_reg_operand")
8288 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8289 "TARGET_FLOAT128_TYPE"
8291 rs6000_expand_float128_convert (operands[0], operands[1], false);
8295 (define_expand "extendtfif2"
8296 [(set (match_operand:IF 0 "gpc_reg_operand")
8297 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8298 "TARGET_FLOAT128_TYPE"
8300 rs6000_expand_float128_convert (operands[0], operands[1], false);
8304 (define_expand "trunciftf2"
8305 [(set (match_operand:TF 0 "gpc_reg_operand")
8306 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8307 "TARGET_FLOAT128_TYPE"
8309 rs6000_expand_float128_convert (operands[0], operands[1], false);
8313 (define_expand "truncifkf2"
8314 [(set (match_operand:KF 0 "gpc_reg_operand")
8315 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8316 "TARGET_FLOAT128_TYPE"
8318 rs6000_expand_float128_convert (operands[0], operands[1], false);
8322 (define_expand "trunckftf2"
8323 [(set (match_operand:TF 0 "gpc_reg_operand")
8324 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8325 "TARGET_FLOAT128_TYPE"
8327 rs6000_expand_float128_convert (operands[0], operands[1], false);
8331 (define_expand "trunctfif2"
8332 [(set (match_operand:IF 0 "gpc_reg_operand")
8333 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8334 "TARGET_FLOAT128_TYPE"
8336 rs6000_expand_float128_convert (operands[0], operands[1], false);
8340 (define_insn_and_split "*extend<mode>tf2_internal"
8341 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8343 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8344 "TARGET_FLOAT128_TYPE
8345 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8347 "&& reload_completed"
8348 [(set (match_dup 0) (match_dup 2))]
8350 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8353 (define_insn_and_split "*extendtf<mode>2_internal"
8354 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8356 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8357 "TARGET_FLOAT128_TYPE
8358 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8360 "&& reload_completed"
8361 [(set (match_dup 0) (match_dup 2))]
8363 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8367 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8368 ;; must have 3 arguments, and scratch register constraint must be a single
8371 ;; Reload patterns to support gpr load/store with misaligned mem.
8372 ;; and multiple gpr load/store at offset >= 0xfffc
8373 (define_expand "reload_<mode>_store"
8374 [(parallel [(match_operand 0 "memory_operand" "=m")
8375 (match_operand 1 "gpc_reg_operand" "r")
8376 (match_operand:GPR 2 "register_operand" "=&b")])]
8379 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8383 (define_expand "reload_<mode>_load"
8384 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8385 (match_operand 1 "memory_operand" "m")
8386 (match_operand:GPR 2 "register_operand" "=b")])]
8389 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8394 ;; Reload patterns for various types using the vector registers. We may need
8395 ;; an additional base register to convert the reg+offset addressing to reg+reg
8396 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8397 ;; index register for gpr registers.
8398 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8399 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8400 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8401 (match_operand:P 2 "register_operand" "=b")])]
8404 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8408 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8409 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8410 (match_operand:RELOAD 1 "memory_operand" "m")
8411 (match_operand:P 2 "register_operand" "=b")])]
8414 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8419 ;; Reload sometimes tries to move the address to a GPR, and can generate
8420 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8421 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8423 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8424 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8425 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8426 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8428 "TARGET_ALTIVEC && reload_completed"
8430 "&& reload_completed"
8432 (plus:P (match_dup 1)
8435 (and:P (match_dup 0)
8438 ;; Power8 merge instructions to allow direct move to/from floating point
8439 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8440 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8441 ;; value, since it is allocated in reload and not all of the flow information
8442 ;; is setup for it. We have two patterns to do the two moves between gprs and
8443 ;; fprs. There isn't a dependancy between the two, but we could potentially
8444 ;; schedule other instructions between the two instructions.
8446 (define_insn "p8_fmrgow_<mode>"
8447 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8449 (match_operand:DF 1 "register_operand" "d")
8450 (match_operand:DF 2 "register_operand" "d")]
8451 UNSPEC_P8V_FMRGOW))]
8452 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8454 [(set_attr "type" "fpsimple")])
8456 (define_insn "p8_mtvsrwz"
8457 [(set (match_operand:DF 0 "register_operand" "=d")
8458 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8459 UNSPEC_P8V_MTVSRWZ))]
8460 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8462 [(set_attr "type" "mftgpr")])
8464 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8465 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8466 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8467 UNSPEC_P8V_RELOAD_FROM_GPR))
8468 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8469 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8471 "&& reload_completed"
8474 rtx dest = operands[0];
8475 rtx src = operands[1];
8476 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8477 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8478 rtx gpr_hi_reg = gen_highpart (SImode, src);
8479 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8481 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8482 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8483 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8486 [(set_attr "length" "12")
8487 (set_attr "type" "three")])
8489 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8490 (define_insn "p8_mtvsrd_df"
8491 [(set (match_operand:DF 0 "register_operand" "=wa")
8492 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8493 UNSPEC_P8V_MTVSRD))]
8494 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8496 [(set_attr "type" "mftgpr")])
8498 (define_insn "p8_xxpermdi_<mode>"
8499 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8500 (unspec:FMOVE128_GPR [
8501 (match_operand:DF 1 "register_operand" "wa")
8502 (match_operand:DF 2 "register_operand" "wa")]
8503 UNSPEC_P8V_XXPERMDI))]
8504 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8505 "xxpermdi %x0,%x1,%x2,0"
8506 [(set_attr "type" "vecperm")])
8508 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8509 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8510 (unspec:FMOVE128_GPR
8511 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8512 UNSPEC_P8V_RELOAD_FROM_GPR))
8513 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8514 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8516 "&& reload_completed"
8519 rtx dest = operands[0];
8520 rtx src = operands[1];
8521 /* You might think that we could use op0 as one temp and a DF clobber
8522 as op2, but you'd be wrong. Secondary reload move patterns don't
8523 check for overlap of the clobber and the destination. */
8524 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8525 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8526 rtx gpr_hi_reg = gen_highpart (DImode, src);
8527 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8529 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8530 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8531 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8534 [(set_attr "length" "12")
8535 (set_attr "type" "three")])
8538 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8539 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8541 && (int_reg_operand (operands[0], <MODE>mode)
8542 || int_reg_operand (operands[1], <MODE>mode))
8543 && (!TARGET_DIRECT_MOVE_128
8544 || (!vsx_register_operand (operands[0], <MODE>mode)
8545 && !vsx_register_operand (operands[1], <MODE>mode)))"
8547 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8549 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8550 ;; type is stored internally as double precision in the VSX registers, we have
8551 ;; to convert it from the vector format.
8552 (define_insn "p8_mtvsrd_sf"
8553 [(set (match_operand:SF 0 "register_operand" "=wa")
8554 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8555 UNSPEC_P8V_MTVSRD))]
8556 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8558 [(set_attr "type" "mftgpr")])
8560 (define_insn_and_split "reload_vsx_from_gprsf"
8561 [(set (match_operand:SF 0 "register_operand" "=wa")
8562 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8563 UNSPEC_P8V_RELOAD_FROM_GPR))
8564 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8565 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8567 "&& reload_completed"
8570 rtx op0 = operands[0];
8571 rtx op1 = operands[1];
8572 rtx op2 = operands[2];
8573 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8575 /* Move SF value to upper 32-bits for xscvspdpn. */
8576 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8577 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8578 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8581 [(set_attr "length" "8")
8582 (set_attr "type" "two")])
8584 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8585 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8586 ;; and then doing a move of that.
8587 (define_insn "p8_mfvsrd_3_<mode>"
8588 [(set (match_operand:DF 0 "register_operand" "=r")
8589 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8590 UNSPEC_P8V_RELOAD_FROM_VSX))]
8591 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8593 [(set_attr "type" "mftgpr")])
8595 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8596 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8597 (unspec:FMOVE128_GPR
8598 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8599 UNSPEC_P8V_RELOAD_FROM_VSX))
8600 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8601 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8603 "&& reload_completed"
8606 rtx dest = operands[0];
8607 rtx src = operands[1];
8608 rtx tmp = operands[2];
8609 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8610 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8612 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8613 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8614 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8617 [(set_attr "length" "12")
8618 (set_attr "type" "three")])
8620 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8621 ;; type is stored internally as double precision, we have to convert it to the
8624 (define_insn_and_split "reload_gpr_from_vsxsf"
8625 [(set (match_operand:SF 0 "register_operand" "=r")
8626 (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8627 UNSPEC_P8V_RELOAD_FROM_VSX))
8628 (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8629 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8631 "&& reload_completed"
8634 rtx op0 = operands[0];
8635 rtx op1 = operands[1];
8636 rtx op2 = operands[2];
8637 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8638 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8640 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8641 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8644 [(set_attr "length" "8")
8645 (set_attr "type" "two")])
8648 ;; Next come the multi-word integer load and store and the load and store
8651 ;; List r->r after r->Y, otherwise reload will try to reload a
8652 ;; non-offsettable address by using r->r which won't make progress.
8653 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8654 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8656 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8657 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8658 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8661 (define_insn "*movdi_internal32"
8662 [(set (match_operand:DI 0 "nonimmediate_operand"
8663 "=Y, r, r, m, ^d, ^d,
8664 r, wY, Z, ^wb, $wv, ^wi,
8665 *wo, *wo, *wv, *wi, *wi, *wv,
8668 (match_operand:DI 1 "input_operand"
8669 "r, Y, r, ^d, m, ^d,
8670 IJKnGHF, ^wb, $wv, wY, Z, ^wi,
8671 Oj, wM, OjwM, Oj, wM, wS,
8675 && (gpc_reg_operand (operands[0], DImode)
8676 || gpc_reg_operand (operands[1], DImode))"
8698 "store, load, *, fpstore, fpload, fpsimple,
8699 *, fpstore, fpstore, fpload, fpload, veclogical,
8700 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8702 (set_attr "size" "64")])
8705 [(set (match_operand:DI 0 "gpc_reg_operand")
8706 (match_operand:DI 1 "const_int_operand"))]
8707 "! TARGET_POWERPC64 && reload_completed
8708 && gpr_or_gpr_p (operands[0], operands[1])
8709 && !direct_move_p (operands[0], operands[1])"
8710 [(set (match_dup 2) (match_dup 4))
8711 (set (match_dup 3) (match_dup 1))]
8713 HOST_WIDE_INT value = INTVAL (operands[1]);
8714 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8716 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8718 operands[4] = GEN_INT (value >> 32);
8719 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8723 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8724 (match_operand:DIFD 1 "input_operand"))]
8725 "reload_completed && !TARGET_POWERPC64
8726 && gpr_or_gpr_p (operands[0], operands[1])
8727 && !direct_move_p (operands[0], operands[1])"
8729 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8731 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8732 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8733 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8734 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8735 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8736 (define_insn "*movdi_internal64"
8737 [(set (match_operand:DI 0 "nonimmediate_operand"
8738 "=YZ, r, r, r, r, r,
8739 m, ^d, ^d, wY, Z, $wb,
8740 $wv, ^wi, *wo, *wo, *wv, *wi,
8741 *wi, *wv, *wv, r, *h, *h,
8742 ?*r, ?*wg, ?*r, ?*wj")
8744 (match_operand:DI 1 "input_operand"
8745 "r, YZ, r, I, L, nF,
8746 ^d, m, ^d, ^wb, $wv, wY,
8747 Z, ^wi, Oj, wM, OjwM, Oj,
8748 wM, wS, wB, *h, r, 0,
8752 && (gpc_reg_operand (operands[0], DImode)
8753 || gpc_reg_operand (operands[1], DImode))"
8784 "store, load, *, *, *, *,
8785 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8786 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8787 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8788 mftgpr, mffgpr, mftgpr, mffgpr")
8790 (set_attr "size" "64")
8798 ; Some DImode loads are best done as a load of -1 followed by a mask
8801 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8802 (match_operand:DI 1 "const_int_operand"))]
8804 && num_insns_constant (operands[1], DImode) > 1
8805 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8806 && rs6000_is_valid_and_mask (operands[1], DImode)"
8810 (and:DI (match_dup 0)
8814 ;; Split a load of a large constant into the appropriate five-instruction
8815 ;; sequence. Handle anything in a constant number of insns.
8816 ;; When non-easy constants can go in the TOC, this should use
8817 ;; easy_fp_constant predicate.
8819 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8820 (match_operand:DI 1 "const_int_operand"))]
8821 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8822 [(set (match_dup 0) (match_dup 2))
8823 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8825 if (rs6000_emit_set_const (operands[0], operands[1]))
8832 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8833 (match_operand:DI 1 "const_scalar_int_operand"))]
8834 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8835 [(set (match_dup 0) (match_dup 2))
8836 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8838 if (rs6000_emit_set_const (operands[0], operands[1]))
8845 [(set (match_operand:DI 0 "altivec_register_operand")
8846 (match_operand:DI 1 "s5bit_cint_operand"))]
8847 "TARGET_VSX && reload_completed"
8850 rtx op0 = operands[0];
8851 rtx op1 = operands[1];
8852 int r = REGNO (op0);
8853 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8855 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8856 if (op1 != const0_rtx && op1 != constm1_rtx)
8858 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8859 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8864 ;; Split integer constants that can be loaded with XXSPLTIB and a
8865 ;; sign extend operation.
8867 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8868 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8869 "TARGET_P9_VECTOR && reload_completed"
8872 rtx op0 = operands[0];
8873 rtx op1 = operands[1];
8874 int r = REGNO (op0);
8875 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8877 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8878 if (<MODE>mode == DImode)
8879 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8880 else if (<MODE>mode == SImode)
8881 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8882 else if (<MODE>mode == HImode)
8884 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8885 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8891 ;; TImode/PTImode is similar, except that we usually want to compute the
8892 ;; address into a register and use lsi/stsi (the exception is during reload).
8894 (define_insn "*mov<mode>_string"
8895 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8896 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8898 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8899 && (gpc_reg_operand (operands[0], <MODE>mode)
8900 || gpc_reg_operand (operands[1], <MODE>mode))"
8902 [(set_attr "type" "store,store,load,load,*,*")
8903 (set_attr "update" "yes")
8904 (set_attr "indexed" "yes")
8905 (set_attr "cell_micro" "conditional")])
8907 (define_insn "*mov<mode>_ppc64"
8908 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8909 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8910 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8911 && (gpc_reg_operand (operands[0], <MODE>mode)
8912 || gpc_reg_operand (operands[1], <MODE>mode)))"
8914 return rs6000_output_move_128bit (operands);
8916 [(set_attr "type" "store,store,load,load,*,*")
8917 (set_attr "length" "8")])
8920 [(set (match_operand:TI2 0 "int_reg_operand")
8921 (match_operand:TI2 1 "const_scalar_int_operand"))]
8923 && (VECTOR_MEM_NONE_P (<MODE>mode)
8924 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8925 [(set (match_dup 2) (match_dup 4))
8926 (set (match_dup 3) (match_dup 5))]
8928 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8930 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8932 if (CONST_WIDE_INT_P (operands[1]))
8934 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8935 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8937 else if (CONST_INT_P (operands[1]))
8939 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8940 operands[5] = operands[1];
8947 [(set (match_operand:TI2 0 "nonimmediate_operand")
8948 (match_operand:TI2 1 "input_operand"))]
8950 && gpr_or_gpr_p (operands[0], operands[1])
8951 && !direct_move_p (operands[0], operands[1])
8952 && !quad_load_store_p (operands[0], operands[1])"
8954 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8956 (define_expand "setmemsi"
8957 [(parallel [(set (match_operand:BLK 0 "")
8958 (match_operand 2 "const_int_operand"))
8959 (use (match_operand:SI 1 ""))
8960 (use (match_operand:SI 3 ""))])]
8963 /* If value to set is not zero, use the library routine. */
8964 if (operands[2] != const0_rtx)
8967 if (expand_block_clear (operands))
8973 ;; String compare N insn.
8974 ;; Argument 0 is the target (result)
8975 ;; Argument 1 is the destination
8976 ;; Argument 2 is the source
8977 ;; Argument 3 is the length
8978 ;; Argument 4 is the alignment
8980 (define_expand "cmpstrnsi"
8981 [(parallel [(set (match_operand:SI 0)
8982 (compare:SI (match_operand:BLK 1)
8983 (match_operand:BLK 2)))
8984 (use (match_operand:SI 3))
8985 (use (match_operand:SI 4))])]
8986 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8988 if (optimize_insn_for_size_p ())
8991 if (expand_strn_compare (operands, 0))
8997 ;; String compare insn.
8998 ;; Argument 0 is the target (result)
8999 ;; Argument 1 is the destination
9000 ;; Argument 2 is the source
9001 ;; Argument 3 is the alignment
9003 (define_expand "cmpstrsi"
9004 [(parallel [(set (match_operand:SI 0)
9005 (compare:SI (match_operand:BLK 1)
9006 (match_operand:BLK 2)))
9007 (use (match_operand:SI 3))])]
9008 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9010 if (optimize_insn_for_size_p ())
9013 if (expand_strn_compare (operands, 1))
9019 ;; Block compare insn.
9020 ;; Argument 0 is the target (result)
9021 ;; Argument 1 is the destination
9022 ;; Argument 2 is the source
9023 ;; Argument 3 is the length
9024 ;; Argument 4 is the alignment
9026 (define_expand "cmpmemsi"
9027 [(parallel [(set (match_operand:SI 0)
9028 (compare:SI (match_operand:BLK 1)
9029 (match_operand:BLK 2)))
9030 (use (match_operand:SI 3))
9031 (use (match_operand:SI 4))])]
9034 if (expand_block_compare (operands))
9040 ;; String/block move insn.
9041 ;; Argument 0 is the destination
9042 ;; Argument 1 is the source
9043 ;; Argument 2 is the length
9044 ;; Argument 3 is the alignment
9046 (define_expand "movmemsi"
9047 [(parallel [(set (match_operand:BLK 0 "")
9048 (match_operand:BLK 1 ""))
9049 (use (match_operand:SI 2 ""))
9050 (use (match_operand:SI 3 ""))])]
9053 if (expand_block_move (operands))
9059 ;; Define insns that do load or store with update. Some of these we can
9060 ;; get by using pre-decrement or pre-increment, but the hardware can also
9061 ;; do cases where the increment is not the size of the object.
9063 ;; In all these cases, we use operands 0 and 1 for the register being
9064 ;; incremented because those are the operands that local-alloc will
9065 ;; tie and these are the pair most likely to be tieable (and the ones
9066 ;; that will benefit the most).
9068 (define_insn "*movdi_update1"
9069 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9070 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9071 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9072 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9073 (plus:DI (match_dup 1) (match_dup 2)))]
9074 "TARGET_POWERPC64 && TARGET_UPDATE
9075 && (!avoiding_indexed_address_p (DImode)
9076 || !gpc_reg_operand (operands[2], DImode))"
9080 [(set_attr "type" "load")
9081 (set_attr "update" "yes")
9082 (set_attr "indexed" "yes,no")])
9084 (define_insn "movdi_<mode>_update"
9085 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9086 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9087 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9088 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9089 (plus:P (match_dup 1) (match_dup 2)))]
9090 "TARGET_POWERPC64 && TARGET_UPDATE
9091 && (!avoiding_indexed_address_p (Pmode)
9092 || !gpc_reg_operand (operands[2], Pmode)
9093 || (REG_P (operands[0])
9094 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9098 [(set_attr "type" "store")
9099 (set_attr "update" "yes")
9100 (set_attr "indexed" "yes,no")])
9102 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9103 ;; needed for stack allocation, even if the user passes -mno-update.
9104 (define_insn "movdi_<mode>_update_stack"
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)))]
9114 [(set_attr "type" "store")
9115 (set_attr "update" "yes")
9116 (set_attr "indexed" "yes,no")])
9118 (define_insn "*movsi_update1"
9119 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9120 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9121 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9122 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9123 (plus:SI (match_dup 1) (match_dup 2)))]
9125 && (!avoiding_indexed_address_p (SImode)
9126 || !gpc_reg_operand (operands[2], SImode))"
9130 [(set_attr "type" "load")
9131 (set_attr "update" "yes")
9132 (set_attr "indexed" "yes,no")])
9134 (define_insn "*movsi_update2"
9135 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9137 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9138 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9139 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9140 (plus:DI (match_dup 1) (match_dup 2)))]
9141 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9143 [(set_attr "type" "load")
9144 (set_attr "sign_extend" "yes")
9145 (set_attr "update" "yes")
9146 (set_attr "indexed" "yes")])
9148 (define_insn "movsi_update"
9149 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9150 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9151 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9152 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9153 (plus:SI (match_dup 1) (match_dup 2)))]
9155 && (!avoiding_indexed_address_p (SImode)
9156 || !gpc_reg_operand (operands[2], SImode)
9157 || (REG_P (operands[0])
9158 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9162 [(set_attr "type" "store")
9163 (set_attr "update" "yes")
9164 (set_attr "indexed" "yes,no")])
9166 ;; This is an unconditional pattern; needed for stack allocation, even
9167 ;; if the user passes -mno-update.
9168 (define_insn "movsi_update_stack"
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)))]
9178 [(set_attr "type" "store")
9179 (set_attr "update" "yes")
9180 (set_attr "indexed" "yes,no")])
9182 (define_insn "*movhi_update1"
9183 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9184 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9185 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9186 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9187 (plus:SI (match_dup 1) (match_dup 2)))]
9189 && (!avoiding_indexed_address_p (SImode)
9190 || !gpc_reg_operand (operands[2], SImode))"
9194 [(set_attr "type" "load")
9195 (set_attr "update" "yes")
9196 (set_attr "indexed" "yes,no")])
9198 (define_insn "*movhi_update2"
9199 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9201 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9202 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9203 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9204 (plus:SI (match_dup 1) (match_dup 2)))]
9206 && (!avoiding_indexed_address_p (SImode)
9207 || !gpc_reg_operand (operands[2], SImode))"
9211 [(set_attr "type" "load")
9212 (set_attr "update" "yes")
9213 (set_attr "indexed" "yes,no")])
9215 (define_insn "*movhi_update3"
9216 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9218 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9219 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9220 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9221 (plus:SI (match_dup 1) (match_dup 2)))]
9223 && !(avoiding_indexed_address_p (SImode)
9224 && gpc_reg_operand (operands[2], SImode))"
9228 [(set_attr "type" "load")
9229 (set_attr "sign_extend" "yes")
9230 (set_attr "update" "yes")
9231 (set_attr "indexed" "yes,no")])
9233 (define_insn "*movhi_update4"
9234 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9235 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9236 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9237 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9238 (plus:SI (match_dup 1) (match_dup 2)))]
9240 && (!avoiding_indexed_address_p (SImode)
9241 || !gpc_reg_operand (operands[2], SImode))"
9245 [(set_attr "type" "store")
9246 (set_attr "update" "yes")
9247 (set_attr "indexed" "yes,no")])
9249 (define_insn "*movqi_update1"
9250 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9251 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9252 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9253 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9254 (plus:SI (match_dup 1) (match_dup 2)))]
9256 && (!avoiding_indexed_address_p (SImode)
9257 || !gpc_reg_operand (operands[2], SImode))"
9261 [(set_attr "type" "load")
9262 (set_attr "update" "yes")
9263 (set_attr "indexed" "yes,no")])
9265 (define_insn "*movqi_update2"
9266 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9268 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9269 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9270 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9271 (plus:SI (match_dup 1) (match_dup 2)))]
9273 && (!avoiding_indexed_address_p (SImode)
9274 || !gpc_reg_operand (operands[2], SImode))"
9278 [(set_attr "type" "load")
9279 (set_attr "update" "yes")
9280 (set_attr "indexed" "yes,no")])
9282 (define_insn "*movqi_update3"
9283 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9284 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9285 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9286 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9287 (plus:SI (match_dup 1) (match_dup 2)))]
9289 && (!avoiding_indexed_address_p (SImode)
9290 || !gpc_reg_operand (operands[2], SImode))"
9294 [(set_attr "type" "store")
9295 (set_attr "update" "yes")
9296 (set_attr "indexed" "yes,no")])
9298 (define_insn "*movsf_update1"
9299 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9300 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9301 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9302 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9303 (plus:SI (match_dup 1) (match_dup 2)))]
9304 "TARGET_HARD_FLOAT && TARGET_UPDATE
9305 && (!avoiding_indexed_address_p (SImode)
9306 || !gpc_reg_operand (operands[2], SImode))"
9310 [(set_attr "type" "fpload")
9311 (set_attr "update" "yes")
9312 (set_attr "indexed" "yes,no")])
9314 (define_insn "*movsf_update2"
9315 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9316 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9317 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9318 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9319 (plus:SI (match_dup 1) (match_dup 2)))]
9320 "TARGET_HARD_FLOAT && TARGET_UPDATE
9321 && (!avoiding_indexed_address_p (SImode)
9322 || !gpc_reg_operand (operands[2], SImode))"
9326 [(set_attr "type" "fpstore")
9327 (set_attr "update" "yes")
9328 (set_attr "indexed" "yes,no")])
9330 (define_insn "*movsf_update3"
9331 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9332 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9333 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9334 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9335 (plus:SI (match_dup 1) (match_dup 2)))]
9336 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9337 && (!avoiding_indexed_address_p (SImode)
9338 || !gpc_reg_operand (operands[2], SImode))"
9342 [(set_attr "type" "load")
9343 (set_attr "update" "yes")
9344 (set_attr "indexed" "yes,no")])
9346 (define_insn "*movsf_update4"
9347 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9348 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9349 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9350 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9351 (plus:SI (match_dup 1) (match_dup 2)))]
9352 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9353 && (!avoiding_indexed_address_p (SImode)
9354 || !gpc_reg_operand (operands[2], SImode))"
9358 [(set_attr "type" "store")
9359 (set_attr "update" "yes")
9360 (set_attr "indexed" "yes,no")])
9362 (define_insn "*movdf_update1"
9363 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9364 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9365 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9366 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9367 (plus:SI (match_dup 1) (match_dup 2)))]
9368 "TARGET_HARD_FLOAT && TARGET_UPDATE
9369 && (!avoiding_indexed_address_p (SImode)
9370 || !gpc_reg_operand (operands[2], SImode))"
9374 [(set_attr "type" "fpload")
9375 (set_attr "update" "yes")
9376 (set_attr "indexed" "yes,no")
9377 (set_attr "size" "64")])
9379 (define_insn "*movdf_update2"
9380 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9381 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9382 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9383 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9384 (plus:SI (match_dup 1) (match_dup 2)))]
9385 "TARGET_HARD_FLOAT && TARGET_UPDATE
9386 && (!avoiding_indexed_address_p (SImode)
9387 || !gpc_reg_operand (operands[2], SImode))"
9391 [(set_attr "type" "fpstore")
9392 (set_attr "update" "yes")
9393 (set_attr "indexed" "yes,no")])
9396 ;; After inserting conditional returns we can sometimes have
9397 ;; unnecessary register moves. Unfortunately we cannot have a
9398 ;; modeless peephole here, because some single SImode sets have early
9399 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9400 ;; sequences, using get_attr_length here will smash the operands
9401 ;; array. Neither is there an early_cobbler_p predicate.
9402 ;; Also this optimization interferes with scalars going into
9403 ;; altivec registers (the code does reloading through the FPRs).
9405 [(set (match_operand:DF 0 "gpc_reg_operand")
9406 (match_operand:DF 1 "any_operand"))
9407 (set (match_operand:DF 2 "gpc_reg_operand")
9410 && peep2_reg_dead_p (2, operands[0])"
9411 [(set (match_dup 2) (match_dup 1))])
9414 [(set (match_operand:SF 0 "gpc_reg_operand")
9415 (match_operand:SF 1 "any_operand"))
9416 (set (match_operand:SF 2 "gpc_reg_operand")
9419 && peep2_reg_dead_p (2, operands[0])"
9420 [(set (match_dup 2) (match_dup 1))])
9425 ;; Mode attributes for different ABIs.
9426 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9427 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9428 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9429 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9431 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9432 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9433 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9434 (match_operand 4 "" "g")))
9435 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9436 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9438 (clobber (reg:SI LR_REGNO))]
9439 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9441 if (TARGET_CMODEL != CMODEL_SMALL)
9442 output_asm_insn ("addis %0,%1,%2@got@tlsgd@ha\;"
9443 "addi %0,%0,%2@got@tlsgd@l", operands);
9445 output_asm_insn ("addi %0,%1,%2@got@tlsgd", operands);
9446 return rs6000_call_template (operands, 3, "");
9448 "&& TARGET_TLS_MARKERS"
9450 (unspec:TLSmode [(match_dup 1)
9453 (parallel [(set (match_dup 0)
9454 (call (mem:TLSmode (match_dup 3))
9456 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9457 (clobber (reg:SI LR_REGNO))])]
9459 [(set_attr "type" "two")
9460 (set (attr "length")
9461 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9465 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9466 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9467 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9468 (match_operand 4 "" "g")))
9469 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9470 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9472 (clobber (reg:SI LR_REGNO))]
9473 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9475 output_asm_insn ("addi %0,%1,%2@got@tlsgd", operands);
9476 return rs6000_call_template (operands, 3, "");
9478 "&& TARGET_TLS_MARKERS"
9480 (unspec:TLSmode [(match_dup 1)
9483 (parallel [(set (match_dup 0)
9484 (call (mem:TLSmode (match_dup 3))
9486 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9487 (clobber (reg:SI LR_REGNO))])]
9489 [(set_attr "type" "two")
9490 (set_attr "length" "8")])
9492 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9493 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9494 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9495 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9497 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9498 "addi %0,%1,%2@got@tlsgd"
9499 "&& TARGET_CMODEL != CMODEL_SMALL"
9502 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9504 (lo_sum:TLSmode (match_dup 3)
9505 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9507 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9509 [(set (attr "length")
9510 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9514 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9515 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9517 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9518 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9520 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9521 "addis %0,%1,%2@got@tlsgd@ha")
9523 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9524 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9525 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9526 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9527 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9529 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9530 "addi %0,%1,%2@got@tlsgd@l")
9532 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9533 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9534 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9535 (match_operand 2 "" "g")))
9536 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9538 (clobber (reg:SI LR_REGNO))]
9539 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9540 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9542 return rs6000_call_template (operands, 1, "(%3@tlsgd)");
9544 [(set_attr "type" "branch")
9545 (set_attr "length" "8")])
9547 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9548 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9549 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9550 (match_operand 2 "" "g")))
9551 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9553 (clobber (reg:SI LR_REGNO))]
9554 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9556 return rs6000_call_template (operands, 1, "(%3@tlsgd)");
9558 [(set_attr "type" "branch")])
9560 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9561 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9562 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9563 (match_operand 3 "" "g")))
9564 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9566 (clobber (reg:SI LR_REGNO))]
9567 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9569 if (TARGET_CMODEL != CMODEL_SMALL)
9570 output_asm_insn ("addis %0,%1,%&@got@tlsld@ha\;"
9571 "addi %0,%0,%&@got@tlsld@l", operands);
9573 output_asm_insn ("addi %0,%1,%&@got@tlsld", operands);
9574 return rs6000_call_template (operands, 2, "");
9576 "&& TARGET_TLS_MARKERS"
9578 (unspec:TLSmode [(match_dup 1)]
9580 (parallel [(set (match_dup 0)
9581 (call (mem:TLSmode (match_dup 2))
9583 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9584 (clobber (reg:SI LR_REGNO))])]
9586 [(set_attr "type" "two")
9587 (set (attr "length")
9588 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9592 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9593 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9594 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9595 (match_operand 3 "" "g")))
9596 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9598 (clobber (reg:SI LR_REGNO))]
9599 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9601 output_asm_insn ("addi %0,%1,%&@got@tlsld", operands);
9602 return rs6000_call_template (operands, 2, "");
9604 "&& TARGET_TLS_MARKERS"
9606 (unspec:TLSmode [(match_dup 1)]
9608 (parallel [(set (match_dup 0)
9609 (call (mem:TLSmode (match_dup 2))
9611 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9612 (clobber (reg:SI LR_REGNO))])]
9614 [(set_attr "length" "8")])
9616 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9617 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9618 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9620 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9621 "addi %0,%1,%&@got@tlsld"
9622 "&& TARGET_CMODEL != CMODEL_SMALL"
9625 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9627 (lo_sum:TLSmode (match_dup 2)
9628 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9630 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9632 [(set (attr "length")
9633 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9637 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9638 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9640 (unspec:TLSmode [(const_int 0)
9641 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9643 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9644 "addis %0,%1,%&@got@tlsld@ha")
9646 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9647 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9648 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9649 (unspec:TLSmode [(const_int 0)
9650 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9652 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9653 "addi %0,%1,%&@got@tlsld@l")
9655 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9656 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9657 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9658 (match_operand 2 "" "g")))
9659 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9660 (clobber (reg:SI LR_REGNO))]
9661 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9662 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9664 return rs6000_call_template (operands, 1, "(%&@tlsld)");
9666 [(set_attr "type" "branch")
9667 (set_attr "length" "8")])
9669 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9670 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9671 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9672 (match_operand 2 "" "g")))
9673 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9674 (clobber (reg:SI LR_REGNO))]
9675 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9677 return rs6000_call_template (operands, 1, "(%&@tlsld)");
9679 [(set_attr "type" "branch")])
9681 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9682 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9683 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9684 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9687 "addi %0,%1,%2@dtprel")
9689 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9690 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9691 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9692 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9693 UNSPEC_TLSDTPRELHA))]
9695 "addis %0,%1,%2@dtprel@ha")
9697 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9698 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9699 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9700 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9701 UNSPEC_TLSDTPRELLO))]
9703 "addi %0,%1,%2@dtprel@l")
9705 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9706 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9707 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9708 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9709 UNSPEC_TLSGOTDTPREL))]
9711 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9712 "&& TARGET_CMODEL != CMODEL_SMALL"
9715 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9717 (lo_sum:TLSmode (match_dup 3)
9718 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9720 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9722 [(set (attr "length")
9723 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9727 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9728 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9730 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9731 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9732 UNSPEC_TLSGOTDTPREL)))]
9733 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9734 "addis %0,%1,%2@got@dtprel@ha")
9736 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9737 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9738 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9739 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9740 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9741 UNSPEC_TLSGOTDTPREL)))]
9742 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9743 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)")
9745 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9746 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9747 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9748 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9751 "addi %0,%1,%2@tprel")
9753 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9754 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9755 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9756 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9757 UNSPEC_TLSTPRELHA))]
9759 "addis %0,%1,%2@tprel@ha")
9761 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9762 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9763 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9764 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9765 UNSPEC_TLSTPRELLO))]
9767 "addi %0,%1,%2@tprel@l")
9769 ;; "b" output constraint here and on tls_tls input to support linker tls
9770 ;; optimization. The linker may edit the instructions emitted by a
9771 ;; tls_got_tprel/tls_tls pair to addis,addi.
9772 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9773 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9774 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9775 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9776 UNSPEC_TLSGOTTPREL))]
9778 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9779 "&& TARGET_CMODEL != CMODEL_SMALL"
9782 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9784 (lo_sum:TLSmode (match_dup 3)
9785 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9787 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9789 [(set (attr "length")
9790 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9794 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9795 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9797 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9798 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9799 UNSPEC_TLSGOTTPREL)))]
9800 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9801 "addis %0,%1,%2@got@tprel@ha")
9803 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9804 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9805 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9806 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9807 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9808 UNSPEC_TLSGOTTPREL)))]
9809 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9810 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)")
9812 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9813 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9814 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9815 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9817 "TARGET_ELF && HAVE_AS_TLS"
9820 (define_expand "tls_get_tpointer"
9821 [(set (match_operand:SI 0 "gpc_reg_operand")
9822 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9823 "TARGET_XCOFF && HAVE_AS_TLS"
9825 emit_insn (gen_tls_get_tpointer_internal ());
9826 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9830 (define_insn "tls_get_tpointer_internal"
9832 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9833 (clobber (reg:SI LR_REGNO))]
9834 "TARGET_XCOFF && HAVE_AS_TLS"
9835 "bla __get_tpointer")
9837 (define_expand "tls_get_addr<mode>"
9838 [(set (match_operand:P 0 "gpc_reg_operand")
9839 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9840 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9841 "TARGET_XCOFF && HAVE_AS_TLS"
9843 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9844 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9845 emit_insn (gen_tls_get_addr_internal<mode> ());
9846 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9850 (define_insn "tls_get_addr_internal<mode>"
9852 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9856 (clobber (reg:P 11))
9857 (clobber (reg:CC CR0_REGNO))
9858 (clobber (reg:P LR_REGNO))]
9859 "TARGET_XCOFF && HAVE_AS_TLS"
9860 "bla __tls_get_addr")
9862 ;; Next come insns related to the calling sequence.
9864 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9865 ;; We move the back-chain and decrement the stack pointer.
9867 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9868 ;; constant alloca, using that predicate will force the generic code to put
9869 ;; the constant size into a register before calling the expander.
9871 ;; As a result the expander would not have the constant size information
9872 ;; in those cases and would have to generate less efficient code.
9874 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9875 ;; the constant size. The value is forced into a register if necessary.
9877 (define_expand "allocate_stack"
9878 [(set (match_operand 0 "gpc_reg_operand")
9879 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9881 (minus (reg 1) (match_dup 1)))]
9884 rtx chain = gen_reg_rtx (Pmode);
9885 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9887 rtx insn, par, set, mem;
9889 /* By allowing reg_or_cint_operand as the predicate we can get
9890 better code for stack-clash-protection because we do not lose
9891 size information. But the rest of the code expects the operand
9892 to be reg_or_short_operand. If it isn't, then force it into
9894 rtx orig_op1 = operands[1];
9895 if (!reg_or_short_operand (operands[1], Pmode))
9896 operands[1] = force_reg (Pmode, operands[1]);
9898 emit_move_insn (chain, stack_bot);
9900 /* Check stack bounds if necessary. */
9901 if (crtl->limit_stack)
9904 available = expand_binop (Pmode, sub_optab,
9905 stack_pointer_rtx, stack_limit_rtx,
9906 NULL_RTX, 1, OPTAB_WIDEN);
9907 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9910 /* Allocate and probe if requested.
9911 This may look similar to the loop we use for prologue allocations,
9912 but it is critically different. For the former we know the loop
9913 will iterate, but do not know that generally here. The former
9914 uses that knowledge to rotate the loop. Combining them would be
9915 possible with some performance cost. */
9916 if (flag_stack_clash_protection)
9918 rtx rounded_size, last_addr, residual;
9919 HOST_WIDE_INT probe_interval;
9920 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9921 &residual, &probe_interval,
9924 /* We do occasionally get in here with constant sizes, we might
9925 as well do a reasonable job when we obviously can. */
9926 if (rounded_size != const0_rtx)
9928 rtx loop_lab, end_loop;
9929 bool rotated = CONST_INT_P (rounded_size);
9930 rtx update = GEN_INT (-probe_interval);
9931 if (probe_interval > 32768)
9932 update = force_reg (Pmode, update);
9934 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9935 last_addr, rotated);
9937 if (Pmode == SImode)
9938 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9942 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9945 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9946 last_addr, rotated);
9949 /* Now handle residuals. We just have to set operands[1] correctly
9950 and let the rest of the expander run. */
9951 operands[1] = residual;
9954 if (!(CONST_INT_P (operands[1])
9955 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9957 operands[1] = force_reg (Pmode, operands[1]);
9958 neg_op0 = gen_reg_rtx (Pmode);
9960 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9962 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9965 neg_op0 = GEN_INT (-INTVAL (operands[1]));
9967 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9968 : gen_movdi_di_update_stack))
9969 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9971 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9972 it now and set the alias set/attributes. The above gen_*_update
9973 calls will generate a PARALLEL with the MEM set being the first
9975 par = PATTERN (insn);
9976 gcc_assert (GET_CODE (par) == PARALLEL);
9977 set = XVECEXP (par, 0, 0);
9978 gcc_assert (GET_CODE (set) == SET);
9979 mem = SET_DEST (set);
9980 gcc_assert (MEM_P (mem));
9981 MEM_NOTRAP_P (mem) = 1;
9982 set_mem_alias_set (mem, get_frame_alias_set ());
9984 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9988 ;; These patterns say how to save and restore the stack pointer. We need not
9989 ;; save the stack pointer at function level since we are careful to
9990 ;; preserve the backchain. At block level, we have to restore the backchain
9991 ;; when we restore the stack pointer.
9993 ;; For nonlocal gotos, we must save both the stack pointer and its
9994 ;; backchain and restore both. Note that in the nonlocal case, the
9995 ;; save area is a memory location.
9997 (define_expand "save_stack_function"
9998 [(match_operand 0 "any_operand")
9999 (match_operand 1 "any_operand")]
10003 (define_expand "restore_stack_function"
10004 [(match_operand 0 "any_operand")
10005 (match_operand 1 "any_operand")]
10009 ;; Adjust stack pointer (op0) to a new value (op1).
10010 ;; First copy old stack backchain to new location, and ensure that the
10011 ;; scheduler won't reorder the sp assignment before the backchain write.
10012 (define_expand "restore_stack_block"
10013 [(set (match_dup 2) (match_dup 3))
10014 (set (match_dup 4) (match_dup 2))
10016 (set (match_operand 0 "register_operand")
10017 (match_operand 1 "register_operand"))]
10022 operands[1] = force_reg (Pmode, operands[1]);
10023 operands[2] = gen_reg_rtx (Pmode);
10024 operands[3] = gen_frame_mem (Pmode, operands[0]);
10025 operands[4] = gen_frame_mem (Pmode, operands[1]);
10026 p = rtvec_alloc (1);
10027 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10029 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10032 (define_expand "save_stack_nonlocal"
10033 [(set (match_dup 3) (match_dup 4))
10034 (set (match_operand 0 "memory_operand") (match_dup 3))
10035 (set (match_dup 2) (match_operand 1 "register_operand"))]
10038 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10040 /* Copy the backchain to the first word, sp to the second. */
10041 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10042 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10043 operands[3] = gen_reg_rtx (Pmode);
10044 operands[4] = gen_frame_mem (Pmode, operands[1]);
10047 (define_expand "restore_stack_nonlocal"
10048 [(set (match_dup 2) (match_operand 1 "memory_operand"))
10049 (set (match_dup 3) (match_dup 4))
10050 (set (match_dup 5) (match_dup 2))
10052 (set (match_operand 0 "register_operand") (match_dup 3))]
10055 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10058 /* Restore the backchain from the first word, sp from the second. */
10059 operands[2] = gen_reg_rtx (Pmode);
10060 operands[3] = gen_reg_rtx (Pmode);
10061 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10062 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10063 operands[5] = gen_frame_mem (Pmode, operands[3]);
10064 p = rtvec_alloc (1);
10065 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10067 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10070 ;; TOC register handling.
10072 ;; Code to initialize the TOC register...
10074 (define_insn "load_toc_aix_si"
10075 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10076 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10077 (use (reg:SI 2))])]
10078 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10081 extern int need_toc_init;
10083 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10084 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10085 operands[2] = gen_rtx_REG (Pmode, 2);
10086 return "lwz %0,%1(%2)";
10088 [(set_attr "type" "load")
10089 (set_attr "update" "no")
10090 (set_attr "indexed" "no")])
10092 (define_insn "load_toc_aix_di"
10093 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10094 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10095 (use (reg:DI 2))])]
10096 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10099 extern int need_toc_init;
10101 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10102 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10104 strcat (buf, "@toc");
10105 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10106 operands[2] = gen_rtx_REG (Pmode, 2);
10107 return "ld %0,%1(%2)";
10109 [(set_attr "type" "load")
10110 (set_attr "update" "no")
10111 (set_attr "indexed" "no")])
10113 (define_insn "load_toc_v4_pic_si"
10114 [(set (reg:SI LR_REGNO)
10115 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10116 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10117 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10118 [(set_attr "type" "branch")])
10120 (define_expand "load_toc_v4_PIC_1"
10121 [(parallel [(set (reg:SI LR_REGNO)
10122 (match_operand:SI 0 "immediate_operand" "s"))
10123 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10124 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10125 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10128 (define_insn "load_toc_v4_PIC_1_normal"
10129 [(set (reg:SI LR_REGNO)
10130 (match_operand:SI 0 "immediate_operand" "s"))
10131 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10132 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10133 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10134 "bcl 20,31,%0\n%0:"
10135 [(set_attr "type" "branch")
10136 (set_attr "cannot_copy" "yes")])
10138 (define_insn "load_toc_v4_PIC_1_476"
10139 [(set (reg:SI LR_REGNO)
10140 (match_operand:SI 0 "immediate_operand" "s"))
10141 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10142 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10143 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10146 static char templ[32];
10148 get_ppc476_thunk_name (name);
10149 sprintf (templ, "bl %s\n%%0:", name);
10152 [(set_attr "type" "branch")
10153 (set_attr "cannot_copy" "yes")])
10155 (define_expand "load_toc_v4_PIC_1b"
10156 [(parallel [(set (reg:SI LR_REGNO)
10157 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10158 (label_ref (match_operand 1 ""))]
10161 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10164 (define_insn "load_toc_v4_PIC_1b_normal"
10165 [(set (reg:SI LR_REGNO)
10166 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10167 (label_ref (match_operand 1 "" ""))]
10170 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10171 "bcl 20,31,$+8\;.long %0-$"
10172 [(set_attr "type" "branch")
10173 (set_attr "length" "8")])
10175 (define_insn "load_toc_v4_PIC_1b_476"
10176 [(set (reg:SI LR_REGNO)
10177 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10178 (label_ref (match_operand 1 "" ""))]
10181 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10184 static char templ[32];
10186 get_ppc476_thunk_name (name);
10187 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10190 [(set_attr "type" "branch")
10191 (set_attr "length" "16")])
10193 (define_insn "load_toc_v4_PIC_2"
10194 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10196 (match_operand:SI 1 "gpc_reg_operand" "b")
10198 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10199 (match_operand:SI 3 "immediate_operand" "s"))))))]
10200 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10202 [(set_attr "type" "load")])
10204 (define_insn "load_toc_v4_PIC_3b"
10205 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10207 (match_operand:SI 1 "gpc_reg_operand" "b")
10210 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10211 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10212 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10213 "addis %0,%1,%2-%3@ha")
10215 (define_insn "load_toc_v4_PIC_3c"
10216 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10218 (match_operand:SI 1 "gpc_reg_operand" "b")
10220 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10221 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10222 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10223 "addi %0,%1,%2-%3@l")
10225 ;; If the TOC is shared over a translation unit, as happens with all
10226 ;; the kinds of PIC that we support, we need to restore the TOC
10227 ;; pointer only when jumping over units of translation.
10228 ;; On Darwin, we need to reload the picbase.
10230 (define_expand "builtin_setjmp_receiver"
10231 [(use (label_ref (match_operand 0 "")))]
10232 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10233 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10234 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10237 if (DEFAULT_ABI == ABI_DARWIN)
10239 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10240 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10244 crtl->uses_pic_offset_table = 1;
10245 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10246 CODE_LABEL_NUMBER (operands[0]));
10247 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10249 emit_insn (gen_load_macho_picbase (tmplabrtx));
10250 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10251 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10255 rs6000_emit_load_toc_table (FALSE);
10259 ;; Largetoc support
10260 (define_insn "*largetoc_high"
10261 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10263 (unspec [(match_operand:DI 1 "" "")
10264 (match_operand:DI 2 "gpc_reg_operand" "b")]
10266 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10267 "addis %0,%2,%1@toc@ha")
10269 (define_insn "*largetoc_high_aix<mode>"
10270 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10272 (unspec [(match_operand:P 1 "" "")
10273 (match_operand:P 2 "gpc_reg_operand" "b")]
10275 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10276 "addis %0,%1@u(%2)")
10278 (define_insn "*largetoc_high_plus"
10279 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10282 (unspec [(match_operand:DI 1 "" "")
10283 (match_operand:DI 2 "gpc_reg_operand" "b")]
10285 (match_operand:DI 3 "add_cint_operand" "n"))))]
10286 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10287 "addis %0,%2,%1+%3@toc@ha")
10289 (define_insn "*largetoc_high_plus_aix<mode>"
10290 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10293 (unspec [(match_operand:P 1 "" "")
10294 (match_operand:P 2 "gpc_reg_operand" "b")]
10296 (match_operand:P 3 "add_cint_operand" "n"))))]
10297 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10298 "addis %0,%1+%3@u(%2)")
10300 (define_insn "*largetoc_low"
10301 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10302 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10303 (match_operand:DI 2 "" "")))]
10304 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10307 (define_insn "*largetoc_low_aix<mode>"
10308 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10309 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10310 (match_operand:P 2 "" "")))]
10311 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10314 (define_insn_and_split "*tocref<mode>"
10315 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10316 (match_operand:P 1 "small_toc_ref" "R"))]
10319 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10320 [(set (match_dup 0) (high:P (match_dup 1)))
10321 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10323 ;; Elf specific ways of loading addresses for non-PIC code.
10324 ;; The output of this could be r0, but we make a very strong
10325 ;; preference for a base register because it will usually
10326 ;; be needed there.
10327 (define_insn "elf_high"
10328 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10329 (high:SI (match_operand 1 "" "")))]
10330 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10333 (define_insn "elf_low"
10334 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10335 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10336 (match_operand 2 "" "")))]
10337 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10340 ;; Call and call_value insns
10341 (define_expand "call"
10342 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10343 (match_operand 1 ""))
10344 (use (match_operand 2 ""))
10345 (clobber (reg:SI LR_REGNO))])]
10349 if (MACHOPIC_INDIRECT)
10350 operands[0] = machopic_indirect_call_target (operands[0]);
10353 gcc_assert (GET_CODE (operands[0]) == MEM);
10354 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10356 operands[0] = XEXP (operands[0], 0);
10358 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10360 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10364 if (GET_CODE (operands[0]) != SYMBOL_REF
10365 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10367 if (INTVAL (operands[2]) & CALL_LONG)
10368 operands[0] = rs6000_longcall_ref (operands[0]);
10370 switch (DEFAULT_ABI)
10374 operands[0] = force_reg (Pmode, operands[0]);
10378 gcc_unreachable ();
10383 (define_expand "call_value"
10384 [(parallel [(set (match_operand 0 "")
10385 (call (mem:SI (match_operand 1 "address_operand"))
10386 (match_operand 2 "")))
10387 (use (match_operand 3 ""))
10388 (clobber (reg:SI LR_REGNO))])]
10392 if (MACHOPIC_INDIRECT)
10393 operands[1] = machopic_indirect_call_target (operands[1]);
10396 gcc_assert (GET_CODE (operands[1]) == MEM);
10397 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10399 operands[1] = XEXP (operands[1], 0);
10401 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10403 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10407 if (GET_CODE (operands[1]) != SYMBOL_REF
10408 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10410 if (INTVAL (operands[3]) & CALL_LONG)
10411 operands[1] = rs6000_longcall_ref (operands[1]);
10413 switch (DEFAULT_ABI)
10417 operands[1] = force_reg (Pmode, operands[1]);
10421 gcc_unreachable ();
10426 ;; Call to function in current module. No TOC pointer reload needed.
10427 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10428 ;; either the function was not prototyped, or it was prototyped as a
10429 ;; variable argument function. It is > 0 if FP registers were passed
10430 ;; and < 0 if they were not.
10432 (define_insn "*call_local32"
10433 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10434 (match_operand 1 "" "g,g"))
10435 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10436 (clobber (reg:SI LR_REGNO))]
10437 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10439 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10440 output_asm_insn ("crxor 6,6,6", operands);
10442 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10443 output_asm_insn ("creqv 6,6,6", operands);
10445 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10447 [(set_attr "type" "branch")
10448 (set_attr "length" "4,8")])
10450 (define_insn "*call_local64"
10451 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10452 (match_operand 1 "" "g,g"))
10453 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10454 (clobber (reg:SI LR_REGNO))]
10455 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10457 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10458 output_asm_insn ("crxor 6,6,6", operands);
10460 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10461 output_asm_insn ("creqv 6,6,6", operands);
10463 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10465 [(set_attr "type" "branch")
10466 (set_attr "length" "4,8")])
10468 (define_insn "*call_value_local32"
10469 [(set (match_operand 0 "" "")
10470 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10471 (match_operand 2 "" "g,g")))
10472 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10473 (clobber (reg:SI LR_REGNO))]
10474 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10476 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10477 output_asm_insn ("crxor 6,6,6", operands);
10479 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10480 output_asm_insn ("creqv 6,6,6", operands);
10482 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10484 [(set_attr "type" "branch")
10485 (set_attr "length" "4,8")])
10488 (define_insn "*call_value_local64"
10489 [(set (match_operand 0 "" "")
10490 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10491 (match_operand 2 "" "g,g")))
10492 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10493 (clobber (reg:SI LR_REGNO))]
10494 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10496 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10497 output_asm_insn ("crxor 6,6,6", operands);
10499 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10500 output_asm_insn ("creqv 6,6,6", operands);
10502 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10504 [(set_attr "type" "branch")
10505 (set_attr "length" "4,8")])
10508 ;; A function pointer under System V is just a normal pointer
10509 ;; operands[0] is the function pointer
10510 ;; operands[1] is the stack size to clean up
10511 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10512 ;; which indicates how to set cr1
10514 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10515 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10516 (match_operand 1 "" "g,g,g,g"))
10517 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10518 (clobber (reg:SI LR_REGNO))]
10519 "DEFAULT_ABI == ABI_V4
10520 || DEFAULT_ABI == ABI_DARWIN"
10522 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10523 output_asm_insn ("crxor 6,6,6", operands);
10525 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10526 output_asm_insn ("creqv 6,6,6", operands);
10528 if (rs6000_speculate_indirect_jumps
10529 || which_alternative == 1 || which_alternative == 3)
10532 return "crset 2\;beq%T0l-";
10534 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10535 (set_attr_alternative "length"
10536 [(if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10539 (const_string "4"))
10541 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10543 (const_string "12")
10544 (const_string "8"))
10545 (const_string "8")])])
10547 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10548 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10549 (match_operand 1 "" "g,g"))
10550 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10551 (clobber (reg:SI LR_REGNO))]
10552 "(DEFAULT_ABI == ABI_DARWIN
10553 || (DEFAULT_ABI == ABI_V4
10554 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10556 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10557 output_asm_insn ("crxor 6,6,6", operands);
10559 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10560 output_asm_insn ("creqv 6,6,6", operands);
10563 return macho_call_template (insn, operands, 0, 2);
10565 return rs6000_call_template (operands, 0, "");
10568 "DEFAULT_ABI == ABI_V4
10569 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10570 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10571 [(parallel [(call (mem:SI (match_dup 0))
10573 (use (match_dup 2))
10574 (use (match_dup 3))
10575 (clobber (reg:SI LR_REGNO))])]
10577 operands[3] = pic_offset_table_rtx;
10579 [(set_attr "type" "branch,branch")
10580 (set_attr "length" "4,8")])
10582 (define_insn "*call_nonlocal_sysv_secure<mode>"
10583 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10584 (match_operand 1 "" "g,g"))
10585 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10586 (use (match_operand:SI 3 "register_operand" "r,r"))
10587 (clobber (reg:SI LR_REGNO))]
10588 "(DEFAULT_ABI == ABI_V4
10589 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10590 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10592 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10593 output_asm_insn ("crxor 6,6,6", operands);
10595 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10596 output_asm_insn ("creqv 6,6,6", operands);
10598 return rs6000_call_template (operands, 0, "");
10600 [(set_attr "type" "branch,branch")
10601 (set_attr "length" "4,8")])
10603 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10604 [(set (match_operand 0 "" "")
10605 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10606 (match_operand 2 "" "g,g,g,g")))
10607 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10608 (clobber (reg:SI LR_REGNO))]
10609 "DEFAULT_ABI == ABI_V4
10610 || DEFAULT_ABI == ABI_DARWIN"
10612 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10613 output_asm_insn ("crxor 6,6,6", operands);
10615 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10616 output_asm_insn ("creqv 6,6,6", operands);
10618 if (rs6000_speculate_indirect_jumps
10619 || which_alternative == 1 || which_alternative == 3)
10622 return "crset 2\;beq%T1l-";
10624 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10625 (set_attr_alternative "length"
10626 [(if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10629 (const_string "4"))
10631 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10633 (const_string "12")
10634 (const_string "8"))
10635 (const_string "8")])])
10637 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10638 [(set (match_operand 0 "" "")
10639 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10640 (match_operand 2 "" "g,g")))
10641 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10642 (clobber (reg:SI LR_REGNO))]
10643 "(DEFAULT_ABI == ABI_DARWIN
10644 || (DEFAULT_ABI == ABI_V4
10645 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10647 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10648 output_asm_insn ("crxor 6,6,6", operands);
10650 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10651 output_asm_insn ("creqv 6,6,6", operands);
10654 return macho_call_template (insn, operands, 1, 3);
10656 return rs6000_call_template (operands, 1, "");
10659 "DEFAULT_ABI == ABI_V4
10660 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10661 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10662 [(parallel [(set (match_dup 0)
10663 (call (mem:SI (match_dup 1))
10665 (use (match_dup 3))
10666 (use (match_dup 4))
10667 (clobber (reg:SI LR_REGNO))])]
10669 operands[4] = pic_offset_table_rtx;
10671 [(set_attr "type" "branch,branch")
10672 (set_attr "length" "4,8")])
10674 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10675 [(set (match_operand 0 "" "")
10676 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10677 (match_operand 2 "" "g,g")))
10678 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10679 (use (match_operand:SI 4 "register_operand" "r,r"))
10680 (clobber (reg:SI LR_REGNO))]
10681 "(DEFAULT_ABI == ABI_V4
10682 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10683 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10685 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10686 output_asm_insn ("crxor 6,6,6", operands);
10688 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10689 output_asm_insn ("creqv 6,6,6", operands);
10691 return rs6000_call_template (operands, 1, "");
10693 [(set_attr "type" "branch,branch")
10694 (set_attr "length" "4,8")])
10697 ;; Call to AIX abi function in the same module.
10699 (define_insn "*call_local_aix<mode>"
10700 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10701 (match_operand 1 "" "g"))
10702 (clobber (reg:P LR_REGNO))]
10703 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10705 [(set_attr "type" "branch")])
10707 (define_insn "*call_value_local_aix<mode>"
10708 [(set (match_operand 0 "" "")
10709 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10710 (match_operand 2 "" "g")))
10711 (clobber (reg:P LR_REGNO))]
10712 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10714 [(set_attr "type" "branch")])
10716 ;; Call to AIX abi function which may be in another module.
10717 ;; Restore the TOC pointer (r2) after the call.
10719 (define_insn "*call_nonlocal_aix<mode>"
10720 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10721 (match_operand 1 "" "g"))
10722 (clobber (reg:P LR_REGNO))]
10723 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10725 return rs6000_call_template (operands, 0, "");
10727 [(set_attr "type" "branch")
10728 (set_attr "length" "8")])
10730 (define_insn "*call_value_nonlocal_aix<mode>"
10731 [(set (match_operand 0 "" "")
10732 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10733 (match_operand 2 "" "g")))
10734 (clobber (reg:P LR_REGNO))]
10735 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10737 return rs6000_call_template (operands, 1, "");
10739 [(set_attr "type" "branch")
10740 (set_attr "length" "8")])
10742 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10743 ;; Operand0 is the addresss of the function to call
10744 ;; Operand2 is the location in the function descriptor to load r2 from
10745 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10747 (define_insn "*call_indirect_aix<mode>"
10748 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10749 (match_operand 1 "" "g,g"))
10750 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10751 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10752 (clobber (reg:P LR_REGNO))]
10753 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10754 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10755 [(set_attr "type" "jmpreg")
10756 (set_attr "length" "12")])
10758 (define_insn "*call_indirect_aix<mode>_nospec"
10759 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10760 (match_operand 1 "" "g,g"))
10761 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10762 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10763 (clobber (reg:P LR_REGNO))]
10764 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10765 "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10766 [(set_attr "type" "jmpreg")
10767 (set_attr "length" "16")])
10769 (define_insn "*call_value_indirect_aix<mode>"
10770 [(set (match_operand 0 "" "")
10771 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10772 (match_operand 2 "" "g,g")))
10773 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10774 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10775 (clobber (reg:P LR_REGNO))]
10776 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10777 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10778 [(set_attr "type" "jmpreg")
10779 (set_attr "length" "12")])
10781 (define_insn "*call_value_indirect_aix<mode>_nospec"
10782 [(set (match_operand 0 "" "")
10783 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10784 (match_operand 2 "" "g,g")))
10785 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10786 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10787 (clobber (reg:P LR_REGNO))]
10788 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10789 "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10790 [(set_attr "type" "jmpreg")
10791 (set_attr "length" "16")])
10793 ;; Call to indirect functions with the ELFv2 ABI.
10794 ;; Operand0 is the addresss of the function to call
10795 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10797 (define_insn "*call_indirect_elfv2<mode>"
10798 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10799 (match_operand 1 "" "g,g"))
10800 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10801 (clobber (reg:P LR_REGNO))]
10802 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10803 "b%T0l\;<ptrload> 2,%2(1)"
10804 [(set_attr "type" "jmpreg")
10805 (set_attr "length" "8")])
10807 ;; Variant with deliberate misprediction.
10808 (define_insn "*call_indirect_elfv2<mode>_nospec"
10809 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10810 (match_operand 1 "" "g,g"))
10811 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10812 (clobber (reg:P LR_REGNO))]
10813 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10814 "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10815 [(set_attr "type" "jmpreg")
10816 (set_attr "length" "12")])
10818 (define_insn "*call_value_indirect_elfv2<mode>"
10819 [(set (match_operand 0 "" "")
10820 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10821 (match_operand 2 "" "g,g")))
10822 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10823 (clobber (reg:P LR_REGNO))]
10824 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10825 "b%T1l\;<ptrload> 2,%3(1)"
10826 [(set_attr "type" "jmpreg")
10827 (set_attr "length" "8")])
10829 ; Variant with deliberate misprediction.
10830 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10831 [(set (match_operand 0 "" "")
10832 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10833 (match_operand 2 "" "g,g")))
10834 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10835 (clobber (reg:P LR_REGNO))]
10836 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10837 "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10838 [(set_attr "type" "jmpreg")
10839 (set_attr "length" "12")])
10841 ;; Call subroutine returning any type.
10842 (define_expand "untyped_call"
10843 [(parallel [(call (match_operand 0 "")
10845 (match_operand 1 "")
10846 (match_operand 2 "")])]
10851 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10853 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10855 rtx set = XVECEXP (operands[2], 0, i);
10856 emit_move_insn (SET_DEST (set), SET_SRC (set));
10859 /* The optimizer does not know that the call sets the function value
10860 registers we stored in the result block. We avoid problems by
10861 claiming that all hard registers are used and clobbered at this
10863 emit_insn (gen_blockage ());
10868 ;; sibling call patterns
10869 (define_expand "sibcall"
10870 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10871 (match_operand 1 ""))
10872 (use (match_operand 2 ""))
10877 if (MACHOPIC_INDIRECT)
10878 operands[0] = machopic_indirect_call_target (operands[0]);
10881 gcc_assert (GET_CODE (operands[0]) == MEM);
10882 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10884 operands[0] = XEXP (operands[0], 0);
10886 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10888 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10893 (define_expand "sibcall_value"
10894 [(parallel [(set (match_operand 0 "register_operand")
10895 (call (mem:SI (match_operand 1 "address_operand"))
10896 (match_operand 2 "")))
10897 (use (match_operand 3 ""))
10902 if (MACHOPIC_INDIRECT)
10903 operands[1] = machopic_indirect_call_target (operands[1]);
10906 gcc_assert (GET_CODE (operands[1]) == MEM);
10907 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10909 operands[1] = XEXP (operands[1], 0);
10911 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10913 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10918 (define_insn "*sibcall_local32"
10919 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10920 (match_operand 1 "" "g,g"))
10921 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10923 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10925 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10926 output_asm_insn ("crxor 6,6,6", operands);
10928 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10929 output_asm_insn ("creqv 6,6,6", operands);
10931 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10933 [(set_attr "type" "branch")
10934 (set_attr "length" "4,8")])
10936 (define_insn "*sibcall_local64"
10937 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10938 (match_operand 1 "" "g,g"))
10939 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10941 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10943 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10944 output_asm_insn ("crxor 6,6,6", operands);
10946 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10947 output_asm_insn ("creqv 6,6,6", operands);
10949 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10951 [(set_attr "type" "branch")
10952 (set_attr "length" "4,8")])
10954 (define_insn "*sibcall_value_local32"
10955 [(set (match_operand 0 "" "")
10956 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10957 (match_operand 2 "" "g,g")))
10958 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10960 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10962 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10963 output_asm_insn ("crxor 6,6,6", operands);
10965 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10966 output_asm_insn ("creqv 6,6,6", operands);
10968 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10970 [(set_attr "type" "branch")
10971 (set_attr "length" "4,8")])
10973 (define_insn "*sibcall_value_local64"
10974 [(set (match_operand 0 "" "")
10975 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10976 (match_operand 2 "" "g,g")))
10977 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10979 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10981 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10982 output_asm_insn ("crxor 6,6,6", operands);
10984 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10985 output_asm_insn ("creqv 6,6,6", operands);
10987 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10989 [(set_attr "type" "branch")
10990 (set_attr "length" "4,8")])
10992 (define_insn "*sibcall_nonlocal_sysv<mode>"
10993 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10994 (match_operand 1 "" ""))
10995 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10997 "(DEFAULT_ABI == ABI_DARWIN
10998 || DEFAULT_ABI == ABI_V4)
10999 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11001 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11002 output_asm_insn ("crxor 6,6,6", operands);
11004 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11005 output_asm_insn ("creqv 6,6,6", operands);
11007 if (which_alternative >= 2)
11009 if (rs6000_speculate_indirect_jumps)
11012 /* Can use CR0 since it is volatile across sibcalls. */
11013 return "crset 2\;beq%T0-\;b $";
11016 return rs6000_sibcall_template (operands, 0, "");
11018 [(set_attr "type" "branch")
11019 (set_attr_alternative "length"
11020 [(const_string "4")
11022 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11024 (const_string "12")
11025 (const_string "4"))
11026 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11028 (const_string "16")
11029 (const_string "8"))])])
11031 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11032 [(set (match_operand 0 "" "")
11033 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11034 (match_operand 2 "" "")))
11035 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11037 "(DEFAULT_ABI == ABI_DARWIN
11038 || DEFAULT_ABI == ABI_V4)
11039 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11041 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11042 output_asm_insn ("crxor 6,6,6", operands);
11044 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11045 output_asm_insn ("creqv 6,6,6", operands);
11047 if (which_alternative >= 2)
11049 if (rs6000_speculate_indirect_jumps)
11052 /* Can use CR0 since it is volatile across sibcalls. */
11053 return "crset 2\;beq%T1-\;b $";
11056 return rs6000_sibcall_template (operands, 1, "");
11058 [(set_attr "type" "branch")
11059 (set_attr_alternative "length"
11060 [(const_string "4")
11062 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11064 (const_string "12")
11065 (const_string "4"))
11066 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps")
11068 (const_string "16")
11069 (const_string "8"))])])
11071 ;; AIX ABI sibling call patterns.
11073 (define_insn "*sibcall_aix<mode>"
11074 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11075 (match_operand 1 "" "g,g"))
11077 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11079 if (which_alternative == 0)
11080 return rs6000_sibcall_template (operands, 0, "");
11084 [(set_attr "type" "branch")])
11086 (define_insn "*sibcall_value_aix<mode>"
11087 [(set (match_operand 0 "" "")
11088 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11089 (match_operand 2 "" "g,g")))
11091 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11093 if (which_alternative == 0)
11094 return rs6000_sibcall_template (operands, 1, "");
11098 [(set_attr "type" "branch")])
11100 (define_expand "sibcall_epilogue"
11101 [(use (const_int 0))]
11104 if (!TARGET_SCHED_PROLOG)
11105 emit_insn (gen_blockage ());
11106 rs6000_emit_epilogue (TRUE);
11110 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11111 ;; all of memory. This blocks insns from being moved across this point.
11113 (define_insn "blockage"
11114 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11117 [(set_attr "length" "0")])
11119 (define_expand "probe_stack_address"
11120 [(use (match_operand 0 "address_operand"))]
11123 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11124 MEM_VOLATILE_P (operands[0]) = 1;
11127 emit_insn (gen_probe_stack_di (operands[0]));
11129 emit_insn (gen_probe_stack_si (operands[0]));
11133 (define_insn "probe_stack_<mode>"
11134 [(set (match_operand:P 0 "memory_operand" "=m")
11135 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11138 operands[1] = gen_rtx_REG (Pmode, 0);
11139 return "st<wd>%U0%X0 %1,%0";
11141 [(set_attr "type" "store")
11142 (set (attr "update")
11143 (if_then_else (match_operand 0 "update_address_mem")
11144 (const_string "yes")
11145 (const_string "no")))
11146 (set (attr "indexed")
11147 (if_then_else (match_operand 0 "indexed_address_mem")
11148 (const_string "yes")
11149 (const_string "no")))])
11151 (define_insn "probe_stack_range<P:mode>"
11152 [(set (match_operand:P 0 "register_operand" "=&r")
11153 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11154 (match_operand:P 2 "register_operand" "r")
11155 (match_operand:P 3 "register_operand" "r")]
11156 UNSPECV_PROBE_STACK_RANGE))]
11158 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11159 [(set_attr "type" "three")])
11161 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11162 ;; signed & unsigned, and one type of branch.
11164 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11165 ;; insns, and branches.
11167 (define_expand "cbranch<mode>4"
11168 [(use (match_operator 0 "comparison_operator"
11169 [(match_operand:GPR 1 "gpc_reg_operand")
11170 (match_operand:GPR 2 "reg_or_short_operand")]))
11171 (use (match_operand 3))]
11174 /* Take care of the possibility that operands[2] might be negative but
11175 this might be a logical operation. That insn doesn't exist. */
11176 if (GET_CODE (operands[2]) == CONST_INT
11177 && INTVAL (operands[2]) < 0)
11179 operands[2] = force_reg (<MODE>mode, operands[2]);
11180 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11181 GET_MODE (operands[0]),
11182 operands[1], operands[2]);
11185 rs6000_emit_cbranch (<MODE>mode, operands);
11189 (define_expand "cbranch<mode>4"
11190 [(use (match_operator 0 "comparison_operator"
11191 [(match_operand:FP 1 "gpc_reg_operand")
11192 (match_operand:FP 2 "gpc_reg_operand")]))
11193 (use (match_operand 3))]
11196 rs6000_emit_cbranch (<MODE>mode, operands);
11200 (define_expand "cstore<mode>4_signed"
11201 [(use (match_operator 1 "signed_comparison_operator"
11202 [(match_operand:P 2 "gpc_reg_operand")
11203 (match_operand:P 3 "gpc_reg_operand")]))
11204 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11207 enum rtx_code cond_code = GET_CODE (operands[1]);
11209 rtx op0 = operands[0];
11210 rtx op1 = operands[2];
11211 rtx op2 = operands[3];
11213 if (cond_code == GE || cond_code == LT)
11215 cond_code = swap_condition (cond_code);
11216 std::swap (op1, op2);
11219 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11220 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11221 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11223 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11224 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11225 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11227 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11229 if (cond_code == LE)
11230 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11233 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11234 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11235 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11241 (define_expand "cstore<mode>4_unsigned"
11242 [(use (match_operator 1 "unsigned_comparison_operator"
11243 [(match_operand:P 2 "gpc_reg_operand")
11244 (match_operand:P 3 "reg_or_short_operand")]))
11245 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11248 enum rtx_code cond_code = GET_CODE (operands[1]);
11250 rtx op0 = operands[0];
11251 rtx op1 = operands[2];
11252 rtx op2 = operands[3];
11254 if (cond_code == GEU || cond_code == LTU)
11256 cond_code = swap_condition (cond_code);
11257 std::swap (op1, op2);
11260 if (!gpc_reg_operand (op1, <MODE>mode))
11261 op1 = force_reg (<MODE>mode, op1);
11262 if (!reg_or_short_operand (op2, <MODE>mode))
11263 op2 = force_reg (<MODE>mode, op2);
11265 rtx tmp = gen_reg_rtx (<MODE>mode);
11266 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11268 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11269 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11271 if (cond_code == LEU)
11272 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11274 emit_insn (gen_neg<mode>2 (op0, tmp2));
11279 (define_expand "cstore_si_as_di"
11280 [(use (match_operator 1 "unsigned_comparison_operator"
11281 [(match_operand:SI 2 "gpc_reg_operand")
11282 (match_operand:SI 3 "reg_or_short_operand")]))
11283 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11286 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11287 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11289 operands[2] = force_reg (SImode, operands[2]);
11290 operands[3] = force_reg (SImode, operands[3]);
11291 rtx op1 = gen_reg_rtx (DImode);
11292 rtx op2 = gen_reg_rtx (DImode);
11293 convert_move (op1, operands[2], uns_flag);
11294 convert_move (op2, operands[3], uns_flag);
11296 if (cond_code == GT || cond_code == LE)
11298 cond_code = swap_condition (cond_code);
11299 std::swap (op1, op2);
11302 rtx tmp = gen_reg_rtx (DImode);
11303 rtx tmp2 = gen_reg_rtx (DImode);
11304 emit_insn (gen_subdi3 (tmp, op1, op2));
11305 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11311 gcc_unreachable ();
11316 tmp3 = gen_reg_rtx (DImode);
11317 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11321 convert_move (operands[0], tmp3, 1);
11326 (define_expand "cstore<mode>4_signed_imm"
11327 [(use (match_operator 1 "signed_comparison_operator"
11328 [(match_operand:GPR 2 "gpc_reg_operand")
11329 (match_operand:GPR 3 "immediate_operand")]))
11330 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11333 bool invert = false;
11335 enum rtx_code cond_code = GET_CODE (operands[1]);
11337 rtx op0 = operands[0];
11338 rtx op1 = operands[2];
11339 HOST_WIDE_INT val = INTVAL (operands[3]);
11341 if (cond_code == GE || cond_code == GT)
11343 cond_code = reverse_condition (cond_code);
11347 if (cond_code == LE)
11350 rtx tmp = gen_reg_rtx (<MODE>mode);
11351 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11352 rtx x = gen_reg_rtx (<MODE>mode);
11354 emit_insn (gen_and<mode>3 (x, op1, tmp));
11356 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11360 rtx tmp = gen_reg_rtx (<MODE>mode);
11361 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11365 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11366 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11371 (define_expand "cstore<mode>4_unsigned_imm"
11372 [(use (match_operator 1 "unsigned_comparison_operator"
11373 [(match_operand:GPR 2 "gpc_reg_operand")
11374 (match_operand:GPR 3 "immediate_operand")]))
11375 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11378 bool invert = false;
11380 enum rtx_code cond_code = GET_CODE (operands[1]);
11382 rtx op0 = operands[0];
11383 rtx op1 = operands[2];
11384 HOST_WIDE_INT val = INTVAL (operands[3]);
11386 if (cond_code == GEU || cond_code == GTU)
11388 cond_code = reverse_condition (cond_code);
11392 if (cond_code == LEU)
11395 rtx tmp = gen_reg_rtx (<MODE>mode);
11396 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11397 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11398 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11399 rtx x = gen_reg_rtx (<MODE>mode);
11401 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11403 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11407 rtx tmp = gen_reg_rtx (<MODE>mode);
11408 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11412 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11413 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11418 (define_expand "cstore<mode>4"
11419 [(use (match_operator 1 "comparison_operator"
11420 [(match_operand:GPR 2 "gpc_reg_operand")
11421 (match_operand:GPR 3 "reg_or_short_operand")]))
11422 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11425 /* Expanding EQ and NE directly to some machine instructions does not help
11426 but does hurt combine. So don't. */
11427 if (GET_CODE (operands[1]) == EQ)
11428 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11429 else if (<MODE>mode == Pmode
11430 && GET_CODE (operands[1]) == NE)
11431 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11432 else if (GET_CODE (operands[1]) == NE)
11434 rtx tmp = gen_reg_rtx (<MODE>mode);
11435 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11436 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11439 /* If ISEL is fast, expand to it. */
11440 else if (TARGET_ISEL)
11441 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11443 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11444 etc. combinations magically work out just right. */
11445 else if (<MODE>mode == Pmode
11446 && unsigned_comparison_operator (operands[1], VOIDmode))
11447 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11448 operands[2], operands[3]));
11450 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11451 else if (<MODE>mode == SImode && Pmode == DImode)
11452 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11453 operands[2], operands[3]));
11455 /* For signed comparisons against a constant, we can do some simple
11457 else if (signed_comparison_operator (operands[1], VOIDmode)
11458 && CONST_INT_P (operands[3]))
11459 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11460 operands[2], operands[3]));
11462 /* And similarly for unsigned comparisons. */
11463 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11464 && CONST_INT_P (operands[3]))
11465 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11466 operands[2], operands[3]));
11468 /* We also do not want to use mfcr for signed comparisons. */
11469 else if (<MODE>mode == Pmode
11470 && signed_comparison_operator (operands[1], VOIDmode))
11471 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11472 operands[2], operands[3]));
11474 /* Everything else, use the mfcr brute force. */
11476 rs6000_emit_sCOND (<MODE>mode, operands);
11481 (define_expand "cstore<mode>4"
11482 [(use (match_operator 1 "comparison_operator"
11483 [(match_operand:FP 2 "gpc_reg_operand")
11484 (match_operand:FP 3 "gpc_reg_operand")]))
11485 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11488 rs6000_emit_sCOND (<MODE>mode, operands);
11493 (define_expand "stack_protect_set"
11494 [(match_operand 0 "memory_operand")
11495 (match_operand 1 "memory_operand")]
11498 if (rs6000_stack_protector_guard == SSP_TLS)
11500 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11501 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11502 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11503 operands[1] = gen_rtx_MEM (Pmode, addr);
11507 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11509 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11514 (define_insn "stack_protect_setsi"
11515 [(set (match_operand:SI 0 "memory_operand" "=m")
11516 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11517 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11519 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11520 [(set_attr "type" "three")
11521 (set_attr "length" "12")])
11523 (define_insn "stack_protect_setdi"
11524 [(set (match_operand:DI 0 "memory_operand" "=Y")
11525 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11526 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11528 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11529 [(set_attr "type" "three")
11530 (set_attr "length" "12")])
11532 (define_expand "stack_protect_test"
11533 [(match_operand 0 "memory_operand")
11534 (match_operand 1 "memory_operand")
11535 (match_operand 2 "")]
11538 rtx guard = operands[1];
11540 if (rs6000_stack_protector_guard == SSP_TLS)
11542 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11543 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11544 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11545 guard = gen_rtx_MEM (Pmode, addr);
11548 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11549 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11550 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11551 emit_jump_insn (jump);
11556 (define_insn "stack_protect_testsi"
11557 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11558 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11559 (match_operand:SI 2 "memory_operand" "m,m")]
11561 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11562 (clobber (match_scratch:SI 3 "=&r,&r"))]
11565 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11566 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11567 [(set_attr "length" "16,20")])
11569 (define_insn "stack_protect_testdi"
11570 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11571 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11572 (match_operand:DI 2 "memory_operand" "Y,Y")]
11574 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11575 (clobber (match_scratch:DI 3 "=&r,&r"))]
11578 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11579 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11580 [(set_attr "length" "16,20")])
11583 ;; Here are the actual compare insns.
11584 (define_insn "*cmp<mode>_signed"
11585 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11586 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11587 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11589 "cmp<wd>%I2 %0,%1,%2"
11590 [(set_attr "type" "cmp")])
11592 (define_insn "*cmp<mode>_unsigned"
11593 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11594 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11595 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11597 "cmpl<wd>%I2 %0,%1,%2"
11598 [(set_attr "type" "cmp")])
11600 ;; If we are comparing a register for equality with a large constant,
11601 ;; we can do this with an XOR followed by a compare. But this is profitable
11602 ;; only if the large constant is only used for the comparison (and in this
11603 ;; case we already have a register to reuse as scratch).
11605 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11606 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11609 [(set (match_operand:SI 0 "register_operand")
11610 (match_operand:SI 1 "logical_const_operand"))
11611 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11613 (match_operand:SI 2 "logical_const_operand")]))
11614 (set (match_operand:CC 4 "cc_reg_operand")
11615 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11618 (if_then_else (match_operator 6 "equality_operator"
11619 [(match_dup 4) (const_int 0)])
11620 (match_operand 7 "")
11621 (match_operand 8 "")))]
11622 "peep2_reg_dead_p (3, operands[0])
11623 && peep2_reg_dead_p (4, operands[4])
11624 && REGNO (operands[0]) != REGNO (operands[5])"
11625 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11626 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11627 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11630 /* Get the constant we are comparing against, and see what it looks like
11631 when sign-extended from 16 to 32 bits. Then see what constant we could
11632 XOR with SEXTC to get the sign-extended value. */
11633 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11635 operands[1], operands[2]);
11636 HOST_WIDE_INT c = INTVAL (cnst);
11637 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11638 HOST_WIDE_INT xorv = c ^ sextc;
11640 operands[9] = GEN_INT (xorv);
11641 operands[10] = GEN_INT (sextc);
11644 ;; Only need to compare second words if first words equal
11645 (define_insn "*cmp<mode>_internal1"
11646 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11647 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11648 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11649 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11650 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11651 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11652 [(set_attr "type" "fpcompare")
11653 (set_attr "length" "12")])
11655 (define_insn_and_split "*cmp<mode>_internal2"
11656 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11657 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11658 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11659 (clobber (match_scratch:DF 3 "=d"))
11660 (clobber (match_scratch:DF 4 "=d"))
11661 (clobber (match_scratch:DF 5 "=d"))
11662 (clobber (match_scratch:DF 6 "=d"))
11663 (clobber (match_scratch:DF 7 "=d"))
11664 (clobber (match_scratch:DF 8 "=d"))
11665 (clobber (match_scratch:DF 9 "=d"))
11666 (clobber (match_scratch:DF 10 "=d"))
11667 (clobber (match_scratch:GPR 11 "=b"))]
11668 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11669 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11671 "&& reload_completed"
11672 [(set (match_dup 3) (match_dup 14))
11673 (set (match_dup 4) (match_dup 15))
11674 (set (match_dup 9) (abs:DF (match_dup 5)))
11675 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11676 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11677 (label_ref (match_dup 12))
11679 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11680 (set (pc) (label_ref (match_dup 13)))
11682 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11683 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11684 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11685 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11688 REAL_VALUE_TYPE rv;
11689 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11690 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11692 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11693 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11694 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11695 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11696 operands[12] = gen_label_rtx ();
11697 operands[13] = gen_label_rtx ();
11699 operands[14] = force_const_mem (DFmode,
11700 const_double_from_real_value (rv, DFmode));
11701 operands[15] = force_const_mem (DFmode,
11702 const_double_from_real_value (dconst0,
11707 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11708 operands[14] = gen_const_mem (DFmode, tocref);
11709 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11710 operands[15] = gen_const_mem (DFmode, tocref);
11711 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11712 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11716 ;; Now we have the scc insns. We can do some combinations because of the
11717 ;; way the machine works.
11719 ;; Note that this is probably faster if we can put an insn between the
11720 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11721 ;; cases the insns below which don't use an intermediate CR field will
11722 ;; be used instead.
11724 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11725 (match_operator:GPR 1 "scc_comparison_operator"
11726 [(match_operand 2 "cc_reg_operand" "y")
11729 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11730 [(set (attr "type")
11731 (cond [(match_test "TARGET_MFCRF")
11732 (const_string "mfcrf")
11734 (const_string "mfcr")))
11735 (set_attr "length" "8")])
11737 (define_insn_and_split ""
11738 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11739 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11740 [(match_operand 2 "cc_reg_operand" "y,y")
11743 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11744 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11747 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11749 "&& reload_completed"
11750 [(set (match_dup 3)
11751 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11753 (compare:CC (match_dup 3)
11756 [(set_attr "type" "shift")
11757 (set_attr "dot" "yes")
11758 (set_attr "length" "8,16")])
11761 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11762 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11763 [(match_operand 2 "cc_reg_operand" "y")
11765 (match_operand:SI 3 "const_int_operand" "n")))]
11768 int is_bit = ccr_bit (operands[1], 1);
11769 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11772 if (is_bit >= put_bit)
11773 count = is_bit - put_bit;
11775 count = 32 - (put_bit - is_bit);
11777 operands[4] = GEN_INT (count);
11778 operands[5] = GEN_INT (put_bit);
11780 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11782 [(set (attr "type")
11783 (cond [(match_test "TARGET_MFCRF")
11784 (const_string "mfcrf")
11786 (const_string "mfcr")))
11787 (set_attr "length" "8")])
11790 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11792 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11793 [(match_operand 2 "cc_reg_operand" "y,y")
11795 (match_operand:SI 3 "const_int_operand" "n,n"))
11797 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11798 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11802 int is_bit = ccr_bit (operands[1], 1);
11803 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11806 /* Force split for non-cc0 compare. */
11807 if (which_alternative == 1)
11810 if (is_bit >= put_bit)
11811 count = is_bit - put_bit;
11813 count = 32 - (put_bit - is_bit);
11815 operands[5] = GEN_INT (count);
11816 operands[6] = GEN_INT (put_bit);
11818 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11820 [(set_attr "type" "shift")
11821 (set_attr "dot" "yes")
11822 (set_attr "length" "8,16")])
11825 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11827 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11828 [(match_operand 2 "cc_reg_operand")
11830 (match_operand:SI 3 "const_int_operand"))
11832 (set (match_operand:SI 4 "gpc_reg_operand")
11833 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11836 [(set (match_dup 4)
11837 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11840 (compare:CC (match_dup 4)
11845 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11846 (define_code_attr UNS [(eq "CC")
11848 (lt "CC") (ltu "CCUNS")
11849 (gt "CC") (gtu "CCUNS")
11850 (le "CC") (leu "CCUNS")
11851 (ge "CC") (geu "CCUNS")])
11852 (define_code_attr UNSu_ [(eq "")
11857 (ge "") (geu "u_")])
11858 (define_code_attr UNSIK [(eq "I")
11863 (ge "I") (geu "K")])
11865 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11866 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11867 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11868 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11869 (clobber (match_scratch:GPR 3 "=r"))
11870 (clobber (match_scratch:GPR 4 "=r"))
11871 (clobber (match_scratch:<UNS> 5 "=y"))]
11873 && !(<CODE> == EQ && operands[2] == const0_rtx)
11874 && !(<CODE> == NE && operands[2] == const0_rtx
11875 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11880 rtx_code code = <CODE>;
11881 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11883 HOST_WIDE_INT val = INTVAL (operands[2]);
11884 if (code == LT && val != -0x8000)
11889 if (code == GT && val != 0x7fff)
11894 if (code == LTU && val != 0)
11899 if (code == GTU && val != 0xffff)
11904 operands[2] = GEN_INT (val);
11907 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11908 operands[3] = const0_rtx;
11911 if (GET_CODE (operands[3]) == SCRATCH)
11912 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11913 emit_move_insn (operands[3], const0_rtx);
11916 if (GET_CODE (operands[4]) == SCRATCH)
11917 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11918 emit_move_insn (operands[4], const1_rtx);
11920 if (GET_CODE (operands[5]) == SCRATCH)
11921 operands[5] = gen_reg_rtx (<UNS>mode);
11923 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11924 emit_insn (gen_rtx_SET (operands[5], c1));
11926 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11927 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11928 emit_move_insn (operands[0], x);
11932 [(set (attr "cost")
11933 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11935 || <CODE> == LE || <CODE> == GE
11936 || <CODE> == LEU || <CODE> == GEU")
11938 (const_string "10")))])
11940 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11943 (define_expand "eq<mode>3"
11945 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11946 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11947 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11948 (clobber (match_scratch:GPR 3 "=r"))
11949 (clobber (match_scratch:GPR 4 "=r"))])]
11952 if (TARGET_ISEL && operands[2] != const0_rtx)
11954 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11960 (define_insn_and_split "*eq<mode>3"
11961 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11962 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11963 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11964 (clobber (match_scratch:GPR 3 "=r"))
11965 (clobber (match_scratch:GPR 4 "=r"))]
11966 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11969 [(set (match_dup 4)
11970 (clz:GPR (match_dup 3)))
11972 (lshiftrt:GPR (match_dup 4)
11975 operands[3] = rs6000_emit_eqne (<MODE>mode,
11976 operands[1], operands[2], operands[3]);
11978 if (GET_CODE (operands[4]) == SCRATCH)
11979 operands[4] = gen_reg_rtx (<MODE>mode);
11981 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11983 [(set (attr "length")
11984 (if_then_else (match_test "operands[2] == const0_rtx")
11986 (const_string "12")))])
11988 (define_expand "ne<mode>3"
11990 (set (match_operand:P 0 "gpc_reg_operand" "=r")
11991 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11992 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11993 (clobber (match_scratch:P 3 "=r"))
11994 (clobber (match_scratch:P 4 "=r"))
11995 (clobber (reg:P CA_REGNO))])]
11998 if (TARGET_ISEL && operands[2] != const0_rtx)
12000 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12006 (define_insn_and_split "*ne<mode>3"
12007 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12008 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12009 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12010 (clobber (match_scratch:P 3 "=r"))
12011 (clobber (match_scratch:P 4 "=r"))
12012 (clobber (reg:P CA_REGNO))]
12013 "!(TARGET_ISEL && operands[2] != const0_rtx)"
12016 [(parallel [(set (match_dup 4)
12017 (plus:P (match_dup 3)
12019 (set (reg:P CA_REGNO)
12020 (ne:P (match_dup 3)
12022 (parallel [(set (match_dup 0)
12023 (plus:P (plus:P (not:P (match_dup 4))
12026 (clobber (reg:P CA_REGNO))])]
12028 operands[3] = rs6000_emit_eqne (<MODE>mode,
12029 operands[1], operands[2], operands[3]);
12031 if (GET_CODE (operands[4]) == SCRATCH)
12032 operands[4] = gen_reg_rtx (<MODE>mode);
12034 [(set (attr "length")
12035 (if_then_else (match_test "operands[2] == const0_rtx")
12037 (const_string "12")))])
12039 (define_insn_and_split "*neg_eq_<mode>"
12040 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12041 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12042 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12043 (clobber (match_scratch:P 3 "=r"))
12044 (clobber (match_scratch:P 4 "=r"))
12045 (clobber (reg:P CA_REGNO))]
12049 [(parallel [(set (match_dup 4)
12050 (plus:P (match_dup 3)
12052 (set (reg:P CA_REGNO)
12053 (ne:P (match_dup 3)
12055 (parallel [(set (match_dup 0)
12056 (plus:P (reg:P CA_REGNO)
12058 (clobber (reg:P CA_REGNO))])]
12060 operands[3] = rs6000_emit_eqne (<MODE>mode,
12061 operands[1], operands[2], operands[3]);
12063 if (GET_CODE (operands[4]) == SCRATCH)
12064 operands[4] = gen_reg_rtx (<MODE>mode);
12066 [(set (attr "length")
12067 (if_then_else (match_test "operands[2] == const0_rtx")
12069 (const_string "12")))])
12071 (define_insn_and_split "*neg_ne_<mode>"
12072 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12073 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12074 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12075 (clobber (match_scratch:P 3 "=r"))
12076 (clobber (match_scratch:P 4 "=r"))
12077 (clobber (reg:P CA_REGNO))]
12081 [(parallel [(set (match_dup 4)
12082 (neg:P (match_dup 3)))
12083 (set (reg:P CA_REGNO)
12084 (eq:P (match_dup 3)
12086 (parallel [(set (match_dup 0)
12087 (plus:P (reg:P CA_REGNO)
12089 (clobber (reg:P CA_REGNO))])]
12091 operands[3] = rs6000_emit_eqne (<MODE>mode,
12092 operands[1], operands[2], operands[3]);
12094 if (GET_CODE (operands[4]) == SCRATCH)
12095 operands[4] = gen_reg_rtx (<MODE>mode);
12097 [(set (attr "length")
12098 (if_then_else (match_test "operands[2] == const0_rtx")
12100 (const_string "12")))])
12102 (define_insn_and_split "*plus_eq_<mode>"
12103 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12104 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12105 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12106 (match_operand:P 3 "gpc_reg_operand" "r")))
12107 (clobber (match_scratch:P 4 "=r"))
12108 (clobber (match_scratch:P 5 "=r"))
12109 (clobber (reg:P CA_REGNO))]
12113 [(parallel [(set (match_dup 5)
12114 (neg:P (match_dup 4)))
12115 (set (reg:P CA_REGNO)
12116 (eq:P (match_dup 4)
12118 (parallel [(set (match_dup 0)
12119 (plus:P (match_dup 3)
12121 (clobber (reg:P CA_REGNO))])]
12123 operands[4] = rs6000_emit_eqne (<MODE>mode,
12124 operands[1], operands[2], operands[4]);
12126 if (GET_CODE (operands[5]) == SCRATCH)
12127 operands[5] = gen_reg_rtx (<MODE>mode);
12129 [(set (attr "length")
12130 (if_then_else (match_test "operands[2] == const0_rtx")
12132 (const_string "12")))])
12134 (define_insn_and_split "*plus_ne_<mode>"
12135 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12136 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12137 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12138 (match_operand:P 3 "gpc_reg_operand" "r")))
12139 (clobber (match_scratch:P 4 "=r"))
12140 (clobber (match_scratch:P 5 "=r"))
12141 (clobber (reg:P CA_REGNO))]
12145 [(parallel [(set (match_dup 5)
12146 (plus:P (match_dup 4)
12148 (set (reg:P CA_REGNO)
12149 (ne:P (match_dup 4)
12151 (parallel [(set (match_dup 0)
12152 (plus:P (match_dup 3)
12154 (clobber (reg:P CA_REGNO))])]
12156 operands[4] = rs6000_emit_eqne (<MODE>mode,
12157 operands[1], operands[2], operands[4]);
12159 if (GET_CODE (operands[5]) == SCRATCH)
12160 operands[5] = gen_reg_rtx (<MODE>mode);
12162 [(set (attr "length")
12163 (if_then_else (match_test "operands[2] == const0_rtx")
12165 (const_string "12")))])
12167 (define_insn_and_split "*minus_eq_<mode>"
12168 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12169 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12170 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12171 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12172 (clobber (match_scratch:P 4 "=r"))
12173 (clobber (match_scratch:P 5 "=r"))
12174 (clobber (reg:P CA_REGNO))]
12178 [(parallel [(set (match_dup 5)
12179 (plus:P (match_dup 4)
12181 (set (reg:P CA_REGNO)
12182 (ne:P (match_dup 4)
12184 (parallel [(set (match_dup 0)
12185 (plus:P (plus:P (match_dup 3)
12188 (clobber (reg:P CA_REGNO))])]
12190 operands[4] = rs6000_emit_eqne (<MODE>mode,
12191 operands[1], operands[2], operands[4]);
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")
12199 (const_string "12")))])
12201 (define_insn_and_split "*minus_ne_<mode>"
12202 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12203 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12204 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12205 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12206 (clobber (match_scratch:P 4 "=r"))
12207 (clobber (match_scratch:P 5 "=r"))
12208 (clobber (reg:P CA_REGNO))]
12212 [(parallel [(set (match_dup 5)
12213 (neg:P (match_dup 4)))
12214 (set (reg:P CA_REGNO)
12215 (eq:P (match_dup 4)
12217 (parallel [(set (match_dup 0)
12218 (plus:P (plus:P (match_dup 3)
12221 (clobber (reg:P CA_REGNO))])]
12223 operands[4] = rs6000_emit_eqne (<MODE>mode,
12224 operands[1], operands[2], operands[4]);
12226 if (GET_CODE (operands[5]) == SCRATCH)
12227 operands[5] = gen_reg_rtx (<MODE>mode);
12229 [(set (attr "length")
12230 (if_then_else (match_test "operands[2] == const0_rtx")
12232 (const_string "12")))])
12234 (define_insn_and_split "*eqsi3_ext<mode>"
12235 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12236 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12237 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12238 (clobber (match_scratch:SI 3 "=r"))
12239 (clobber (match_scratch:SI 4 "=r"))]
12243 [(set (match_dup 4)
12244 (clz:SI (match_dup 3)))
12247 (lshiftrt:SI (match_dup 4)
12250 operands[3] = rs6000_emit_eqne (SImode,
12251 operands[1], operands[2], operands[3]);
12253 if (GET_CODE (operands[4]) == SCRATCH)
12254 operands[4] = gen_reg_rtx (SImode);
12256 [(set (attr "length")
12257 (if_then_else (match_test "operands[2] == const0_rtx")
12259 (const_string "12")))])
12261 (define_insn_and_split "*nesi3_ext<mode>"
12262 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12263 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12264 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12265 (clobber (match_scratch:SI 3 "=r"))
12266 (clobber (match_scratch:SI 4 "=r"))
12267 (clobber (match_scratch:EXTSI 5 "=r"))]
12271 [(set (match_dup 4)
12272 (clz:SI (match_dup 3)))
12275 (lshiftrt:SI (match_dup 4)
12278 (xor:EXTSI (match_dup 5)
12281 operands[3] = rs6000_emit_eqne (SImode,
12282 operands[1], operands[2], operands[3]);
12284 if (GET_CODE (operands[4]) == SCRATCH)
12285 operands[4] = gen_reg_rtx (SImode);
12286 if (GET_CODE (operands[5]) == SCRATCH)
12287 operands[5] = gen_reg_rtx (<MODE>mode);
12289 [(set (attr "length")
12290 (if_then_else (match_test "operands[2] == const0_rtx")
12291 (const_string "12")
12292 (const_string "16")))])
12294 ;; Conditional branches.
12295 ;; These either are a single bc insn, or a bc around a b.
12297 (define_insn "*cbranch"
12299 (if_then_else (match_operator 1 "branch_comparison_operator"
12300 [(match_operand 2 "cc_reg_operand" "y")
12302 (label_ref (match_operand 0))
12306 return output_cbranch (operands[1], "%l0", 0, insn);
12308 [(set_attr "type" "branch")
12309 (set (attr "length")
12310 (if_then_else (and (ge (minus (match_dup 0) (pc))
12311 (const_int -32768))
12312 (lt (minus (match_dup 0) (pc))
12313 (const_int 32764)))
12317 ;; Conditional return.
12318 (define_insn "*creturn"
12320 (if_then_else (match_operator 0 "branch_comparison_operator"
12321 [(match_operand 1 "cc_reg_operand" "y")
12327 return output_cbranch (operands[0], NULL, 0, insn);
12329 [(set_attr "type" "jmpreg")])
12331 ;; Logic on condition register values.
12333 ; This pattern matches things like
12334 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12335 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12337 ; which are generated by the branch logic.
12338 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12340 (define_insn "cceq_ior_compare"
12341 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12342 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12343 [(match_operator:SI 2
12344 "branch_positive_comparison_operator"
12346 "cc_reg_operand" "y,y")
12348 (match_operator:SI 4
12349 "branch_positive_comparison_operator"
12351 "cc_reg_operand" "0,y")
12355 "cr%q1 %E0,%j2,%j4"
12356 [(set_attr "type" "cr_logical")
12357 (set_attr "cr_logical_3op" "no,yes")])
12359 ; Why is the constant -1 here, but 1 in the previous pattern?
12360 ; Because ~1 has all but the low bit set.
12361 (define_insn "cceq_ior_compare_complement"
12362 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12363 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12364 [(not:SI (match_operator:SI 2
12365 "branch_positive_comparison_operator"
12367 "cc_reg_operand" "y,y")
12369 (match_operator:SI 4
12370 "branch_positive_comparison_operator"
12372 "cc_reg_operand" "0,y")
12376 "cr%q1 %E0,%j2,%j4"
12377 [(set_attr "type" "cr_logical")
12378 (set_attr "cr_logical_3op" "no,yes")])
12380 (define_insn "*cceq_rev_compare"
12381 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12382 (compare:CCEQ (match_operator:SI 1
12383 "branch_positive_comparison_operator"
12385 "cc_reg_operand" "0,y")
12390 [(set_attr "type" "cr_logical")
12391 (set_attr "cr_logical_3op" "no,yes")])
12393 ;; If we are comparing the result of two comparisons, this can be done
12394 ;; using creqv or crxor.
12396 (define_insn_and_split ""
12397 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12398 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12399 [(match_operand 2 "cc_reg_operand" "y")
12401 (match_operator 3 "branch_comparison_operator"
12402 [(match_operand 4 "cc_reg_operand" "y")
12407 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12410 int positive_1, positive_2;
12412 positive_1 = branch_positive_comparison_operator (operands[1],
12413 GET_MODE (operands[1]));
12414 positive_2 = branch_positive_comparison_operator (operands[3],
12415 GET_MODE (operands[3]));
12418 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12419 GET_CODE (operands[1])),
12421 operands[2], const0_rtx);
12422 else if (GET_MODE (operands[1]) != SImode)
12423 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12424 operands[2], const0_rtx);
12427 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12428 GET_CODE (operands[3])),
12430 operands[4], const0_rtx);
12431 else if (GET_MODE (operands[3]) != SImode)
12432 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12433 operands[4], const0_rtx);
12435 if (positive_1 == positive_2)
12437 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12438 operands[5] = constm1_rtx;
12442 operands[5] = const1_rtx;
12446 ;; Unconditional branch and return.
12448 (define_insn "jump"
12450 (label_ref (match_operand 0)))]
12453 [(set_attr "type" "branch")])
12455 (define_insn "<return_str>return"
12459 [(set_attr "type" "jmpreg")])
12461 (define_expand "indirect_jump"
12462 [(set (pc) (match_operand 0 "register_operand"))]
12465 if (!rs6000_speculate_indirect_jumps) {
12466 rtx ccreg = gen_reg_rtx (CCmode);
12467 if (Pmode == DImode)
12468 emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12470 emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12475 (define_insn "*indirect_jump<mode>"
12477 (match_operand:P 0 "register_operand" "c,*l"))]
12478 "rs6000_speculate_indirect_jumps"
12480 [(set_attr "type" "jmpreg")])
12482 (define_insn "indirect_jump<mode>_nospec"
12483 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12484 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12485 "!rs6000_speculate_indirect_jumps"
12486 "crset %E1\;beq%T0- %1\;b $"
12487 [(set_attr "type" "jmpreg")
12488 (set_attr "length" "12")])
12490 ;; Table jump for switch statements:
12491 (define_expand "tablejump"
12492 [(use (match_operand 0))
12493 (use (label_ref (match_operand 1)))]
12496 if (rs6000_speculate_indirect_jumps)
12499 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12501 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12505 rtx ccreg = gen_reg_rtx (CCmode);
12508 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12510 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12511 emit_jump_insn (jump);
12516 (define_expand "tablejumpsi"
12517 [(set (match_dup 3)
12518 (plus:SI (match_operand:SI 0)
12520 (parallel [(set (pc)
12522 (use (label_ref (match_operand 1)))])]
12523 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12525 operands[0] = force_reg (SImode, operands[0]);
12526 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12527 operands[3] = gen_reg_rtx (SImode);
12530 (define_expand "tablejumpsi_nospec"
12531 [(set (match_dup 4)
12532 (plus:SI (match_operand:SI 0)
12534 (parallel [(set (pc)
12536 (use (label_ref (match_operand 1)))
12537 (clobber (match_operand 2))])]
12538 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12540 operands[0] = force_reg (SImode, operands[0]);
12541 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12542 operands[4] = gen_reg_rtx (SImode);
12545 (define_expand "tablejumpdi"
12546 [(set (match_dup 4)
12547 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12549 (plus:DI (match_dup 4)
12551 (parallel [(set (pc)
12553 (use (label_ref (match_operand 1)))])]
12554 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12556 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12557 operands[3] = gen_reg_rtx (DImode);
12558 operands[4] = gen_reg_rtx (DImode);
12561 (define_expand "tablejumpdi_nospec"
12562 [(set (match_dup 5)
12563 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12565 (plus:DI (match_dup 5)
12567 (parallel [(set (pc)
12569 (use (label_ref (match_operand 1)))
12570 (clobber (match_operand 2))])]
12571 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12573 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12574 operands[4] = gen_reg_rtx (DImode);
12575 operands[5] = gen_reg_rtx (DImode);
12578 (define_insn "*tablejump<mode>_internal1"
12580 (match_operand:P 0 "register_operand" "c,*l"))
12581 (use (label_ref (match_operand 1)))]
12582 "rs6000_speculate_indirect_jumps"
12584 [(set_attr "type" "jmpreg")])
12586 (define_insn "*tablejump<mode>_internal1_nospec"
12588 (match_operand:P 0 "register_operand" "c,*l"))
12589 (use (label_ref (match_operand 1)))
12590 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12591 "!rs6000_speculate_indirect_jumps"
12592 "crset %E2\;beq%T0- %2\;b $"
12593 [(set_attr "type" "jmpreg")
12594 (set_attr "length" "12")])
12597 [(unspec [(const_int 0)] UNSPEC_NOP)]
12601 (define_insn "group_ending_nop"
12602 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12605 if (rs6000_tune == PROCESSOR_POWER6)
12606 return "ori 1,1,0";
12607 return "ori 2,2,0";
12610 (define_insn "speculation_barrier"
12611 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12615 ;; Define the subtract-one-and-jump insns, starting with the template
12616 ;; so loop.c knows what to generate.
12618 (define_expand "doloop_end"
12619 [(use (match_operand 0)) ; loop pseudo
12620 (use (match_operand 1))] ; label
12625 if (GET_MODE (operands[0]) != DImode)
12627 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12631 if (GET_MODE (operands[0]) != SImode)
12633 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12638 (define_expand "ctr<mode>"
12639 [(parallel [(set (pc)
12640 (if_then_else (ne (match_operand:P 0 "register_operand")
12642 (label_ref (match_operand 1))
12645 (plus:P (match_dup 0)
12647 (clobber (match_scratch:CC 2))
12648 (clobber (match_scratch:P 3))])]
12652 ;; We need to be able to do this for any operand, including MEM, or we
12653 ;; will cause reload to blow up since we don't allow output reloads on
12655 ;; For the length attribute to be calculated correctly, the
12656 ;; label MUST be operand 0.
12657 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12658 ;; the ctr<mode> insns.
12660 (define_code_iterator eqne [eq ne])
12661 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12662 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12664 (define_insn "<bd>_<mode>"
12666 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12668 (label_ref (match_operand 0))
12670 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12671 (plus:P (match_dup 1)
12673 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12674 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12677 if (which_alternative != 0)
12679 else if (get_attr_length (insn) == 4)
12682 return "<bd_neg> $+8\;b %l0";
12684 [(set_attr "type" "branch")
12685 (set_attr_alternative "length"
12686 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12687 (const_int -32768))
12688 (lt (minus (match_dup 0) (pc))
12689 (const_int 32764)))
12692 (const_string "16")
12693 (const_string "20")
12694 (const_string "20")])])
12696 ;; Now the splitter if we could not allocate the CTR register
12699 (if_then_else (match_operator 2 "comparison_operator"
12700 [(match_operand:P 1 "gpc_reg_operand")
12703 (match_operand 6)))
12704 (set (match_operand:P 0 "nonimmediate_operand")
12705 (plus:P (match_dup 1)
12707 (clobber (match_scratch:CC 3))
12708 (clobber (match_scratch:P 4))]
12711 (if_then_else (match_dup 7)
12715 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12717 emit_insn (gen_rtx_SET (operands[3],
12718 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12719 if (gpc_reg_operand (operands[0], <MODE>mode))
12720 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12723 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12724 emit_move_insn (operands[0], operands[4]);
12726 /* No DONE so branch comes from the pattern. */
12729 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12730 ;; Note that in the case of long branches we have to decompose this into
12731 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12732 ;; and the CR bit, which means there is no way to conveniently invert the
12733 ;; comparison as is done with plain bdnz/bdz.
12735 (define_insn "<bd>tf_<mode>"
12739 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12741 (match_operator 3 "branch_comparison_operator"
12742 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12744 (label_ref (match_operand 0))
12746 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12747 (plus:P (match_dup 1)
12749 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12750 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12751 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12754 if (which_alternative != 0)
12756 else if (get_attr_length (insn) == 4)
12758 if (branch_positive_comparison_operator (operands[3],
12759 GET_MODE (operands[3])))
12760 return "<bd>t %j3,%l0";
12762 return "<bd>f %j3,%l0";
12766 static char seq[96];
12767 char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12768 sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12772 [(set_attr "type" "branch")
12773 (set_attr_alternative "length"
12774 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12775 (const_int -32768))
12776 (lt (minus (match_dup 0) (pc))
12777 (const_int 32764)))
12780 (const_string "16")
12781 (const_string "20")
12782 (const_string "20")])])
12784 ;; Now the splitter if we could not allocate the CTR register
12789 (match_operator 1 "comparison_operator"
12790 [(match_operand:P 0 "gpc_reg_operand")
12792 (match_operator 3 "branch_comparison_operator"
12793 [(match_operand 2 "cc_reg_operand")
12796 (match_operand 5)))
12797 (set (match_operand:P 6 "int_reg_operand")
12798 (plus:P (match_dup 0)
12800 (clobber (match_scratch:P 7))
12801 (clobber (match_scratch:CC 8))
12802 (clobber (match_scratch:CCEQ 9))]
12806 rtx ctr = operands[0];
12807 rtx ctrcmp = operands[1];
12808 rtx ccin = operands[2];
12809 rtx cccmp = operands[3];
12810 rtx dst1 = operands[4];
12811 rtx dst2 = operands[5];
12812 rtx ctrout = operands[6];
12813 rtx ctrtmp = operands[7];
12814 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12815 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12817 cmpcode = reverse_condition (cmpcode);
12818 /* Generate crand/crandc here. */
12819 emit_insn (gen_rtx_SET (operands[8],
12820 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12821 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12823 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12825 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12826 operands[8], cccmp, ccin));
12828 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12829 operands[8], cccmp, ccin));
12830 if (gpc_reg_operand (operands[0], <MODE>mode))
12831 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12834 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12835 emit_move_insn (ctrout, ctrtmp);
12837 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12838 emit_jump_insn (gen_rtx_SET (pc_rtx,
12839 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12845 (define_insn "trap"
12846 [(trap_if (const_int 1) (const_int 0))]
12849 [(set_attr "type" "trap")])
12851 (define_expand "ctrap<mode>4"
12852 [(trap_if (match_operator 0 "ordered_comparison_operator"
12853 [(match_operand:GPR 1 "register_operand")
12854 (match_operand:GPR 2 "reg_or_short_operand")])
12855 (match_operand 3 "zero_constant" ""))]
12860 [(trap_if (match_operator 0 "ordered_comparison_operator"
12861 [(match_operand:GPR 1 "register_operand" "r")
12862 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12865 "t<wd>%V0%I2 %1,%2"
12866 [(set_attr "type" "trap")])
12868 ;; Insns related to generating the function prologue and epilogue.
12870 (define_expand "prologue"
12871 [(use (const_int 0))]
12874 rs6000_emit_prologue ();
12875 if (!TARGET_SCHED_PROLOG)
12876 emit_insn (gen_blockage ());
12880 (define_insn "*movesi_from_cr_one"
12881 [(match_parallel 0 "mfcr_operation"
12882 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12883 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12884 (match_operand 3 "immediate_operand" "n")]
12885 UNSPEC_MOVESI_FROM_CR))])]
12890 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12892 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12893 operands[4] = GEN_INT (mask);
12894 output_asm_insn ("mfcr %1,%4", operands);
12898 [(set_attr "type" "mfcrf")])
12900 ;; Don't include the volatile CRs since their values are not used wrt CR save
12901 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12902 ;; prologue past an insn (early exit test) that defines a register used in the
12904 (define_insn "prologue_movesi_from_cr"
12905 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12906 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12907 (reg:CC CR4_REGNO)]
12908 UNSPEC_MOVESI_FROM_CR))]
12911 [(set_attr "type" "mfcr")])
12913 (define_insn "*crsave"
12914 [(match_parallel 0 "crsave_operation"
12915 [(set (match_operand:SI 1 "memory_operand" "=m")
12916 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12919 [(set_attr "type" "store")])
12921 (define_insn "*stmw"
12922 [(match_parallel 0 "stmw_operation"
12923 [(set (match_operand:SI 1 "memory_operand" "=m")
12924 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12927 [(set_attr "type" "store")
12928 (set_attr "update" "yes")
12929 (set_attr "indexed" "yes")])
12931 ; The following comment applies to:
12935 ; return_and_restore_gpregs*
12936 ; return_and_restore_fpregs*
12937 ; return_and_restore_fpregs_aix*
12939 ; The out-of-line save / restore functions expects one input argument.
12940 ; Since those are not standard call_insn's, we must avoid using
12941 ; MATCH_OPERAND for that argument. That way the register rename
12942 ; optimization will not try to rename this register.
12943 ; Each pattern is repeated for each possible register number used in
12944 ; various ABIs (r11, r1, and for some functions r12)
12946 (define_insn "*save_gpregs_<mode>_r11"
12947 [(match_parallel 0 "any_parallel_operand"
12948 [(clobber (reg:P LR_REGNO))
12949 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12951 (set (match_operand:P 2 "memory_operand" "=m")
12952 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12955 [(set_attr "type" "branch")])
12957 (define_insn "*save_gpregs_<mode>_r12"
12958 [(match_parallel 0 "any_parallel_operand"
12959 [(clobber (reg:P LR_REGNO))
12960 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12962 (set (match_operand:P 2 "memory_operand" "=m")
12963 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12966 [(set_attr "type" "branch")])
12968 (define_insn "*save_gpregs_<mode>_r1"
12969 [(match_parallel 0 "any_parallel_operand"
12970 [(clobber (reg:P LR_REGNO))
12971 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12973 (set (match_operand:P 2 "memory_operand" "=m")
12974 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12977 [(set_attr "type" "branch")])
12979 (define_insn "*save_fpregs_<mode>_r11"
12980 [(match_parallel 0 "any_parallel_operand"
12981 [(clobber (reg:P LR_REGNO))
12982 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12984 (set (match_operand:DF 2 "memory_operand" "=m")
12985 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12988 [(set_attr "type" "branch")])
12990 (define_insn "*save_fpregs_<mode>_r12"
12991 [(match_parallel 0 "any_parallel_operand"
12992 [(clobber (reg:P LR_REGNO))
12993 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12995 (set (match_operand:DF 2 "memory_operand" "=m")
12996 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12999 [(set_attr "type" "branch")])
13001 (define_insn "*save_fpregs_<mode>_r1"
13002 [(match_parallel 0 "any_parallel_operand"
13003 [(clobber (reg:P LR_REGNO))
13004 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13006 (set (match_operand:DF 2 "memory_operand" "=m")
13007 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13010 [(set_attr "type" "branch")])
13012 ; This is to explain that changes to the stack pointer should
13013 ; not be moved over loads from or stores to stack memory.
13014 (define_insn "stack_tie"
13015 [(match_parallel 0 "tie_operand"
13016 [(set (mem:BLK (reg 1)) (const_int 0))])]
13019 [(set_attr "length" "0")])
13021 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13022 ; stay behind all restores from the stack, it cannot be reordered to before
13023 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13024 (define_insn "stack_restore_tie"
13025 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13026 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13027 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13028 (set (mem:BLK (scratch)) (const_int 0))]
13033 [(set_attr "type" "*,add")])
13035 (define_expand "epilogue"
13036 [(use (const_int 0))]
13039 if (!TARGET_SCHED_PROLOG)
13040 emit_insn (gen_blockage ());
13041 rs6000_emit_epilogue (FALSE);
13045 ; On some processors, doing the mtcrf one CC register at a time is
13046 ; faster (like on the 604e). On others, doing them all at once is
13047 ; faster; for instance, on the 601 and 750.
13049 (define_expand "movsi_to_cr_one"
13050 [(set (match_operand:CC 0 "cc_reg_operand")
13051 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13052 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13054 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13056 (define_insn "*movsi_to_cr"
13057 [(match_parallel 0 "mtcrf_operation"
13058 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13059 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13060 (match_operand 3 "immediate_operand" "n")]
13061 UNSPEC_MOVESI_TO_CR))])]
13066 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13067 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13068 operands[4] = GEN_INT (mask);
13069 return "mtcrf %4,%2";
13071 [(set_attr "type" "mtcr")])
13073 (define_insn "*mtcrfsi"
13074 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13075 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13076 (match_operand 2 "immediate_operand" "n")]
13077 UNSPEC_MOVESI_TO_CR))]
13078 "GET_CODE (operands[0]) == REG
13079 && CR_REGNO_P (REGNO (operands[0]))
13080 && GET_CODE (operands[2]) == CONST_INT
13081 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13083 [(set_attr "type" "mtcr")])
13085 ; The load-multiple instructions have similar properties.
13086 ; Note that "load_multiple" is a name known to the machine-independent
13087 ; code that actually corresponds to the PowerPC load-string.
13089 (define_insn "*lmw"
13090 [(match_parallel 0 "lmw_operation"
13091 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13092 (match_operand:SI 2 "memory_operand" "m"))])]
13095 [(set_attr "type" "load")
13096 (set_attr "update" "yes")
13097 (set_attr "indexed" "yes")
13098 (set_attr "cell_micro" "always")])
13100 ; FIXME: "any_parallel_operand" is a bit flexible...
13102 ; The following comment applies to:
13106 ; return_and_restore_gpregs*
13107 ; return_and_restore_fpregs*
13108 ; return_and_restore_fpregs_aix*
13110 ; The out-of-line save / restore functions expects one input argument.
13111 ; Since those are not standard call_insn's, we must avoid using
13112 ; MATCH_OPERAND for that argument. That way the register rename
13113 ; optimization will not try to rename this register.
13114 ; Each pattern is repeated for each possible register number used in
13115 ; various ABIs (r11, r1, and for some functions r12)
13117 (define_insn "*restore_gpregs_<mode>_r11"
13118 [(match_parallel 0 "any_parallel_operand"
13119 [(clobber (reg:P LR_REGNO))
13120 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13122 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13123 (match_operand:P 3 "memory_operand" "m"))])]
13126 [(set_attr "type" "branch")])
13128 (define_insn "*restore_gpregs_<mode>_r12"
13129 [(match_parallel 0 "any_parallel_operand"
13130 [(clobber (reg:P LR_REGNO))
13131 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13133 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13134 (match_operand:P 3 "memory_operand" "m"))])]
13137 [(set_attr "type" "branch")])
13139 (define_insn "*restore_gpregs_<mode>_r1"
13140 [(match_parallel 0 "any_parallel_operand"
13141 [(clobber (reg:P LR_REGNO))
13142 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13144 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13145 (match_operand:P 3 "memory_operand" "m"))])]
13148 [(set_attr "type" "branch")])
13150 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13151 [(match_parallel 0 "any_parallel_operand"
13153 (clobber (reg:P LR_REGNO))
13154 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13156 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13157 (match_operand:P 3 "memory_operand" "m"))])]
13160 [(set_attr "type" "branch")])
13162 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13163 [(match_parallel 0 "any_parallel_operand"
13165 (clobber (reg:P LR_REGNO))
13166 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13168 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13169 (match_operand:P 3 "memory_operand" "m"))])]
13172 [(set_attr "type" "branch")])
13174 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13175 [(match_parallel 0 "any_parallel_operand"
13177 (clobber (reg:P LR_REGNO))
13178 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13180 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13181 (match_operand:P 3 "memory_operand" "m"))])]
13184 [(set_attr "type" "branch")])
13186 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13187 [(match_parallel 0 "any_parallel_operand"
13189 (clobber (reg:P LR_REGNO))
13190 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13192 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13193 (match_operand:DF 3 "memory_operand" "m"))])]
13196 [(set_attr "type" "branch")])
13198 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13199 [(match_parallel 0 "any_parallel_operand"
13201 (clobber (reg:P LR_REGNO))
13202 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13204 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13205 (match_operand:DF 3 "memory_operand" "m"))])]
13208 [(set_attr "type" "branch")])
13210 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13211 [(match_parallel 0 "any_parallel_operand"
13213 (clobber (reg:P LR_REGNO))
13214 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13216 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13217 (match_operand:DF 3 "memory_operand" "m"))])]
13220 [(set_attr "type" "branch")])
13222 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13223 [(match_parallel 0 "any_parallel_operand"
13225 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13227 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13228 (match_operand:DF 3 "memory_operand" "m"))])]
13231 [(set_attr "type" "branch")])
13233 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13234 [(match_parallel 0 "any_parallel_operand"
13236 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13238 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13239 (match_operand:DF 3 "memory_operand" "m"))])]
13242 [(set_attr "type" "branch")])
13244 ; This is used in compiling the unwind routines.
13245 (define_expand "eh_return"
13246 [(use (match_operand 0 "general_operand"))]
13250 emit_insn (gen_eh_set_lr_si (operands[0]));
13252 emit_insn (gen_eh_set_lr_di (operands[0]));
13256 ; We can't expand this before we know where the link register is stored.
13257 (define_insn "eh_set_lr_<mode>"
13258 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13260 (clobber (match_scratch:P 1 "=&b"))]
13265 [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13266 (clobber (match_scratch 1))]
13270 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13274 (define_insn "prefetch"
13275 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13276 (match_operand:SI 1 "const_int_operand" "n")
13277 (match_operand:SI 2 "const_int_operand" "n"))]
13282 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13283 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13284 The AIX assembler does not support the three operand form of dcbt
13285 and dcbtst on Power 7 (-mpwr7). */
13286 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13288 if (REG_P (operands[0]))
13290 if (INTVAL (operands[1]) == 0)
13291 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13293 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13297 if (INTVAL (operands[1]) == 0)
13298 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13300 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13303 [(set_attr "type" "load")])
13305 ;; Handle -fsplit-stack.
13307 (define_expand "split_stack_prologue"
13311 rs6000_expand_split_stack_prologue ();
13315 (define_expand "load_split_stack_limit"
13316 [(set (match_operand 0)
13317 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13320 emit_insn (gen_rtx_SET (operands[0],
13321 gen_rtx_UNSPEC (Pmode,
13322 gen_rtvec (1, const0_rtx),
13323 UNSPEC_STACK_CHECK)));
13327 (define_insn "load_split_stack_limit_di"
13328 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13329 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13331 "ld %0,-0x7040(13)"
13332 [(set_attr "type" "load")
13333 (set_attr "update" "no")
13334 (set_attr "indexed" "no")])
13336 (define_insn "load_split_stack_limit_si"
13337 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13338 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13340 "lwz %0,-0x7020(2)"
13341 [(set_attr "type" "load")
13342 (set_attr "update" "no")
13343 (set_attr "indexed" "no")])
13345 ;; A return instruction which the middle-end doesn't see.
13346 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13347 ;; after the call to __morestack.
13348 (define_insn "split_stack_return"
13349 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13352 [(set_attr "type" "jmpreg")])
13354 ;; If there are operand 0 bytes available on the stack, jump to
13356 (define_expand "split_stack_space_check"
13357 [(set (match_dup 2)
13358 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13360 (minus (reg STACK_POINTER_REGNUM)
13361 (match_operand 0)))
13362 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13363 (set (pc) (if_then_else
13364 (geu (match_dup 4) (const_int 0))
13365 (label_ref (match_operand 1))
13369 rs6000_split_stack_space_check (operands[0], operands[1]);
13373 (define_insn "bpermd_<mode>"
13374 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13375 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13376 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13379 [(set_attr "type" "popcnt")])
13382 ;; Builtin fma support. Handle
13383 ;; Note that the conditions for expansion are in the FMA_F iterator.
13385 (define_expand "fma<mode>4"
13386 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13388 (match_operand:FMA_F 1 "gpc_reg_operand")
13389 (match_operand:FMA_F 2 "gpc_reg_operand")
13390 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13394 (define_insn "*fma<mode>4_fpr"
13395 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13397 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13398 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13399 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13400 "TARGET_HARD_FLOAT"
13402 fmadd<Ftrad> %0,%1,%2,%3
13403 xsmadda<Fvsx> %x0,%x1,%x2
13404 xsmaddm<Fvsx> %x0,%x1,%x3"
13405 [(set_attr "type" "fp")])
13407 ; Altivec only has fma and nfms.
13408 (define_expand "fms<mode>4"
13409 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13411 (match_operand:FMA_F 1 "gpc_reg_operand")
13412 (match_operand:FMA_F 2 "gpc_reg_operand")
13413 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13414 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13417 (define_insn "*fms<mode>4_fpr"
13418 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13420 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13421 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13422 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13423 "TARGET_HARD_FLOAT"
13425 fmsub<Ftrad> %0,%1,%2,%3
13426 xsmsuba<Fvsx> %x0,%x1,%x2
13427 xsmsubm<Fvsx> %x0,%x1,%x3"
13428 [(set_attr "type" "fp")])
13430 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13431 (define_expand "fnma<mode>4"
13432 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13435 (match_operand:FMA_F 1 "gpc_reg_operand")
13436 (match_operand:FMA_F 2 "gpc_reg_operand")
13437 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13438 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13441 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13442 (define_expand "fnms<mode>4"
13443 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13446 (match_operand:FMA_F 1 "gpc_reg_operand")
13447 (match_operand:FMA_F 2 "gpc_reg_operand")
13448 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13449 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13452 ; Not an official optab name, but used from builtins.
13453 (define_expand "nfma<mode>4"
13454 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13457 (match_operand:FMA_F 1 "gpc_reg_operand")
13458 (match_operand:FMA_F 2 "gpc_reg_operand")
13459 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13460 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13463 (define_insn "*nfma<mode>4_fpr"
13464 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13467 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13468 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13469 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13470 "TARGET_HARD_FLOAT"
13472 fnmadd<Ftrad> %0,%1,%2,%3
13473 xsnmadda<Fvsx> %x0,%x1,%x2
13474 xsnmaddm<Fvsx> %x0,%x1,%x3"
13475 [(set_attr "type" "fp")])
13477 ; Not an official optab name, but used from builtins.
13478 (define_expand "nfms<mode>4"
13479 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13482 (match_operand:FMA_F 1 "gpc_reg_operand")
13483 (match_operand:FMA_F 2 "gpc_reg_operand")
13484 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13488 (define_insn "*nfmssf4_fpr"
13489 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13492 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13493 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13495 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13496 "TARGET_HARD_FLOAT"
13498 fnmsub<Ftrad> %0,%1,%2,%3
13499 xsnmsuba<Fvsx> %x0,%x1,%x2
13500 xsnmsubm<Fvsx> %x0,%x1,%x3"
13501 [(set_attr "type" "fp")])
13504 (define_expand "rs6000_get_timebase"
13505 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13508 if (TARGET_POWERPC64)
13509 emit_insn (gen_rs6000_mftb_di (operands[0]));
13511 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13515 (define_insn "rs6000_get_timebase_ppc32"
13516 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13517 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13518 (clobber (match_scratch:SI 1 "=r"))
13519 (clobber (match_scratch:CC 2 "=y"))]
13520 "!TARGET_POWERPC64"
13522 if (WORDS_BIG_ENDIAN)
13525 return "mfspr %0,269\;"
13533 return "mftbu %0\;"
13542 return "mfspr %L0,269\;"
13550 return "mftbu %L0\;"
13557 [(set_attr "length" "20")])
13559 (define_insn "rs6000_mftb_<mode>"
13560 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13561 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13565 return "mfspr %0,268";
13571 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13572 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13573 (define_insn "rs6000_mffsl_hw"
13574 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13575 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13576 "TARGET_HARD_FLOAT"
13579 (define_expand "rs6000_mffsl"
13580 [(set (match_operand:DF 0 "gpc_reg_operand")
13581 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13582 "TARGET_HARD_FLOAT"
13584 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13585 otherwise fall back to the older mffs instruction to emulate the mffsl
13588 if (!TARGET_P9_MISC)
13590 rtx tmp_di = gen_reg_rtx (DImode);
13591 rtx tmp_df = gen_reg_rtx (DFmode);
13593 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13594 instruction using the mffs instruction and masking off the bits
13595 the mmsl instruciton actually reads. */
13596 emit_insn (gen_rs6000_mffs (tmp_df));
13597 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13598 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13600 operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13604 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13608 (define_insn "rs6000_mffs"
13609 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13610 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13611 "TARGET_HARD_FLOAT"
13614 (define_insn "rs6000_mtfsf"
13615 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13616 (match_operand:DF 1 "gpc_reg_operand" "d")]
13618 "TARGET_HARD_FLOAT"
13621 (define_insn "rs6000_mtfsf_hi"
13622 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13623 (match_operand:DF 1 "gpc_reg_operand" "d")]
13625 "TARGET_HARD_FLOAT"
13629 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13630 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13631 ;; register that is being loaded. The fused ops must be physically adjacent.
13633 ;; On Power8 GPR loads, we try to use the register that is being load. The
13634 ;; peephole2 then gathers any other fused possibilities that it can find after
13635 ;; register allocation. If power9 fusion is selected, we also fuse floating
13636 ;; point loads/stores.
13638 ;; Find cases where the addis that feeds into a load instruction is either used
13639 ;; once or is the same as the target register, and replace it with the fusion
13643 [(set (match_operand:P 0 "base_reg_operand")
13644 (match_operand:P 1 "fusion_gpr_addis"))
13645 (set (match_operand:INT1 2 "base_reg_operand")
13646 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13648 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13652 expand_fusion_gpr_load (operands);
13656 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13659 (define_insn "*fusion_gpr_load_<mode>"
13660 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13661 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13662 UNSPEC_FUSION_GPR))]
13665 return emit_fusion_gpr_load (operands[0], operands[1]);
13667 [(set_attr "type" "load")
13668 (set_attr "length" "8")])
13671 ;; Optimize cases where we want to do a D-form load (register+offset) on
13672 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13677 ;; and we change this to:
13682 [(match_scratch:P 0 "b")
13683 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13684 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13685 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13687 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13688 [(set (match_dup 0)
13693 rtx tmp_reg = operands[0];
13694 rtx mem = operands[2];
13695 rtx addr = XEXP (mem, 0);
13696 rtx add_op0, add_op1, new_addr;
13698 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13699 add_op0 = XEXP (addr, 0);
13700 add_op1 = XEXP (addr, 1);
13701 gcc_assert (REG_P (add_op0));
13702 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13704 operands[4] = add_op1;
13705 operands[5] = change_address (mem, <MODE>mode, new_addr);
13708 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13709 ;; Altivec register, and the register allocator has generated:
13713 ;; and we change this to:
13718 [(match_scratch:P 0 "b")
13719 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13720 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13721 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13723 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13724 [(set (match_dup 0)
13729 rtx tmp_reg = operands[0];
13730 rtx mem = operands[3];
13731 rtx addr = XEXP (mem, 0);
13732 rtx add_op0, add_op1, new_addr;
13734 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13735 add_op0 = XEXP (addr, 0);
13736 add_op1 = XEXP (addr, 1);
13737 gcc_assert (REG_P (add_op0));
13738 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13740 operands[4] = add_op1;
13741 operands[5] = change_address (mem, <MODE>mode, new_addr);
13745 ;; Miscellaneous ISA 2.06 (power7) instructions
13746 (define_insn "addg6s"
13747 [(set (match_operand:SI 0 "register_operand" "=r")
13748 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13749 (match_operand:SI 2 "register_operand" "r")]
13753 [(set_attr "type" "integer")])
13755 (define_insn "cdtbcd"
13756 [(set (match_operand:SI 0 "register_operand" "=r")
13757 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13761 [(set_attr "type" "integer")])
13763 (define_insn "cbcdtd"
13764 [(set (match_operand:SI 0 "register_operand" "=r")
13765 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13769 [(set_attr "type" "integer")])
13771 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13774 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13775 (UNSPEC_DIVEU "eu")])
13777 (define_insn "div<div_extend>_<mode>"
13778 [(set (match_operand:GPR 0 "register_operand" "=r")
13779 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13780 (match_operand:GPR 2 "register_operand" "r")]
13781 UNSPEC_DIV_EXTEND))]
13783 "div<wd><div_extend> %0,%1,%2"
13784 [(set_attr "type" "div")
13785 (set_attr "size" "<bits>")])
13788 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13790 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13791 (define_mode_attr FP128_64 [(TF "DF")
13796 (define_expand "unpack<mode>"
13797 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13799 [(match_operand:FMOVE128 1 "register_operand")
13800 (match_operand:QI 2 "const_0_to_1_operand")]
13801 UNSPEC_UNPACK_128BIT))]
13802 "FLOAT128_2REG_P (<MODE>mode)"
13805 (define_insn_and_split "unpack<mode>_dm"
13806 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13808 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13809 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13810 UNSPEC_UNPACK_128BIT))]
13811 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13813 "&& reload_completed"
13814 [(set (match_dup 0) (match_dup 3))]
13816 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13818 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13820 emit_note (NOTE_INSN_DELETED);
13824 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13826 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13828 (define_insn_and_split "unpack<mode>_nodm"
13829 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13831 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13832 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13833 UNSPEC_UNPACK_128BIT))]
13834 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13836 "&& reload_completed"
13837 [(set (match_dup 0) (match_dup 3))]
13839 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13841 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13843 emit_note (NOTE_INSN_DELETED);
13847 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13849 [(set_attr "type" "fp,fpstore")])
13851 (define_insn_and_split "pack<mode>"
13852 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13854 [(match_operand:<FP128_64> 1 "register_operand" "d")
13855 (match_operand:<FP128_64> 2 "register_operand" "d")]
13856 UNSPEC_PACK_128BIT))]
13857 "FLOAT128_2REG_P (<MODE>mode)"
13859 "&& reload_completed"
13860 [(set (match_dup 3) (match_dup 1))
13861 (set (match_dup 4) (match_dup 2))]
13863 unsigned dest_hi = REGNO (operands[0]);
13864 unsigned dest_lo = dest_hi + 1;
13866 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13867 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13869 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13870 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13872 [(set_attr "type" "fp")
13873 (set_attr "length" "8")])
13875 (define_insn "unpack<mode>"
13876 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13877 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13878 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13879 UNSPEC_UNPACK_128BIT))]
13880 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13882 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13883 return ASM_COMMENT_START " xxpermdi to same register";
13885 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13886 return "xxpermdi %x0,%x1,%x1,%3";
13888 [(set_attr "type" "vecperm")])
13890 (define_insn "pack<mode>"
13891 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13892 (unspec:FMOVE128_VSX
13893 [(match_operand:DI 1 "register_operand" "wa")
13894 (match_operand:DI 2 "register_operand" "wa")]
13895 UNSPEC_PACK_128BIT))]
13897 "xxpermdi %x0,%x1,%x2,0"
13898 [(set_attr "type" "vecperm")])
13902 ;; ISA 2.08 IEEE 128-bit floating point support.
13904 (define_insn "add<mode>3"
13905 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13907 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13908 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13909 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13911 [(set_attr "type" "vecfloat")
13912 (set_attr "size" "128")])
13914 (define_insn "sub<mode>3"
13915 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13917 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13918 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13919 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13921 [(set_attr "type" "vecfloat")
13922 (set_attr "size" "128")])
13924 (define_insn "mul<mode>3"
13925 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13927 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13928 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13929 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13931 [(set_attr "type" "qmul")
13932 (set_attr "size" "128")])
13934 (define_insn "div<mode>3"
13935 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13937 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13938 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13939 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13941 [(set_attr "type" "vecdiv")
13942 (set_attr "size" "128")])
13944 (define_insn "sqrt<mode>2"
13945 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13947 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13948 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13950 [(set_attr "type" "vecdiv")
13951 (set_attr "size" "128")])
13953 (define_expand "copysign<mode>3"
13954 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13955 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13956 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13957 "FLOAT128_IEEE_P (<MODE>mode)"
13959 if (TARGET_FLOAT128_HW)
13960 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13963 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13968 (define_insn "copysign<mode>3_hard"
13969 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13971 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13972 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13974 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13975 "xscpsgnqp %0,%2,%1"
13976 [(set_attr "type" "vecmove")
13977 (set_attr "size" "128")])
13979 (define_insn "copysign<mode>3_soft"
13980 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13982 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13983 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13985 (clobber (match_scratch:IEEE128 3 "=&v"))]
13986 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13987 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13988 [(set_attr "type" "veccomplex")
13989 (set_attr "length" "8")])
13991 (define_insn "neg<mode>2_hw"
13992 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13994 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13995 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13997 [(set_attr "type" "vecmove")
13998 (set_attr "size" "128")])
14001 (define_insn "abs<mode>2_hw"
14002 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14004 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14005 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14007 [(set_attr "type" "vecmove")
14008 (set_attr "size" "128")])
14011 (define_insn "*nabs<mode>2_hw"
14012 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14015 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14016 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14018 [(set_attr "type" "vecmove")
14019 (set_attr "size" "128")])
14021 ;; Initially don't worry about doing fusion
14022 (define_insn "fma<mode>4_hw"
14023 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14025 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14026 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14027 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14028 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14029 "xsmaddqp %0,%1,%2"
14030 [(set_attr "type" "qmul")
14031 (set_attr "size" "128")])
14033 (define_insn "*fms<mode>4_hw"
14034 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14036 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14037 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14039 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14040 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14041 "xsmsubqp %0,%1,%2"
14042 [(set_attr "type" "qmul")
14043 (set_attr "size" "128")])
14045 (define_insn "*nfma<mode>4_hw"
14046 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14049 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14050 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14051 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14052 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14053 "xsnmaddqp %0,%1,%2"
14054 [(set_attr "type" "qmul")
14055 (set_attr "size" "128")])
14057 (define_insn "*nfms<mode>4_hw"
14058 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14061 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14062 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14064 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14065 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14066 "xsnmsubqp %0,%1,%2"
14067 [(set_attr "type" "qmul")
14068 (set_attr "size" "128")])
14070 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14071 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14072 (float_extend:IEEE128
14073 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14074 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14076 [(set_attr "type" "vecfloat")
14077 (set_attr "size" "128")])
14079 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14080 ;; point is a simple copy.
14081 (define_insn_and_split "extendkftf2"
14082 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14083 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14084 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14088 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14091 emit_note (NOTE_INSN_DELETED);
14094 [(set_attr "type" "*,veclogical")
14095 (set_attr "length" "0,4")])
14097 (define_insn_and_split "trunctfkf2"
14098 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14099 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14100 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14104 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14107 emit_note (NOTE_INSN_DELETED);
14110 [(set_attr "type" "*,veclogical")
14111 (set_attr "length" "0,4")])
14113 (define_insn "trunc<mode>df2_hw"
14114 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14116 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14117 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14119 [(set_attr "type" "vecfloat")
14120 (set_attr "size" "128")])
14122 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14123 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14125 (define_insn_and_split "trunc<mode>sf2_hw"
14126 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14128 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14129 (clobber (match_scratch:DF 2 "=v"))]
14130 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14133 [(set (match_dup 2)
14134 (unspec:DF [(match_dup 1)]
14135 UNSPEC_TRUNC_ROUND_TO_ODD))
14137 (float_truncate:SF (match_dup 2)))]
14139 if (GET_CODE (operands[2]) == SCRATCH)
14140 operands[2] = gen_reg_rtx (DFmode);
14142 [(set_attr "type" "vecfloat")
14143 (set_attr "length" "8")])
14145 ;; Conversion between IEEE 128-bit and integer types
14147 ;; The fix function for DImode and SImode was declared earlier as a
14148 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14149 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14150 ;; unless we have the IEEE 128-bit hardware.
14152 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14153 ;; to provide a GPR target that used direct move and a conversion in the GPR
14154 ;; which works around QImode/HImode not being allowed in vector registers in
14155 ;; ISA 2.07 (power8).
14156 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14157 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14158 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14159 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14160 "xscvqp<su><wd>z %0,%1"
14161 [(set_attr "type" "vecfloat")
14162 (set_attr "size" "128")])
14164 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14165 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14167 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14168 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14169 "xscvqp<su>wz %0,%1"
14170 [(set_attr "type" "vecfloat")
14171 (set_attr "size" "128")])
14173 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14174 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14175 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14176 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14178 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14179 (clobber (match_scratch:QHSI 2 "=v"))]
14180 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14182 "&& reload_completed"
14183 [(set (match_dup 2)
14184 (any_fix:QHSI (match_dup 1)))
14188 (define_insn "float_<mode>di2_hw"
14189 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14190 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14191 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14193 [(set_attr "type" "vecfloat")
14194 (set_attr "size" "128")])
14196 (define_insn_and_split "float_<mode>si2_hw"
14197 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14198 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14199 (clobber (match_scratch:DI 2 "=v"))]
14200 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14203 [(set (match_dup 2)
14204 (sign_extend:DI (match_dup 1)))
14206 (float:IEEE128 (match_dup 2)))]
14208 if (GET_CODE (operands[2]) == SCRATCH)
14209 operands[2] = gen_reg_rtx (DImode);
14211 if (MEM_P (operands[1]))
14212 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14215 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14216 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14217 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14218 (clobber (match_scratch:DI 2 "=X,r,X"))]
14219 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14221 "&& reload_completed"
14224 rtx dest = operands[0];
14225 rtx src = operands[1];
14226 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14228 if (altivec_register_operand (src, <QHI:MODE>mode))
14229 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14230 else if (int_reg_operand (src, <QHI:MODE>mode))
14232 rtx ext_di = operands[2];
14233 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14234 emit_move_insn (dest_di, ext_di);
14236 else if (MEM_P (src))
14238 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14239 emit_move_insn (dest_qhi, src);
14240 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14243 gcc_unreachable ();
14245 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14248 [(set_attr "length" "8,12,12")
14249 (set_attr "type" "vecfloat")
14250 (set_attr "size" "128")])
14252 (define_insn "floatuns_<mode>di2_hw"
14253 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14254 (unsigned_float:IEEE128
14255 (match_operand:DI 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 (define_insn_and_split "floatuns_<mode>si2_hw"
14262 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14263 (unsigned_float:IEEE128
14264 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14265 (clobber (match_scratch:DI 2 "=v"))]
14266 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14269 [(set (match_dup 2)
14270 (zero_extend:DI (match_dup 1)))
14272 (float:IEEE128 (match_dup 2)))]
14274 if (GET_CODE (operands[2]) == SCRATCH)
14275 operands[2] = gen_reg_rtx (DImode);
14277 if (MEM_P (operands[1]))
14278 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14281 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14282 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14283 (unsigned_float:IEEE128
14284 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14285 (clobber (match_scratch:DI 2 "=X,r,X"))]
14286 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14288 "&& reload_completed"
14291 rtx dest = operands[0];
14292 rtx src = operands[1];
14293 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14295 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14296 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14297 else if (int_reg_operand (src, <QHI:MODE>mode))
14299 rtx ext_di = operands[2];
14300 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14301 emit_move_insn (dest_di, ext_di);
14304 gcc_unreachable ();
14306 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14309 [(set_attr "length" "8,12,8")
14310 (set_attr "type" "vecfloat")
14311 (set_attr "size" "128")])
14313 ;; IEEE 128-bit round to integer built-in functions
14314 (define_insn "floor<mode>2"
14315 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14317 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14319 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14321 [(set_attr "type" "vecfloat")
14322 (set_attr "size" "128")])
14324 (define_insn "ceil<mode>2"
14325 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14327 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14329 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14331 [(set_attr "type" "vecfloat")
14332 (set_attr "size" "128")])
14334 (define_insn "btrunc<mode>2"
14335 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14337 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14339 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14341 [(set_attr "type" "vecfloat")
14342 (set_attr "size" "128")])
14344 (define_insn "round<mode>2"
14345 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14347 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14349 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14351 [(set_attr "type" "vecfloat")
14352 (set_attr "size" "128")])
14354 ;; IEEE 128-bit instructions with round to odd semantics
14355 (define_insn "add<mode>3_odd"
14356 [(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")]
14360 UNSPEC_ADD_ROUND_TO_ODD))]
14361 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14362 "xsaddqpo %0,%1,%2"
14363 [(set_attr "type" "vecfloat")
14364 (set_attr "size" "128")])
14366 (define_insn "sub<mode>3_odd"
14367 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14369 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14370 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14371 UNSPEC_SUB_ROUND_TO_ODD))]
14372 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14373 "xssubqpo %0,%1,%2"
14374 [(set_attr "type" "vecfloat")
14375 (set_attr "size" "128")])
14377 (define_insn "mul<mode>3_odd"
14378 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14380 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14381 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14382 UNSPEC_MUL_ROUND_TO_ODD))]
14383 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14384 "xsmulqpo %0,%1,%2"
14385 [(set_attr "type" "qmul")
14386 (set_attr "size" "128")])
14388 (define_insn "div<mode>3_odd"
14389 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14391 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14392 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14393 UNSPEC_DIV_ROUND_TO_ODD))]
14394 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14395 "xsdivqpo %0,%1,%2"
14396 [(set_attr "type" "vecdiv")
14397 (set_attr "size" "128")])
14399 (define_insn "sqrt<mode>2_odd"
14400 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14402 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14403 UNSPEC_SQRT_ROUND_TO_ODD))]
14404 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14406 [(set_attr "type" "vecdiv")
14407 (set_attr "size" "128")])
14409 (define_insn "fma<mode>4_odd"
14410 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14412 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14413 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14414 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14415 UNSPEC_FMA_ROUND_TO_ODD))]
14416 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14417 "xsmaddqpo %0,%1,%2"
14418 [(set_attr "type" "qmul")
14419 (set_attr "size" "128")])
14421 (define_insn "*fms<mode>4_odd"
14422 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14424 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14425 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14427 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14428 UNSPEC_FMA_ROUND_TO_ODD))]
14429 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14430 "xsmsubqpo %0,%1,%2"
14431 [(set_attr "type" "qmul")
14432 (set_attr "size" "128")])
14434 (define_insn "*nfma<mode>4_odd"
14435 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14438 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14439 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14440 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14441 UNSPEC_FMA_ROUND_TO_ODD)))]
14442 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14443 "xsnmaddqpo %0,%1,%2"
14444 [(set_attr "type" "qmul")
14445 (set_attr "size" "128")])
14447 (define_insn "*nfms<mode>4_odd"
14448 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14451 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14452 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14454 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14455 UNSPEC_FMA_ROUND_TO_ODD)))]
14456 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14457 "xsnmsubqpo %0,%1,%2"
14458 [(set_attr "type" "qmul")
14459 (set_attr "size" "128")])
14461 (define_insn "trunc<mode>df2_odd"
14462 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14463 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14464 UNSPEC_TRUNC_ROUND_TO_ODD))]
14465 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14467 [(set_attr "type" "vecfloat")
14468 (set_attr "size" "128")])
14470 ;; IEEE 128-bit comparisons
14471 (define_insn "*cmp<mode>_hw"
14472 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14473 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14474 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14475 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14476 "xscmpuqp %0,%1,%2"
14477 [(set_attr "type" "veccmp")
14478 (set_attr "size" "128")])
14482 (include "sync.md")
14483 (include "vector.md")
14485 (include "altivec.md")
14487 (include "crypto.md")