1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2017 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)
55 (FRAME_POINTER_REGNUM 113)
59 (FIRST_SPE_HIGH_REGNO 117)
60 (LAST_SPE_HIGH_REGNO 148)
67 (define_c_enum "unspec"
68 [UNSPEC_FRSP ; frsp for POWER machines
69 UNSPEC_PROBE_STACK ; probe stack memory reference
70 UNSPEC_TOCPTR ; address of a word pointing to the TOC
71 UNSPEC_TOC ; address of the TOC (more-or-less)
72 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
74 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
81 UNSPEC_LD_MPIC ; load_macho_picbase
82 UNSPEC_RELD_MPIC ; re-load_macho_picbase
83 UNSPEC_MPIC_CORRECT ; macho_correct_pic
97 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
98 UNSPEC_MV_CR_GT ; move_from_CR_gt_bit
116 UNSPEC_MACHOPIC_OFFSET
130 UNSPEC_P8V_RELOAD_FROM_GPR
133 UNSPEC_P8V_RELOAD_FROM_VSX
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
160 UNSPECV_LL ; load-locked
161 UNSPECV_SC ; store-conditional
162 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
163 UNSPECV_EH_RR ; eh_reg_restore
164 UNSPECV_ISYNC ; isync instruction
165 UNSPECV_MFTB ; move from time base
166 UNSPECV_NLGR ; non-local goto receiver
167 UNSPECV_MFFS ; Move from FPSCR
168 UNSPECV_MTFSF ; Move to FPSCR Fields
169 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
173 ;; Define an insn type attribute. This is used in function unit delay
177 add,logical,shift,insert,
179 exts,cntlz,popcnt,isel,
180 load,store,fpload,fpstore,vecload,vecstore,
182 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
184 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
186 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
187 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
188 veclogical,veccmpfx,vecexts,vecmove,
190 (const_string "integer"))
192 ;; What data size does this instruction work on?
193 ;; This is used for insert, mul and others as necessary.
194 (define_attr "size" "8,16,32,64,128" (const_string "32"))
196 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
197 ;; This is used for add, logical, shift, exts, mul.
198 (define_attr "dot" "no,yes" (const_string "no"))
200 ;; Does this instruction sign-extend its result?
201 ;; This is used for load insns.
202 (define_attr "sign_extend" "no,yes" (const_string "no"))
204 ;; Does this instruction use indexed (that is, reg+reg) addressing?
205 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
206 ;; it is automatically set based on that. If a load or store instruction
207 ;; has fewer than two operands it needs to set this attribute manually
208 ;; or the compiler will crash.
209 (define_attr "indexed" "no,yes"
210 (if_then_else (ior (match_operand 0 "indexed_address_mem")
211 (match_operand 1 "indexed_address_mem"))
213 (const_string "no")))
215 ;; Does this instruction use update addressing?
216 ;; This is used for load and store insns. See the comments for "indexed".
217 (define_attr "update" "no,yes"
218 (if_then_else (ior (match_operand 0 "update_address_mem")
219 (match_operand 1 "update_address_mem"))
221 (const_string "no")))
223 ;; Is this instruction using operands[2] as shift amount, and can that be a
225 ;; This is used for shift insns.
226 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
228 ;; Is this instruction using a shift amount from a register?
229 ;; This is used for shift insns.
230 (define_attr "var_shift" "no,yes"
231 (if_then_else (and (eq_attr "type" "shift")
232 (eq_attr "maybe_var_shift" "yes"))
233 (if_then_else (match_operand 2 "gpc_reg_operand")
236 (const_string "no")))
238 ;; Is copying of this instruction disallowed?
239 (define_attr "cannot_copy" "no,yes" (const_string "no"))
241 ;; Define floating point instruction sub-types for use with Xfpu.md
242 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
244 ;; Length (in bytes).
245 ; '(pc)' in the following doesn't include the instruction itself; it is
246 ; calculated as if the instruction had zero size.
247 (define_attr "length" ""
248 (if_then_else (eq_attr "type" "branch")
249 (if_then_else (and (ge (minus (match_dup 0) (pc))
251 (lt (minus (match_dup 0) (pc))
257 ;; Processor type -- this attribute must exactly match the processor_type
258 ;; enumeration in rs6000-opts.h.
260 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
261 ppc750,ppc7400,ppc7450,
262 ppc403,ppc405,ppc440,ppc476,
263 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
264 power4,power5,power6,power7,power8,power9,
265 rs64a,mpccore,cell,ppca2,titan"
266 (const (symbol_ref "rs6000_cpu_attr")))
269 ;; If this instruction is microcoded on the CELL processor
270 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
271 (define_attr "cell_micro" "not,conditional,always"
272 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
273 (eq_attr "dot" "yes"))
274 (and (eq_attr "type" "load")
275 (eq_attr "sign_extend" "yes"))
276 (and (eq_attr "type" "shift")
277 (eq_attr "var_shift" "yes")))
278 (const_string "always")
279 (const_string "not")))
281 (automata_option "ndfa")
294 (include "e300c2c3.md")
295 (include "e500mc.md")
296 (include "e500mc64.md")
299 (include "power4.md")
300 (include "power5.md")
301 (include "power6.md")
302 (include "power7.md")
303 (include "power8.md")
304 (include "power9.md")
310 (include "predicates.md")
311 (include "constraints.md")
313 (include "darwin.md")
318 ; This mode iterator allows :GPR to be used to indicate the allowable size
319 ; of whole values in GPRs.
320 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
322 ; Any supported integer mode.
323 (define_mode_iterator INT [QI HI SI DI TI PTI])
325 ; Any supported integer mode that fits in one register.
326 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
328 ; Integer modes supported in VSX registers with ISA 3.0 instructions
329 (define_mode_iterator INT_ISA3 [QI HI SI DI])
331 ; Everything we can extend QImode to.
332 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
334 ; Everything we can extend HImode to.
335 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
337 ; Everything we can extend SImode to.
338 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
340 ; QImode or HImode for small integer moves and small atomic ops
341 (define_mode_iterator QHI [QI HI])
343 ; QImode, HImode, SImode for fused ops only for GPR loads
344 (define_mode_iterator QHSI [QI HI SI])
346 ; HImode or SImode for sign extended fusion ops
347 (define_mode_iterator HSI [HI SI])
349 ; SImode or DImode, even if DImode doesn't fit in GPRs.
350 (define_mode_iterator SDI [SI DI])
352 ; Types that can be fused with an ADDIS instruction to load or store a GPR
353 ; register that has reg+offset addressing.
354 (define_mode_iterator GPR_FUSION [QI
357 (DI "TARGET_POWERPC64")
359 (DF "TARGET_POWERPC64")])
361 ; Types that can be fused with an ADDIS instruction to load or store a FPR
362 ; register that has reg+offset addressing.
363 (define_mode_iterator FPR_FUSION [DI SF DF])
365 ; The size of a pointer. Also, the size of the value that a record-condition
366 ; (one with a '.') will compare; and the size used for arithmetic carries.
367 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
369 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
370 ; PTImode is GPR only)
371 (define_mode_iterator TI2 [TI PTI])
373 ; Any hardware-supported floating-point mode
374 (define_mode_iterator FP [
375 (SF "TARGET_HARD_FLOAT
376 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
377 (DF "TARGET_HARD_FLOAT
378 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
379 (TF "TARGET_HARD_FLOAT
380 && (TARGET_FPRS || TARGET_E500_DOUBLE)
381 && TARGET_LONG_DOUBLE_128")
382 (IF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")
383 (KF "TARGET_FLOAT128_TYPE")
387 ; Any fma capable floating-point mode.
388 (define_mode_iterator FMA_F [
389 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
390 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
391 || VECTOR_UNIT_VSX_P (DFmode)")
392 (V2SF "TARGET_PAIRED_FLOAT")
393 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
394 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
395 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
396 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
399 ; Floating point move iterators to combine binary and decimal moves
400 (define_mode_iterator FMOVE32 [SF SD])
401 (define_mode_iterator FMOVE64 [DF DD])
402 (define_mode_iterator FMOVE64X [DI DF DD])
403 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
404 (IF "FLOAT128_IBM_P (IFmode)")
405 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
407 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
408 (IF "FLOAT128_2REG_P (IFmode)")
409 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
411 ; Iterators for 128 bit types for direct move
412 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
420 (KF "FLOAT128_VECTOR_P (KFmode)")
421 (TF "FLOAT128_VECTOR_P (TFmode)")])
423 ; Iterator for 128-bit VSX types for pack/unpack
424 (define_mode_iterator FMOVE128_VSX [V1TI KF])
426 ; Whether a floating point move is ok, don't allow SD without hardware FP
427 (define_mode_attr fmove_ok [(SF "")
429 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
432 ; Convert REAL_VALUE to the appropriate bits
433 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
434 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
435 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
436 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
438 ; Whether 0.0 has an all-zero bit pattern
439 (define_mode_attr zero_fp [(SF "j")
448 ; Definitions for 64-bit VSX
449 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
451 ; Definitions for 64-bit direct move
452 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
454 ; Definitions for 64-bit use of altivec registers
455 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
457 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
458 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
460 ; These modes do not fit in integer registers in 32-bit mode.
461 ; but on e500v2, the gpr are 64 bit registers
462 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
464 ; Iterator for reciprocal estimate instructions
465 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
467 ; Iterator for just SF/DF
468 (define_mode_iterator SFDF [SF DF])
470 ; Like SFDF, but a different name to match conditional move where the
471 ; comparison operands may be a different mode than the input operands.
472 (define_mode_iterator SFDF2 [SF DF])
474 ; Iterator for 128-bit floating point that uses the IBM double-double format
475 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
476 (TF "FLOAT128_IBM_P (TFmode)")])
478 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
479 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
480 (TF "FLOAT128_IEEE_P (TFmode)")])
482 ; Iterator for 128-bit floating point
483 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
484 (IF "TARGET_FLOAT128_TYPE")
485 (TF "TARGET_LONG_DOUBLE_128")])
487 ; Iterator for signbit on 64-bit machines with direct move
488 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
489 (TF "FLOAT128_VECTOR_P (TFmode)")])
491 ; Iterator for ISA 3.0 supported floating point types
492 (define_mode_iterator FP_ISA3 [SF DF])
494 ; SF/DF suffix for traditional floating instructions
495 (define_mode_attr Ftrad [(SF "s") (DF "")])
497 ; SF/DF suffix for VSX instructions
498 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
500 ; SF/DF constraint for arithmetic on traditional floating point registers
501 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
503 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
504 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
505 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
507 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
509 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
510 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
511 ; instructions added in ISA 2.07 (power8)
512 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
514 ; SF/DF constraint for arithmetic on altivec registers
515 (define_mode_attr Fa [(SF "wu") (DF "wv")])
517 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
518 (define_mode_attr Fs [(SF "s") (DF "d")])
521 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
522 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
524 ; Conditional returns.
525 (define_code_iterator any_return [return simple_return])
526 (define_code_attr return_pred [(return "direct_return ()")
527 (simple_return "1")])
528 (define_code_attr return_str [(return "") (simple_return "simple_")])
531 (define_code_iterator iorxor [ior xor])
532 (define_code_iterator and_ior_xor [and ior xor])
534 ; Signed/unsigned variants of ops.
535 (define_code_iterator any_extend [sign_extend zero_extend])
536 (define_code_iterator any_fix [fix unsigned_fix])
537 (define_code_iterator any_float [float unsigned_float])
539 (define_code_attr u [(sign_extend "")
544 (define_code_attr su [(sign_extend "s")
549 (unsigned_float "u")])
551 (define_code_attr az [(sign_extend "a")
556 (unsigned_float "z")])
558 (define_code_attr uns [(fix "")
561 (unsigned_float "uns")])
563 ; Various instructions that come in SI and DI forms.
564 ; A generic w/d attribute, for things like cmpw/cmpd.
565 (define_mode_attr wd [(QI "b")
576 ;; How many bits in this mode?
577 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
580 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
582 ;; ISEL/ISEL64 target selection
583 (define_mode_attr sel [(SI "") (DI "64")])
585 ;; Bitmask for shift instructions
586 (define_mode_attr hH [(SI "h") (DI "H")])
588 ;; A mode twice the size of the given mode
589 (define_mode_attr dmode [(SI "di") (DI "ti")])
590 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
592 ;; Suffix for reload patterns
593 (define_mode_attr ptrsize [(SI "32bit")
596 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
597 (DI "TARGET_64BIT")])
599 (define_mode_attr mptrsize [(SI "si")
602 (define_mode_attr ptrload [(SI "lwz")
605 (define_mode_attr ptrm [(SI "m")
608 (define_mode_attr rreg [(SF "f")
615 (define_mode_attr rreg2 [(SF "f")
618 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
619 (DF "TARGET_FCFID")])
621 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
622 (DF "TARGET_E500_DOUBLE")])
624 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
625 (DF "TARGET_DOUBLE_FLOAT")])
627 ;; Mode iterator for logical operations on 128-bit types
628 (define_mode_iterator BOOL_128 [TI
630 (V16QI "TARGET_ALTIVEC")
631 (V8HI "TARGET_ALTIVEC")
632 (V4SI "TARGET_ALTIVEC")
633 (V4SF "TARGET_ALTIVEC")
634 (V2DI "TARGET_ALTIVEC")
635 (V2DF "TARGET_ALTIVEC")
636 (V1TI "TARGET_ALTIVEC")])
638 ;; For the GPRs we use 3 constraints for register outputs, two that are the
639 ;; same as the output register, and a third where the output register is an
640 ;; early clobber, so we don't have to deal with register overlaps. For the
641 ;; vector types, we prefer to use the vector registers. For TI mode, allow
644 ;; Mode attribute for boolean operation register constraints for output
645 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
647 (V16QI "wa,v,&?r,?r,?r")
648 (V8HI "wa,v,&?r,?r,?r")
649 (V4SI "wa,v,&?r,?r,?r")
650 (V4SF "wa,v,&?r,?r,?r")
651 (V2DI "wa,v,&?r,?r,?r")
652 (V2DF "wa,v,&?r,?r,?r")
653 (V1TI "wa,v,&?r,?r,?r")])
655 ;; Mode attribute for boolean operation register constraints for operand1
656 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
664 (V1TI "wa,v,r,0,r")])
666 ;; Mode attribute for boolean operation register constraints for operand2
667 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
675 (V1TI "wa,v,r,r,0")])
677 ;; Mode attribute for boolean operation register constraints for operand1
678 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
679 ;; is used for operand1 or operand2
680 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
688 (V1TI "wa,v,r,0,0")])
690 ;; Reload iterator for creating the function to allocate a base register to
691 ;; supplement addressing modes.
692 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
693 SF SD SI DF DD DI TI PTI KF IF TF])
695 ;; Iterate over smin, smax
696 (define_code_iterator fp_minmax [smin smax])
698 (define_code_attr minmax [(smin "min")
701 (define_code_attr SMINMAX [(smin "SMIN")
705 ;; Start with fixed-point load and store insns. Here we put only the more
706 ;; complex forms. Basic data transfer is done later.
708 (define_insn "zero_extendqi<mode>2"
709 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
710 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
717 [(set_attr "type" "load,shift,fpload,vecperm")])
719 (define_insn_and_split "*zero_extendqi<mode>2_dot"
720 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
721 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
723 (clobber (match_scratch:EXTQI 0 "=r,r"))]
724 "rs6000_gen_cell_microcode"
728 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
730 (zero_extend:EXTQI (match_dup 1)))
732 (compare:CC (match_dup 0)
735 [(set_attr "type" "logical")
736 (set_attr "dot" "yes")
737 (set_attr "length" "4,8")])
739 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
740 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
741 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
743 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
744 (zero_extend:EXTQI (match_dup 1)))]
745 "rs6000_gen_cell_microcode"
749 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
751 (zero_extend:EXTQI (match_dup 1)))
753 (compare:CC (match_dup 0)
756 [(set_attr "type" "logical")
757 (set_attr "dot" "yes")
758 (set_attr "length" "4,8")])
761 (define_insn "zero_extendhi<mode>2"
762 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
763 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
767 rlwinm %0,%1,0,0xffff
770 [(set_attr "type" "load,shift,fpload,vecperm")])
772 (define_insn_and_split "*zero_extendhi<mode>2_dot"
773 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
774 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
776 (clobber (match_scratch:EXTHI 0 "=r,r"))]
777 "rs6000_gen_cell_microcode"
781 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
783 (zero_extend:EXTHI (match_dup 1)))
785 (compare:CC (match_dup 0)
788 [(set_attr "type" "logical")
789 (set_attr "dot" "yes")
790 (set_attr "length" "4,8")])
792 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
793 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
794 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
796 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
797 (zero_extend:EXTHI (match_dup 1)))]
798 "rs6000_gen_cell_microcode"
802 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
804 (zero_extend:EXTHI (match_dup 1)))
806 (compare:CC (match_dup 0)
809 [(set_attr "type" "logical")
810 (set_attr "dot" "yes")
811 (set_attr "length" "4,8")])
814 (define_insn "zero_extendsi<mode>2"
815 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
816 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
825 xxextractuw %x0,%x1,4"
826 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
828 (define_insn_and_split "*zero_extendsi<mode>2_dot"
829 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
830 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
832 (clobber (match_scratch:EXTSI 0 "=r,r"))]
833 "rs6000_gen_cell_microcode"
837 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
839 (zero_extend:DI (match_dup 1)))
841 (compare:CC (match_dup 0)
844 [(set_attr "type" "shift")
845 (set_attr "dot" "yes")
846 (set_attr "length" "4,8")])
848 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
849 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
850 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
852 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
853 (zero_extend:EXTSI (match_dup 1)))]
854 "rs6000_gen_cell_microcode"
858 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
860 (zero_extend:EXTSI (match_dup 1)))
862 (compare:CC (match_dup 0)
865 [(set_attr "type" "shift")
866 (set_attr "dot" "yes")
867 (set_attr "length" "4,8")])
870 (define_insn "extendqi<mode>2"
871 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
872 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
877 [(set_attr "type" "exts,vecperm")])
879 (define_insn_and_split "*extendqi<mode>2_dot"
880 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
881 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
883 (clobber (match_scratch:EXTQI 0 "=r,r"))]
884 "rs6000_gen_cell_microcode"
888 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
890 (sign_extend:EXTQI (match_dup 1)))
892 (compare:CC (match_dup 0)
895 [(set_attr "type" "exts")
896 (set_attr "dot" "yes")
897 (set_attr "length" "4,8")])
899 (define_insn_and_split "*extendqi<mode>2_dot2"
900 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
901 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
903 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
904 (sign_extend:EXTQI (match_dup 1)))]
905 "rs6000_gen_cell_microcode"
909 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
911 (sign_extend:EXTQI (match_dup 1)))
913 (compare:CC (match_dup 0)
916 [(set_attr "type" "exts")
917 (set_attr "dot" "yes")
918 (set_attr "length" "4,8")])
921 (define_expand "extendhi<mode>2"
922 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
923 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
927 (define_insn "*extendhi<mode>2"
928 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
929 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
930 "rs6000_gen_cell_microcode || TARGET_VSX_SMALL_INTEGER"
936 [(set_attr "type" "load,exts,fpload,vecperm")
937 (set_attr "sign_extend" "yes")
938 (set_attr "length" "4,4,8,4")])
941 [(set (match_operand:EXTHI 0 "altivec_register_operand")
943 (match_operand:HI 1 "indexed_or_indirect_operand")))]
944 "TARGET_P9_VECTOR && reload_completed"
948 (sign_extend:EXTHI (match_dup 2)))]
950 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));
953 (define_insn "*extendhi<mode>2_noload"
954 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
955 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
956 "!rs6000_gen_cell_microcode"
958 [(set_attr "type" "exts")])
960 (define_insn_and_split "*extendhi<mode>2_dot"
961 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
962 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
964 (clobber (match_scratch:EXTHI 0 "=r,r"))]
965 "rs6000_gen_cell_microcode"
969 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
971 (sign_extend:EXTHI (match_dup 1)))
973 (compare:CC (match_dup 0)
976 [(set_attr "type" "exts")
977 (set_attr "dot" "yes")
978 (set_attr "length" "4,8")])
980 (define_insn_and_split "*extendhi<mode>2_dot2"
981 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
982 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
984 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
985 (sign_extend:EXTHI (match_dup 1)))]
986 "rs6000_gen_cell_microcode"
990 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
992 (sign_extend:EXTHI (match_dup 1)))
994 (compare:CC (match_dup 0)
997 [(set_attr "type" "exts")
998 (set_attr "dot" "yes")
999 (set_attr "length" "4,8")])
1002 (define_insn "extendsi<mode>2"
1003 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK,wH")
1004 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK,wH")))]
1014 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm")
1015 (set_attr "sign_extend" "yes")
1016 (set_attr "length" "4,4,4,4,4,4,8")])
1019 [(set (match_operand:DI 0 "altivec_register_operand")
1020 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1021 "TARGET_VSX_SMALL_INTEGER && TARGET_P8_VECTOR && !TARGET_P9_VECTOR
1022 && reload_completed"
1025 rtx dest = operands[0];
1026 rtx src = operands[1];
1027 int dest_regno = REGNO (dest);
1028 int src_regno = REGNO (src);
1029 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1030 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1032 if (VECTOR_ELT_ORDER_BIG)
1034 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1035 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1039 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1040 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1045 (define_insn_and_split "*extendsi<mode>2_dot"
1046 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1047 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1049 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1050 "rs6000_gen_cell_microcode"
1054 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1056 (sign_extend:EXTSI (match_dup 1)))
1058 (compare:CC (match_dup 0)
1061 [(set_attr "type" "exts")
1062 (set_attr "dot" "yes")
1063 (set_attr "length" "4,8")])
1065 (define_insn_and_split "*extendsi<mode>2_dot2"
1066 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1067 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1069 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1070 (sign_extend:EXTSI (match_dup 1)))]
1071 "rs6000_gen_cell_microcode"
1075 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1077 (sign_extend:EXTSI (match_dup 1)))
1079 (compare:CC (match_dup 0)
1082 [(set_attr "type" "exts")
1083 (set_attr "dot" "yes")
1084 (set_attr "length" "4,8")])
1086 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1088 (define_insn "*macchwc"
1089 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1090 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1091 (match_operand:SI 2 "gpc_reg_operand" "r")
1094 (match_operand:HI 1 "gpc_reg_operand" "r")))
1095 (match_operand:SI 4 "gpc_reg_operand" "0"))
1097 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1098 (plus:SI (mult:SI (ashiftrt:SI
1106 [(set_attr "type" "halfmul")])
1108 (define_insn "*macchw"
1109 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1110 (plus:SI (mult:SI (ashiftrt:SI
1111 (match_operand:SI 2 "gpc_reg_operand" "r")
1114 (match_operand:HI 1 "gpc_reg_operand" "r")))
1115 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1118 [(set_attr "type" "halfmul")])
1120 (define_insn "*macchwuc"
1121 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1122 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1123 (match_operand:SI 2 "gpc_reg_operand" "r")
1126 (match_operand:HI 1 "gpc_reg_operand" "r")))
1127 (match_operand:SI 4 "gpc_reg_operand" "0"))
1129 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1130 (plus:SI (mult:SI (lshiftrt:SI
1138 [(set_attr "type" "halfmul")])
1140 (define_insn "*macchwu"
1141 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1142 (plus:SI (mult:SI (lshiftrt:SI
1143 (match_operand:SI 2 "gpc_reg_operand" "r")
1146 (match_operand:HI 1 "gpc_reg_operand" "r")))
1147 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1150 [(set_attr "type" "halfmul")])
1152 (define_insn "*machhwc"
1153 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1154 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1155 (match_operand:SI 1 "gpc_reg_operand" "%r")
1158 (match_operand:SI 2 "gpc_reg_operand" "r")
1160 (match_operand:SI 4 "gpc_reg_operand" "0"))
1162 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1163 (plus:SI (mult:SI (ashiftrt:SI
1172 [(set_attr "type" "halfmul")])
1174 (define_insn "*machhw"
1175 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1176 (plus:SI (mult:SI (ashiftrt:SI
1177 (match_operand:SI 1 "gpc_reg_operand" "%r")
1180 (match_operand:SI 2 "gpc_reg_operand" "r")
1182 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1185 [(set_attr "type" "halfmul")])
1187 (define_insn "*machhwuc"
1188 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1189 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1190 (match_operand:SI 1 "gpc_reg_operand" "%r")
1193 (match_operand:SI 2 "gpc_reg_operand" "r")
1195 (match_operand:SI 4 "gpc_reg_operand" "0"))
1197 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1198 (plus:SI (mult:SI (lshiftrt:SI
1207 [(set_attr "type" "halfmul")])
1209 (define_insn "*machhwu"
1210 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1211 (plus:SI (mult:SI (lshiftrt:SI
1212 (match_operand:SI 1 "gpc_reg_operand" "%r")
1215 (match_operand:SI 2 "gpc_reg_operand" "r")
1217 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1220 [(set_attr "type" "halfmul")])
1222 (define_insn "*maclhwc"
1223 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1224 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1225 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1227 (match_operand:HI 2 "gpc_reg_operand" "r")))
1228 (match_operand:SI 4 "gpc_reg_operand" "0"))
1230 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1231 (plus:SI (mult:SI (sign_extend:SI
1238 [(set_attr "type" "halfmul")])
1240 (define_insn "*maclhw"
1241 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1242 (plus:SI (mult:SI (sign_extend:SI
1243 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1245 (match_operand:HI 2 "gpc_reg_operand" "r")))
1246 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1249 [(set_attr "type" "halfmul")])
1251 (define_insn "*maclhwuc"
1252 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1253 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1254 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1256 (match_operand:HI 2 "gpc_reg_operand" "r")))
1257 (match_operand:SI 4 "gpc_reg_operand" "0"))
1259 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1260 (plus:SI (mult:SI (zero_extend:SI
1267 [(set_attr "type" "halfmul")])
1269 (define_insn "*maclhwu"
1270 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1271 (plus:SI (mult:SI (zero_extend:SI
1272 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1274 (match_operand:HI 2 "gpc_reg_operand" "r")))
1275 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1278 [(set_attr "type" "halfmul")])
1280 (define_insn "*nmacchwc"
1281 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1282 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1283 (mult:SI (ashiftrt:SI
1284 (match_operand:SI 2 "gpc_reg_operand" "r")
1287 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1289 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1290 (minus:SI (match_dup 4)
1291 (mult:SI (ashiftrt:SI
1298 [(set_attr "type" "halfmul")])
1300 (define_insn "*nmacchw"
1301 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1302 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1303 (mult:SI (ashiftrt:SI
1304 (match_operand:SI 2 "gpc_reg_operand" "r")
1307 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1310 [(set_attr "type" "halfmul")])
1312 (define_insn "*nmachhwc"
1313 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1314 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1315 (mult:SI (ashiftrt:SI
1316 (match_operand:SI 1 "gpc_reg_operand" "%r")
1319 (match_operand:SI 2 "gpc_reg_operand" "r")
1322 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1323 (minus:SI (match_dup 4)
1324 (mult:SI (ashiftrt:SI
1332 [(set_attr "type" "halfmul")])
1334 (define_insn "*nmachhw"
1335 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1336 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1337 (mult:SI (ashiftrt:SI
1338 (match_operand:SI 1 "gpc_reg_operand" "%r")
1341 (match_operand:SI 2 "gpc_reg_operand" "r")
1345 [(set_attr "type" "halfmul")])
1347 (define_insn "*nmaclhwc"
1348 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1349 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1350 (mult:SI (sign_extend:SI
1351 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1353 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1355 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1356 (minus:SI (match_dup 4)
1357 (mult:SI (sign_extend:SI
1363 [(set_attr "type" "halfmul")])
1365 (define_insn "*nmaclhw"
1366 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1367 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1368 (mult:SI (sign_extend:SI
1369 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1371 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1374 [(set_attr "type" "halfmul")])
1376 (define_insn "*mulchwc"
1377 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1378 (compare:CC (mult:SI (ashiftrt:SI
1379 (match_operand:SI 2 "gpc_reg_operand" "r")
1382 (match_operand:HI 1 "gpc_reg_operand" "r")))
1384 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1385 (mult:SI (ashiftrt:SI
1392 [(set_attr "type" "halfmul")])
1394 (define_insn "*mulchw"
1395 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1396 (mult:SI (ashiftrt:SI
1397 (match_operand:SI 2 "gpc_reg_operand" "r")
1400 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1403 [(set_attr "type" "halfmul")])
1405 (define_insn "*mulchwuc"
1406 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1407 (compare:CC (mult:SI (lshiftrt:SI
1408 (match_operand:SI 2 "gpc_reg_operand" "r")
1411 (match_operand:HI 1 "gpc_reg_operand" "r")))
1413 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1414 (mult:SI (lshiftrt:SI
1421 [(set_attr "type" "halfmul")])
1423 (define_insn "*mulchwu"
1424 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1425 (mult:SI (lshiftrt:SI
1426 (match_operand:SI 2 "gpc_reg_operand" "r")
1429 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1432 [(set_attr "type" "halfmul")])
1434 (define_insn "*mulhhwc"
1435 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1436 (compare:CC (mult:SI (ashiftrt:SI
1437 (match_operand:SI 1 "gpc_reg_operand" "%r")
1440 (match_operand:SI 2 "gpc_reg_operand" "r")
1443 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1444 (mult:SI (ashiftrt:SI
1452 [(set_attr "type" "halfmul")])
1454 (define_insn "*mulhhw"
1455 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1456 (mult:SI (ashiftrt:SI
1457 (match_operand:SI 1 "gpc_reg_operand" "%r")
1460 (match_operand:SI 2 "gpc_reg_operand" "r")
1464 [(set_attr "type" "halfmul")])
1466 (define_insn "*mulhhwuc"
1467 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1468 (compare:CC (mult:SI (lshiftrt:SI
1469 (match_operand:SI 1 "gpc_reg_operand" "%r")
1472 (match_operand:SI 2 "gpc_reg_operand" "r")
1475 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1476 (mult:SI (lshiftrt:SI
1484 [(set_attr "type" "halfmul")])
1486 (define_insn "*mulhhwu"
1487 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1488 (mult:SI (lshiftrt:SI
1489 (match_operand:SI 1 "gpc_reg_operand" "%r")
1492 (match_operand:SI 2 "gpc_reg_operand" "r")
1496 [(set_attr "type" "halfmul")])
1498 (define_insn "*mullhwc"
1499 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1500 (compare:CC (mult:SI (sign_extend:SI
1501 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1503 (match_operand:HI 2 "gpc_reg_operand" "r")))
1505 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1506 (mult:SI (sign_extend:SI
1512 [(set_attr "type" "halfmul")])
1514 (define_insn "*mullhw"
1515 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1516 (mult:SI (sign_extend:SI
1517 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1519 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1522 [(set_attr "type" "halfmul")])
1524 (define_insn "*mullhwuc"
1525 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1526 (compare:CC (mult:SI (zero_extend:SI
1527 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1529 (match_operand:HI 2 "gpc_reg_operand" "r")))
1531 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1532 (mult:SI (zero_extend:SI
1538 [(set_attr "type" "halfmul")])
1540 (define_insn "*mullhwu"
1541 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1542 (mult:SI (zero_extend:SI
1543 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1545 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1548 [(set_attr "type" "halfmul")])
1550 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1551 (define_insn "dlmzb"
1552 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1553 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1554 (match_operand:SI 2 "gpc_reg_operand" "r")]
1556 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1557 (unspec:SI [(match_dup 1)
1563 (define_expand "strlensi"
1564 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1565 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1566 (match_operand:QI 2 "const_int_operand" "")
1567 (match_operand 3 "const_int_operand" "")]
1568 UNSPEC_DLMZB_STRLEN))
1569 (clobber (match_scratch:CC 4 "=x"))]
1570 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1572 rtx result = operands[0];
1573 rtx src = operands[1];
1574 rtx search_char = operands[2];
1575 rtx align = operands[3];
1576 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1577 rtx loop_label, end_label, mem, cr0, cond;
1578 if (search_char != const0_rtx
1579 || GET_CODE (align) != CONST_INT
1580 || INTVAL (align) < 8)
1582 word1 = gen_reg_rtx (SImode);
1583 word2 = gen_reg_rtx (SImode);
1584 scratch_dlmzb = gen_reg_rtx (SImode);
1585 scratch_string = gen_reg_rtx (Pmode);
1586 loop_label = gen_label_rtx ();
1587 end_label = gen_label_rtx ();
1588 addr = force_reg (Pmode, XEXP (src, 0));
1589 emit_move_insn (scratch_string, addr);
1590 emit_label (loop_label);
1591 mem = change_address (src, SImode, scratch_string);
1592 emit_move_insn (word1, mem);
1593 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1594 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1595 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1596 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1597 emit_jump_insn (gen_rtx_SET (pc_rtx,
1598 gen_rtx_IF_THEN_ELSE (VOIDmode,
1604 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1605 emit_jump_insn (gen_rtx_SET (pc_rtx,
1606 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1608 emit_label (end_label);
1609 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1610 emit_insn (gen_subsi3 (result, scratch_string, addr));
1611 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1615 ;; Fixed-point arithmetic insns.
1617 (define_expand "add<mode>3"
1618 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1619 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1620 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1623 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1625 rtx lo0 = gen_lowpart (SImode, operands[0]);
1626 rtx lo1 = gen_lowpart (SImode, operands[1]);
1627 rtx lo2 = gen_lowpart (SImode, operands[2]);
1628 rtx hi0 = gen_highpart (SImode, operands[0]);
1629 rtx hi1 = gen_highpart (SImode, operands[1]);
1630 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1632 if (!reg_or_short_operand (lo2, SImode))
1633 lo2 = force_reg (SImode, lo2);
1634 if (!adde_operand (hi2, SImode))
1635 hi2 = force_reg (SImode, hi2);
1637 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1638 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1642 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1644 rtx tmp = ((!can_create_pseudo_p ()
1645 || rtx_equal_p (operands[0], operands[1]))
1646 ? operands[0] : gen_reg_rtx (<MODE>mode));
1648 HOST_WIDE_INT val = INTVAL (operands[2]);
1649 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1650 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1652 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1655 /* The ordering here is important for the prolog expander.
1656 When space is allocated from the stack, adding 'low' first may
1657 produce a temporary deallocation (which would be bad). */
1658 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1659 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1664 (define_insn "*add<mode>3"
1665 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1666 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1667 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1673 [(set_attr "type" "add")])
1675 (define_insn "addsi3_high"
1676 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1677 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1678 (high:SI (match_operand 2 "" ""))))]
1679 "TARGET_MACHO && !TARGET_64BIT"
1680 "addis %0,%1,ha16(%2)"
1681 [(set_attr "type" "add")])
1683 (define_insn_and_split "*add<mode>3_dot"
1684 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1685 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1686 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1688 (clobber (match_scratch:GPR 0 "=r,r"))]
1689 "<MODE>mode == Pmode"
1693 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1695 (plus:GPR (match_dup 1)
1698 (compare:CC (match_dup 0)
1701 [(set_attr "type" "add")
1702 (set_attr "dot" "yes")
1703 (set_attr "length" "4,8")])
1705 (define_insn_and_split "*add<mode>3_dot2"
1706 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1707 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1708 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1710 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1711 (plus:GPR (match_dup 1)
1713 "<MODE>mode == Pmode"
1717 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1719 (plus:GPR (match_dup 1)
1722 (compare:CC (match_dup 0)
1725 [(set_attr "type" "add")
1726 (set_attr "dot" "yes")
1727 (set_attr "length" "4,8")])
1729 (define_insn_and_split "*add<mode>3_imm_dot"
1730 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1731 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1732 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1734 (clobber (match_scratch:GPR 0 "=r,r"))
1735 (clobber (reg:GPR CA_REGNO))]
1736 "<MODE>mode == Pmode"
1740 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1742 (plus:GPR (match_dup 1)
1745 (compare:CC (match_dup 0)
1748 [(set_attr "type" "add")
1749 (set_attr "dot" "yes")
1750 (set_attr "length" "4,8")])
1752 (define_insn_and_split "*add<mode>3_imm_dot2"
1753 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1754 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1755 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1757 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1758 (plus:GPR (match_dup 1)
1760 (clobber (reg:GPR CA_REGNO))]
1761 "<MODE>mode == Pmode"
1765 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1767 (plus:GPR (match_dup 1)
1770 (compare:CC (match_dup 0)
1773 [(set_attr "type" "add")
1774 (set_attr "dot" "yes")
1775 (set_attr "length" "4,8")])
1777 ;; Split an add that we can't do in one insn into two insns, each of which
1778 ;; does one 16-bit part. This is used by combine. Note that the low-order
1779 ;; add should be last in case the result gets used in an address.
1782 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1783 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1784 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1786 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1787 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1789 HOST_WIDE_INT val = INTVAL (operands[2]);
1790 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1791 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1793 operands[4] = GEN_INT (low);
1794 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1795 operands[3] = GEN_INT (rest);
1796 else if (can_create_pseudo_p ())
1798 operands[3] = gen_reg_rtx (DImode);
1799 emit_move_insn (operands[3], operands[2]);
1800 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1808 (define_insn "add<mode>3_carry"
1809 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1810 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1811 (match_operand:P 2 "reg_or_short_operand" "rI")))
1812 (set (reg:P CA_REGNO)
1813 (ltu:P (plus:P (match_dup 1)
1818 [(set_attr "type" "add")])
1820 (define_insn "*add<mode>3_imm_carry_pos"
1821 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1822 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1823 (match_operand:P 2 "short_cint_operand" "n")))
1824 (set (reg:P CA_REGNO)
1825 (geu:P (match_dup 1)
1826 (match_operand:P 3 "const_int_operand" "n")))]
1827 "INTVAL (operands[2]) > 0
1828 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1830 [(set_attr "type" "add")])
1832 (define_insn "*add<mode>3_imm_carry_0"
1833 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1834 (match_operand:P 1 "gpc_reg_operand" "r"))
1835 (set (reg:P CA_REGNO)
1839 [(set_attr "type" "add")])
1841 (define_insn "*add<mode>3_imm_carry_m1"
1842 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1843 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1845 (set (reg:P CA_REGNO)
1850 [(set_attr "type" "add")])
1852 (define_insn "*add<mode>3_imm_carry_neg"
1853 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1854 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1855 (match_operand:P 2 "short_cint_operand" "n")))
1856 (set (reg:P CA_REGNO)
1857 (gtu:P (match_dup 1)
1858 (match_operand:P 3 "const_int_operand" "n")))]
1859 "INTVAL (operands[2]) < 0
1860 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1862 [(set_attr "type" "add")])
1865 (define_expand "add<mode>3_carry_in"
1867 (set (match_operand:GPR 0 "gpc_reg_operand")
1868 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1869 (match_operand:GPR 2 "adde_operand"))
1870 (reg:GPR CA_REGNO)))
1871 (clobber (reg:GPR CA_REGNO))])]
1874 if (operands[2] == const0_rtx)
1876 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1879 if (operands[2] == constm1_rtx)
1881 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1886 (define_insn "*add<mode>3_carry_in_internal"
1887 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1888 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1889 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1890 (reg:GPR CA_REGNO)))
1891 (clobber (reg:GPR CA_REGNO))]
1894 [(set_attr "type" "add")])
1896 (define_insn "add<mode>3_carry_in_0"
1897 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1898 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1899 (reg:GPR CA_REGNO)))
1900 (clobber (reg:GPR CA_REGNO))]
1903 [(set_attr "type" "add")])
1905 (define_insn "add<mode>3_carry_in_m1"
1906 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1907 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1910 (clobber (reg:GPR CA_REGNO))]
1913 [(set_attr "type" "add")])
1916 (define_expand "one_cmpl<mode>2"
1917 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1918 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1921 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1923 rs6000_split_logical (operands, NOT, false, false, false);
1928 (define_insn "*one_cmpl<mode>2"
1929 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1930 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1934 (define_insn_and_split "*one_cmpl<mode>2_dot"
1935 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1936 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1938 (clobber (match_scratch:GPR 0 "=r,r"))]
1939 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1943 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1945 (not:GPR (match_dup 1)))
1947 (compare:CC (match_dup 0)
1950 [(set_attr "type" "logical")
1951 (set_attr "dot" "yes")
1952 (set_attr "length" "4,8")])
1954 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1955 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1956 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1958 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1959 (not:GPR (match_dup 1)))]
1960 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1964 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1966 (not:GPR (match_dup 1)))
1968 (compare:CC (match_dup 0)
1971 [(set_attr "type" "logical")
1972 (set_attr "dot" "yes")
1973 (set_attr "length" "4,8")])
1976 (define_expand "sub<mode>3"
1977 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1978 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1979 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1982 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1984 rtx lo0 = gen_lowpart (SImode, operands[0]);
1985 rtx lo1 = gen_lowpart (SImode, operands[1]);
1986 rtx lo2 = gen_lowpart (SImode, operands[2]);
1987 rtx hi0 = gen_highpart (SImode, operands[0]);
1988 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1989 rtx hi2 = gen_highpart (SImode, operands[2]);
1991 if (!reg_or_short_operand (lo1, SImode))
1992 lo1 = force_reg (SImode, lo1);
1993 if (!adde_operand (hi1, SImode))
1994 hi1 = force_reg (SImode, hi1);
1996 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1997 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2001 if (short_cint_operand (operands[1], <MODE>mode))
2003 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2008 (define_insn "*subf<mode>3"
2009 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2010 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2011 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2014 [(set_attr "type" "add")])
2016 (define_insn_and_split "*subf<mode>3_dot"
2017 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2018 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2019 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2021 (clobber (match_scratch:GPR 0 "=r,r"))]
2022 "<MODE>mode == Pmode"
2026 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2028 (minus:GPR (match_dup 2)
2031 (compare:CC (match_dup 0)
2034 [(set_attr "type" "add")
2035 (set_attr "dot" "yes")
2036 (set_attr "length" "4,8")])
2038 (define_insn_and_split "*subf<mode>3_dot2"
2039 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2040 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2041 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2043 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2044 (minus:GPR (match_dup 2)
2046 "<MODE>mode == Pmode"
2050 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2052 (minus:GPR (match_dup 2)
2055 (compare:CC (match_dup 0)
2058 [(set_attr "type" "add")
2059 (set_attr "dot" "yes")
2060 (set_attr "length" "4,8")])
2062 (define_insn "subf<mode>3_imm"
2063 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2064 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2065 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2066 (clobber (reg:GPR CA_REGNO))]
2069 [(set_attr "type" "add")])
2071 (define_insn_and_split "subf<mode>3_carry_dot2"
2072 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2073 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2074 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2076 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2077 (minus:P (match_dup 2)
2079 (set (reg:P CA_REGNO)
2080 (leu:P (match_dup 1)
2082 "<MODE>mode == Pmode"
2086 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2087 [(parallel [(set (match_dup 0)
2088 (minus:P (match_dup 2)
2090 (set (reg:P CA_REGNO)
2091 (leu:P (match_dup 1)
2094 (compare:CC (match_dup 0)
2097 [(set_attr "type" "add")
2098 (set_attr "dot" "yes")
2099 (set_attr "length" "4,8")])
2101 (define_insn "subf<mode>3_carry"
2102 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2103 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2104 (match_operand:P 1 "gpc_reg_operand" "r")))
2105 (set (reg:P CA_REGNO)
2106 (leu:P (match_dup 1)
2110 [(set_attr "type" "add")])
2112 (define_insn "*subf<mode>3_imm_carry_0"
2113 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2114 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2115 (set (reg:P CA_REGNO)
2120 [(set_attr "type" "add")])
2122 (define_insn "*subf<mode>3_imm_carry_m1"
2123 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2124 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2125 (set (reg:P CA_REGNO)
2129 [(set_attr "type" "add")])
2132 (define_expand "subf<mode>3_carry_in"
2134 (set (match_operand:GPR 0 "gpc_reg_operand")
2135 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2137 (match_operand:GPR 2 "adde_operand")))
2138 (clobber (reg:GPR CA_REGNO))])]
2141 if (operands[2] == const0_rtx)
2143 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2146 if (operands[2] == constm1_rtx)
2148 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2153 (define_insn "*subf<mode>3_carry_in_internal"
2154 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2155 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2157 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2158 (clobber (reg:GPR CA_REGNO))]
2161 [(set_attr "type" "add")])
2163 (define_insn "subf<mode>3_carry_in_0"
2164 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2165 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2166 (reg:GPR CA_REGNO)))
2167 (clobber (reg:GPR CA_REGNO))]
2170 [(set_attr "type" "add")])
2172 (define_insn "subf<mode>3_carry_in_m1"
2173 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2174 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2175 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2177 (clobber (reg:GPR CA_REGNO))]
2180 [(set_attr "type" "add")])
2182 (define_insn "subf<mode>3_carry_in_xx"
2183 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2184 (plus:GPR (reg:GPR CA_REGNO)
2186 (clobber (reg:GPR CA_REGNO))]
2189 [(set_attr "type" "add")])
2192 (define_insn "neg<mode>2"
2193 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2194 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2197 [(set_attr "type" "add")])
2199 (define_insn_and_split "*neg<mode>2_dot"
2200 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2201 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2203 (clobber (match_scratch:GPR 0 "=r,r"))]
2204 "<MODE>mode == Pmode"
2208 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2210 (neg:GPR (match_dup 1)))
2212 (compare:CC (match_dup 0)
2215 [(set_attr "type" "add")
2216 (set_attr "dot" "yes")
2217 (set_attr "length" "4,8")])
2219 (define_insn_and_split "*neg<mode>2_dot2"
2220 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2221 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2223 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2224 (neg:GPR (match_dup 1)))]
2225 "<MODE>mode == Pmode"
2229 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2231 (neg:GPR (match_dup 1)))
2233 (compare:CC (match_dup 0)
2236 [(set_attr "type" "add")
2237 (set_attr "dot" "yes")
2238 (set_attr "length" "4,8")])
2241 (define_insn "clz<mode>2"
2242 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2243 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2246 [(set_attr "type" "cntlz")])
2248 (define_expand "ctz<mode>2"
2249 [(set (match_operand:GPR 0 "gpc_reg_operand")
2250 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2255 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2259 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2260 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2261 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2265 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2266 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2267 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2268 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2272 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2273 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2274 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2275 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2281 (define_insn "ctz<mode>2_hw"
2282 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2283 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2286 [(set_attr "type" "cntlz")])
2288 (define_expand "ffs<mode>2"
2289 [(set (match_operand:GPR 0 "gpc_reg_operand")
2290 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2293 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2294 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2295 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2296 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2297 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2298 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2299 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2304 (define_expand "popcount<mode>2"
2305 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2306 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2307 "TARGET_POPCNTB || TARGET_POPCNTD"
2309 rs6000_emit_popcount (operands[0], operands[1]);
2313 (define_insn "popcntb<mode>2"
2314 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2315 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2319 [(set_attr "type" "popcnt")])
2321 (define_insn "popcntd<mode>2"
2322 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2323 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2326 [(set_attr "type" "popcnt")])
2329 (define_expand "parity<mode>2"
2330 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2331 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2334 rs6000_emit_parity (operands[0], operands[1]);
2338 (define_insn "parity<mode>2_cmpb"
2339 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2340 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2341 "TARGET_CMPB && TARGET_POPCNTB"
2343 [(set_attr "type" "popcnt")])
2345 (define_insn "cmpb<mode>3"
2346 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2347 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2348 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2351 [(set_attr "type" "cmp")])
2353 ;; Since the hardware zeros the upper part of the register, save generating the
2354 ;; AND immediate if we are converting to unsigned
2355 (define_insn "*bswap<mode>2_extenddi"
2356 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2358 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2361 [(set_attr "length" "4")
2362 (set_attr "type" "load")])
2364 (define_insn "*bswaphi2_extendsi"
2365 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2367 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2370 [(set_attr "length" "4")
2371 (set_attr "type" "load")])
2373 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2374 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2375 ;; load with byte swap, which can be slower than doing it in the registers. It
2376 ;; also prevents certain failures with the RELOAD register allocator.
2378 (define_expand "bswap<mode>2"
2379 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2380 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2383 rtx dest = operands[0];
2384 rtx src = operands[1];
2386 if (!REG_P (dest) && !REG_P (src))
2387 src = force_reg (<MODE>mode, src);
2390 emit_insn (gen_bswap<mode>2_load (dest, src));
2391 else if (MEM_P (dest))
2392 emit_insn (gen_bswap<mode>2_store (dest, src));
2394 emit_insn (gen_bswap<mode>2_reg (dest, src));
2398 (define_insn "bswap<mode>2_load"
2399 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2400 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2403 [(set_attr "type" "load")])
2405 (define_insn "bswap<mode>2_store"
2406 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2407 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2410 [(set_attr "type" "store")])
2412 (define_insn_and_split "bswaphi2_reg"
2413 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
2415 (match_operand:HI 1 "gpc_reg_operand" "r")))
2416 (clobber (match_scratch:SI 2 "=&r"))]
2421 (and:SI (lshiftrt:SI (match_dup 4)
2425 (and:SI (ashift:SI (match_dup 4)
2427 (const_int 65280))) ;; 0xff00
2429 (ior:SI (match_dup 3)
2432 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2433 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2435 [(set_attr "length" "12")
2436 (set_attr "type" "*")])
2438 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2439 ;; zero_extract insns do not change for -mlittle.
2440 (define_insn_and_split "bswapsi2_reg"
2441 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
2443 (match_operand:SI 1 "gpc_reg_operand" "r")))]
2447 [(set (match_dup 0) ; DABC
2448 (rotate:SI (match_dup 1)
2450 (set (match_dup 0) ; DCBC
2451 (ior:SI (and:SI (ashift:SI (match_dup 1)
2453 (const_int 16711680))
2454 (and:SI (match_dup 0)
2455 (const_int -16711681))))
2456 (set (match_dup 0) ; DCBA
2457 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2460 (and:SI (match_dup 0)
2461 (const_int -256))))]
2464 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2465 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2468 (define_expand "bswapdi2"
2469 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2471 (match_operand:DI 1 "reg_or_mem_operand" "")))
2472 (clobber (match_scratch:DI 2 ""))
2473 (clobber (match_scratch:DI 3 ""))])]
2476 rtx dest = operands[0];
2477 rtx src = operands[1];
2479 if (!REG_P (dest) && !REG_P (src))
2480 operands[1] = src = force_reg (DImode, src);
2482 if (TARGET_POWERPC64 && TARGET_LDBRX)
2485 emit_insn (gen_bswapdi2_load (dest, src));
2486 else if (MEM_P (dest))
2487 emit_insn (gen_bswapdi2_store (dest, src));
2489 emit_insn (gen_bswapdi2_reg (dest, src));
2493 if (!TARGET_POWERPC64)
2495 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2496 that uses 64-bit registers needs the same scratch registers as 64-bit
2498 emit_insn (gen_bswapdi2_32bit (dest, src));
2503 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2504 (define_insn "bswapdi2_load"
2505 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2506 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2507 "TARGET_POWERPC64 && TARGET_LDBRX"
2509 [(set_attr "type" "load")])
2511 (define_insn "bswapdi2_store"
2512 [(set (match_operand:DI 0 "memory_operand" "=Z")
2513 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2514 "TARGET_POWERPC64 && TARGET_LDBRX"
2516 [(set_attr "type" "store")])
2518 (define_insn "bswapdi2_reg"
2519 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2520 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2521 (clobber (match_scratch:DI 2 "=&r"))
2522 (clobber (match_scratch:DI 3 "=&r"))]
2523 "TARGET_POWERPC64 && TARGET_LDBRX"
2525 [(set_attr "length" "36")])
2527 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2528 (define_insn "*bswapdi2_64bit"
2529 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2530 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2531 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2532 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2533 "TARGET_POWERPC64 && !TARGET_LDBRX
2534 && (REG_P (operands[0]) || REG_P (operands[1]))
2535 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2536 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2538 [(set_attr "length" "16,12,36")])
2541 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2542 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2543 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2544 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2545 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2549 rtx dest = operands[0];
2550 rtx src = operands[1];
2551 rtx op2 = operands[2];
2552 rtx op3 = operands[3];
2553 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2554 BYTES_BIG_ENDIAN ? 4 : 0);
2555 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2556 BYTES_BIG_ENDIAN ? 4 : 0);
2562 addr1 = XEXP (src, 0);
2563 if (GET_CODE (addr1) == PLUS)
2565 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2566 if (TARGET_AVOID_XFORM)
2568 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2572 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2574 else if (TARGET_AVOID_XFORM)
2576 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2581 emit_move_insn (op2, GEN_INT (4));
2582 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2585 word1 = change_address (src, SImode, addr1);
2586 word2 = change_address (src, SImode, addr2);
2588 if (BYTES_BIG_ENDIAN)
2590 emit_insn (gen_bswapsi2 (op3_32, word2));
2591 emit_insn (gen_bswapsi2 (dest_32, word1));
2595 emit_insn (gen_bswapsi2 (op3_32, word1));
2596 emit_insn (gen_bswapsi2 (dest_32, word2));
2599 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2600 emit_insn (gen_iordi3 (dest, dest, op3));
2605 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2606 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2607 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2608 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2609 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2613 rtx dest = operands[0];
2614 rtx src = operands[1];
2615 rtx op2 = operands[2];
2616 rtx op3 = operands[3];
2617 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2618 BYTES_BIG_ENDIAN ? 4 : 0);
2619 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2620 BYTES_BIG_ENDIAN ? 4 : 0);
2626 addr1 = XEXP (dest, 0);
2627 if (GET_CODE (addr1) == PLUS)
2629 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2630 if (TARGET_AVOID_XFORM)
2632 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2636 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2638 else if (TARGET_AVOID_XFORM)
2640 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2645 emit_move_insn (op2, GEN_INT (4));
2646 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2649 word1 = change_address (dest, SImode, addr1);
2650 word2 = change_address (dest, SImode, addr2);
2652 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2654 if (BYTES_BIG_ENDIAN)
2656 emit_insn (gen_bswapsi2 (word1, src_si));
2657 emit_insn (gen_bswapsi2 (word2, op3_si));
2661 emit_insn (gen_bswapsi2 (word2, src_si));
2662 emit_insn (gen_bswapsi2 (word1, op3_si));
2668 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2669 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2670 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2671 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2672 "TARGET_POWERPC64 && reload_completed"
2676 rtx dest = operands[0];
2677 rtx src = operands[1];
2678 rtx op2 = operands[2];
2679 rtx op3 = operands[3];
2680 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2681 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2682 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2683 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2684 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2686 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2687 emit_insn (gen_bswapsi2 (dest_si, src_si));
2688 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2689 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2690 emit_insn (gen_iordi3 (dest, dest, op3));
2694 (define_insn "bswapdi2_32bit"
2695 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2696 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2697 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2698 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2700 [(set_attr "length" "16,12,36")])
2703 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2704 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2705 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2706 "!TARGET_POWERPC64 && reload_completed"
2710 rtx dest = operands[0];
2711 rtx src = operands[1];
2712 rtx op2 = operands[2];
2713 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2714 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2720 addr1 = XEXP (src, 0);
2721 if (GET_CODE (addr1) == PLUS)
2723 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2724 if (TARGET_AVOID_XFORM
2725 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2727 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2731 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2733 else if (TARGET_AVOID_XFORM
2734 || REGNO (addr1) == REGNO (dest2))
2736 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2741 emit_move_insn (op2, GEN_INT (4));
2742 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2745 word1 = change_address (src, SImode, addr1);
2746 word2 = change_address (src, SImode, addr2);
2748 emit_insn (gen_bswapsi2 (dest2, word1));
2749 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2750 thus allowing us to omit an early clobber on the output. */
2751 emit_insn (gen_bswapsi2 (dest1, word2));
2756 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2757 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2758 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2759 "!TARGET_POWERPC64 && reload_completed"
2763 rtx dest = operands[0];
2764 rtx src = operands[1];
2765 rtx op2 = operands[2];
2766 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2767 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2773 addr1 = XEXP (dest, 0);
2774 if (GET_CODE (addr1) == PLUS)
2776 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2777 if (TARGET_AVOID_XFORM)
2779 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2783 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2785 else if (TARGET_AVOID_XFORM)
2787 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2792 emit_move_insn (op2, GEN_INT (4));
2793 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2796 word1 = change_address (dest, SImode, addr1);
2797 word2 = change_address (dest, SImode, addr2);
2799 emit_insn (gen_bswapsi2 (word2, src1));
2800 emit_insn (gen_bswapsi2 (word1, src2));
2805 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2806 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2807 (clobber (match_operand:SI 2 "" ""))]
2808 "!TARGET_POWERPC64 && reload_completed"
2812 rtx dest = operands[0];
2813 rtx src = operands[1];
2814 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2815 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2816 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2817 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2819 emit_insn (gen_bswapsi2 (dest1, src2));
2820 emit_insn (gen_bswapsi2 (dest2, src1));
2825 (define_insn "mul<mode>3"
2826 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2827 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2828 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2833 [(set_attr "type" "mul")
2835 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2837 (match_operand:GPR 2 "short_cint_operand" "")
2838 (const_string "16")]
2839 (const_string "<bits>")))])
2841 (define_insn_and_split "*mul<mode>3_dot"
2842 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2843 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2844 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2846 (clobber (match_scratch:GPR 0 "=r,r"))]
2847 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2851 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2853 (mult:GPR (match_dup 1)
2856 (compare:CC (match_dup 0)
2859 [(set_attr "type" "mul")
2860 (set_attr "size" "<bits>")
2861 (set_attr "dot" "yes")
2862 (set_attr "length" "4,8")])
2864 (define_insn_and_split "*mul<mode>3_dot2"
2865 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2866 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2867 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2869 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2870 (mult:GPR (match_dup 1)
2872 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2876 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2878 (mult:GPR (match_dup 1)
2881 (compare:CC (match_dup 0)
2884 [(set_attr "type" "mul")
2885 (set_attr "size" "<bits>")
2886 (set_attr "dot" "yes")
2887 (set_attr "length" "4,8")])
2890 (define_expand "<su>mul<mode>3_highpart"
2891 [(set (match_operand:GPR 0 "gpc_reg_operand")
2893 (mult:<DMODE> (any_extend:<DMODE>
2894 (match_operand:GPR 1 "gpc_reg_operand"))
2896 (match_operand:GPR 2 "gpc_reg_operand")))
2900 if (<MODE>mode == SImode && TARGET_POWERPC64)
2902 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2907 if (!WORDS_BIG_ENDIAN)
2909 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2915 (define_insn "*<su>mul<mode>3_highpart"
2916 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2918 (mult:<DMODE> (any_extend:<DMODE>
2919 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2921 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2923 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2924 "mulh<wd><u> %0,%1,%2"
2925 [(set_attr "type" "mul")
2926 (set_attr "size" "<bits>")])
2928 (define_insn "<su>mulsi3_highpart_le"
2929 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2931 (mult:DI (any_extend:DI
2932 (match_operand:SI 1 "gpc_reg_operand" "r"))
2934 (match_operand:SI 2 "gpc_reg_operand" "r")))
2936 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2938 [(set_attr "type" "mul")])
2940 (define_insn "<su>muldi3_highpart_le"
2941 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2943 (mult:TI (any_extend:TI
2944 (match_operand:DI 1 "gpc_reg_operand" "r"))
2946 (match_operand:DI 2 "gpc_reg_operand" "r")))
2948 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2950 [(set_attr "type" "mul")
2951 (set_attr "size" "64")])
2953 (define_insn "<su>mulsi3_highpart_64"
2954 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2957 (mult:DI (any_extend:DI
2958 (match_operand:SI 1 "gpc_reg_operand" "r"))
2960 (match_operand:SI 2 "gpc_reg_operand" "r")))
2964 [(set_attr "type" "mul")])
2966 (define_expand "<u>mul<mode><dmode>3"
2967 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2968 (mult:<DMODE> (any_extend:<DMODE>
2969 (match_operand:GPR 1 "gpc_reg_operand"))
2971 (match_operand:GPR 2 "gpc_reg_operand"))))]
2972 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2974 rtx l = gen_reg_rtx (<MODE>mode);
2975 rtx h = gen_reg_rtx (<MODE>mode);
2976 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2977 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2978 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2979 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2983 (define_insn "*maddld4"
2984 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2985 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2986 (match_operand:DI 2 "gpc_reg_operand" "r"))
2987 (match_operand:DI 3 "gpc_reg_operand" "r")))]
2989 "maddld %0,%1,%2,%3"
2990 [(set_attr "type" "mul")])
2992 (define_insn "udiv<mode>3"
2993 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2994 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2995 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2998 [(set_attr "type" "div")
2999 (set_attr "size" "<bits>")])
3002 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3003 ;; modulus. If it isn't a power of two, force operands into register and do
3005 (define_expand "div<mode>3"
3006 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3007 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3008 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3011 if (CONST_INT_P (operands[2])
3012 && INTVAL (operands[2]) > 0
3013 && exact_log2 (INTVAL (operands[2])) >= 0)
3015 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3019 operands[2] = force_reg (<MODE>mode, operands[2]);
3022 (define_insn "*div<mode>3"
3023 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3024 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3025 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3028 [(set_attr "type" "div")
3029 (set_attr "size" "<bits>")])
3031 (define_insn "div<mode>3_sra"
3032 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3033 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3034 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3035 (clobber (reg:GPR CA_REGNO))]
3037 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3038 [(set_attr "type" "two")
3039 (set_attr "length" "8")])
3041 (define_insn_and_split "*div<mode>3_sra_dot"
3042 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3043 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3044 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3046 (clobber (match_scratch:GPR 0 "=r,r"))
3047 (clobber (reg:GPR CA_REGNO))]
3048 "<MODE>mode == Pmode"
3050 sra<wd>i %0,%1,%p2\;addze. %0,%0
3052 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3053 [(parallel [(set (match_dup 0)
3054 (div:GPR (match_dup 1)
3056 (clobber (reg:GPR CA_REGNO))])
3058 (compare:CC (match_dup 0)
3061 [(set_attr "type" "two")
3062 (set_attr "length" "8,12")
3063 (set_attr "cell_micro" "not")])
3065 (define_insn_and_split "*div<mode>3_sra_dot2"
3066 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3067 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3068 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3070 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3071 (div:GPR (match_dup 1)
3073 (clobber (reg:GPR CA_REGNO))]
3074 "<MODE>mode == Pmode"
3076 sra<wd>i %0,%1,%p2\;addze. %0,%0
3078 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3079 [(parallel [(set (match_dup 0)
3080 (div:GPR (match_dup 1)
3082 (clobber (reg:GPR CA_REGNO))])
3084 (compare:CC (match_dup 0)
3087 [(set_attr "type" "two")
3088 (set_attr "length" "8,12")
3089 (set_attr "cell_micro" "not")])
3091 (define_expand "mod<mode>3"
3092 [(set (match_operand:GPR 0 "gpc_reg_operand")
3093 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3094 (match_operand:GPR 2 "reg_or_cint_operand")))]
3101 if (GET_CODE (operands[2]) != CONST_INT
3102 || INTVAL (operands[2]) <= 0
3103 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3108 operands[2] = force_reg (<MODE>mode, operands[2]);
3112 temp1 = gen_reg_rtx (<MODE>mode);
3113 temp2 = gen_reg_rtx (<MODE>mode);
3115 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3116 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3117 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3122 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3123 ;; mod, prefer putting the result of mod into a different register
3124 (define_insn "*mod<mode>3"
3125 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3126 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3127 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3130 [(set_attr "type" "div")
3131 (set_attr "size" "<bits>")])
3134 (define_insn "umod<mode>3"
3135 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3136 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3137 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3140 [(set_attr "type" "div")
3141 (set_attr "size" "<bits>")])
3143 ;; On machines with modulo support, do a combined div/mod the old fashioned
3144 ;; method, since the multiply/subtract is faster than doing the mod instruction
3148 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3149 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3150 (match_operand:GPR 2 "gpc_reg_operand" "")))
3151 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3152 (mod:GPR (match_dup 1)
3155 && ! reg_mentioned_p (operands[0], operands[1])
3156 && ! reg_mentioned_p (operands[0], operands[2])
3157 && ! reg_mentioned_p (operands[3], operands[1])
3158 && ! reg_mentioned_p (operands[3], operands[2])"
3160 (div:GPR (match_dup 1)
3163 (mult:GPR (match_dup 0)
3166 (minus:GPR (match_dup 1)
3170 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3171 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3172 (match_operand:GPR 2 "gpc_reg_operand" "")))
3173 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3174 (umod:GPR (match_dup 1)
3177 && ! reg_mentioned_p (operands[0], operands[1])
3178 && ! reg_mentioned_p (operands[0], operands[2])
3179 && ! reg_mentioned_p (operands[3], operands[1])
3180 && ! reg_mentioned_p (operands[3], operands[2])"
3182 (udiv:GPR (match_dup 1)
3185 (mult:GPR (match_dup 0)
3188 (minus:GPR (match_dup 1)
3192 ;; Logical instructions
3193 ;; The logical instructions are mostly combined by using match_operator,
3194 ;; but the plain AND insns are somewhat different because there is no
3195 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3196 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3198 (define_expand "and<mode>3"
3199 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3200 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3201 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3204 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3206 rs6000_split_logical (operands, AND, false, false, false);
3210 if (CONST_INT_P (operands[2]))
3212 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3214 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3218 if (logical_const_operand (operands[2], <MODE>mode)
3219 && rs6000_gen_cell_microcode)
3221 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3225 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3227 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3231 operands[2] = force_reg (<MODE>mode, operands[2]);
3236 (define_insn "and<mode>3_imm"
3237 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3238 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3239 (match_operand:GPR 2 "logical_const_operand" "n")))
3240 (clobber (match_scratch:CC 3 "=x"))]
3241 "rs6000_gen_cell_microcode
3242 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3243 "andi%e2. %0,%1,%u2"
3244 [(set_attr "type" "logical")
3245 (set_attr "dot" "yes")])
3247 (define_insn_and_split "*and<mode>3_imm_dot"
3248 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3249 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3250 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3252 (clobber (match_scratch:GPR 0 "=r,r"))
3253 (clobber (match_scratch:CC 4 "=X,x"))]
3254 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3255 && rs6000_gen_cell_microcode
3256 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3260 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3261 [(parallel [(set (match_dup 0)
3262 (and:GPR (match_dup 1)
3264 (clobber (match_dup 4))])
3266 (compare:CC (match_dup 0)
3269 [(set_attr "type" "logical")
3270 (set_attr "dot" "yes")
3271 (set_attr "length" "4,8")])
3273 (define_insn_and_split "*and<mode>3_imm_dot2"
3274 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3275 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3276 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3278 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3279 (and:GPR (match_dup 1)
3281 (clobber (match_scratch:CC 4 "=X,x"))]
3282 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3283 && rs6000_gen_cell_microcode
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_mask_dot"
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 (clobber (match_scratch:GPR 0 "=r,r"))]
3307 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3308 && rs6000_gen_cell_microcode
3309 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3313 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3315 (and:GPR (match_dup 1)
3318 (compare:CC (match_dup 0)
3321 [(set_attr "type" "logical")
3322 (set_attr "dot" "yes")
3323 (set_attr "length" "4,8")])
3325 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3326 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3327 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3328 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3330 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3331 (and:GPR (match_dup 1)
3333 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3334 && rs6000_gen_cell_microcode
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<mode>3_imm_dot_shifted"
3352 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3355 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3356 (match_operand:SI 4 "const_int_operand" "n"))
3357 (match_operand:GPR 2 "const_int_operand" "n"))
3359 (clobber (match_scratch:GPR 0 "=r"))]
3360 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3361 << INTVAL (operands[4])),
3363 && (<MODE>mode == Pmode
3364 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3365 && rs6000_gen_cell_microcode"
3367 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3368 return "andi%e2. %0,%1,%u2";
3370 [(set_attr "type" "logical")
3371 (set_attr "dot" "yes")])
3374 (define_insn "and<mode>3_mask"
3375 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3376 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3377 (match_operand:GPR 2 "const_int_operand" "n")))]
3378 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3380 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3382 [(set_attr "type" "shift")])
3384 (define_insn_and_split "*and<mode>3_mask_dot"
3385 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3386 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3387 (match_operand:GPR 2 "const_int_operand" "n,n"))
3389 (clobber (match_scratch:GPR 0 "=r,r"))]
3390 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3391 && rs6000_gen_cell_microcode
3392 && !logical_const_operand (operands[2], <MODE>mode)
3393 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3395 if (which_alternative == 0)
3396 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3400 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3402 (and:GPR (match_dup 1)
3405 (compare:CC (match_dup 0)
3408 [(set_attr "type" "shift")
3409 (set_attr "dot" "yes")
3410 (set_attr "length" "4,8")])
3412 (define_insn_and_split "*and<mode>3_mask_dot2"
3413 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3414 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3415 (match_operand:GPR 2 "const_int_operand" "n,n"))
3417 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3418 (and:GPR (match_dup 1)
3420 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3421 && rs6000_gen_cell_microcode
3422 && !logical_const_operand (operands[2], <MODE>mode)
3423 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3425 if (which_alternative == 0)
3426 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3430 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3432 (and:GPR (match_dup 1)
3435 (compare:CC (match_dup 0)
3438 [(set_attr "type" "shift")
3439 (set_attr "dot" "yes")
3440 (set_attr "length" "4,8")])
3443 (define_insn_and_split "*and<mode>3_2insn"
3444 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3445 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3446 (match_operand:GPR 2 "const_int_operand" "n")))]
3447 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3448 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3449 || (logical_const_operand (operands[2], <MODE>mode)
3450 && rs6000_gen_cell_microcode))"
3455 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3458 [(set_attr "type" "shift")
3459 (set_attr "length" "8")])
3461 (define_insn_and_split "*and<mode>3_2insn_dot"
3462 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3463 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3464 (match_operand:GPR 2 "const_int_operand" "n,n"))
3466 (clobber (match_scratch:GPR 0 "=r,r"))]
3467 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3468 && rs6000_gen_cell_microcode
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)
3472 && rs6000_gen_cell_microcode))"
3474 "&& reload_completed"
3477 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3480 [(set_attr "type" "shift")
3481 (set_attr "dot" "yes")
3482 (set_attr "length" "8,12")])
3484 (define_insn_and_split "*and<mode>3_2insn_dot2"
3485 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3486 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3487 (match_operand:GPR 2 "const_int_operand" "n,n"))
3489 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3490 (and:GPR (match_dup 1)
3492 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3493 && rs6000_gen_cell_microcode
3494 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3495 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3496 || (logical_const_operand (operands[2], <MODE>mode)
3497 && rs6000_gen_cell_microcode))"
3499 "&& reload_completed"
3502 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3505 [(set_attr "type" "shift")
3506 (set_attr "dot" "yes")
3507 (set_attr "length" "8,12")])
3510 (define_expand "<code><mode>3"
3511 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3512 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3513 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3516 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3518 rs6000_split_logical (operands, <CODE>, false, false, false);
3522 if (non_logical_cint_operand (operands[2], <MODE>mode))
3524 rtx tmp = ((!can_create_pseudo_p ()
3525 || rtx_equal_p (operands[0], operands[1]))
3526 ? operands[0] : gen_reg_rtx (<MODE>mode));
3528 HOST_WIDE_INT value = INTVAL (operands[2]);
3529 HOST_WIDE_INT lo = value & 0xffff;
3530 HOST_WIDE_INT hi = value - lo;
3532 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3533 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3537 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3538 operands[2] = force_reg (<MODE>mode, operands[2]);
3542 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3543 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3544 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3547 (iorxor:GPR (match_dup 1)
3550 (iorxor:GPR (match_dup 3)
3553 operands[3] = ((!can_create_pseudo_p ()
3554 || rtx_equal_p (operands[0], operands[1]))
3555 ? operands[0] : gen_reg_rtx (<MODE>mode));
3557 HOST_WIDE_INT value = INTVAL (operands[2]);
3558 HOST_WIDE_INT lo = value & 0xffff;
3559 HOST_WIDE_INT hi = value - lo;
3561 operands[4] = GEN_INT (hi);
3562 operands[5] = GEN_INT (lo);
3565 (define_insn "*bool<mode>3_imm"
3566 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3567 (match_operator:GPR 3 "boolean_or_operator"
3568 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3569 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3572 [(set_attr "type" "logical")])
3574 (define_insn "*bool<mode>3"
3575 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3576 (match_operator:GPR 3 "boolean_operator"
3577 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3578 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3581 [(set_attr "type" "logical")])
3583 (define_insn_and_split "*bool<mode>3_dot"
3584 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3585 (compare:CC (match_operator:GPR 3 "boolean_operator"
3586 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3587 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3589 (clobber (match_scratch:GPR 0 "=r,r"))]
3590 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3594 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3598 (compare:CC (match_dup 0)
3601 [(set_attr "type" "logical")
3602 (set_attr "dot" "yes")
3603 (set_attr "length" "4,8")])
3605 (define_insn_and_split "*bool<mode>3_dot2"
3606 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3607 (compare:CC (match_operator:GPR 3 "boolean_operator"
3608 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3609 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3611 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3613 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3617 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3621 (compare:CC (match_dup 0)
3624 [(set_attr "type" "logical")
3625 (set_attr "dot" "yes")
3626 (set_attr "length" "4,8")])
3629 (define_insn "*boolc<mode>3"
3630 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3631 (match_operator:GPR 3 "boolean_operator"
3632 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3633 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3636 [(set_attr "type" "logical")])
3638 (define_insn_and_split "*boolc<mode>3_dot"
3639 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3640 (compare:CC (match_operator:GPR 3 "boolean_operator"
3641 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3642 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3644 (clobber (match_scratch:GPR 0 "=r,r"))]
3645 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3649 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3653 (compare:CC (match_dup 0)
3656 [(set_attr "type" "logical")
3657 (set_attr "dot" "yes")
3658 (set_attr "length" "4,8")])
3660 (define_insn_and_split "*boolc<mode>3_dot2"
3661 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3662 (compare:CC (match_operator:GPR 3 "boolean_operator"
3663 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3664 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3666 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3668 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3672 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3676 (compare:CC (match_dup 0)
3679 [(set_attr "type" "logical")
3680 (set_attr "dot" "yes")
3681 (set_attr "length" "4,8")])
3684 (define_insn "*boolcc<mode>3"
3685 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3686 (match_operator:GPR 3 "boolean_operator"
3687 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3688 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3691 [(set_attr "type" "logical")])
3693 (define_insn_and_split "*boolcc<mode>3_dot"
3694 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3695 (compare:CC (match_operator:GPR 3 "boolean_operator"
3696 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3697 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3699 (clobber (match_scratch:GPR 0 "=r,r"))]
3700 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3704 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3708 (compare:CC (match_dup 0)
3711 [(set_attr "type" "logical")
3712 (set_attr "dot" "yes")
3713 (set_attr "length" "4,8")])
3715 (define_insn_and_split "*boolcc<mode>3_dot2"
3716 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3717 (compare:CC (match_operator:GPR 3 "boolean_operator"
3718 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3719 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3721 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3723 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3727 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3731 (compare:CC (match_dup 0)
3734 [(set_attr "type" "logical")
3735 (set_attr "dot" "yes")
3736 (set_attr "length" "4,8")])
3739 ;; TODO: Should have dots of this as well.
3740 (define_insn "*eqv<mode>3"
3741 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3742 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3743 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3746 [(set_attr "type" "logical")])
3748 ;; Rotate-and-mask and insert.
3750 (define_insn "*rotl<mode>3_mask"
3751 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3752 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3753 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3754 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3755 (match_operand:GPR 3 "const_int_operand" "n")))]
3756 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3758 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3760 [(set_attr "type" "shift")
3761 (set_attr "maybe_var_shift" "yes")])
3763 (define_insn_and_split "*rotl<mode>3_mask_dot"
3764 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3766 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3767 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3768 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3769 (match_operand:GPR 3 "const_int_operand" "n,n"))
3771 (clobber (match_scratch:GPR 0 "=r,r"))]
3772 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3773 && rs6000_gen_cell_microcode
3774 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3776 if (which_alternative == 0)
3777 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3781 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3783 (and:GPR (match_dup 4)
3786 (compare:CC (match_dup 0)
3789 [(set_attr "type" "shift")
3790 (set_attr "maybe_var_shift" "yes")
3791 (set_attr "dot" "yes")
3792 (set_attr "length" "4,8")])
3794 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3795 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3797 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3798 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3799 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3800 (match_operand:GPR 3 "const_int_operand" "n,n"))
3802 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3803 (and:GPR (match_dup 4)
3805 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3806 && rs6000_gen_cell_microcode
3807 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3809 if (which_alternative == 0)
3810 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3814 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3816 (and:GPR (match_dup 4)
3819 (compare:CC (match_dup 0)
3822 [(set_attr "type" "shift")
3823 (set_attr "maybe_var_shift" "yes")
3824 (set_attr "dot" "yes")
3825 (set_attr "length" "4,8")])
3827 ; Special case for less-than-0. We can do it with just one machine
3828 ; instruction, but the generic optimizers do not realise it is cheap.
3829 (define_insn "*lt0_disi"
3830 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3831 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3834 "rlwinm %0,%1,1,31,31"
3835 [(set_attr "type" "shift")])
3839 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3840 ; both are an AND so are the same precedence).
3841 (define_insn "*rotl<mode>3_insert"
3842 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3843 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3844 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3845 (match_operand:SI 2 "const_int_operand" "n")])
3846 (match_operand:GPR 3 "const_int_operand" "n"))
3847 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3848 (match_operand:GPR 6 "const_int_operand" "n"))))]
3849 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3850 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3852 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3854 [(set_attr "type" "insert")])
3855 ; FIXME: this needs an attr "size", so that the scheduler can see the
3856 ; difference between rlwimi and rldimi. We also might want dot forms,
3857 ; but not for rlwimi on POWER4 and similar processors.
3859 (define_insn "*rotl<mode>3_insert_2"
3860 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3861 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3862 (match_operand:GPR 6 "const_int_operand" "n"))
3863 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3864 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3865 (match_operand:SI 2 "const_int_operand" "n")])
3866 (match_operand:GPR 3 "const_int_operand" "n"))))]
3867 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3868 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3870 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3872 [(set_attr "type" "insert")])
3874 ; There are also some forms without one of the ANDs.
3875 (define_insn "*rotl<mode>3_insert_3"
3876 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3877 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3878 (match_operand:GPR 4 "const_int_operand" "n"))
3879 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3880 (match_operand:SI 2 "const_int_operand" "n"))))]
3881 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3883 if (<MODE>mode == SImode)
3884 return "rlwimi %0,%1,%h2,0,31-%h2";
3886 return "rldimi %0,%1,%H2,0";
3888 [(set_attr "type" "insert")])
3890 (define_insn "*rotl<mode>3_insert_4"
3891 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3892 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3893 (match_operand:GPR 4 "const_int_operand" "n"))
3894 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3895 (match_operand:SI 2 "const_int_operand" "n"))))]
3896 "<MODE>mode == SImode &&
3897 GET_MODE_PRECISION (<MODE>mode)
3898 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3900 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3901 - INTVAL (operands[2]));
3902 if (<MODE>mode == SImode)
3903 return "rlwimi %0,%1,%h2,32-%h2,31";
3905 return "rldimi %0,%1,%H2,64-%H2";
3907 [(set_attr "type" "insert")])
3909 (define_insn "*rotlsi3_insert_5"
3910 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3911 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3912 (match_operand:SI 2 "const_int_operand" "n,n"))
3913 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3914 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3915 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3916 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3917 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3921 [(set_attr "type" "insert")])
3923 (define_insn "*rotldi3_insert_6"
3924 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3925 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3926 (match_operand:DI 2 "const_int_operand" "n"))
3927 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3928 (match_operand:DI 4 "const_int_operand" "n"))))]
3929 "exact_log2 (-UINTVAL (operands[2])) > 0
3930 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3932 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3933 return "rldimi %0,%3,0,%5";
3935 [(set_attr "type" "insert")
3936 (set_attr "size" "64")])
3938 (define_insn "*rotldi3_insert_7"
3939 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3940 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3941 (match_operand:DI 4 "const_int_operand" "n"))
3942 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3943 (match_operand:DI 2 "const_int_operand" "n"))))]
3944 "exact_log2 (-UINTVAL (operands[2])) > 0
3945 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3947 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3948 return "rldimi %0,%3,0,%5";
3950 [(set_attr "type" "insert")
3951 (set_attr "size" "64")])
3954 ; This handles the important case of multiple-precision shifts. There is
3955 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3957 [(set (match_operand:GPR 0 "gpc_reg_operand")
3958 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3959 (match_operand:SI 3 "const_int_operand"))
3960 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3961 (match_operand:SI 4 "const_int_operand"))))]
3962 "can_create_pseudo_p ()
3963 && INTVAL (operands[3]) + INTVAL (operands[4])
3964 >= GET_MODE_PRECISION (<MODE>mode)"
3966 (lshiftrt:GPR (match_dup 2)
3969 (ior:GPR (and:GPR (match_dup 5)
3971 (ashift:GPR (match_dup 1)
3974 unsigned HOST_WIDE_INT mask = 1;
3975 mask = (mask << INTVAL (operands[3])) - 1;
3976 operands[5] = gen_reg_rtx (<MODE>mode);
3977 operands[6] = GEN_INT (mask);
3981 [(set (match_operand:GPR 0 "gpc_reg_operand")
3982 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3983 (match_operand:SI 4 "const_int_operand"))
3984 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3985 (match_operand:SI 3 "const_int_operand"))))]
3986 "can_create_pseudo_p ()
3987 && INTVAL (operands[3]) + INTVAL (operands[4])
3988 >= GET_MODE_PRECISION (<MODE>mode)"
3990 (lshiftrt:GPR (match_dup 2)
3993 (ior:GPR (and:GPR (match_dup 5)
3995 (ashift:GPR (match_dup 1)
3998 unsigned HOST_WIDE_INT mask = 1;
3999 mask = (mask << INTVAL (operands[3])) - 1;
4000 operands[5] = gen_reg_rtx (<MODE>mode);
4001 operands[6] = GEN_INT (mask);
4005 ; Another important case is setting some bits to 1; we can do that with
4006 ; an insert instruction, in many cases.
4007 (define_insn_and_split "*ior<mode>_mask"
4008 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4009 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4010 (match_operand:GPR 2 "const_int_operand" "n")))
4011 (clobber (match_scratch:GPR 3 "=r"))]
4012 "!logical_const_operand (operands[2], <MODE>mode)
4013 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4019 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4022 (and:GPR (match_dup 1)
4026 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4027 if (GET_CODE (operands[3]) == SCRATCH)
4028 operands[3] = gen_reg_rtx (<MODE>mode);
4029 operands[4] = GEN_INT (ne);
4030 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4032 [(set_attr "type" "two")
4033 (set_attr "length" "8")])
4036 ;; Now the simple shifts.
4038 (define_insn "rotl<mode>3"
4039 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4040 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4041 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4043 "rotl<wd>%I2 %0,%1,%<hH>2"
4044 [(set_attr "type" "shift")
4045 (set_attr "maybe_var_shift" "yes")])
4047 (define_insn "*rotlsi3_64"
4048 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4050 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4051 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4053 "rotlw%I2 %0,%1,%h2"
4054 [(set_attr "type" "shift")
4055 (set_attr "maybe_var_shift" "yes")])
4057 (define_insn_and_split "*rotl<mode>3_dot"
4058 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4059 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4060 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4062 (clobber (match_scratch:GPR 0 "=r,r"))]
4063 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4065 rotl<wd>%I2. %0,%1,%<hH>2
4067 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4069 (rotate:GPR (match_dup 1)
4072 (compare:CC (match_dup 0)
4075 [(set_attr "type" "shift")
4076 (set_attr "maybe_var_shift" "yes")
4077 (set_attr "dot" "yes")
4078 (set_attr "length" "4,8")])
4080 (define_insn_and_split "*rotl<mode>3_dot2"
4081 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4082 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4083 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4085 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4086 (rotate:GPR (match_dup 1)
4088 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4090 rotl<wd>%I2. %0,%1,%<hH>2
4092 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4094 (rotate:GPR (match_dup 1)
4097 (compare:CC (match_dup 0)
4100 [(set_attr "type" "shift")
4101 (set_attr "maybe_var_shift" "yes")
4102 (set_attr "dot" "yes")
4103 (set_attr "length" "4,8")])
4106 (define_insn "ashl<mode>3"
4107 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4108 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4109 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4111 "sl<wd>%I2 %0,%1,%<hH>2"
4112 [(set_attr "type" "shift")
4113 (set_attr "maybe_var_shift" "yes")])
4115 (define_insn "*ashlsi3_64"
4116 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4118 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4119 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4122 [(set_attr "type" "shift")
4123 (set_attr "maybe_var_shift" "yes")])
4125 (define_insn_and_split "*ashl<mode>3_dot"
4126 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4127 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4128 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4130 (clobber (match_scratch:GPR 0 "=r,r"))]
4131 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4133 sl<wd>%I2. %0,%1,%<hH>2
4135 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4137 (ashift:GPR (match_dup 1)
4140 (compare:CC (match_dup 0)
4143 [(set_attr "type" "shift")
4144 (set_attr "maybe_var_shift" "yes")
4145 (set_attr "dot" "yes")
4146 (set_attr "length" "4,8")])
4148 (define_insn_and_split "*ashl<mode>3_dot2"
4149 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4150 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4151 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4153 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4154 (ashift:GPR (match_dup 1)
4156 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4158 sl<wd>%I2. %0,%1,%<hH>2
4160 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4162 (ashift:GPR (match_dup 1)
4165 (compare:CC (match_dup 0)
4168 [(set_attr "type" "shift")
4169 (set_attr "maybe_var_shift" "yes")
4170 (set_attr "dot" "yes")
4171 (set_attr "length" "4,8")])
4173 ;; Pretend we have a memory form of extswsli until register allocation is done
4174 ;; so that we use LWZ to load the value from memory, instead of LWA.
4175 (define_insn_and_split "ashdi3_extswsli"
4176 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4178 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4179 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4184 "&& reload_completed && MEM_P (operands[1])"
4188 (ashift:DI (sign_extend:DI (match_dup 3))
4191 operands[3] = gen_lowpart (SImode, operands[0]);
4193 [(set_attr "type" "shift")
4194 (set_attr "maybe_var_shift" "no")])
4197 (define_insn_and_split "ashdi3_extswsli_dot"
4198 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4201 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4202 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4204 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4211 "&& reload_completed
4212 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4213 || memory_operand (operands[1], SImode))"
4216 rtx dest = operands[0];
4217 rtx src = operands[1];
4218 rtx shift = operands[2];
4219 rtx cr = operands[3];
4226 src2 = gen_lowpart (SImode, dest);
4227 emit_move_insn (src2, src);
4230 if (REGNO (cr) == CR0_REGNO)
4232 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4236 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4237 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4240 [(set_attr "type" "shift")
4241 (set_attr "maybe_var_shift" "no")
4242 (set_attr "dot" "yes")
4243 (set_attr "length" "4,8,8,12")])
4245 (define_insn_and_split "ashdi3_extswsli_dot2"
4246 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4249 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4250 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4252 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4253 (ashift:DI (sign_extend:DI (match_dup 1))
4261 "&& reload_completed
4262 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4263 || memory_operand (operands[1], SImode))"
4266 rtx dest = operands[0];
4267 rtx src = operands[1];
4268 rtx shift = operands[2];
4269 rtx cr = operands[3];
4276 src2 = gen_lowpart (SImode, dest);
4277 emit_move_insn (src2, src);
4280 if (REGNO (cr) == CR0_REGNO)
4282 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4286 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4287 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4290 [(set_attr "type" "shift")
4291 (set_attr "maybe_var_shift" "no")
4292 (set_attr "dot" "yes")
4293 (set_attr "length" "4,8,8,12")])
4295 (define_insn "lshr<mode>3"
4296 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4297 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4298 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4300 "sr<wd>%I2 %0,%1,%<hH>2"
4301 [(set_attr "type" "shift")
4302 (set_attr "maybe_var_shift" "yes")])
4304 (define_insn "*lshrsi3_64"
4305 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4307 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4308 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4311 [(set_attr "type" "shift")
4312 (set_attr "maybe_var_shift" "yes")])
4314 (define_insn_and_split "*lshr<mode>3_dot"
4315 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4316 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4317 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4319 (clobber (match_scratch:GPR 0 "=r,r"))]
4320 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4322 sr<wd>%I2. %0,%1,%<hH>2
4324 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4326 (lshiftrt:GPR (match_dup 1)
4329 (compare:CC (match_dup 0)
4332 [(set_attr "type" "shift")
4333 (set_attr "maybe_var_shift" "yes")
4334 (set_attr "dot" "yes")
4335 (set_attr "length" "4,8")])
4337 (define_insn_and_split "*lshr<mode>3_dot2"
4338 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4339 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4340 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4342 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4343 (lshiftrt:GPR (match_dup 1)
4345 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4347 sr<wd>%I2. %0,%1,%<hH>2
4349 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4351 (lshiftrt:GPR (match_dup 1)
4354 (compare:CC (match_dup 0)
4357 [(set_attr "type" "shift")
4358 (set_attr "maybe_var_shift" "yes")
4359 (set_attr "dot" "yes")
4360 (set_attr "length" "4,8")])
4363 (define_insn "ashr<mode>3"
4364 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4365 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4366 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4367 (clobber (reg:GPR CA_REGNO))]
4369 "sra<wd>%I2 %0,%1,%<hH>2"
4370 [(set_attr "type" "shift")
4371 (set_attr "maybe_var_shift" "yes")])
4373 (define_insn "*ashrsi3_64"
4374 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4376 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4377 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4378 (clobber (reg:SI CA_REGNO))]
4381 [(set_attr "type" "shift")
4382 (set_attr "maybe_var_shift" "yes")])
4384 (define_insn_and_split "*ashr<mode>3_dot"
4385 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4386 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4387 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4389 (clobber (match_scratch:GPR 0 "=r,r"))
4390 (clobber (reg:GPR CA_REGNO))]
4391 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4393 sra<wd>%I2. %0,%1,%<hH>2
4395 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4396 [(parallel [(set (match_dup 0)
4397 (ashiftrt:GPR (match_dup 1)
4399 (clobber (reg:GPR CA_REGNO))])
4401 (compare:CC (match_dup 0)
4404 [(set_attr "type" "shift")
4405 (set_attr "maybe_var_shift" "yes")
4406 (set_attr "dot" "yes")
4407 (set_attr "length" "4,8")])
4409 (define_insn_and_split "*ashr<mode>3_dot2"
4410 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4411 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4412 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4414 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4415 (ashiftrt:GPR (match_dup 1)
4417 (clobber (reg:GPR CA_REGNO))]
4418 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4420 sra<wd>%I2. %0,%1,%<hH>2
4422 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4423 [(parallel [(set (match_dup 0)
4424 (ashiftrt:GPR (match_dup 1)
4426 (clobber (reg:GPR CA_REGNO))])
4428 (compare:CC (match_dup 0)
4431 [(set_attr "type" "shift")
4432 (set_attr "maybe_var_shift" "yes")
4433 (set_attr "dot" "yes")
4434 (set_attr "length" "4,8")])
4436 ;; Builtins to replace a division to generate FRE reciprocal estimate
4437 ;; instructions and the necessary fixup instructions
4438 (define_expand "recip<mode>3"
4439 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4440 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4441 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4442 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4444 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4448 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4449 ;; hardware division. This is only done before register allocation and with
4450 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4451 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4452 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4454 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4455 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4456 (match_operand 2 "gpc_reg_operand" "")))]
4457 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4458 && can_create_pseudo_p () && flag_finite_math_only
4459 && !flag_trapping_math && flag_reciprocal_math"
4462 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4466 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4467 ;; appropriate fixup.
4468 (define_expand "rsqrt<mode>2"
4469 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4470 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4471 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4473 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4477 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4478 ;; modes here, and also add in conditional vsx/power8-vector support to access
4479 ;; values in the traditional Altivec registers if the appropriate
4480 ;; -mupper-regs-{df,sf} option is enabled.
4482 (define_expand "abs<mode>2"
4483 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4484 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4485 "TARGET_<MODE>_INSN"
4488 (define_insn "*abs<mode>2_fpr"
4489 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4490 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4495 [(set_attr "type" "fpsimple")
4496 (set_attr "fp_type" "fp_addsub_<Fs>")])
4498 (define_insn "*nabs<mode>2_fpr"
4499 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4502 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4507 [(set_attr "type" "fpsimple")
4508 (set_attr "fp_type" "fp_addsub_<Fs>")])
4510 (define_expand "neg<mode>2"
4511 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4512 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4513 "TARGET_<MODE>_INSN"
4516 (define_insn "*neg<mode>2_fpr"
4517 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4518 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4523 [(set_attr "type" "fpsimple")
4524 (set_attr "fp_type" "fp_addsub_<Fs>")])
4526 (define_expand "add<mode>3"
4527 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4528 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4529 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4530 "TARGET_<MODE>_INSN"
4533 (define_insn "*add<mode>3_fpr"
4534 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4535 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4536 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4539 fadd<Ftrad> %0,%1,%2
4540 xsadd<Fvsx> %x0,%x1,%x2"
4541 [(set_attr "type" "fp")
4542 (set_attr "fp_type" "fp_addsub_<Fs>")])
4544 (define_expand "sub<mode>3"
4545 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4546 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4547 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4548 "TARGET_<MODE>_INSN"
4551 (define_insn "*sub<mode>3_fpr"
4552 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4553 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4554 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4557 fsub<Ftrad> %0,%1,%2
4558 xssub<Fvsx> %x0,%x1,%x2"
4559 [(set_attr "type" "fp")
4560 (set_attr "fp_type" "fp_addsub_<Fs>")])
4562 (define_expand "mul<mode>3"
4563 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4564 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4565 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4566 "TARGET_<MODE>_INSN"
4569 (define_insn "*mul<mode>3_fpr"
4570 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4571 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4572 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4575 fmul<Ftrad> %0,%1,%2
4576 xsmul<Fvsx> %x0,%x1,%x2"
4577 [(set_attr "type" "dmul")
4578 (set_attr "fp_type" "fp_mul_<Fs>")])
4580 (define_expand "div<mode>3"
4581 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4582 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4583 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4584 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4586 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4587 && can_create_pseudo_p () && flag_finite_math_only
4588 && !flag_trapping_math && flag_reciprocal_math)
4590 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4595 (define_insn "*div<mode>3_fpr"
4596 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4597 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4598 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4599 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4601 fdiv<Ftrad> %0,%1,%2
4602 xsdiv<Fvsx> %x0,%x1,%x2"
4603 [(set_attr "type" "<Fs>div")
4604 (set_attr "fp_type" "fp_div_<Fs>")])
4606 (define_insn "*sqrt<mode>2_internal"
4607 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4608 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4609 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4610 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4613 xssqrt<Fvsx> %x0,%x1"
4614 [(set_attr "type" "<Fs>sqrt")
4615 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4617 (define_expand "sqrt<mode>2"
4618 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4619 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4620 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4621 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4623 if (<MODE>mode == SFmode
4624 && TARGET_RECIP_PRECISION
4625 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4626 && !optimize_function_for_size_p (cfun)
4627 && flag_finite_math_only && !flag_trapping_math
4628 && flag_unsafe_math_optimizations)
4630 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4635 ;; Floating point reciprocal approximation
4636 (define_insn "fre<Fs>"
4637 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4638 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4644 [(set_attr "type" "fp")])
4646 (define_insn "*rsqrt<mode>2"
4647 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4648 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4650 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4652 frsqrte<Ftrad> %0,%1
4653 xsrsqrte<Fvsx> %x0,%x1"
4654 [(set_attr "type" "fp")])
4656 ;; Floating point comparisons
4657 (define_insn "*cmp<mode>_fpr"
4658 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4659 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4660 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4664 xscmpudp %0,%x1,%x2"
4665 [(set_attr "type" "fpcompare")])
4667 ;; Floating point conversions
4668 (define_expand "extendsfdf2"
4669 [(set (match_operand:DF 0 "gpc_reg_operand")
4670 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand")))]
4671 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4673 if (HONOR_SNANS (SFmode))
4674 operands[1] = force_reg (SFmode, operands[1]);
4677 (define_insn_and_split "*extendsfdf2_fpr"
4678 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4679 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4680 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4681 && !HONOR_SNANS (SFmode)"
4687 xscpsgndp %x0,%x1,%x1
4690 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4693 emit_note (NOTE_INSN_DELETED);
4696 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4698 (define_insn "*extendsfdf2_snan"
4699 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4700 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4701 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4702 && HONOR_SNANS (SFmode)"
4706 [(set_attr "type" "fp")])
4708 (define_expand "truncdfsf2"
4709 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4710 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4711 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4714 (define_insn "*truncdfsf2_fpr"
4715 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4716 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4717 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4721 [(set_attr "type" "fp")])
4723 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4724 ;; builtins.c and optabs.c that are not correct for IBM long double
4725 ;; when little-endian.
4726 (define_expand "signbit<mode>2"
4728 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4730 (subreg:DI (match_dup 2) 0))
4733 (set (match_operand:SI 0 "gpc_reg_operand" "")
4736 && (TARGET_FPRS || TARGET_E500_DOUBLE)
4737 && (!FLOAT128_IEEE_P (<MODE>mode)
4738 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4740 if (FLOAT128_IEEE_P (<MODE>mode))
4742 if (<MODE>mode == KFmode)
4743 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4744 else if (<MODE>mode == TFmode)
4745 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4750 operands[2] = gen_reg_rtx (DFmode);
4751 operands[3] = gen_reg_rtx (DImode);
4752 if (TARGET_POWERPC64)
4754 operands[4] = gen_reg_rtx (DImode);
4755 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4756 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4757 WORDS_BIG_ENDIAN ? 4 : 0);
4761 operands[4] = gen_reg_rtx (SImode);
4762 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4763 WORDS_BIG_ENDIAN ? 0 : 4);
4764 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4768 (define_expand "copysign<mode>3"
4770 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4772 (neg:SFDF (abs:SFDF (match_dup 1))))
4773 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4774 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4778 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4779 && ((TARGET_PPC_GFXOPT
4780 && !HONOR_NANS (<MODE>mode)
4781 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4783 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4785 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4787 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4792 operands[3] = gen_reg_rtx (<MODE>mode);
4793 operands[4] = gen_reg_rtx (<MODE>mode);
4794 operands[5] = CONST0_RTX (<MODE>mode);
4797 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4799 (define_insn_and_split "signbit<mode>2_dm"
4800 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4802 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4804 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4806 "&& reload_completed"
4809 rs6000_split_signbit (operands[0], operands[1]);
4812 [(set_attr "length" "8,8,4")
4813 (set_attr "type" "mftgpr,load,integer")])
4815 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4816 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4819 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4821 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4823 "&& reload_completed"
4826 rs6000_split_signbit (operands[0], operands[1]);
4829 [(set_attr "length" "8,8,4")
4830 (set_attr "type" "mftgpr,load,integer")])
4832 ;; MODES_TIEABLE_P doesn't allow DImode to be tied with the various floating
4833 ;; point types, which makes normal SUBREG's problematical. Instead use a
4834 ;; special pattern to avoid using a normal movdi.
4835 (define_insn "signbit<mode>2_dm2"
4836 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4837 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4840 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4842 [(set_attr "type" "mftgpr")])
4845 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4846 ;; compiler from optimizing -0.0
4847 (define_insn "copysign<mode>3_fcpsgn"
4848 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4849 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4850 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4852 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4855 xscpsgndp %x0,%x2,%x1"
4856 [(set_attr "type" "fpsimple")])
4858 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4859 ;; fsel instruction and some auxiliary computations. Then we just have a
4860 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4862 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4863 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4864 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4865 ;; define_splits to make them if made by combine. On VSX machines we have the
4866 ;; min/max instructions.
4868 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4869 ;; to allow either DF/SF to use only traditional registers.
4871 (define_expand "s<minmax><mode>3"
4872 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4873 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4874 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4875 "TARGET_MINMAX_<MODE>"
4877 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4881 (define_insn "*s<minmax><mode>3_vsx"
4882 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4883 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4884 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4885 "TARGET_VSX && TARGET_<MODE>_FPR"
4887 return (TARGET_P9_MINMAX
4888 ? "xs<minmax>cdp %x0,%x1,%x2"
4889 : "xs<minmax>dp %x0,%x1,%x2");
4891 [(set_attr "type" "fp")])
4893 ;; The conditional move instructions allow us to perform max and min operations
4894 ;; even when we don't have the appropriate max/min instruction using the FSEL
4897 (define_insn_and_split "*s<minmax><mode>3_fpr"
4898 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4899 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4900 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4901 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4906 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4910 (define_expand "mov<mode>cc"
4911 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4912 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4913 (match_operand:GPR 2 "gpc_reg_operand" "")
4914 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4918 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4924 ;; We use the BASE_REGS for the isel input operands because, if rA is
4925 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4926 ;; because we may switch the operands and rB may end up being rA.
4928 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4929 ;; leave out the mode in operand 4 and use one pattern, but reload can
4930 ;; change the mode underneath our feet and then gets confused trying
4931 ;; to reload the value.
4932 (define_insn "isel_signed_<mode>"
4933 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4935 (match_operator 1 "scc_comparison_operator"
4936 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4938 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4939 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4942 { return output_isel (operands); }"
4943 [(set_attr "type" "isel")
4944 (set_attr "length" "4")])
4946 (define_insn "isel_unsigned_<mode>"
4947 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4949 (match_operator 1 "scc_comparison_operator"
4950 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4952 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4953 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4956 { return output_isel (operands); }"
4957 [(set_attr "type" "isel")
4958 (set_attr "length" "4")])
4960 ;; These patterns can be useful for combine; they let combine know that
4961 ;; isel can handle reversed comparisons so long as the operands are
4964 (define_insn "*isel_reversed_signed_<mode>"
4965 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4967 (match_operator 1 "scc_rev_comparison_operator"
4968 [(match_operand:CC 4 "cc_reg_operand" "y")
4970 (match_operand:GPR 2 "gpc_reg_operand" "b")
4971 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4974 { return output_isel (operands); }"
4975 [(set_attr "type" "isel")
4976 (set_attr "length" "4")])
4978 (define_insn "*isel_reversed_unsigned_<mode>"
4979 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4981 (match_operator 1 "scc_rev_comparison_operator"
4982 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4984 (match_operand:GPR 2 "gpc_reg_operand" "b")
4985 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4988 { return output_isel (operands); }"
4989 [(set_attr "type" "isel")
4990 (set_attr "length" "4")])
4992 ;; Floating point conditional move
4993 (define_expand "mov<mode>cc"
4994 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4995 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
4996 (match_operand:SFDF 2 "gpc_reg_operand" "")
4997 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
4998 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5001 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5007 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5008 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5010 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5011 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5012 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5013 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5014 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5016 [(set_attr "type" "fp")])
5018 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5019 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5021 (match_operator:CCFP 1 "fpmask_comparison_operator"
5022 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5023 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5024 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5025 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5026 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5031 (if_then_else:V2DI (match_dup 1)
5035 (if_then_else:SFDF (ne (match_dup 6)
5040 if (GET_CODE (operands[6]) == SCRATCH)
5041 operands[6] = gen_reg_rtx (V2DImode);
5043 operands[7] = CONSTM1_RTX (V2DImode);
5044 operands[8] = CONST0_RTX (V2DImode);
5046 [(set_attr "length" "8")
5047 (set_attr "type" "vecperm")])
5049 ;; Handle inverting the fpmask comparisons.
5050 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5051 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5053 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5054 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5055 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5056 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5057 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5058 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5063 (if_then_else:V2DI (match_dup 9)
5067 (if_then_else:SFDF (ne (match_dup 6)
5072 rtx op1 = operands[1];
5073 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5075 if (GET_CODE (operands[6]) == SCRATCH)
5076 operands[6] = gen_reg_rtx (V2DImode);
5078 operands[7] = CONSTM1_RTX (V2DImode);
5079 operands[8] = CONST0_RTX (V2DImode);
5081 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5083 [(set_attr "length" "8")
5084 (set_attr "type" "vecperm")])
5086 (define_insn "*fpmask<mode>"
5087 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5089 (match_operator:CCFP 1 "fpmask_comparison_operator"
5090 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5091 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5092 (match_operand:V2DI 4 "all_ones_constant" "")
5093 (match_operand:V2DI 5 "zero_constant" "")))]
5095 "xscmp%V1dp %x0,%x2,%x3"
5096 [(set_attr "type" "fpcompare")])
5098 (define_insn "*xxsel<mode>"
5099 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5100 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5101 (match_operand:V2DI 2 "zero_constant" ""))
5102 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5103 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5105 "xxsel %x0,%x4,%x3,%x1"
5106 [(set_attr "type" "vecmove")])
5109 ;; Conversions to and from floating-point.
5111 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5112 ; don't want to support putting SImode in FPR registers.
5113 (define_insn "lfiwax"
5114 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5115 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5117 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5123 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5125 ; This split must be run before register allocation because it allocates the
5126 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5127 ; it earlier to allow for the combiner to merge insns together where it might
5128 ; not be needed and also in case the insns are deleted as dead code.
5130 (define_insn_and_split "floatsi<mode>2_lfiwax"
5131 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5132 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5133 (clobber (match_scratch:DI 2 "=wi"))]
5134 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5135 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5141 rtx dest = operands[0];
5142 rtx src = operands[1];
5145 if (!MEM_P (src) && TARGET_POWERPC64
5146 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5147 tmp = convert_to_mode (DImode, src, false);
5151 if (GET_CODE (tmp) == SCRATCH)
5152 tmp = gen_reg_rtx (DImode);
5155 src = rs6000_address_for_fpconvert (src);
5156 emit_insn (gen_lfiwax (tmp, src));
5160 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5161 emit_move_insn (stack, src);
5162 emit_insn (gen_lfiwax (tmp, stack));
5165 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5168 [(set_attr "length" "12")
5169 (set_attr "type" "fpload")])
5171 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5172 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5175 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5176 (clobber (match_scratch:DI 2 "=wi"))]
5177 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5184 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5185 if (GET_CODE (operands[2]) == SCRATCH)
5186 operands[2] = gen_reg_rtx (DImode);
5187 if (TARGET_VSX_SMALL_INTEGER)
5188 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5190 emit_insn (gen_lfiwax (operands[2], operands[1]));
5191 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5194 [(set_attr "length" "8")
5195 (set_attr "type" "fpload")])
5197 (define_insn "lfiwzx"
5198 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5199 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5201 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5206 xxextractuw %x0,%x1,4"
5207 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5209 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5210 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5211 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5212 (clobber (match_scratch:DI 2 "=wi"))]
5213 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5220 rtx dest = operands[0];
5221 rtx src = operands[1];
5224 if (!MEM_P (src) && TARGET_POWERPC64
5225 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5226 tmp = convert_to_mode (DImode, src, true);
5230 if (GET_CODE (tmp) == SCRATCH)
5231 tmp = gen_reg_rtx (DImode);
5234 src = rs6000_address_for_fpconvert (src);
5235 emit_insn (gen_lfiwzx (tmp, src));
5239 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5240 emit_move_insn (stack, src);
5241 emit_insn (gen_lfiwzx (tmp, stack));
5244 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5247 [(set_attr "length" "12")
5248 (set_attr "type" "fpload")])
5250 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5251 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5252 (unsigned_float:SFDF
5254 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5255 (clobber (match_scratch:DI 2 "=wi"))]
5256 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
5263 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5264 if (GET_CODE (operands[2]) == SCRATCH)
5265 operands[2] = gen_reg_rtx (DImode);
5266 if (TARGET_VSX_SMALL_INTEGER)
5267 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5269 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5270 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5273 [(set_attr "length" "8")
5274 (set_attr "type" "fpload")])
5276 ; For each of these conversions, there is a define_expand, a define_insn
5277 ; with a '#' template, and a define_split (with C code). The idea is
5278 ; to allow constant folding with the template of the define_insn,
5279 ; then to have the insns split later (between sched1 and final).
5281 (define_expand "floatsidf2"
5282 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5283 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5286 (clobber (match_dup 4))
5287 (clobber (match_dup 5))
5288 (clobber (match_dup 6))])]
5290 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5293 if (TARGET_E500_DOUBLE)
5295 if (!REG_P (operands[1]))
5296 operands[1] = force_reg (SImode, operands[1]);
5297 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5300 else if (TARGET_LFIWAX && TARGET_FCFID)
5302 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5305 else if (TARGET_FCFID)
5307 rtx dreg = operands[1];
5309 dreg = force_reg (SImode, dreg);
5310 dreg = convert_to_mode (DImode, dreg, false);
5311 emit_insn (gen_floatdidf2 (operands[0], dreg));
5315 if (!REG_P (operands[1]))
5316 operands[1] = force_reg (SImode, operands[1]);
5317 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5318 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5319 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5320 operands[5] = gen_reg_rtx (DFmode);
5321 operands[6] = gen_reg_rtx (SImode);
5324 (define_insn_and_split "*floatsidf2_internal"
5325 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5326 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5327 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5328 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5329 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5330 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5331 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5332 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5338 rtx lowword, highword;
5339 gcc_assert (MEM_P (operands[4]));
5340 highword = adjust_address (operands[4], SImode, 0);
5341 lowword = adjust_address (operands[4], SImode, 4);
5342 if (! WORDS_BIG_ENDIAN)
5343 std::swap (lowword, highword);
5345 emit_insn (gen_xorsi3 (operands[6], operands[1],
5346 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5347 emit_move_insn (lowword, operands[6]);
5348 emit_move_insn (highword, operands[2]);
5349 emit_move_insn (operands[5], operands[4]);
5350 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5353 [(set_attr "length" "24")
5354 (set_attr "type" "fp")])
5356 ;; If we don't have a direct conversion to single precision, don't enable this
5357 ;; conversion for 32-bit without fast math, because we don't have the insn to
5358 ;; generate the fixup swizzle to avoid double rounding problems.
5359 (define_expand "floatunssisf2"
5360 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5361 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5362 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5365 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5366 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5367 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5372 if (!REG_P (operands[1]))
5373 operands[1] = force_reg (SImode, operands[1]);
5375 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5377 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5382 rtx dreg = operands[1];
5384 dreg = force_reg (SImode, dreg);
5385 dreg = convert_to_mode (DImode, dreg, true);
5386 emit_insn (gen_floatdisf2 (operands[0], dreg));
5391 (define_expand "floatunssidf2"
5392 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5393 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5396 (clobber (match_dup 4))
5397 (clobber (match_dup 5))])]
5399 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5402 if (TARGET_E500_DOUBLE)
5404 if (!REG_P (operands[1]))
5405 operands[1] = force_reg (SImode, operands[1]);
5406 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5409 else if (TARGET_LFIWZX && TARGET_FCFID)
5411 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5414 else if (TARGET_FCFID)
5416 rtx dreg = operands[1];
5418 dreg = force_reg (SImode, dreg);
5419 dreg = convert_to_mode (DImode, dreg, true);
5420 emit_insn (gen_floatdidf2 (operands[0], dreg));
5424 if (!REG_P (operands[1]))
5425 operands[1] = force_reg (SImode, operands[1]);
5426 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5427 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5428 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5429 operands[5] = gen_reg_rtx (DFmode);
5432 (define_insn_and_split "*floatunssidf2_internal"
5433 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5434 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5435 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5436 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5437 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5438 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5439 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5440 && !(TARGET_FCFID && TARGET_POWERPC64)"
5446 rtx lowword, highword;
5447 gcc_assert (MEM_P (operands[4]));
5448 highword = adjust_address (operands[4], SImode, 0);
5449 lowword = adjust_address (operands[4], SImode, 4);
5450 if (! WORDS_BIG_ENDIAN)
5451 std::swap (lowword, highword);
5453 emit_move_insn (lowword, operands[1]);
5454 emit_move_insn (highword, operands[2]);
5455 emit_move_insn (operands[5], operands[4]);
5456 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5459 [(set_attr "length" "20")
5460 (set_attr "type" "fp")])
5462 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5463 ;; vector registers. These insns favor doing the sign/zero extension in
5464 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5465 ;; extension and then a direct move.
5467 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5468 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5470 (match_operand:QHI 1 "input_operand")))
5471 (clobber (match_scratch:DI 2))
5472 (clobber (match_scratch:DI 3))
5473 (clobber (match_scratch:<QHI:MODE> 4))])]
5474 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5475 && TARGET_VSX_SMALL_INTEGER"
5477 if (MEM_P (operands[1]))
5478 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5481 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5482 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5484 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5485 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5486 (clobber (match_scratch:DI 3 "=X,r,X"))
5487 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5488 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5489 && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER"
5491 "&& reload_completed"
5494 rtx result = operands[0];
5495 rtx input = operands[1];
5496 rtx di = operands[2];
5500 rtx tmp = operands[3];
5501 if (altivec_register_operand (input, <QHI:MODE>mode))
5502 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5503 else if (GET_CODE (tmp) == SCRATCH)
5504 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5507 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5508 emit_move_insn (di, tmp);
5513 rtx tmp = operands[4];
5514 emit_move_insn (tmp, input);
5515 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5518 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5522 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5523 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5524 (unsigned_float:FP_ISA3
5525 (match_operand:QHI 1 "input_operand" "")))
5526 (clobber (match_scratch:DI 2 ""))
5527 (clobber (match_scratch:DI 3 ""))])]
5528 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5529 && TARGET_VSX_SMALL_INTEGER"
5531 if (MEM_P (operands[1]))
5532 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5535 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5536 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5537 (unsigned_float:FP_ISA3
5538 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5539 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5540 (clobber (match_scratch:DI 3 "=X,r,X"))]
5541 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64
5542 && TARGET_VSX_SMALL_INTEGER"
5544 "&& reload_completed"
5547 rtx result = operands[0];
5548 rtx input = operands[1];
5549 rtx di = operands[2];
5551 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5552 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5555 rtx tmp = operands[3];
5556 if (GET_CODE (tmp) == SCRATCH)
5557 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5560 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5561 emit_move_insn (di, tmp);
5565 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5569 (define_expand "fix_trunc<mode>si2"
5570 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5571 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5572 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5575 if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
5577 rtx src = force_reg (<MODE>mode, operands[1]);
5580 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5583 rtx tmp = gen_reg_rtx (DImode);
5584 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5585 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5592 ; Like the convert to float patterns, this insn must be split before
5593 ; register allocation so that it can allocate the memory slot if it
5595 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5596 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5597 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5598 (clobber (match_scratch:DI 2 "=d"))]
5599 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5600 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5601 && TARGET_STFIWX && can_create_pseudo_p ()
5602 && !TARGET_VSX_SMALL_INTEGER"
5607 rtx dest = operands[0];
5608 rtx src = operands[1];
5609 rtx tmp = operands[2];
5611 if (GET_CODE (tmp) == SCRATCH)
5612 tmp = gen_reg_rtx (DImode);
5614 emit_insn (gen_fctiwz_<mode> (tmp, src));
5617 dest = rs6000_address_for_fpconvert (dest);
5618 emit_insn (gen_stfiwx (dest, tmp));
5621 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5623 dest = gen_lowpart (DImode, dest);
5624 emit_move_insn (dest, tmp);
5629 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5630 emit_insn (gen_stfiwx (stack, tmp));
5631 emit_move_insn (dest, stack);
5635 [(set_attr "length" "12")
5636 (set_attr "type" "fp")])
5638 (define_insn_and_split "fix_trunc<mode>si2_internal"
5639 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5640 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5641 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5642 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5643 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5644 && !TARGET_VSX_SMALL_INTEGER"
5651 gcc_assert (MEM_P (operands[3]));
5652 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5654 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5655 emit_move_insn (operands[3], operands[2]);
5656 emit_move_insn (operands[0], lowword);
5659 [(set_attr "length" "16")
5660 (set_attr "type" "fp")])
5662 (define_expand "fix_trunc<mode>di2"
5663 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5664 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5665 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5669 (define_insn "*fix_trunc<mode>di2_fctidz"
5670 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5671 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5672 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5677 [(set_attr "type" "fp")])
5679 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5680 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5681 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5682 (clobber (match_scratch:DI 2))])]
5683 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5684 && TARGET_VSX_SMALL_INTEGER"
5686 if (MEM_P (operands[0]))
5687 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5690 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5691 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5693 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5694 (clobber (match_scratch:DI 2 "=X,wi"))]
5695 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5696 && TARGET_VSX_SMALL_INTEGER"
5698 "&& reload_completed"
5701 rtx dest = operands[0];
5702 rtx src = operands[1];
5704 if (vsx_register_operand (dest, <QHI:MODE>mode))
5706 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5707 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5711 rtx tmp = operands[2];
5712 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5714 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5715 emit_move_insn (dest, tmp2);
5720 (define_expand "fixuns_trunc<mode>si2"
5721 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5722 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5724 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5728 if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER)
5730 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5735 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5736 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5737 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5738 (clobber (match_scratch:DI 2 "=d"))]
5739 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5740 && TARGET_STFIWX && can_create_pseudo_p ()
5741 && !TARGET_VSX_SMALL_INTEGER"
5746 rtx dest = operands[0];
5747 rtx src = operands[1];
5748 rtx tmp = operands[2];
5750 if (GET_CODE (tmp) == SCRATCH)
5751 tmp = gen_reg_rtx (DImode);
5753 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5756 dest = rs6000_address_for_fpconvert (dest);
5757 emit_insn (gen_stfiwx (dest, tmp));
5760 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5762 dest = gen_lowpart (DImode, dest);
5763 emit_move_insn (dest, tmp);
5768 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5769 emit_insn (gen_stfiwx (stack, tmp));
5770 emit_move_insn (dest, stack);
5774 [(set_attr "length" "12")
5775 (set_attr "type" "fp")])
5777 (define_insn "fixuns_trunc<mode>di2"
5778 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5779 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5780 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ"
5784 [(set_attr "type" "fp")])
5786 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5787 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5788 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5789 (clobber (match_scratch:DI 2))])]
5790 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5791 && TARGET_VSX_SMALL_INTEGER"
5793 if (MEM_P (operands[0]))
5794 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5797 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5798 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5800 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5801 (clobber (match_scratch:DI 2 "=X,wi"))]
5802 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT
5803 && TARGET_VSX_SMALL_INTEGER"
5805 "&& reload_completed"
5808 rtx dest = operands[0];
5809 rtx src = operands[1];
5811 if (vsx_register_operand (dest, <QHI:MODE>mode))
5813 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5814 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5818 rtx tmp = operands[2];
5819 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5821 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5822 emit_move_insn (dest, tmp2);
5827 ;; If -mvsx-small-integer, we can represent the FIX operation directly. On
5828 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5829 ;; to another location, since SImode is not allowed in vector registers.
5830 (define_insn "*fctiw<u>z_<mode>_smallint"
5831 [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5832 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5833 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5834 && TARGET_VSX_SMALL_INTEGER"
5837 xscvdp<su>xws %x0,%x1"
5838 [(set_attr "type" "fp")])
5840 ;; Combiner pattern to prevent moving the result of converting a floating point
5841 ;; value to 32-bit integer to GPR in order to save it.
5842 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5843 [(set (match_operand:SI 0 "memory_operand" "=Z")
5844 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5845 (clobber (match_scratch:SI 2 "=wa"))]
5846 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5847 && TARGET_VSX_SMALL_INTEGER"
5849 "&& reload_completed"
5851 (any_fix:SI (match_dup 1)))
5855 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5856 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5857 ;; because the first makes it clear that operand 0 is not live
5858 ;; before the instruction.
5859 (define_insn "fctiwz_<mode>"
5860 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5862 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5864 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5868 [(set_attr "type" "fp")])
5870 (define_insn "fctiwuz_<mode>"
5871 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5872 (unspec:DI [(unsigned_fix:SI
5873 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5875 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5879 [(set_attr "type" "fp")])
5881 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5882 ;; since the friz instruction does not truncate the value if the floating
5883 ;; point value is < LONG_MIN or > LONG_MAX.
5884 (define_insn "*friz"
5885 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5886 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5887 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5888 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5892 [(set_attr "type" "fp")])
5894 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5895 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5896 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5897 ;; extend it, store it back on the stack from the GPR, load it back into the
5898 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5899 ;; disable using store and load to sign/zero extend the value.
5900 (define_insn_and_split "*round32<mode>2_fprs"
5901 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5903 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5904 (clobber (match_scratch:DI 2 "=d"))
5905 (clobber (match_scratch:DI 3 "=d"))]
5906 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5907 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5908 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5913 rtx dest = operands[0];
5914 rtx src = operands[1];
5915 rtx tmp1 = operands[2];
5916 rtx tmp2 = operands[3];
5917 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5919 if (GET_CODE (tmp1) == SCRATCH)
5920 tmp1 = gen_reg_rtx (DImode);
5921 if (GET_CODE (tmp2) == SCRATCH)
5922 tmp2 = gen_reg_rtx (DImode);
5924 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5925 emit_insn (gen_stfiwx (stack, tmp1));
5926 emit_insn (gen_lfiwax (tmp2, stack));
5927 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5930 [(set_attr "type" "fpload")
5931 (set_attr "length" "16")])
5933 (define_insn_and_split "*roundu32<mode>2_fprs"
5934 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5935 (unsigned_float:SFDF
5936 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5937 (clobber (match_scratch:DI 2 "=d"))
5938 (clobber (match_scratch:DI 3 "=d"))]
5939 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5940 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5941 && can_create_pseudo_p ()"
5946 rtx dest = operands[0];
5947 rtx src = operands[1];
5948 rtx tmp1 = operands[2];
5949 rtx tmp2 = operands[3];
5950 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5952 if (GET_CODE (tmp1) == SCRATCH)
5953 tmp1 = gen_reg_rtx (DImode);
5954 if (GET_CODE (tmp2) == SCRATCH)
5955 tmp2 = gen_reg_rtx (DImode);
5957 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5958 emit_insn (gen_stfiwx (stack, tmp1));
5959 emit_insn (gen_lfiwzx (tmp2, stack));
5960 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5963 [(set_attr "type" "fpload")
5964 (set_attr "length" "16")])
5966 ;; No VSX equivalent to fctid
5967 (define_insn "lrint<mode>di2"
5968 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5969 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5971 "TARGET_<MODE>_FPR && TARGET_FPRND"
5973 [(set_attr "type" "fp")])
5975 (define_insn "btrunc<mode>2"
5976 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5977 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5979 "TARGET_<MODE>_FPR && TARGET_FPRND"
5983 [(set_attr "type" "fp")
5984 (set_attr "fp_type" "fp_addsub_<Fs>")])
5986 (define_insn "ceil<mode>2"
5987 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5988 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5990 "TARGET_<MODE>_FPR && TARGET_FPRND"
5994 [(set_attr "type" "fp")
5995 (set_attr "fp_type" "fp_addsub_<Fs>")])
5997 (define_insn "floor<mode>2"
5998 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5999 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6001 "TARGET_<MODE>_FPR && TARGET_FPRND"
6005 [(set_attr "type" "fp")
6006 (set_attr "fp_type" "fp_addsub_<Fs>")])
6008 ;; No VSX equivalent to frin
6009 (define_insn "round<mode>2"
6010 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6011 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6013 "TARGET_<MODE>_FPR && TARGET_FPRND"
6015 [(set_attr "type" "fp")
6016 (set_attr "fp_type" "fp_addsub_<Fs>")])
6018 (define_insn "*xsrdpi<mode>2"
6019 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6020 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6022 "TARGET_<MODE>_FPR && TARGET_VSX"
6024 [(set_attr "type" "fp")
6025 (set_attr "fp_type" "fp_addsub_<Fs>")])
6027 (define_expand "lround<mode>di2"
6029 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6031 (set (match_operand:DI 0 "gpc_reg_operand" "")
6032 (unspec:DI [(match_dup 2)]
6034 "TARGET_<MODE>_FPR && TARGET_VSX"
6036 operands[2] = gen_reg_rtx (<MODE>mode);
6039 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6040 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6041 ; is only generated for Power8 or later.
6042 (define_insn "stfiwx"
6043 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6044 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6050 [(set_attr "type" "fpstore")])
6052 ;; If we don't have a direct conversion to single precision, don't enable this
6053 ;; conversion for 32-bit without fast math, because we don't have the insn to
6054 ;; generate the fixup swizzle to avoid double rounding problems.
6055 (define_expand "floatsisf2"
6056 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6057 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6058 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6061 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6062 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6063 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
6068 if (!REG_P (operands[1]))
6069 operands[1] = force_reg (SImode, operands[1]);
6071 else if (TARGET_FCFIDS && TARGET_LFIWAX)
6073 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6076 else if (TARGET_FCFID && TARGET_LFIWAX)
6078 rtx dfreg = gen_reg_rtx (DFmode);
6079 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6080 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6085 rtx dreg = operands[1];
6087 dreg = force_reg (SImode, dreg);
6088 dreg = convert_to_mode (DImode, dreg, false);
6089 emit_insn (gen_floatdisf2 (operands[0], dreg));
6094 (define_expand "floatdidf2"
6095 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6096 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6097 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6100 (define_insn "*floatdidf2_fpr"
6101 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6102 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6103 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6107 [(set_attr "type" "fp")])
6109 ; Allow the combiner to merge source memory operands to the conversion so that
6110 ; the optimizer/register allocator doesn't try to load the value too early in a
6111 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6112 ; hit. We will split after reload to avoid the trip through the GPRs
6114 (define_insn_and_split "*floatdidf2_mem"
6115 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6116 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6117 (clobber (match_scratch:DI 2 "=d,wi"))]
6118 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
6120 "&& reload_completed"
6121 [(set (match_dup 2) (match_dup 1))
6122 (set (match_dup 0) (float:DF (match_dup 2)))]
6124 [(set_attr "length" "8")
6125 (set_attr "type" "fpload")])
6127 (define_expand "floatunsdidf2"
6128 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6130 (match_operand:DI 1 "gpc_reg_operand" "")))]
6131 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6134 (define_insn "*floatunsdidf2_fcfidu"
6135 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6136 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6137 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6141 [(set_attr "type" "fp")
6142 (set_attr "length" "4")])
6144 (define_insn_and_split "*floatunsdidf2_mem"
6145 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6146 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6147 (clobber (match_scratch:DI 2 "=d,wi"))]
6148 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6150 "&& reload_completed"
6151 [(set (match_dup 2) (match_dup 1))
6152 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6154 [(set_attr "length" "8")
6155 (set_attr "type" "fpload")])
6157 (define_expand "floatdisf2"
6158 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6159 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6160 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6161 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6166 rtx val = operands[1];
6167 if (!flag_unsafe_math_optimizations)
6169 rtx label = gen_label_rtx ();
6170 val = gen_reg_rtx (DImode);
6171 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6174 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6179 (define_insn "floatdisf2_fcfids"
6180 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6181 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6182 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6183 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6187 [(set_attr "type" "fp")])
6189 (define_insn_and_split "*floatdisf2_mem"
6190 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6191 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6192 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6193 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6194 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6196 "&& reload_completed"
6200 emit_move_insn (operands[2], operands[1]);
6201 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6204 [(set_attr "length" "8")])
6206 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6207 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6208 ;; from double rounding.
6209 ;; Instead of creating a new cpu type for two FP operations, just use fp
6210 (define_insn_and_split "floatdisf2_internal1"
6211 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6212 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6213 (clobber (match_scratch:DF 2 "=d"))]
6214 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6217 "&& reload_completed"
6219 (float:DF (match_dup 1)))
6221 (float_truncate:SF (match_dup 2)))]
6223 [(set_attr "length" "8")
6224 (set_attr "type" "fp")])
6226 ;; Twiddles bits to avoid double rounding.
6227 ;; Bits that might be truncated when converting to DFmode are replaced
6228 ;; by a bit that won't be lost at that stage, but is below the SFmode
6229 ;; rounding position.
6230 (define_expand "floatdisf2_internal2"
6231 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6233 (clobber (reg:DI CA_REGNO))])
6234 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6236 (set (match_dup 3) (plus:DI (match_dup 3)
6238 (set (match_dup 0) (plus:DI (match_dup 0)
6240 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6242 (set (match_dup 0) (ior:DI (match_dup 0)
6244 (set (match_dup 0) (and:DI (match_dup 0)
6246 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6247 (label_ref (match_operand:DI 2 "" ""))
6249 (set (match_dup 0) (match_dup 1))]
6250 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6254 operands[3] = gen_reg_rtx (DImode);
6255 operands[4] = gen_reg_rtx (CCUNSmode);
6258 (define_expand "floatunsdisf2"
6259 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6260 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6261 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6262 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6265 (define_insn "floatunsdisf2_fcfidus"
6266 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6267 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6268 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6269 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6273 [(set_attr "type" "fp")])
6275 (define_insn_and_split "*floatunsdisf2_mem"
6276 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6277 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6278 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6279 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
6280 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6282 "&& reload_completed"
6286 emit_move_insn (operands[2], operands[1]);
6287 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6290 [(set_attr "length" "8")
6291 (set_attr "type" "fpload")])
6293 ;; Define the TImode operations that can be done in a small number
6294 ;; of instructions. The & constraints are to prevent the register
6295 ;; allocator from allocating registers that overlap with the inputs
6296 ;; (for example, having an input in 7,8 and an output in 6,7). We
6297 ;; also allow for the output being the same as one of the inputs.
6299 (define_expand "addti3"
6300 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6301 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6302 (match_operand:TI 2 "reg_or_short_operand" "")))]
6305 rtx lo0 = gen_lowpart (DImode, operands[0]);
6306 rtx lo1 = gen_lowpart (DImode, operands[1]);
6307 rtx lo2 = gen_lowpart (DImode, operands[2]);
6308 rtx hi0 = gen_highpart (DImode, operands[0]);
6309 rtx hi1 = gen_highpart (DImode, operands[1]);
6310 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6312 if (!reg_or_short_operand (lo2, DImode))
6313 lo2 = force_reg (DImode, lo2);
6314 if (!adde_operand (hi2, DImode))
6315 hi2 = force_reg (DImode, hi2);
6317 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6318 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6322 (define_expand "subti3"
6323 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6324 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6325 (match_operand:TI 2 "gpc_reg_operand" "")))]
6328 rtx lo0 = gen_lowpart (DImode, operands[0]);
6329 rtx lo1 = gen_lowpart (DImode, operands[1]);
6330 rtx lo2 = gen_lowpart (DImode, operands[2]);
6331 rtx hi0 = gen_highpart (DImode, operands[0]);
6332 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6333 rtx hi2 = gen_highpart (DImode, operands[2]);
6335 if (!reg_or_short_operand (lo1, DImode))
6336 lo1 = force_reg (DImode, lo1);
6337 if (!adde_operand (hi1, DImode))
6338 hi1 = force_reg (DImode, hi1);
6340 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6341 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6345 ;; 128-bit logical operations expanders
6347 (define_expand "and<mode>3"
6348 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6349 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6350 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6354 (define_expand "ior<mode>3"
6355 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6356 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6357 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6361 (define_expand "xor<mode>3"
6362 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6363 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6364 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6368 (define_expand "one_cmpl<mode>2"
6369 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6370 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6374 (define_expand "nor<mode>3"
6375 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6377 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6378 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6382 (define_expand "andc<mode>3"
6383 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6385 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6386 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6390 ;; Power8 vector logical instructions.
6391 (define_expand "eqv<mode>3"
6392 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6394 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6395 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6396 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6399 ;; Rewrite nand into canonical form
6400 (define_expand "nand<mode>3"
6401 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6403 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6404 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6405 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6408 ;; The canonical form is to have the negated element first, so we need to
6409 ;; reverse arguments.
6410 (define_expand "orc<mode>3"
6411 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6413 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6414 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6415 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6418 ;; 128-bit logical operations insns and split operations
6419 (define_insn_and_split "*and<mode>3_internal"
6420 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6422 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6423 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6426 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6427 return "xxland %x0,%x1,%x2";
6429 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6430 return "vand %0,%1,%2";
6434 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6437 rs6000_split_logical (operands, AND, false, false, false);
6442 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6443 (const_string "veclogical")
6444 (const_string "integer")))
6445 (set (attr "length")
6447 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6450 (match_test "TARGET_POWERPC64")
6452 (const_string "16"))))])
6455 (define_insn_and_split "*bool<mode>3_internal"
6456 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6457 (match_operator:BOOL_128 3 "boolean_or_operator"
6458 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6459 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6462 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6463 return "xxl%q3 %x0,%x1,%x2";
6465 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6466 return "v%q3 %0,%1,%2";
6470 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6473 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6478 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6479 (const_string "veclogical")
6480 (const_string "integer")))
6481 (set (attr "length")
6483 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6486 (match_test "TARGET_POWERPC64")
6488 (const_string "16"))))])
6491 (define_insn_and_split "*boolc<mode>3_internal1"
6492 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6493 (match_operator:BOOL_128 3 "boolean_operator"
6495 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6496 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6497 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6499 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6500 return "xxl%q3 %x0,%x1,%x2";
6502 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6503 return "v%q3 %0,%1,%2";
6507 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6508 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6511 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6516 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6517 (const_string "veclogical")
6518 (const_string "integer")))
6519 (set (attr "length")
6521 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6524 (match_test "TARGET_POWERPC64")
6526 (const_string "16"))))])
6528 (define_insn_and_split "*boolc<mode>3_internal2"
6529 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6530 (match_operator:TI2 3 "boolean_operator"
6532 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6533 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6534 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6536 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6539 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6542 [(set_attr "type" "integer")
6543 (set (attr "length")
6545 (match_test "TARGET_POWERPC64")
6547 (const_string "16")))])
6550 (define_insn_and_split "*boolcc<mode>3_internal1"
6551 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6552 (match_operator:BOOL_128 3 "boolean_operator"
6554 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6556 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6557 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6559 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6560 return "xxl%q3 %x0,%x1,%x2";
6562 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6563 return "v%q3 %0,%1,%2";
6567 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6568 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6571 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6576 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6577 (const_string "veclogical")
6578 (const_string "integer")))
6579 (set (attr "length")
6581 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6584 (match_test "TARGET_POWERPC64")
6586 (const_string "16"))))])
6588 (define_insn_and_split "*boolcc<mode>3_internal2"
6589 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6590 (match_operator:TI2 3 "boolean_operator"
6592 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6594 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6595 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6597 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6600 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6603 [(set_attr "type" "integer")
6604 (set (attr "length")
6606 (match_test "TARGET_POWERPC64")
6608 (const_string "16")))])
6612 (define_insn_and_split "*eqv<mode>3_internal1"
6613 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6616 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6617 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6620 if (vsx_register_operand (operands[0], <MODE>mode))
6621 return "xxleqv %x0,%x1,%x2";
6625 "TARGET_P8_VECTOR && reload_completed
6626 && int_reg_operand (operands[0], <MODE>mode)"
6629 rs6000_split_logical (operands, XOR, true, false, false);
6634 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6635 (const_string "veclogical")
6636 (const_string "integer")))
6637 (set (attr "length")
6639 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6642 (match_test "TARGET_POWERPC64")
6644 (const_string "16"))))])
6646 (define_insn_and_split "*eqv<mode>3_internal2"
6647 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6650 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6651 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6654 "reload_completed && !TARGET_P8_VECTOR"
6657 rs6000_split_logical (operands, XOR, true, false, false);
6660 [(set_attr "type" "integer")
6661 (set (attr "length")
6663 (match_test "TARGET_POWERPC64")
6665 (const_string "16")))])
6667 ;; 128-bit one's complement
6668 (define_insn_and_split "*one_cmpl<mode>3_internal"
6669 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6671 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6674 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6675 return "xxlnor %x0,%x1,%x1";
6677 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6678 return "vnor %0,%1,%1";
6682 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6685 rs6000_split_logical (operands, NOT, false, false, false);
6690 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6691 (const_string "veclogical")
6692 (const_string "integer")))
6693 (set (attr "length")
6695 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6698 (match_test "TARGET_POWERPC64")
6700 (const_string "16"))))])
6703 ;; Now define ways of moving data around.
6705 ;; Set up a register with a value from the GOT table
6707 (define_expand "movsi_got"
6708 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6709 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6710 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6711 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6714 if (GET_CODE (operands[1]) == CONST)
6716 rtx offset = const0_rtx;
6717 HOST_WIDE_INT value;
6719 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6720 value = INTVAL (offset);
6723 rtx tmp = (!can_create_pseudo_p ()
6725 : gen_reg_rtx (Pmode));
6726 emit_insn (gen_movsi_got (tmp, operands[1]));
6727 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6732 operands[2] = rs6000_got_register (operands[1]);
6735 (define_insn "*movsi_got_internal"
6736 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6737 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6738 (match_operand:SI 2 "gpc_reg_operand" "b")]
6740 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6741 "lwz %0,%a1@got(%2)"
6742 [(set_attr "type" "load")])
6744 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6745 ;; didn't get allocated to a hard register.
6747 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6748 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6749 (match_operand:SI 2 "memory_operand" "")]
6751 "DEFAULT_ABI == ABI_V4
6753 && (reload_in_progress || reload_completed)"
6754 [(set (match_dup 0) (match_dup 2))
6755 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6759 ;; For SI, we special-case integers that can't be loaded in one insn. We
6760 ;; do the load 16-bits at a time. We could do this by loading from memory,
6761 ;; and this is even supposed to be faster, but it is simpler not to get
6762 ;; integers in the TOC.
6763 (define_insn "movsi_low"
6764 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6765 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6766 (match_operand 2 "" ""))))]
6767 "TARGET_MACHO && ! TARGET_64BIT"
6768 "lwz %0,lo16(%2)(%1)"
6769 [(set_attr "type" "load")
6770 (set_attr "length" "4")])
6772 ;; MR LA LWZ LFIWZX LXSIWZX
6773 ;; STW STFIWX STXSIWX LI LIS
6774 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6775 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6776 ;; MF%1 MT%0 MT%0 NOP
6777 (define_insn "*movsi_internal1"
6778 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6779 "=r, r, r, ?*wI, ?*wH,
6781 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6782 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6785 (match_operand:SI 1 "input_operand"
6792 "!TARGET_SINGLE_FPU &&
6793 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6820 "*, *, load, fpload, fpload,
6821 store, fpstore, fpstore, *, *,
6822 *, veclogical, vecsimple, vecsimple, vecsimple,
6823 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6833 (define_insn "*movsi_internal1_single"
6834 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6835 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6836 "TARGET_SINGLE_FPU &&
6837 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6852 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6853 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6855 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6856 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6858 ;; Because SF values are actually stored as DF values within the vector
6859 ;; registers, we need to convert the value to the vector SF format when
6860 ;; we need to use the bits in a union or similar cases. We only need
6861 ;; to do this transformation when the value is a vector register. Loads,
6862 ;; stores, and transfers within GPRs are assumed to be safe.
6864 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6865 ;; no alternatives, because the call is created as part of secondary_reload,
6866 ;; and operand #2's register class is used to allocate the temporary register.
6867 ;; This function is called before reload, and it creates the temporary as
6870 ;; MR LWZ LFIWZX LXSIWZX STW
6871 ;; STFS STXSSP STXSSPX VSX->GPR MTVSRWZ
6874 (define_insn_and_split "movsi_from_sf"
6875 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand"
6876 "=r, r, ?*wI, ?*wH, m,
6880 (unspec:SI [(match_operand:SF 1 "input_operand"
6886 (clobber (match_scratch:V4SF 2
6891 "TARGET_NO_SF_SUBREG
6892 && (register_operand (operands[0], SImode)
6893 || register_operand (operands[1], SFmode))"
6906 "&& reload_completed
6907 && register_operand (operands[0], SImode)
6908 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6911 rtx op0 = operands[0];
6912 rtx op1 = operands[1];
6913 rtx op2 = operands[2];
6914 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
6916 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6918 if (int_reg_operand (op0, SImode))
6920 emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2));
6921 emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32)));
6925 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6926 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6927 emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off));
6933 "*, load, fpload, fpload, store,
6934 fpstore, fpstore, fpstore, mftgpr, mffgpr,
6942 ;; movsi_from_sf with zero extension
6944 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6947 (define_insn_and_split "*movdi_from_sf_zero_ext"
6948 [(set (match_operand:DI 0 "gpc_reg_operand"
6949 "=r, r, ?*wI, ?*wH, r,
6953 (unspec:SI [(match_operand:SF 1 "input_operand"
6956 UNSPEC_SI_FROM_SF)))
6958 (clobber (match_scratch:V4SF 2
6962 "TARGET_DIRECT_MOVE_64BIT
6963 && (register_operand (operands[0], DImode)
6964 || register_operand (operands[1], SImode))"
6973 "&& reload_completed
6974 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6977 rtx op0 = operands[0];
6978 rtx op1 = operands[1];
6979 rtx op2 = operands[2];
6981 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6983 if (int_reg_operand (op0, DImode))
6985 emit_insn (gen_p8_mfvsrd_4_disf (op0, op2));
6986 emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32)));
6990 rtx op0_si = gen_rtx_REG (SImode, REGNO (op0));
6991 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1));
6992 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12);
6993 emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off));
6999 "*, load, fpload, fpload, mftgpr,
7000 mffgpr, veclogical")
7006 ;; Split a load of a large constant into the appropriate two-insn
7010 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7011 (match_operand:SI 1 "const_int_operand" ""))]
7012 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7013 && (INTVAL (operands[1]) & 0xffff) != 0"
7017 (ior:SI (match_dup 0)
7021 if (rs6000_emit_set_const (operands[0], operands[1]))
7027 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7029 [(set (match_operand:DI 0 "altivec_register_operand")
7030 (match_operand:DI 1 "xxspltib_constant_split"))]
7031 "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed"
7034 rtx op0 = operands[0];
7035 rtx op1 = operands[1];
7036 int r = REGNO (op0);
7037 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7039 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7040 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7044 (define_insn "*mov<mode>_internal2"
7045 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7046 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7048 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7054 [(set_attr "type" "cmp,logical,cmp")
7055 (set_attr "dot" "yes")
7056 (set_attr "length" "4,4,8")])
7059 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
7060 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
7062 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
7064 [(set (match_dup 0) (match_dup 1))
7066 (compare:CC (match_dup 0)
7070 (define_expand "mov<mode>"
7071 [(set (match_operand:INT 0 "general_operand" "")
7072 (match_operand:INT 1 "any_operand" ""))]
7074 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7076 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7077 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7078 ;; MTVSRWZ MF%1 MT%1 NOP
7079 (define_insn "*mov<mode>_internal"
7080 [(set (match_operand:QHI 0 "nonimmediate_operand"
7081 "=r, r, ?*wJwK, m, Z, r,
7082 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7083 ?*wJwK, r, *c*l, *h")
7085 (match_operand:QHI 1 "input_operand"
7086 "r, m, Z, r, wJwK, i,
7087 wJwK, O, wM, wB, wS, ?*wJwK,
7090 "gpc_reg_operand (operands[0], <MODE>mode)
7091 || gpc_reg_operand (operands[1], <MODE>mode)"
7110 "*, load, fpload, store, fpstore, *,
7111 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7112 mffgpr, mfjmpr, mtjmpr, *")
7120 ;; Here is how to move condition codes around. When we store CC data in
7121 ;; an integer register or memory, we store just the high-order 4 bits.
7122 ;; This lets us not shift in the most common case of CR0.
7123 (define_expand "movcc"
7124 [(set (match_operand:CC 0 "nonimmediate_operand" "")
7125 (match_operand:CC 1 "nonimmediate_operand" ""))]
7129 (define_insn "*movcc_internal1"
7130 [(set (match_operand:CC 0 "nonimmediate_operand"
7131 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7132 (match_operand:CC 1 "general_operand"
7133 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7134 "register_operand (operands[0], CCmode)
7135 || register_operand (operands[1], CCmode)"
7139 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7142 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7150 (cond [(eq_attr "alternative" "0,3")
7151 (const_string "cr_logical")
7152 (eq_attr "alternative" "1,2")
7153 (const_string "mtcr")
7154 (eq_attr "alternative" "6,7")
7155 (const_string "integer")
7156 (eq_attr "alternative" "8")
7157 (const_string "mfjmpr")
7158 (eq_attr "alternative" "9")
7159 (const_string "mtjmpr")
7160 (eq_attr "alternative" "10")
7161 (const_string "load")
7162 (eq_attr "alternative" "11")
7163 (const_string "store")
7164 (match_test "TARGET_MFCRF")
7165 (const_string "mfcrf")
7167 (const_string "mfcr")))
7168 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7170 ;; For floating-point, we normally deal with the floating-point registers
7171 ;; unless -msoft-float is used. The sole exception is that parameter passing
7172 ;; can produce floating-point values in fixed-point registers. Unless the
7173 ;; value is a simple constant or already in memory, we deal with this by
7174 ;; allocating memory and copying the value explicitly via that memory location.
7176 ;; Move 32-bit binary/decimal floating point
7177 (define_expand "mov<mode>"
7178 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7179 (match_operand:FMOVE32 1 "any_operand" ""))]
7181 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7184 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7185 (match_operand:FMOVE32 1 "const_double_operand" ""))]
7187 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7188 || (GET_CODE (operands[0]) == SUBREG
7189 && GET_CODE (SUBREG_REG (operands[0])) == REG
7190 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7191 [(set (match_dup 2) (match_dup 3))]
7196 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7198 if (! TARGET_POWERPC64)
7199 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7201 operands[2] = gen_lowpart (SImode, operands[0]);
7203 operands[3] = gen_int_mode (l, SImode);
7206 ;; Originally, we tried to keep movsf and movsd common, but the differences
7207 ;; addressing was making it rather difficult to hide with mode attributes. In
7208 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7209 ;; before the VSX stores meant that the register allocator would tend to do a
7210 ;; direct move to the GPR (which involves conversion from scalar to
7211 ;; vector/memory formats) to save values in the traditional Altivec registers,
7212 ;; while SDmode had problems on power6 if the GPR store was not first due to
7213 ;; the power6 not having an integer store operation.
7215 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7216 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7217 ;; MR MT<x> MF<x> NOP
7219 (define_insn "movsf_hardfloat"
7220 [(set (match_operand:SF 0 "nonimmediate_operand"
7221 "=!r, f, wb, wu, m, wY,
7222 Z, m, ww, !r, f, ww,
7224 (match_operand:SF 1 "input_operand"
7225 "m, m, wY, Z, f, wb,
7228 "(register_operand (operands[0], SFmode)
7229 || register_operand (operands[1], SFmode))
7230 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7231 && (TARGET_ALLOW_SF_SUBREG
7232 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7245 xscpsgndp %x0,%x1,%x1
7251 "load, fpload, fpload, fpload, fpstore, fpstore,
7252 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7253 *, mtjmpr, mfjmpr, *")])
7255 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7256 ;; FMR MR MT%0 MF%1 NOP
7257 (define_insn "movsd_hardfloat"
7258 [(set (match_operand:SD 0 "nonimmediate_operand"
7259 "=!r, wz, m, Z, ?wh, ?r,
7260 f, !r, *c*l, !r, *h")
7261 (match_operand:SD 1 "input_operand"
7262 "m, Z, r, wx, r, wh,
7264 "(register_operand (operands[0], SDmode)
7265 || register_operand (operands[1], SDmode))
7266 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
7280 "load, fpload, store, fpstore, mffgpr, mftgpr,
7281 fpsimple, *, mtjmpr, mfjmpr, *")])
7283 (define_insn "*mov<mode>_softfloat"
7284 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7285 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7286 "(gpc_reg_operand (operands[0], <MODE>mode)
7287 || gpc_reg_operand (operands[1], <MODE>mode))
7288 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
7300 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7301 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7303 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7304 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7306 ;; Because SF values are actually stored as DF values within the vector
7307 ;; registers, we need to convert the value to the vector SF format when
7308 ;; we need to use the bits in a union or similar cases. We only need
7309 ;; to do this transformation when the value is a vector register. Loads,
7310 ;; stores, and transfers within GPRs are assumed to be safe.
7312 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7313 ;; no alternatives, because the call is created as part of secondary_reload,
7314 ;; and operand #2's register class is used to allocate the temporary register.
7315 ;; This function is called before reload, and it creates the temporary as
7318 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7319 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7320 (define_insn_and_split "movsf_from_si"
7321 [(set (match_operand:SF 0 "rs6000_nonimmediate_operand"
7322 "=!r, f, wb, wu, m, Z,
7325 (unspec:SF [(match_operand:SI 1 "input_operand"
7330 (clobber (match_scratch:DI 2
7334 "TARGET_NO_SF_SUBREG
7335 && (register_operand (operands[0], SFmode)
7336 || register_operand (operands[1], SImode))"
7349 "&& reload_completed
7350 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7351 && int_reg_operand_not_pseudo (operands[1], SImode)"
7354 rtx op0 = operands[0];
7355 rtx op1 = operands[1];
7356 rtx op2 = operands[2];
7357 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7359 /* Move SF value to upper 32-bits for xscvspdpn. */
7360 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7361 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7362 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7369 "load, fpload, fpload, fpload, store, fpstore,
7370 fpstore, vecfloat, mffgpr, *")])
7373 ;; Move 64-bit binary/decimal floating point
7374 (define_expand "mov<mode>"
7375 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7376 (match_operand:FMOVE64 1 "any_operand" ""))]
7378 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7381 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7382 (match_operand:FMOVE64 1 "const_int_operand" ""))]
7383 "! TARGET_POWERPC64 && reload_completed
7384 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7385 || (GET_CODE (operands[0]) == SUBREG
7386 && GET_CODE (SUBREG_REG (operands[0])) == REG
7387 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7388 [(set (match_dup 2) (match_dup 4))
7389 (set (match_dup 3) (match_dup 1))]
7392 int endian = (WORDS_BIG_ENDIAN == 0);
7393 HOST_WIDE_INT value = INTVAL (operands[1]);
7395 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7396 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7397 operands[4] = GEN_INT (value >> 32);
7398 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7402 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7403 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7404 "! TARGET_POWERPC64 && reload_completed
7405 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7406 || (GET_CODE (operands[0]) == SUBREG
7407 && GET_CODE (SUBREG_REG (operands[0])) == REG
7408 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7409 [(set (match_dup 2) (match_dup 4))
7410 (set (match_dup 3) (match_dup 5))]
7413 int endian = (WORDS_BIG_ENDIAN == 0);
7416 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7418 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7419 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7420 operands[4] = gen_int_mode (l[endian], SImode);
7421 operands[5] = gen_int_mode (l[1 - endian], SImode);
7425 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7426 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7427 "TARGET_POWERPC64 && reload_completed
7428 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7429 || (GET_CODE (operands[0]) == SUBREG
7430 && GET_CODE (SUBREG_REG (operands[0])) == REG
7431 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7432 [(set (match_dup 2) (match_dup 3))]
7435 int endian = (WORDS_BIG_ENDIAN == 0);
7439 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7441 operands[2] = gen_lowpart (DImode, operands[0]);
7442 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7443 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7444 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7446 operands[3] = gen_int_mode (val, DImode);
7449 ;; Don't have reload use general registers to load a constant. It is
7450 ;; less efficient than loading the constant into an FP register, since
7451 ;; it will probably be used there.
7453 ;; The move constraints are ordered to prefer floating point registers before
7454 ;; general purpose registers to avoid doing a store and a load to get the value
7455 ;; into a floating point register when it is needed for a floating point
7456 ;; operation. Prefer traditional floating point registers over VSX registers,
7457 ;; since the D-form version of the memory instructions does not need a GPR for
7458 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7461 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7462 ;; except for 0.0 which can be created on VSX with an xor instruction.
7464 (define_insn "*mov<mode>_hardfloat32"
7465 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7466 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7467 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7468 && (gpc_reg_operand (operands[0], <MODE>mode)
7469 || gpc_reg_operand (operands[1], <MODE>mode))"
7484 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7485 (set_attr "size" "64")
7486 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7488 (define_insn "*mov<mode>_softfloat32"
7489 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7490 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7492 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
7493 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
7494 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
7495 && (gpc_reg_operand (operands[0], <MODE>mode)
7496 || gpc_reg_operand (operands[1], <MODE>mode))"
7498 [(set_attr "type" "store,load,two,*,*,*")
7499 (set_attr "length" "8,8,8,8,12,16")])
7501 ; ld/std require word-aligned displacements -> 'Y' constraint.
7502 ; List Y->r and r->Y before r->r for reload.
7503 (define_insn "*mov<mode>_hardfloat64"
7504 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
7505 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
7506 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7507 && (gpc_reg_operand (operands[0], <MODE>mode)
7508 || gpc_reg_operand (operands[1], <MODE>mode))"
7530 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7531 (set_attr "size" "64")
7532 (set_attr "length" "4")])
7534 (define_insn "*mov<mode>_softfloat64"
7535 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7536 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7537 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7538 && (gpc_reg_operand (operands[0], <MODE>mode)
7539 || gpc_reg_operand (operands[1], <MODE>mode))"
7550 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7551 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7553 (define_expand "mov<mode>"
7554 [(set (match_operand:FMOVE128 0 "general_operand" "")
7555 (match_operand:FMOVE128 1 "any_operand" ""))]
7557 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7559 ;; It's important to list Y->r and r->Y before r->r because otherwise
7560 ;; reload, given m->r, will try to pick r->r and reload it, which
7561 ;; doesn't make progress.
7563 ;; We can't split little endian direct moves of TDmode, because the words are
7564 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7565 ;; problematical. Don't allow direct move for this case.
7567 (define_insn_and_split "*mov<mode>_64bit_dm"
7568 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7569 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7570 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
7571 && FLOAT128_2REG_P (<MODE>mode)
7572 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7573 && (gpc_reg_operand (operands[0], <MODE>mode)
7574 || gpc_reg_operand (operands[1], <MODE>mode))"
7576 "&& reload_completed"
7578 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7579 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7581 (define_insn_and_split "*movtd_64bit_nodm"
7582 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7583 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7584 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7585 && (gpc_reg_operand (operands[0], TDmode)
7586 || gpc_reg_operand (operands[1], TDmode))"
7588 "&& reload_completed"
7590 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7591 [(set_attr "length" "8,8,8,12,12,8")])
7593 (define_insn_and_split "*mov<mode>_32bit"
7594 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7595 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7596 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7597 && (FLOAT128_2REG_P (<MODE>mode)
7598 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7599 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7600 && (gpc_reg_operand (operands[0], <MODE>mode)
7601 || gpc_reg_operand (operands[1], <MODE>mode))"
7603 "&& reload_completed"
7605 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7606 [(set_attr "length" "8,8,8,8,20,20,16")])
7608 (define_insn_and_split "*mov<mode>_softfloat"
7609 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7610 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7611 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7612 && (gpc_reg_operand (operands[0], <MODE>mode)
7613 || gpc_reg_operand (operands[1], <MODE>mode))"
7615 "&& reload_completed"
7617 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7618 [(set_attr "length" "20,20,16")])
7620 (define_expand "extenddf<mode>2"
7621 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7622 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7623 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
7624 && TARGET_LONG_DOUBLE_128"
7626 if (FLOAT128_IEEE_P (<MODE>mode))
7627 rs6000_expand_float128_convert (operands[0], operands[1], false);
7628 else if (TARGET_E500_DOUBLE)
7630 gcc_assert (<MODE>mode == TFmode);
7631 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7633 else if (TARGET_VSX)
7635 if (<MODE>mode == TFmode)
7636 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7637 else if (<MODE>mode == IFmode)
7638 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7644 rtx zero = gen_reg_rtx (DFmode);
7645 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7647 if (<MODE>mode == TFmode)
7648 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7649 else if (<MODE>mode == IFmode)
7650 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7657 ;; Allow memory operands for the source to be created by the combiner.
7658 (define_insn_and_split "extenddf<mode>2_fprs"
7659 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7660 (float_extend:IBM128
7661 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7662 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7663 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7664 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7666 "&& reload_completed"
7667 [(set (match_dup 3) (match_dup 1))
7668 (set (match_dup 4) (match_dup 2))]
7670 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7671 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7673 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7674 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7677 (define_insn_and_split "extenddf<mode>2_vsx"
7678 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7679 (float_extend:IBM128
7680 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7681 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7683 "&& reload_completed"
7684 [(set (match_dup 2) (match_dup 1))
7685 (set (match_dup 3) (match_dup 4))]
7687 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7688 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7690 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7691 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7692 operands[4] = CONST0_RTX (DFmode);
7695 (define_expand "extendsf<mode>2"
7696 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7697 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7699 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7700 && TARGET_LONG_DOUBLE_128"
7702 if (FLOAT128_IEEE_P (<MODE>mode))
7703 rs6000_expand_float128_convert (operands[0], operands[1], false);
7706 rtx tmp = gen_reg_rtx (DFmode);
7707 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7708 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7713 (define_expand "trunc<mode>df2"
7714 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7715 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7717 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7718 && TARGET_LONG_DOUBLE_128"
7720 if (FLOAT128_IEEE_P (<MODE>mode))
7722 rs6000_expand_float128_convert (operands[0], operands[1], false);
7727 (define_insn_and_split "trunc<mode>df2_internal1"
7728 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7730 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7731 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7732 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7736 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7739 emit_note (NOTE_INSN_DELETED);
7742 [(set_attr "type" "fpsimple")])
7744 (define_insn "trunc<mode>df2_internal2"
7745 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7746 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7747 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7748 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7750 [(set_attr "type" "fp")
7751 (set_attr "fp_type" "fp_addsub_d")])
7753 (define_expand "trunc<mode>sf2"
7754 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7755 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7757 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7758 && TARGET_LONG_DOUBLE_128"
7760 if (FLOAT128_IEEE_P (<MODE>mode))
7761 rs6000_expand_float128_convert (operands[0], operands[1], false);
7762 else if (TARGET_E500_DOUBLE)
7764 gcc_assert (<MODE>mode == TFmode);
7765 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7767 else if (<MODE>mode == TFmode)
7768 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7769 else if (<MODE>mode == IFmode)
7770 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7776 (define_insn_and_split "trunc<mode>sf2_fprs"
7777 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7778 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7779 (clobber (match_scratch:DF 2 "=d"))]
7780 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7781 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7783 "&& reload_completed"
7785 (float_truncate:DF (match_dup 1)))
7787 (float_truncate:SF (match_dup 2)))]
7790 (define_expand "floatsi<mode>2"
7791 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7792 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7793 (clobber (match_scratch:DI 2))])]
7795 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7796 && TARGET_LONG_DOUBLE_128"
7798 rtx op0 = operands[0];
7799 rtx op1 = operands[1];
7801 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7803 else if (FLOAT128_IEEE_P (<MODE>mode))
7805 rs6000_expand_float128_convert (op0, op1, false);
7810 rtx tmp = gen_reg_rtx (DFmode);
7811 expand_float (tmp, op1, false);
7812 if (<MODE>mode == TFmode)
7813 emit_insn (gen_extenddftf2 (op0, tmp));
7814 else if (<MODE>mode == IFmode)
7815 emit_insn (gen_extenddfif2 (op0, tmp));
7822 ; fadd, but rounding towards zero.
7823 ; This is probably not the optimal code sequence.
7824 (define_insn "fix_trunc_helper<mode>"
7825 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7826 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7827 UNSPEC_FIX_TRUNC_TF))
7828 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7829 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7830 && FLOAT128_IBM_P (<MODE>mode)"
7831 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7832 [(set_attr "type" "fp")
7833 (set_attr "length" "20")])
7835 (define_expand "fix_trunc<mode>si2"
7836 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7837 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7839 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7841 rtx op0 = operands[0];
7842 rtx op1 = operands[1];
7844 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7848 if (FLOAT128_IEEE_P (<MODE>mode))
7849 rs6000_expand_float128_convert (op0, op1, false);
7850 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7851 emit_insn (gen_spe_fix_trunctfsi2 (op0, op1));
7852 else if (<MODE>mode == TFmode)
7853 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7854 else if (<MODE>mode == IFmode)
7855 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7862 (define_expand "fix_trunc<mode>si2_fprs"
7863 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7864 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7865 (clobber (match_dup 2))
7866 (clobber (match_dup 3))
7867 (clobber (match_dup 4))
7868 (clobber (match_dup 5))])]
7869 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7871 operands[2] = gen_reg_rtx (DFmode);
7872 operands[3] = gen_reg_rtx (DFmode);
7873 operands[4] = gen_reg_rtx (DImode);
7874 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7877 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7878 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7879 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7880 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7881 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7882 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7883 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7884 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7890 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7893 gcc_assert (MEM_P (operands[5]));
7894 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7896 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7897 emit_move_insn (operands[5], operands[4]);
7898 emit_move_insn (operands[0], lowword);
7902 (define_expand "fix_trunc<mode>di2"
7903 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7904 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7905 "TARGET_FLOAT128_TYPE"
7907 if (!TARGET_FLOAT128_HW)
7909 rs6000_expand_float128_convert (operands[0], operands[1], false);
7914 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7915 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7916 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7917 "TARGET_FLOAT128_TYPE"
7919 rs6000_expand_float128_convert (operands[0], operands[1], true);
7923 (define_expand "floatdi<mode>2"
7924 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7925 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7926 "TARGET_FLOAT128_TYPE"
7928 if (!TARGET_FLOAT128_HW)
7930 rs6000_expand_float128_convert (operands[0], operands[1], false);
7935 (define_expand "floatunsdi<IEEE128:mode>2"
7936 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7937 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7938 "TARGET_FLOAT128_TYPE"
7940 if (!TARGET_FLOAT128_HW)
7942 rs6000_expand_float128_convert (operands[0], operands[1], true);
7947 (define_expand "floatuns<IEEE128:mode>2"
7948 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7949 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7950 "TARGET_FLOAT128_TYPE"
7952 rtx op0 = operands[0];
7953 rtx op1 = operands[1];
7955 if (TARGET_FLOAT128_HW)
7956 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7958 rs6000_expand_float128_convert (op0, op1, true);
7962 (define_expand "neg<mode>2"
7963 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7964 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7965 "FLOAT128_IEEE_P (<MODE>mode)
7966 || (FLOAT128_IBM_P (<MODE>mode)
7967 && TARGET_HARD_FLOAT
7968 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7971 if (FLOAT128_IEEE_P (<MODE>mode))
7973 if (TARGET_FLOAT128_HW)
7975 if (<MODE>mode == TFmode)
7976 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7977 else if (<MODE>mode == KFmode)
7978 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7982 else if (TARGET_FLOAT128_TYPE)
7984 if (<MODE>mode == TFmode)
7985 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7986 else if (<MODE>mode == KFmode)
7987 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7993 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7994 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7996 operands[1], <MODE>mode);
7998 if (target && !rtx_equal_p (target, operands[0]))
7999 emit_move_insn (operands[0], target);
8005 (define_insn "neg<mode>2_internal"
8006 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8007 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8008 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
8011 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8012 return \"fneg %L0,%L1\;fneg %0,%1\";
8014 return \"fneg %0,%1\;fneg %L0,%L1\";
8016 [(set_attr "type" "fpsimple")
8017 (set_attr "length" "8")])
8019 (define_expand "abs<mode>2"
8020 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
8021 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
8022 "FLOAT128_IEEE_P (<MODE>mode)
8023 || (FLOAT128_IBM_P (<MODE>mode)
8024 && TARGET_HARD_FLOAT
8025 && (TARGET_FPRS || TARGET_E500_DOUBLE))"
8030 if (FLOAT128_IEEE_P (<MODE>mode))
8032 if (TARGET_FLOAT128_HW)
8034 if (<MODE>mode == TFmode)
8035 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
8036 else if (<MODE>mode == KFmode)
8037 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
8042 else if (TARGET_FLOAT128_TYPE)
8044 if (<MODE>mode == TFmode)
8045 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8046 else if (<MODE>mode == KFmode)
8047 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8056 label = gen_label_rtx ();
8057 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
8059 if (flag_finite_math_only && !flag_trapping_math)
8060 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
8062 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
8064 else if (<MODE>mode == TFmode)
8065 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8066 else if (<MODE>mode == TFmode)
8067 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8074 (define_expand "abs<mode>2_internal"
8075 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
8076 (match_operand:IBM128 1 "gpc_reg_operand" ""))
8077 (set (match_dup 3) (match_dup 5))
8078 (set (match_dup 5) (abs:DF (match_dup 5)))
8079 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8080 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8081 (label_ref (match_operand 2 "" ""))
8083 (set (match_dup 6) (neg:DF (match_dup 6)))]
8084 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
8085 && TARGET_LONG_DOUBLE_128"
8088 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8089 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8090 operands[3] = gen_reg_rtx (DFmode);
8091 operands[4] = gen_reg_rtx (CCFPmode);
8092 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8093 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8097 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8100 (define_expand "ieee_128bit_negative_zero"
8101 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8102 "TARGET_FLOAT128_TYPE"
8104 rtvec v = rtvec_alloc (16);
8107 for (i = 0; i < 16; i++)
8108 RTVEC_ELT (v, i) = const0_rtx;
8110 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8111 RTVEC_ELT (v, high) = GEN_INT (0x80);
8113 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8117 ;; IEEE 128-bit negate
8119 ;; We have 2 insns here for negate and absolute value. The first uses
8120 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8121 ;; insns, and second insn after the first split pass loads up the bit to
8122 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8123 ;; neg/abs to create the constant just once.
8125 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8126 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8127 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8128 (clobber (match_scratch:V16QI 2 "=v"))]
8129 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8132 [(parallel [(set (match_dup 0)
8133 (neg:IEEE128 (match_dup 1)))
8134 (use (match_dup 2))])]
8136 if (GET_CODE (operands[2]) == SCRATCH)
8137 operands[2] = gen_reg_rtx (V16QImode);
8139 operands[3] = gen_reg_rtx (V16QImode);
8140 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8142 [(set_attr "length" "8")
8143 (set_attr "type" "vecsimple")])
8145 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8146 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8147 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8148 (use (match_operand:V16QI 2 "register_operand" "v"))]
8149 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8150 "xxlxor %x0,%x1,%x2"
8151 [(set_attr "type" "veclogical")])
8153 ;; IEEE 128-bit absolute value
8154 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8155 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8156 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8157 (clobber (match_scratch:V16QI 2 "=v"))]
8158 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8161 [(parallel [(set (match_dup 0)
8162 (abs:IEEE128 (match_dup 1)))
8163 (use (match_dup 2))])]
8165 if (GET_CODE (operands[2]) == SCRATCH)
8166 operands[2] = gen_reg_rtx (V16QImode);
8168 operands[3] = gen_reg_rtx (V16QImode);
8169 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8171 [(set_attr "length" "8")
8172 (set_attr "type" "vecsimple")])
8174 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8175 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8176 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8177 (use (match_operand:V16QI 2 "register_operand" "v"))]
8178 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8179 "xxlandc %x0,%x1,%x2"
8180 [(set_attr "type" "veclogical")])
8182 ;; IEEE 128-bit negative absolute value
8183 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8184 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8187 (match_operand:IEEE128 1 "register_operand" "wa"))))
8188 (clobber (match_scratch:V16QI 2 "=v"))]
8189 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8190 && FLOAT128_IEEE_P (<MODE>mode)"
8193 [(parallel [(set (match_dup 0)
8194 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8195 (use (match_dup 2))])]
8197 if (GET_CODE (operands[2]) == SCRATCH)
8198 operands[2] = gen_reg_rtx (V16QImode);
8200 operands[3] = gen_reg_rtx (V16QImode);
8201 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8203 [(set_attr "length" "8")
8204 (set_attr "type" "vecsimple")])
8206 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8207 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8210 (match_operand:IEEE128 1 "register_operand" "wa"))))
8211 (use (match_operand:V16QI 2 "register_operand" "v"))]
8212 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8214 [(set_attr "type" "veclogical")])
8216 ;; Float128 conversion functions. These expand to library function calls.
8217 ;; We use expand to convert from IBM double double to IEEE 128-bit
8218 ;; and trunc for the opposite.
8219 (define_expand "extendiftf2"
8220 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8221 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8222 "TARGET_FLOAT128_TYPE"
8224 rs6000_expand_float128_convert (operands[0], operands[1], false);
8228 (define_expand "extendifkf2"
8229 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8230 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8231 "TARGET_FLOAT128_TYPE"
8233 rs6000_expand_float128_convert (operands[0], operands[1], false);
8237 (define_expand "extendtfkf2"
8238 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8239 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8240 "TARGET_FLOAT128_TYPE"
8242 rs6000_expand_float128_convert (operands[0], operands[1], false);
8246 (define_expand "trunciftf2"
8247 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8248 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8249 "TARGET_FLOAT128_TYPE"
8251 rs6000_expand_float128_convert (operands[0], operands[1], false);
8255 (define_expand "truncifkf2"
8256 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8257 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8258 "TARGET_FLOAT128_TYPE"
8260 rs6000_expand_float128_convert (operands[0], operands[1], false);
8264 (define_expand "trunckftf2"
8265 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8266 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8267 "TARGET_FLOAT128_TYPE"
8269 rs6000_expand_float128_convert (operands[0], operands[1], false);
8273 (define_expand "trunctfif2"
8274 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8275 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8276 "TARGET_FLOAT128_TYPE"
8278 rs6000_expand_float128_convert (operands[0], operands[1], false);
8283 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8284 ;; must have 3 arguments, and scratch register constraint must be a single
8287 ;; Reload patterns to support gpr load/store with misaligned mem.
8288 ;; and multiple gpr load/store at offset >= 0xfffc
8289 (define_expand "reload_<mode>_store"
8290 [(parallel [(match_operand 0 "memory_operand" "=m")
8291 (match_operand 1 "gpc_reg_operand" "r")
8292 (match_operand:GPR 2 "register_operand" "=&b")])]
8295 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8299 (define_expand "reload_<mode>_load"
8300 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8301 (match_operand 1 "memory_operand" "m")
8302 (match_operand:GPR 2 "register_operand" "=b")])]
8305 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8310 ;; Reload patterns for various types using the vector registers. We may need
8311 ;; an additional base register to convert the reg+offset addressing to reg+reg
8312 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8313 ;; index register for gpr registers.
8314 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8315 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8316 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8317 (match_operand:P 2 "register_operand" "=b")])]
8320 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8324 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8325 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8326 (match_operand:RELOAD 1 "memory_operand" "m")
8327 (match_operand:P 2 "register_operand" "=b")])]
8330 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8335 ;; Reload sometimes tries to move the address to a GPR, and can generate
8336 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8337 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8339 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8340 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8341 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8342 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8344 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
8346 "&& reload_completed"
8348 (plus:P (match_dup 1)
8351 (and:P (match_dup 0)
8354 ;; Power8 merge instructions to allow direct move to/from floating point
8355 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8356 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8357 ;; value, since it is allocated in reload and not all of the flow information
8358 ;; is setup for it. We have two patterns to do the two moves between gprs and
8359 ;; fprs. There isn't a dependancy between the two, but we could potentially
8360 ;; schedule other instructions between the two instructions.
8362 (define_insn "p8_fmrgow_<mode>"
8363 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8365 (match_operand:DF 1 "register_operand" "d")
8366 (match_operand:DF 2 "register_operand" "d")]
8367 UNSPEC_P8V_FMRGOW))]
8368 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8370 [(set_attr "type" "fpsimple")])
8372 (define_insn "p8_mtvsrwz"
8373 [(set (match_operand:DF 0 "register_operand" "=d")
8374 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8375 UNSPEC_P8V_MTVSRWZ))]
8376 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8378 [(set_attr "type" "mftgpr")])
8380 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8381 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8382 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8383 UNSPEC_P8V_RELOAD_FROM_GPR))
8384 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8385 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8387 "&& reload_completed"
8390 rtx dest = operands[0];
8391 rtx src = operands[1];
8392 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8393 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8394 rtx gpr_hi_reg = gen_highpart (SImode, src);
8395 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8397 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8398 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8399 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8402 [(set_attr "length" "12")
8403 (set_attr "type" "three")])
8405 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8406 (define_insn "p8_mtvsrd_df"
8407 [(set (match_operand:DF 0 "register_operand" "=wa")
8408 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8409 UNSPEC_P8V_MTVSRD))]
8410 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8412 [(set_attr "type" "mftgpr")])
8414 (define_insn "p8_xxpermdi_<mode>"
8415 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8416 (unspec:FMOVE128_GPR [
8417 (match_operand:DF 1 "register_operand" "wa")
8418 (match_operand:DF 2 "register_operand" "wa")]
8419 UNSPEC_P8V_XXPERMDI))]
8420 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8421 "xxpermdi %x0,%x1,%x2,0"
8422 [(set_attr "type" "vecperm")])
8424 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8425 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8426 (unspec:FMOVE128_GPR
8427 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8428 UNSPEC_P8V_RELOAD_FROM_GPR))
8429 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8430 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8432 "&& reload_completed"
8435 rtx dest = operands[0];
8436 rtx src = operands[1];
8437 /* You might think that we could use op0 as one temp and a DF clobber
8438 as op2, but you'd be wrong. Secondary reload move patterns don't
8439 check for overlap of the clobber and the destination. */
8440 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8441 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8442 rtx gpr_hi_reg = gen_highpart (DImode, src);
8443 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8445 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8446 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8447 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8450 [(set_attr "length" "12")
8451 (set_attr "type" "three")])
8454 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8455 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8457 && (int_reg_operand (operands[0], <MODE>mode)
8458 || int_reg_operand (operands[1], <MODE>mode))
8459 && (!TARGET_DIRECT_MOVE_128
8460 || (!vsx_register_operand (operands[0], <MODE>mode)
8461 && !vsx_register_operand (operands[1], <MODE>mode)))"
8463 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8465 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8466 ;; type is stored internally as double precision in the VSX registers, we have
8467 ;; to convert it from the vector format.
8468 (define_insn "p8_mtvsrd_sf"
8469 [(set (match_operand:SF 0 "register_operand" "=wa")
8470 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8471 UNSPEC_P8V_MTVSRD))]
8472 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8474 [(set_attr "type" "mftgpr")])
8476 (define_insn_and_split "reload_vsx_from_gprsf"
8477 [(set (match_operand:SF 0 "register_operand" "=wa")
8478 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8479 UNSPEC_P8V_RELOAD_FROM_GPR))
8480 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8481 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8483 "&& reload_completed"
8486 rtx op0 = operands[0];
8487 rtx op1 = operands[1];
8488 rtx op2 = operands[2];
8489 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8491 /* Move SF value to upper 32-bits for xscvspdpn. */
8492 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8493 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8494 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8497 [(set_attr "length" "8")
8498 (set_attr "type" "two")])
8500 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8501 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8502 ;; and then doing a move of that.
8503 (define_insn "p8_mfvsrd_3_<mode>"
8504 [(set (match_operand:DF 0 "register_operand" "=r")
8505 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8506 UNSPEC_P8V_RELOAD_FROM_VSX))]
8507 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8509 [(set_attr "type" "mftgpr")])
8511 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8512 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8513 (unspec:FMOVE128_GPR
8514 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8515 UNSPEC_P8V_RELOAD_FROM_VSX))
8516 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8517 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8519 "&& reload_completed"
8522 rtx dest = operands[0];
8523 rtx src = operands[1];
8524 rtx tmp = operands[2];
8525 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8526 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8528 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8529 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8530 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8533 [(set_attr "length" "12")
8534 (set_attr "type" "three")])
8536 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8537 ;; type is stored internally as double precision, we have to convert it to the
8540 (define_insn_and_split "reload_gpr_from_vsxsf"
8541 [(set (match_operand:SF 0 "register_operand" "=r")
8542 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8543 UNSPEC_P8V_RELOAD_FROM_VSX))
8544 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8545 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8547 "&& reload_completed"
8550 rtx op0 = operands[0];
8551 rtx op1 = operands[1];
8552 rtx op2 = operands[2];
8553 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
8555 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8556 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
8557 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
8560 [(set_attr "length" "12")
8561 (set_attr "type" "three")])
8563 (define_insn "p8_mfvsrd_4_disf"
8564 [(set (match_operand:DI 0 "register_operand" "=r")
8565 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
8566 UNSPEC_P8V_RELOAD_FROM_VSX))]
8567 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8569 [(set_attr "type" "mftgpr")])
8572 ;; Next come the multi-word integer load and store and the load and store
8575 ;; List r->r after r->Y, otherwise reload will try to reload a
8576 ;; non-offsettable address by using r->r which won't make progress.
8577 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8578 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8580 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8581 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8582 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8585 (define_insn "*movdi_internal32"
8586 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand"
8587 "=Y, r, r, ^m, ^d, ^d,
8588 r, ^wY, $Z, ^wb, $wv, ^wi,
8589 *wo, *wo, *wv, *wi, *wi, *wv,
8592 (match_operand:DI 1 "input_operand"
8594 IJKnGHF, wb, wv, wY, Z, wi,
8595 Oj, wM, OjwM, Oj, wM, wS,
8599 && (gpc_reg_operand (operands[0], DImode)
8600 || gpc_reg_operand (operands[1], DImode))"
8622 "store, load, *, fpstore, fpload, fpsimple,
8623 *, fpstore, fpstore, fpload, fpload, veclogical,
8624 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8626 (set_attr "size" "64")])
8629 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8630 (match_operand:DI 1 "const_int_operand" ""))]
8631 "! TARGET_POWERPC64 && reload_completed
8632 && gpr_or_gpr_p (operands[0], operands[1])
8633 && !direct_move_p (operands[0], operands[1])"
8634 [(set (match_dup 2) (match_dup 4))
8635 (set (match_dup 3) (match_dup 1))]
8638 HOST_WIDE_INT value = INTVAL (operands[1]);
8639 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8641 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8643 operands[4] = GEN_INT (value >> 32);
8644 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8648 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
8649 (match_operand:DIFD 1 "input_operand" ""))]
8650 "reload_completed && !TARGET_POWERPC64
8651 && gpr_or_gpr_p (operands[0], operands[1])
8652 && !direct_move_p (operands[0], operands[1])"
8654 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8656 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8657 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8658 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8659 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8660 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8661 (define_insn "*movdi_internal64"
8662 [(set (match_operand:DI 0 "nonimmediate_operand"
8664 ^m, ^d, ^d, ^wY, $Z, $wb,
8665 $wv, ^wi, *wo, *wo, *wv, *wi,
8666 *wi, *wv, *wv, r, *h, *h,
8667 ?*r, ?*wg, ?*r, ?*wj")
8669 (match_operand:DI 1 "input_operand"
8671 d, m, d, wb, wv, wY,
8672 Z, wi, Oj, wM, OjwM, Oj,
8673 wM, wS, wB, *h, r, 0,
8677 && (gpc_reg_operand (operands[0], DImode)
8678 || gpc_reg_operand (operands[1], DImode))"
8709 "store, load, *, *, *, *,
8710 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8711 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8712 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8713 mftgpr, mffgpr, mftgpr, mffgpr")
8715 (set_attr "size" "64")
8723 ; Some DImode loads are best done as a load of -1 followed by a mask
8726 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8727 (match_operand:DI 1 "const_int_operand"))]
8729 && num_insns_constant (operands[1], DImode) > 1
8730 && rs6000_is_valid_and_mask (operands[1], DImode)"
8734 (and:DI (match_dup 0)
8738 ;; Split a load of a large constant into the appropriate five-instruction
8739 ;; sequence. Handle anything in a constant number of insns.
8740 ;; When non-easy constants can go in the TOC, this should use
8741 ;; easy_fp_constant predicate.
8743 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8744 (match_operand:DI 1 "const_int_operand" ""))]
8745 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8746 [(set (match_dup 0) (match_dup 2))
8747 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8750 if (rs6000_emit_set_const (operands[0], operands[1]))
8757 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8758 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8759 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8760 [(set (match_dup 0) (match_dup 2))
8761 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8764 if (rs6000_emit_set_const (operands[0], operands[1]))
8771 [(set (match_operand:DI 0 "altivec_register_operand" "")
8772 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8773 "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed"
8776 rtx op0 = operands[0];
8777 rtx op1 = operands[1];
8778 int r = REGNO (op0);
8779 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8781 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8782 if (op1 != const0_rtx && op1 != constm1_rtx)
8784 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8785 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8790 ;; Split integer constants that can be loaded with XXSPLTIB and a
8791 ;; sign extend operation.
8793 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8794 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8795 "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed"
8798 rtx op0 = operands[0];
8799 rtx op1 = operands[1];
8800 int r = REGNO (op0);
8801 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8803 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8804 if (<MODE>mode == DImode)
8805 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8806 else if (<MODE>mode == SImode)
8807 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8808 else if (<MODE>mode == HImode)
8810 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8811 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8817 ;; TImode/PTImode is similar, except that we usually want to compute the
8818 ;; address into a register and use lsi/stsi (the exception is during reload).
8820 (define_insn "*mov<mode>_string"
8821 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8822 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8824 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8825 && (gpc_reg_operand (operands[0], <MODE>mode)
8826 || gpc_reg_operand (operands[1], <MODE>mode))"
8829 switch (which_alternative)
8835 return \"stswi %1,%P0,16\";
8840 /* If the address is not used in the output, we can use lsi. Otherwise,
8841 fall through to generating four loads. */
8843 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8844 return \"lswi %0,%P1,16\";
8852 [(set_attr "type" "store,store,load,load,*,*")
8853 (set_attr "update" "yes")
8854 (set_attr "indexed" "yes")
8855 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8856 (const_string "always")
8857 (const_string "conditional")))])
8859 (define_insn "*mov<mode>_ppc64"
8860 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8861 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8862 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8863 && (gpc_reg_operand (operands[0], <MODE>mode)
8864 || gpc_reg_operand (operands[1], <MODE>mode)))"
8866 return rs6000_output_move_128bit (operands);
8868 [(set_attr "type" "store,store,load,load,*,*")
8869 (set_attr "length" "8")])
8872 [(set (match_operand:TI2 0 "int_reg_operand" "")
8873 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8875 && (VECTOR_MEM_NONE_P (<MODE>mode)
8876 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8877 [(set (match_dup 2) (match_dup 4))
8878 (set (match_dup 3) (match_dup 5))]
8881 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8883 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8885 if (CONST_WIDE_INT_P (operands[1]))
8887 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8888 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8890 else if (CONST_INT_P (operands[1]))
8892 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8893 operands[5] = operands[1];
8900 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8901 (match_operand:TI2 1 "input_operand" ""))]
8903 && gpr_or_gpr_p (operands[0], operands[1])
8904 && !direct_move_p (operands[0], operands[1])
8905 && !quad_load_store_p (operands[0], operands[1])"
8907 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8909 (define_expand "load_multiple"
8910 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8911 (match_operand:SI 1 "" ""))
8912 (use (match_operand:SI 2 "" ""))])]
8913 "TARGET_STRING && !TARGET_POWERPC64"
8921 /* Support only loading a constant number of fixed-point registers from
8922 memory and only bother with this if more than two; the machine
8923 doesn't support more than eight. */
8924 if (GET_CODE (operands[2]) != CONST_INT
8925 || INTVAL (operands[2]) <= 2
8926 || INTVAL (operands[2]) > 8
8927 || GET_CODE (operands[1]) != MEM
8928 || GET_CODE (operands[0]) != REG
8929 || REGNO (operands[0]) >= 32)
8932 count = INTVAL (operands[2]);
8933 regno = REGNO (operands[0]);
8935 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8936 op1 = replace_equiv_address (operands[1],
8937 force_reg (SImode, XEXP (operands[1], 0)));
8939 for (i = 0; i < count; i++)
8940 XVECEXP (operands[3], 0, i)
8941 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8942 adjust_address_nv (op1, SImode, i * 4));
8945 (define_insn "*ldmsi8"
8946 [(match_parallel 0 "load_multiple_operation"
8947 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8948 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8949 (set (match_operand:SI 3 "gpc_reg_operand" "")
8950 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8951 (set (match_operand:SI 4 "gpc_reg_operand" "")
8952 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8953 (set (match_operand:SI 5 "gpc_reg_operand" "")
8954 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8955 (set (match_operand:SI 6 "gpc_reg_operand" "")
8956 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8957 (set (match_operand:SI 7 "gpc_reg_operand" "")
8958 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8959 (set (match_operand:SI 8 "gpc_reg_operand" "")
8960 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8961 (set (match_operand:SI 9 "gpc_reg_operand" "")
8962 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8963 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8965 { return rs6000_output_load_multiple (operands); }"
8966 [(set_attr "type" "load")
8967 (set_attr "update" "yes")
8968 (set_attr "indexed" "yes")
8969 (set_attr "length" "32")])
8971 (define_insn "*ldmsi7"
8972 [(match_parallel 0 "load_multiple_operation"
8973 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8974 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8975 (set (match_operand:SI 3 "gpc_reg_operand" "")
8976 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8977 (set (match_operand:SI 4 "gpc_reg_operand" "")
8978 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8979 (set (match_operand:SI 5 "gpc_reg_operand" "")
8980 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8981 (set (match_operand:SI 6 "gpc_reg_operand" "")
8982 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8983 (set (match_operand:SI 7 "gpc_reg_operand" "")
8984 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8985 (set (match_operand:SI 8 "gpc_reg_operand" "")
8986 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8987 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8989 { return rs6000_output_load_multiple (operands); }"
8990 [(set_attr "type" "load")
8991 (set_attr "update" "yes")
8992 (set_attr "indexed" "yes")
8993 (set_attr "length" "32")])
8995 (define_insn "*ldmsi6"
8996 [(match_parallel 0 "load_multiple_operation"
8997 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8998 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8999 (set (match_operand:SI 3 "gpc_reg_operand" "")
9000 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9001 (set (match_operand:SI 4 "gpc_reg_operand" "")
9002 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9003 (set (match_operand:SI 5 "gpc_reg_operand" "")
9004 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9005 (set (match_operand:SI 6 "gpc_reg_operand" "")
9006 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
9007 (set (match_operand:SI 7 "gpc_reg_operand" "")
9008 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
9009 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9011 { return rs6000_output_load_multiple (operands); }"
9012 [(set_attr "type" "load")
9013 (set_attr "update" "yes")
9014 (set_attr "indexed" "yes")
9015 (set_attr "length" "32")])
9017 (define_insn "*ldmsi5"
9018 [(match_parallel 0 "load_multiple_operation"
9019 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9020 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9021 (set (match_operand:SI 3 "gpc_reg_operand" "")
9022 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9023 (set (match_operand:SI 4 "gpc_reg_operand" "")
9024 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9025 (set (match_operand:SI 5 "gpc_reg_operand" "")
9026 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
9027 (set (match_operand:SI 6 "gpc_reg_operand" "")
9028 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
9029 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9031 { return rs6000_output_load_multiple (operands); }"
9032 [(set_attr "type" "load")
9033 (set_attr "update" "yes")
9034 (set_attr "indexed" "yes")
9035 (set_attr "length" "32")])
9037 (define_insn "*ldmsi4"
9038 [(match_parallel 0 "load_multiple_operation"
9039 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9040 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9041 (set (match_operand:SI 3 "gpc_reg_operand" "")
9042 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9043 (set (match_operand:SI 4 "gpc_reg_operand" "")
9044 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
9045 (set (match_operand:SI 5 "gpc_reg_operand" "")
9046 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
9047 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9049 { return rs6000_output_load_multiple (operands); }"
9050 [(set_attr "type" "load")
9051 (set_attr "update" "yes")
9052 (set_attr "indexed" "yes")
9053 (set_attr "length" "32")])
9055 (define_insn "*ldmsi3"
9056 [(match_parallel 0 "load_multiple_operation"
9057 [(set (match_operand:SI 2 "gpc_reg_operand" "")
9058 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
9059 (set (match_operand:SI 3 "gpc_reg_operand" "")
9060 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9061 (set (match_operand:SI 4 "gpc_reg_operand" "")
9062 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
9063 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
9065 { return rs6000_output_load_multiple (operands); }"
9066 [(set_attr "type" "load")
9067 (set_attr "update" "yes")
9068 (set_attr "indexed" "yes")
9069 (set_attr "length" "32")])
9071 (define_expand "store_multiple"
9072 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9073 (match_operand:SI 1 "" ""))
9074 (clobber (scratch:SI))
9075 (use (match_operand:SI 2 "" ""))])]
9076 "TARGET_STRING && !TARGET_POWERPC64"
9085 /* Support only storing a constant number of fixed-point registers to
9086 memory and only bother with this if more than two; the machine
9087 doesn't support more than eight. */
9088 if (GET_CODE (operands[2]) != CONST_INT
9089 || INTVAL (operands[2]) <= 2
9090 || INTVAL (operands[2]) > 8
9091 || GET_CODE (operands[0]) != MEM
9092 || GET_CODE (operands[1]) != REG
9093 || REGNO (operands[1]) >= 32)
9096 count = INTVAL (operands[2]);
9097 regno = REGNO (operands[1]);
9099 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9100 to = force_reg (SImode, XEXP (operands[0], 0));
9101 op0 = replace_equiv_address (operands[0], to);
9103 XVECEXP (operands[3], 0, 0)
9104 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
9105 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9106 gen_rtx_SCRATCH (SImode));
9108 for (i = 1; i < count; i++)
9109 XVECEXP (operands[3], 0, i + 1)
9110 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9111 gen_rtx_REG (SImode, regno + i));
9114 (define_insn "*stmsi8"
9115 [(match_parallel 0 "store_multiple_operation"
9116 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9117 (match_operand:SI 2 "gpc_reg_operand" "r"))
9118 (clobber (match_scratch:SI 3 "=X"))
9119 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9120 (match_operand:SI 4 "gpc_reg_operand" "r"))
9121 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9122 (match_operand:SI 5 "gpc_reg_operand" "r"))
9123 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9124 (match_operand:SI 6 "gpc_reg_operand" "r"))
9125 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9126 (match_operand:SI 7 "gpc_reg_operand" "r"))
9127 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9128 (match_operand:SI 8 "gpc_reg_operand" "r"))
9129 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9130 (match_operand:SI 9 "gpc_reg_operand" "r"))
9131 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9132 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9133 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9135 [(set_attr "type" "store")
9136 (set_attr "update" "yes")
9137 (set_attr "indexed" "yes")
9138 (set_attr "cell_micro" "always")])
9140 (define_insn "*stmsi7"
9141 [(match_parallel 0 "store_multiple_operation"
9142 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9143 (match_operand:SI 2 "gpc_reg_operand" "r"))
9144 (clobber (match_scratch:SI 3 "=X"))
9145 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9146 (match_operand:SI 4 "gpc_reg_operand" "r"))
9147 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9148 (match_operand:SI 5 "gpc_reg_operand" "r"))
9149 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9150 (match_operand:SI 6 "gpc_reg_operand" "r"))
9151 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9152 (match_operand:SI 7 "gpc_reg_operand" "r"))
9153 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9154 (match_operand:SI 8 "gpc_reg_operand" "r"))
9155 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9156 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9157 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9159 [(set_attr "type" "store")
9160 (set_attr "update" "yes")
9161 (set_attr "indexed" "yes")
9162 (set_attr "cell_micro" "always")])
9164 (define_insn "*stmsi6"
9165 [(match_parallel 0 "store_multiple_operation"
9166 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9167 (match_operand:SI 2 "gpc_reg_operand" "r"))
9168 (clobber (match_scratch:SI 3 "=X"))
9169 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9170 (match_operand:SI 4 "gpc_reg_operand" "r"))
9171 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9172 (match_operand:SI 5 "gpc_reg_operand" "r"))
9173 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9174 (match_operand:SI 6 "gpc_reg_operand" "r"))
9175 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9176 (match_operand:SI 7 "gpc_reg_operand" "r"))
9177 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9178 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9179 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9181 [(set_attr "type" "store")
9182 (set_attr "update" "yes")
9183 (set_attr "indexed" "yes")
9184 (set_attr "cell_micro" "always")])
9186 (define_insn "*stmsi5"
9187 [(match_parallel 0 "store_multiple_operation"
9188 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9189 (match_operand:SI 2 "gpc_reg_operand" "r"))
9190 (clobber (match_scratch:SI 3 "=X"))
9191 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9192 (match_operand:SI 4 "gpc_reg_operand" "r"))
9193 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9194 (match_operand:SI 5 "gpc_reg_operand" "r"))
9195 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9196 (match_operand:SI 6 "gpc_reg_operand" "r"))
9197 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9198 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9199 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9201 [(set_attr "type" "store")
9202 (set_attr "update" "yes")
9203 (set_attr "indexed" "yes")
9204 (set_attr "cell_micro" "always")])
9206 (define_insn "*stmsi4"
9207 [(match_parallel 0 "store_multiple_operation"
9208 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9209 (match_operand:SI 2 "gpc_reg_operand" "r"))
9210 (clobber (match_scratch:SI 3 "=X"))
9211 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9212 (match_operand:SI 4 "gpc_reg_operand" "r"))
9213 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9214 (match_operand:SI 5 "gpc_reg_operand" "r"))
9215 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9216 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9217 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9219 [(set_attr "type" "store")
9220 (set_attr "update" "yes")
9221 (set_attr "indexed" "yes")
9222 (set_attr "cell_micro" "always")])
9224 (define_insn "*stmsi3"
9225 [(match_parallel 0 "store_multiple_operation"
9226 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9227 (match_operand:SI 2 "gpc_reg_operand" "r"))
9228 (clobber (match_scratch:SI 3 "=X"))
9229 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9230 (match_operand:SI 4 "gpc_reg_operand" "r"))
9231 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9232 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9233 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9235 [(set_attr "type" "store")
9236 (set_attr "update" "yes")
9237 (set_attr "indexed" "yes")
9238 (set_attr "cell_micro" "always")])
9240 (define_expand "setmemsi"
9241 [(parallel [(set (match_operand:BLK 0 "" "")
9242 (match_operand 2 "const_int_operand" ""))
9243 (use (match_operand:SI 1 "" ""))
9244 (use (match_operand:SI 3 "" ""))])]
9248 /* If value to set is not zero, use the library routine. */
9249 if (operands[2] != const0_rtx)
9252 if (expand_block_clear (operands))
9258 ;; String compare N insn.
9259 ;; Argument 0 is the target (result)
9260 ;; Argument 1 is the destination
9261 ;; Argument 2 is the source
9262 ;; Argument 3 is the length
9263 ;; Argument 4 is the alignment
9265 (define_expand "cmpstrnsi"
9266 [(parallel [(set (match_operand:SI 0)
9267 (compare:SI (match_operand:BLK 1)
9268 (match_operand:BLK 2)))
9269 (use (match_operand:SI 3))
9270 (use (match_operand:SI 4))])]
9271 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9273 if (optimize_insn_for_size_p ())
9276 if (expand_strn_compare (operands, 0))
9282 ;; String compare insn.
9283 ;; Argument 0 is the target (result)
9284 ;; Argument 1 is the destination
9285 ;; Argument 2 is the source
9286 ;; Argument 3 is the alignment
9288 (define_expand "cmpstrsi"
9289 [(parallel [(set (match_operand:SI 0)
9290 (compare:SI (match_operand:BLK 1)
9291 (match_operand:BLK 2)))
9292 (use (match_operand:SI 3))])]
9293 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9295 if (optimize_insn_for_size_p ())
9298 if (expand_strn_compare (operands, 1))
9304 ;; Block compare insn.
9305 ;; Argument 0 is the target (result)
9306 ;; Argument 1 is the destination
9307 ;; Argument 2 is the source
9308 ;; Argument 3 is the length
9309 ;; Argument 4 is the alignment
9311 (define_expand "cmpmemsi"
9312 [(parallel [(set (match_operand:SI 0)
9313 (compare:SI (match_operand:BLK 1)
9314 (match_operand:BLK 2)))
9315 (use (match_operand:SI 3))
9316 (use (match_operand:SI 4))])]
9319 if (expand_block_compare (operands))
9325 ;; String/block move insn.
9326 ;; Argument 0 is the destination
9327 ;; Argument 1 is the source
9328 ;; Argument 2 is the length
9329 ;; Argument 3 is the alignment
9331 (define_expand "movmemsi"
9332 [(parallel [(set (match_operand:BLK 0 "" "")
9333 (match_operand:BLK 1 "" ""))
9334 (use (match_operand:SI 2 "" ""))
9335 (use (match_operand:SI 3 "" ""))])]
9339 if (expand_block_move (operands))
9345 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
9346 ;; register allocator doesn't have a clue about allocating 8 word registers.
9347 ;; rD/rS = r5 is preferred, efficient form.
9348 (define_expand "movmemsi_8reg"
9349 [(parallel [(set (match_operand 0 "" "")
9350 (match_operand 1 "" ""))
9351 (use (match_operand 2 "" ""))
9352 (use (match_operand 3 "" ""))
9353 (clobber (reg:SI 5))
9354 (clobber (reg:SI 6))
9355 (clobber (reg:SI 7))
9356 (clobber (reg:SI 8))
9357 (clobber (reg:SI 9))
9358 (clobber (reg:SI 10))
9359 (clobber (reg:SI 11))
9360 (clobber (reg:SI 12))
9361 (clobber (match_scratch:SI 4 ""))])]
9366 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9367 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9368 (use (match_operand:SI 2 "immediate_operand" "i"))
9369 (use (match_operand:SI 3 "immediate_operand" "i"))
9370 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9371 (clobber (reg:SI 6))
9372 (clobber (reg:SI 7))
9373 (clobber (reg:SI 8))
9374 (clobber (reg:SI 9))
9375 (clobber (reg:SI 10))
9376 (clobber (reg:SI 11))
9377 (clobber (reg:SI 12))
9378 (clobber (match_scratch:SI 5 "=X"))]
9380 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9381 || INTVAL (operands[2]) == 0)
9382 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9383 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9384 && REGNO (operands[4]) == 5"
9385 "lswi %4,%1,%2\;stswi %4,%0,%2"
9386 [(set_attr "type" "store")
9387 (set_attr "update" "yes")
9388 (set_attr "indexed" "yes")
9389 (set_attr "cell_micro" "always")
9390 (set_attr "length" "8")])
9392 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
9393 ;; register allocator doesn't have a clue about allocating 6 word registers.
9394 ;; rD/rS = r5 is preferred, efficient form.
9395 (define_expand "movmemsi_6reg"
9396 [(parallel [(set (match_operand 0 "" "")
9397 (match_operand 1 "" ""))
9398 (use (match_operand 2 "" ""))
9399 (use (match_operand 3 "" ""))
9400 (clobber (reg:SI 5))
9401 (clobber (reg:SI 6))
9402 (clobber (reg:SI 7))
9403 (clobber (reg:SI 8))
9404 (clobber (reg:SI 9))
9405 (clobber (reg:SI 10))
9406 (clobber (match_scratch:SI 4 ""))])]
9411 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9412 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9413 (use (match_operand:SI 2 "immediate_operand" "i"))
9414 (use (match_operand:SI 3 "immediate_operand" "i"))
9415 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9416 (clobber (reg:SI 6))
9417 (clobber (reg:SI 7))
9418 (clobber (reg:SI 8))
9419 (clobber (reg:SI 9))
9420 (clobber (reg:SI 10))
9421 (clobber (match_scratch:SI 5 "=X"))]
9423 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9424 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9425 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9426 && REGNO (operands[4]) == 5"
9427 "lswi %4,%1,%2\;stswi %4,%0,%2"
9428 [(set_attr "type" "store")
9429 (set_attr "update" "yes")
9430 (set_attr "indexed" "yes")
9431 (set_attr "cell_micro" "always")
9432 (set_attr "length" "8")])
9434 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9435 ;; problems with TImode.
9436 ;; rD/rS = r5 is preferred, efficient form.
9437 (define_expand "movmemsi_4reg"
9438 [(parallel [(set (match_operand 0 "" "")
9439 (match_operand 1 "" ""))
9440 (use (match_operand 2 "" ""))
9441 (use (match_operand 3 "" ""))
9442 (clobber (reg:SI 5))
9443 (clobber (reg:SI 6))
9444 (clobber (reg:SI 7))
9445 (clobber (reg:SI 8))
9446 (clobber (match_scratch:SI 4 ""))])]
9451 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9452 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9453 (use (match_operand:SI 2 "immediate_operand" "i"))
9454 (use (match_operand:SI 3 "immediate_operand" "i"))
9455 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9456 (clobber (reg:SI 6))
9457 (clobber (reg:SI 7))
9458 (clobber (reg:SI 8))
9459 (clobber (match_scratch:SI 5 "=X"))]
9461 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9462 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9463 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9464 && REGNO (operands[4]) == 5"
9465 "lswi %4,%1,%2\;stswi %4,%0,%2"
9466 [(set_attr "type" "store")
9467 (set_attr "update" "yes")
9468 (set_attr "indexed" "yes")
9469 (set_attr "cell_micro" "always")
9470 (set_attr "length" "8")])
9472 ;; Move up to 8 bytes at a time.
9473 (define_expand "movmemsi_2reg"
9474 [(parallel [(set (match_operand 0 "" "")
9475 (match_operand 1 "" ""))
9476 (use (match_operand 2 "" ""))
9477 (use (match_operand 3 "" ""))
9478 (clobber (match_scratch:DI 4 ""))
9479 (clobber (match_scratch:SI 5 ""))])]
9480 "TARGET_STRING && ! TARGET_POWERPC64"
9484 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9485 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9486 (use (match_operand:SI 2 "immediate_operand" "i"))
9487 (use (match_operand:SI 3 "immediate_operand" "i"))
9488 (clobber (match_scratch:DI 4 "=&r"))
9489 (clobber (match_scratch:SI 5 "=X"))]
9490 "TARGET_STRING && ! TARGET_POWERPC64
9491 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9492 "lswi %4,%1,%2\;stswi %4,%0,%2"
9493 [(set_attr "type" "store")
9494 (set_attr "update" "yes")
9495 (set_attr "indexed" "yes")
9496 (set_attr "cell_micro" "always")
9497 (set_attr "length" "8")])
9499 ;; Move up to 4 bytes at a time.
9500 (define_expand "movmemsi_1reg"
9501 [(parallel [(set (match_operand 0 "" "")
9502 (match_operand 1 "" ""))
9503 (use (match_operand 2 "" ""))
9504 (use (match_operand 3 "" ""))
9505 (clobber (match_scratch:SI 4 ""))
9506 (clobber (match_scratch:SI 5 ""))])]
9511 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9512 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9513 (use (match_operand:SI 2 "immediate_operand" "i"))
9514 (use (match_operand:SI 3 "immediate_operand" "i"))
9515 (clobber (match_scratch:SI 4 "=&r"))
9516 (clobber (match_scratch:SI 5 "=X"))]
9517 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9518 "lswi %4,%1,%2\;stswi %4,%0,%2"
9519 [(set_attr "type" "store")
9520 (set_attr "update" "yes")
9521 (set_attr "indexed" "yes")
9522 (set_attr "cell_micro" "always")
9523 (set_attr "length" "8")])
9525 ;; Define insns that do load or store with update. Some of these we can
9526 ;; get by using pre-decrement or pre-increment, but the hardware can also
9527 ;; do cases where the increment is not the size of the object.
9529 ;; In all these cases, we use operands 0 and 1 for the register being
9530 ;; incremented because those are the operands that local-alloc will
9531 ;; tie and these are the pair most likely to be tieable (and the ones
9532 ;; that will benefit the most).
9534 (define_insn "*movdi_update1"
9535 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9536 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9537 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9538 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9539 (plus:DI (match_dup 1) (match_dup 2)))]
9540 "TARGET_POWERPC64 && TARGET_UPDATE
9541 && (!avoiding_indexed_address_p (DImode)
9542 || !gpc_reg_operand (operands[2], DImode))"
9546 [(set_attr "type" "load")
9547 (set_attr "update" "yes")
9548 (set_attr "indexed" "yes,no")])
9550 (define_insn "movdi_<mode>_update"
9551 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9552 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9553 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9554 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9555 (plus:P (match_dup 1) (match_dup 2)))]
9556 "TARGET_POWERPC64 && TARGET_UPDATE
9557 && (!avoiding_indexed_address_p (Pmode)
9558 || !gpc_reg_operand (operands[2], Pmode)
9559 || (REG_P (operands[0])
9560 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9564 [(set_attr "type" "store")
9565 (set_attr "update" "yes")
9566 (set_attr "indexed" "yes,no")])
9568 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9569 ;; needed for stack allocation, even if the user passes -mno-update.
9570 (define_insn "movdi_<mode>_update_stack"
9571 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9572 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9573 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9574 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9575 (plus:P (match_dup 1) (match_dup 2)))]
9580 [(set_attr "type" "store")
9581 (set_attr "update" "yes")
9582 (set_attr "indexed" "yes,no")])
9584 (define_insn "*movsi_update1"
9585 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9586 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9587 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9588 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9589 (plus:SI (match_dup 1) (match_dup 2)))]
9591 && (!avoiding_indexed_address_p (SImode)
9592 || !gpc_reg_operand (operands[2], SImode))"
9596 [(set_attr "type" "load")
9597 (set_attr "update" "yes")
9598 (set_attr "indexed" "yes,no")])
9600 (define_insn "*movsi_update2"
9601 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9603 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9604 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9605 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9606 (plus:DI (match_dup 1) (match_dup 2)))]
9607 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
9608 && !avoiding_indexed_address_p (DImode)"
9610 [(set_attr "type" "load")
9611 (set_attr "sign_extend" "yes")
9612 (set_attr "update" "yes")
9613 (set_attr "indexed" "yes")])
9615 (define_insn "movsi_update"
9616 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9617 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9618 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9619 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9620 (plus:SI (match_dup 1) (match_dup 2)))]
9622 && (!avoiding_indexed_address_p (SImode)
9623 || !gpc_reg_operand (operands[2], SImode)
9624 || (REG_P (operands[0])
9625 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9629 [(set_attr "type" "store")
9630 (set_attr "update" "yes")
9631 (set_attr "indexed" "yes,no")])
9633 ;; This is an unconditional pattern; needed for stack allocation, even
9634 ;; if the user passes -mno-update.
9635 (define_insn "movsi_update_stack"
9636 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9637 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9638 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9639 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9640 (plus:SI (match_dup 1) (match_dup 2)))]
9645 [(set_attr "type" "store")
9646 (set_attr "update" "yes")
9647 (set_attr "indexed" "yes,no")])
9649 (define_insn "*movhi_update1"
9650 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9651 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9652 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9653 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9654 (plus:SI (match_dup 1) (match_dup 2)))]
9656 && (!avoiding_indexed_address_p (SImode)
9657 || !gpc_reg_operand (operands[2], SImode))"
9661 [(set_attr "type" "load")
9662 (set_attr "update" "yes")
9663 (set_attr "indexed" "yes,no")])
9665 (define_insn "*movhi_update2"
9666 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9668 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9669 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9670 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9671 (plus:SI (match_dup 1) (match_dup 2)))]
9673 && (!avoiding_indexed_address_p (SImode)
9674 || !gpc_reg_operand (operands[2], SImode))"
9678 [(set_attr "type" "load")
9679 (set_attr "update" "yes")
9680 (set_attr "indexed" "yes,no")])
9682 (define_insn "*movhi_update3"
9683 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9685 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9686 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9687 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9688 (plus:SI (match_dup 1) (match_dup 2)))]
9689 "TARGET_UPDATE && rs6000_gen_cell_microcode
9690 && (!avoiding_indexed_address_p (SImode)
9691 || !gpc_reg_operand (operands[2], SImode))"
9695 [(set_attr "type" "load")
9696 (set_attr "sign_extend" "yes")
9697 (set_attr "update" "yes")
9698 (set_attr "indexed" "yes,no")])
9700 (define_insn "*movhi_update4"
9701 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9702 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9703 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9704 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9705 (plus:SI (match_dup 1) (match_dup 2)))]
9707 && (!avoiding_indexed_address_p (SImode)
9708 || !gpc_reg_operand (operands[2], SImode))"
9712 [(set_attr "type" "store")
9713 (set_attr "update" "yes")
9714 (set_attr "indexed" "yes,no")])
9716 (define_insn "*movqi_update1"
9717 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9718 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9719 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9720 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9721 (plus:SI (match_dup 1) (match_dup 2)))]
9723 && (!avoiding_indexed_address_p (SImode)
9724 || !gpc_reg_operand (operands[2], SImode))"
9728 [(set_attr "type" "load")
9729 (set_attr "update" "yes")
9730 (set_attr "indexed" "yes,no")])
9732 (define_insn "*movqi_update2"
9733 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9735 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9736 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9737 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9738 (plus:SI (match_dup 1) (match_dup 2)))]
9740 && (!avoiding_indexed_address_p (SImode)
9741 || !gpc_reg_operand (operands[2], SImode))"
9745 [(set_attr "type" "load")
9746 (set_attr "update" "yes")
9747 (set_attr "indexed" "yes,no")])
9749 (define_insn "*movqi_update3"
9750 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9751 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9752 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9753 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9754 (plus:SI (match_dup 1) (match_dup 2)))]
9756 && (!avoiding_indexed_address_p (SImode)
9757 || !gpc_reg_operand (operands[2], SImode))"
9761 [(set_attr "type" "store")
9762 (set_attr "update" "yes")
9763 (set_attr "indexed" "yes,no")])
9765 (define_insn "*movsf_update1"
9766 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9767 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9768 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9769 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9770 (plus:SI (match_dup 1) (match_dup 2)))]
9771 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9772 && (!avoiding_indexed_address_p (SImode)
9773 || !gpc_reg_operand (operands[2], SImode))"
9777 [(set_attr "type" "fpload")
9778 (set_attr "update" "yes")
9779 (set_attr "indexed" "yes,no")])
9781 (define_insn "*movsf_update2"
9782 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9783 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9784 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9785 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9786 (plus:SI (match_dup 1) (match_dup 2)))]
9787 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9788 && (!avoiding_indexed_address_p (SImode)
9789 || !gpc_reg_operand (operands[2], SImode))"
9793 [(set_attr "type" "fpstore")
9794 (set_attr "update" "yes")
9795 (set_attr "indexed" "yes,no")])
9797 (define_insn "*movsf_update3"
9798 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9799 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9800 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9801 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9802 (plus:SI (match_dup 1) (match_dup 2)))]
9803 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9804 && (!avoiding_indexed_address_p (SImode)
9805 || !gpc_reg_operand (operands[2], SImode))"
9809 [(set_attr "type" "load")
9810 (set_attr "update" "yes")
9811 (set_attr "indexed" "yes,no")])
9813 (define_insn "*movsf_update4"
9814 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9815 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9816 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9817 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9818 (plus:SI (match_dup 1) (match_dup 2)))]
9819 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
9820 && (!avoiding_indexed_address_p (SImode)
9821 || !gpc_reg_operand (operands[2], SImode))"
9825 [(set_attr "type" "store")
9826 (set_attr "update" "yes")
9827 (set_attr "indexed" "yes,no")])
9829 (define_insn "*movdf_update1"
9830 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9831 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9832 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9833 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9834 (plus:SI (match_dup 1) (match_dup 2)))]
9835 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9836 && (!avoiding_indexed_address_p (SImode)
9837 || !gpc_reg_operand (operands[2], SImode))"
9841 [(set_attr "type" "fpload")
9842 (set_attr "update" "yes")
9843 (set_attr "indexed" "yes,no")
9844 (set_attr "size" "64")])
9846 (define_insn "*movdf_update2"
9847 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9848 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9849 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9850 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9851 (plus:SI (match_dup 1) (match_dup 2)))]
9852 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9853 && (!avoiding_indexed_address_p (SImode)
9854 || !gpc_reg_operand (operands[2], SImode))"
9858 [(set_attr "type" "fpstore")
9859 (set_attr "update" "yes")
9860 (set_attr "indexed" "yes,no")])
9863 ;; After inserting conditional returns we can sometimes have
9864 ;; unnecessary register moves. Unfortunately we cannot have a
9865 ;; modeless peephole here, because some single SImode sets have early
9866 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9867 ;; sequences, using get_attr_length here will smash the operands
9868 ;; array. Neither is there an early_cobbler_p predicate.
9869 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9870 ;; Also this optimization interferes with scalars going into
9871 ;; altivec registers (the code does reloading through the FPRs).
9873 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9874 (match_operand:DF 1 "any_operand" ""))
9875 (set (match_operand:DF 2 "gpc_reg_operand" "")
9877 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9878 && !TARGET_UPPER_REGS_DF
9879 && peep2_reg_dead_p (2, operands[0])"
9880 [(set (match_dup 2) (match_dup 1))])
9883 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9884 (match_operand:SF 1 "any_operand" ""))
9885 (set (match_operand:SF 2 "gpc_reg_operand" "")
9887 "!TARGET_UPPER_REGS_SF
9888 && peep2_reg_dead_p (2, operands[0])"
9889 [(set (match_dup 2) (match_dup 1))])
9894 ;; Mode attributes for different ABIs.
9895 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9896 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9897 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9898 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9900 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9901 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9902 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9903 (match_operand 4 "" "g")))
9904 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9905 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9907 (clobber (reg:SI LR_REGNO))]
9908 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9910 if (TARGET_CMODEL != CMODEL_SMALL)
9911 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9914 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9916 "&& TARGET_TLS_MARKERS"
9918 (unspec:TLSmode [(match_dup 1)
9921 (parallel [(set (match_dup 0)
9922 (call (mem:TLSmode (match_dup 3))
9924 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9925 (clobber (reg:SI LR_REGNO))])]
9927 [(set_attr "type" "two")
9928 (set (attr "length")
9929 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9933 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9934 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9935 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9936 (match_operand 4 "" "g")))
9937 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9938 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9940 (clobber (reg:SI LR_REGNO))]
9941 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9945 if (TARGET_SECURE_PLT && flag_pic == 2)
9946 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9948 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9951 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9953 "&& TARGET_TLS_MARKERS"
9955 (unspec:TLSmode [(match_dup 1)
9958 (parallel [(set (match_dup 0)
9959 (call (mem:TLSmode (match_dup 3))
9961 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9962 (clobber (reg:SI LR_REGNO))])]
9964 [(set_attr "type" "two")
9965 (set_attr "length" "8")])
9967 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9968 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9969 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9970 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9972 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9973 "addi %0,%1,%2@got@tlsgd"
9974 "&& TARGET_CMODEL != CMODEL_SMALL"
9977 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9979 (lo_sum:TLSmode (match_dup 3)
9980 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9983 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9985 [(set (attr "length")
9986 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9990 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9991 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9993 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9994 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9996 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9997 "addis %0,%1,%2@got@tlsgd@ha"
9998 [(set_attr "length" "4")])
10000 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
10001 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10002 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10003 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10004 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10006 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10007 "addi %0,%1,%2@got@tlsgd@l"
10008 [(set_attr "length" "4")])
10010 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
10011 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10012 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10013 (match_operand 2 "" "g")))
10014 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10016 (clobber (reg:SI LR_REGNO))]
10017 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10018 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10019 "bl %z1(%3@tlsgd)\;nop"
10020 [(set_attr "type" "branch")
10021 (set_attr "length" "8")])
10023 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
10024 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10025 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10026 (match_operand 2 "" "g")))
10027 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
10029 (clobber (reg:SI LR_REGNO))]
10030 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10034 if (TARGET_SECURE_PLT && flag_pic == 2)
10035 return "bl %z1+32768(%3@tlsgd)@plt";
10036 return "bl %z1(%3@tlsgd)@plt";
10038 return "bl %z1(%3@tlsgd)";
10040 [(set_attr "type" "branch")
10041 (set_attr "length" "4")])
10043 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
10044 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10045 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10046 (match_operand 3 "" "g")))
10047 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10049 (clobber (reg:SI LR_REGNO))]
10050 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10052 if (TARGET_CMODEL != CMODEL_SMALL)
10053 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
10056 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
10058 "&& TARGET_TLS_MARKERS"
10059 [(set (match_dup 0)
10060 (unspec:TLSmode [(match_dup 1)]
10062 (parallel [(set (match_dup 0)
10063 (call (mem:TLSmode (match_dup 2))
10065 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10066 (clobber (reg:SI LR_REGNO))])]
10068 [(set_attr "type" "two")
10069 (set (attr "length")
10070 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10074 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
10075 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10076 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10077 (match_operand 3 "" "g")))
10078 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10080 (clobber (reg:SI LR_REGNO))]
10081 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
10085 if (TARGET_SECURE_PLT && flag_pic == 2)
10086 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
10088 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
10091 return "addi %0,%1,%&@got@tlsld\;bl %z2";
10093 "&& TARGET_TLS_MARKERS"
10094 [(set (match_dup 0)
10095 (unspec:TLSmode [(match_dup 1)]
10097 (parallel [(set (match_dup 0)
10098 (call (mem:TLSmode (match_dup 2))
10100 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10101 (clobber (reg:SI LR_REGNO))])]
10103 [(set_attr "length" "8")])
10105 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10106 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10107 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10109 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10110 "addi %0,%1,%&@got@tlsld"
10111 "&& TARGET_CMODEL != CMODEL_SMALL"
10112 [(set (match_dup 2)
10114 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10116 (lo_sum:TLSmode (match_dup 2)
10117 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10120 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10122 [(set (attr "length")
10123 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10127 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10128 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10130 (unspec:TLSmode [(const_int 0)
10131 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10133 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10134 "addis %0,%1,%&@got@tlsld@ha"
10135 [(set_attr "length" "4")])
10137 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10138 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10139 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10140 (unspec:TLSmode [(const_int 0)
10141 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10143 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10144 "addi %0,%1,%&@got@tlsld@l"
10145 [(set_attr "length" "4")])
10147 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10148 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10149 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10150 (match_operand 2 "" "g")))
10151 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10152 (clobber (reg:SI LR_REGNO))]
10153 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10154 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10155 "bl %z1(%&@tlsld)\;nop"
10156 [(set_attr "type" "branch")
10157 (set_attr "length" "8")])
10159 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10160 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10161 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10162 (match_operand 2 "" "g")))
10163 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10164 (clobber (reg:SI LR_REGNO))]
10165 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10169 if (TARGET_SECURE_PLT && flag_pic == 2)
10170 return "bl %z1+32768(%&@tlsld)@plt";
10171 return "bl %z1(%&@tlsld)@plt";
10173 return "bl %z1(%&@tlsld)";
10175 [(set_attr "type" "branch")
10176 (set_attr "length" "4")])
10178 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10179 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10180 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10181 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10182 UNSPEC_TLSDTPREL))]
10184 "addi %0,%1,%2@dtprel")
10186 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10187 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10188 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10189 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10190 UNSPEC_TLSDTPRELHA))]
10192 "addis %0,%1,%2@dtprel@ha")
10194 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10195 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10196 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10197 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10198 UNSPEC_TLSDTPRELLO))]
10200 "addi %0,%1,%2@dtprel@l")
10202 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10203 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10204 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10205 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10206 UNSPEC_TLSGOTDTPREL))]
10208 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10209 "&& TARGET_CMODEL != CMODEL_SMALL"
10210 [(set (match_dup 3)
10212 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10214 (lo_sum:TLSmode (match_dup 3)
10215 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10218 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10220 [(set (attr "length")
10221 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10225 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10226 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10228 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10229 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10230 UNSPEC_TLSGOTDTPREL)))]
10231 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10232 "addis %0,%1,%2@got@dtprel@ha"
10233 [(set_attr "length" "4")])
10235 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10236 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10237 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10238 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10239 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10240 UNSPEC_TLSGOTDTPREL)))]
10241 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10242 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10243 [(set_attr "length" "4")])
10245 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10246 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10247 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10248 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10251 "addi %0,%1,%2@tprel")
10253 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10254 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10255 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10256 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10257 UNSPEC_TLSTPRELHA))]
10259 "addis %0,%1,%2@tprel@ha")
10261 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10262 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10263 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10264 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10265 UNSPEC_TLSTPRELLO))]
10267 "addi %0,%1,%2@tprel@l")
10269 ;; "b" output constraint here and on tls_tls input to support linker tls
10270 ;; optimization. The linker may edit the instructions emitted by a
10271 ;; tls_got_tprel/tls_tls pair to addis,addi.
10272 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10273 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10274 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10275 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10276 UNSPEC_TLSGOTTPREL))]
10278 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10279 "&& TARGET_CMODEL != CMODEL_SMALL"
10280 [(set (match_dup 3)
10282 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10284 (lo_sum:TLSmode (match_dup 3)
10285 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10288 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10290 [(set (attr "length")
10291 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10295 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10296 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10298 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10299 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10300 UNSPEC_TLSGOTTPREL)))]
10301 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10302 "addis %0,%1,%2@got@tprel@ha"
10303 [(set_attr "length" "4")])
10305 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10306 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10307 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10308 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10309 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10310 UNSPEC_TLSGOTTPREL)))]
10311 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10312 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10313 [(set_attr "length" "4")])
10315 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10316 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10317 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10318 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10320 "TARGET_ELF && HAVE_AS_TLS"
10321 "add %0,%1,%2@tls")
10323 (define_expand "tls_get_tpointer"
10324 [(set (match_operand:SI 0 "gpc_reg_operand" "")
10325 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10326 "TARGET_XCOFF && HAVE_AS_TLS"
10329 emit_insn (gen_tls_get_tpointer_internal ());
10330 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10334 (define_insn "tls_get_tpointer_internal"
10336 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10337 (clobber (reg:SI LR_REGNO))]
10338 "TARGET_XCOFF && HAVE_AS_TLS"
10339 "bla __get_tpointer")
10341 (define_expand "tls_get_addr<mode>"
10342 [(set (match_operand:P 0 "gpc_reg_operand" "")
10343 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10344 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10345 "TARGET_XCOFF && HAVE_AS_TLS"
10348 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10349 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10350 emit_insn (gen_tls_get_addr_internal<mode> ());
10351 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10355 (define_insn "tls_get_addr_internal<mode>"
10357 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10358 (clobber (reg:P 0))
10359 (clobber (reg:P 4))
10360 (clobber (reg:P 5))
10361 (clobber (reg:P 11))
10362 (clobber (reg:CC CR0_REGNO))
10363 (clobber (reg:P LR_REGNO))]
10364 "TARGET_XCOFF && HAVE_AS_TLS"
10365 "bla __tls_get_addr")
10367 ;; Next come insns related to the calling sequence.
10369 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10370 ;; We move the back-chain and decrement the stack pointer.
10372 (define_expand "allocate_stack"
10373 [(set (match_operand 0 "gpc_reg_operand" "")
10374 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
10376 (minus (reg 1) (match_dup 1)))]
10379 { rtx chain = gen_reg_rtx (Pmode);
10380 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10382 rtx insn, par, set, mem;
10384 emit_move_insn (chain, stack_bot);
10386 /* Check stack bounds if necessary. */
10387 if (crtl->limit_stack)
10390 available = expand_binop (Pmode, sub_optab,
10391 stack_pointer_rtx, stack_limit_rtx,
10392 NULL_RTX, 1, OPTAB_WIDEN);
10393 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10396 if (GET_CODE (operands[1]) != CONST_INT
10397 || INTVAL (operands[1]) < -32767
10398 || INTVAL (operands[1]) > 32768)
10400 neg_op0 = gen_reg_rtx (Pmode);
10402 emit_insn (gen_negsi2 (neg_op0, operands[1]));
10404 emit_insn (gen_negdi2 (neg_op0, operands[1]));
10407 neg_op0 = GEN_INT (- INTVAL (operands[1]));
10409 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10410 : gen_movdi_di_update_stack))
10411 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10413 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10414 it now and set the alias set/attributes. The above gen_*_update
10415 calls will generate a PARALLEL with the MEM set being the first
10417 par = PATTERN (insn);
10418 gcc_assert (GET_CODE (par) == PARALLEL);
10419 set = XVECEXP (par, 0, 0);
10420 gcc_assert (GET_CODE (set) == SET);
10421 mem = SET_DEST (set);
10422 gcc_assert (MEM_P (mem));
10423 MEM_NOTRAP_P (mem) = 1;
10424 set_mem_alias_set (mem, get_frame_alias_set ());
10426 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10430 ;; These patterns say how to save and restore the stack pointer. We need not
10431 ;; save the stack pointer at function level since we are careful to
10432 ;; preserve the backchain. At block level, we have to restore the backchain
10433 ;; when we restore the stack pointer.
10435 ;; For nonlocal gotos, we must save both the stack pointer and its
10436 ;; backchain and restore both. Note that in the nonlocal case, the
10437 ;; save area is a memory location.
10439 (define_expand "save_stack_function"
10440 [(match_operand 0 "any_operand" "")
10441 (match_operand 1 "any_operand" "")]
10445 (define_expand "restore_stack_function"
10446 [(match_operand 0 "any_operand" "")
10447 (match_operand 1 "any_operand" "")]
10451 ;; Adjust stack pointer (op0) to a new value (op1).
10452 ;; First copy old stack backchain to new location, and ensure that the
10453 ;; scheduler won't reorder the sp assignment before the backchain write.
10454 (define_expand "restore_stack_block"
10455 [(set (match_dup 2) (match_dup 3))
10456 (set (match_dup 4) (match_dup 2))
10458 (set (match_operand 0 "register_operand" "")
10459 (match_operand 1 "register_operand" ""))]
10465 operands[1] = force_reg (Pmode, operands[1]);
10466 operands[2] = gen_reg_rtx (Pmode);
10467 operands[3] = gen_frame_mem (Pmode, operands[0]);
10468 operands[4] = gen_frame_mem (Pmode, operands[1]);
10469 p = rtvec_alloc (1);
10470 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10472 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10475 (define_expand "save_stack_nonlocal"
10476 [(set (match_dup 3) (match_dup 4))
10477 (set (match_operand 0 "memory_operand" "") (match_dup 3))
10478 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10482 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10484 /* Copy the backchain to the first word, sp to the second. */
10485 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10486 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10487 operands[3] = gen_reg_rtx (Pmode);
10488 operands[4] = gen_frame_mem (Pmode, operands[1]);
10491 (define_expand "restore_stack_nonlocal"
10492 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10493 (set (match_dup 3) (match_dup 4))
10494 (set (match_dup 5) (match_dup 2))
10496 (set (match_operand 0 "register_operand" "") (match_dup 3))]
10500 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10503 /* Restore the backchain from the first word, sp from the second. */
10504 operands[2] = gen_reg_rtx (Pmode);
10505 operands[3] = gen_reg_rtx (Pmode);
10506 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10507 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10508 operands[5] = gen_frame_mem (Pmode, operands[3]);
10509 p = rtvec_alloc (1);
10510 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10512 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10515 ;; TOC register handling.
10517 ;; Code to initialize the TOC register...
10519 (define_insn "load_toc_aix_si"
10520 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10521 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10522 (use (reg:SI 2))])]
10523 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10527 extern int need_toc_init;
10529 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10530 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10531 operands[2] = gen_rtx_REG (Pmode, 2);
10532 return \"lwz %0,%1(%2)\";
10534 [(set_attr "type" "load")
10535 (set_attr "update" "no")
10536 (set_attr "indexed" "no")])
10538 (define_insn "load_toc_aix_di"
10539 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10540 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10541 (use (reg:DI 2))])]
10542 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10546 extern int need_toc_init;
10548 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10549 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10551 strcat (buf, \"@toc\");
10552 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10553 operands[2] = gen_rtx_REG (Pmode, 2);
10554 return \"ld %0,%1(%2)\";
10556 [(set_attr "type" "load")
10557 (set_attr "update" "no")
10558 (set_attr "indexed" "no")])
10560 (define_insn "load_toc_v4_pic_si"
10561 [(set (reg:SI LR_REGNO)
10562 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10563 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10564 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10565 [(set_attr "type" "branch")
10566 (set_attr "length" "4")])
10568 (define_expand "load_toc_v4_PIC_1"
10569 [(parallel [(set (reg:SI LR_REGNO)
10570 (match_operand:SI 0 "immediate_operand" "s"))
10571 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10572 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10573 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10576 (define_insn "load_toc_v4_PIC_1_normal"
10577 [(set (reg:SI LR_REGNO)
10578 (match_operand:SI 0 "immediate_operand" "s"))
10579 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10580 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10581 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10582 "bcl 20,31,%0\\n%0:"
10583 [(set_attr "type" "branch")
10584 (set_attr "length" "4")
10585 (set_attr "cannot_copy" "yes")])
10587 (define_insn "load_toc_v4_PIC_1_476"
10588 [(set (reg:SI LR_REGNO)
10589 (match_operand:SI 0 "immediate_operand" "s"))
10590 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10591 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10592 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10596 static char templ[32];
10598 get_ppc476_thunk_name (name);
10599 sprintf (templ, \"bl %s\\n%%0:\", name);
10602 [(set_attr "type" "branch")
10603 (set_attr "length" "4")
10604 (set_attr "cannot_copy" "yes")])
10606 (define_expand "load_toc_v4_PIC_1b"
10607 [(parallel [(set (reg:SI LR_REGNO)
10608 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10609 (label_ref (match_operand 1 "" ""))]
10612 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10615 (define_insn "load_toc_v4_PIC_1b_normal"
10616 [(set (reg:SI LR_REGNO)
10617 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10618 (label_ref (match_operand 1 "" ""))]
10621 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10622 "bcl 20,31,$+8\;.long %0-$"
10623 [(set_attr "type" "branch")
10624 (set_attr "length" "8")])
10626 (define_insn "load_toc_v4_PIC_1b_476"
10627 [(set (reg:SI LR_REGNO)
10628 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10629 (label_ref (match_operand 1 "" ""))]
10632 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10636 static char templ[32];
10638 get_ppc476_thunk_name (name);
10639 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10642 [(set_attr "type" "branch")
10643 (set_attr "length" "16")])
10645 (define_insn "load_toc_v4_PIC_2"
10646 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10647 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10648 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10649 (match_operand:SI 3 "immediate_operand" "s")))))]
10650 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10652 [(set_attr "type" "load")])
10654 (define_insn "load_toc_v4_PIC_3b"
10655 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10656 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10658 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10659 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10660 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10661 "addis %0,%1,%2-%3@ha")
10663 (define_insn "load_toc_v4_PIC_3c"
10664 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10665 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10666 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10667 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10668 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10669 "addi %0,%1,%2-%3@l")
10671 ;; If the TOC is shared over a translation unit, as happens with all
10672 ;; the kinds of PIC that we support, we need to restore the TOC
10673 ;; pointer only when jumping over units of translation.
10674 ;; On Darwin, we need to reload the picbase.
10676 (define_expand "builtin_setjmp_receiver"
10677 [(use (label_ref (match_operand 0 "" "")))]
10678 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10679 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10680 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10684 if (DEFAULT_ABI == ABI_DARWIN)
10686 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10687 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10691 crtl->uses_pic_offset_table = 1;
10692 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10693 CODE_LABEL_NUMBER (operands[0]));
10694 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10696 emit_insn (gen_load_macho_picbase (tmplabrtx));
10697 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10698 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10702 rs6000_emit_load_toc_table (FALSE);
10706 ;; Largetoc support
10707 (define_insn "*largetoc_high"
10708 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10710 (unspec [(match_operand:DI 1 "" "")
10711 (match_operand:DI 2 "gpc_reg_operand" "b")]
10713 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10714 "addis %0,%2,%1@toc@ha")
10716 (define_insn "*largetoc_high_aix<mode>"
10717 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10719 (unspec [(match_operand:P 1 "" "")
10720 (match_operand:P 2 "gpc_reg_operand" "b")]
10722 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10723 "addis %0,%1@u(%2)")
10725 (define_insn "*largetoc_high_plus"
10726 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10729 (unspec [(match_operand:DI 1 "" "")
10730 (match_operand:DI 2 "gpc_reg_operand" "b")]
10732 (match_operand:DI 3 "add_cint_operand" "n"))))]
10733 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10734 "addis %0,%2,%1+%3@toc@ha")
10736 (define_insn "*largetoc_high_plus_aix<mode>"
10737 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10740 (unspec [(match_operand:P 1 "" "")
10741 (match_operand:P 2 "gpc_reg_operand" "b")]
10743 (match_operand:P 3 "add_cint_operand" "n"))))]
10744 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10745 "addis %0,%1+%3@u(%2)")
10747 (define_insn "*largetoc_low"
10748 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10749 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10750 (match_operand:DI 2 "" "")))]
10751 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10754 (define_insn "*largetoc_low_aix<mode>"
10755 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10756 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10757 (match_operand:P 2 "" "")))]
10758 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10761 (define_insn_and_split "*tocref<mode>"
10762 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10763 (match_operand:P 1 "small_toc_ref" "R"))]
10766 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10767 [(set (match_dup 0) (high:P (match_dup 1)))
10768 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10770 ;; Elf specific ways of loading addresses for non-PIC code.
10771 ;; The output of this could be r0, but we make a very strong
10772 ;; preference for a base register because it will usually
10773 ;; be needed there.
10774 (define_insn "elf_high"
10775 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10776 (high:SI (match_operand 1 "" "")))]
10777 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10780 (define_insn "elf_low"
10781 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10782 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10783 (match_operand 2 "" "")))]
10784 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10787 ;; Call and call_value insns
10788 (define_expand "call"
10789 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10790 (match_operand 1 "" ""))
10791 (use (match_operand 2 "" ""))
10792 (clobber (reg:SI LR_REGNO))])]
10797 if (MACHOPIC_INDIRECT)
10798 operands[0] = machopic_indirect_call_target (operands[0]);
10801 gcc_assert (GET_CODE (operands[0]) == MEM);
10802 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10804 operands[0] = XEXP (operands[0], 0);
10806 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10808 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10812 if (GET_CODE (operands[0]) != SYMBOL_REF
10813 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10815 if (INTVAL (operands[2]) & CALL_LONG)
10816 operands[0] = rs6000_longcall_ref (operands[0]);
10818 switch (DEFAULT_ABI)
10822 operands[0] = force_reg (Pmode, operands[0]);
10826 gcc_unreachable ();
10831 (define_expand "call_value"
10832 [(parallel [(set (match_operand 0 "" "")
10833 (call (mem:SI (match_operand 1 "address_operand" ""))
10834 (match_operand 2 "" "")))
10835 (use (match_operand 3 "" ""))
10836 (clobber (reg:SI LR_REGNO))])]
10841 if (MACHOPIC_INDIRECT)
10842 operands[1] = machopic_indirect_call_target (operands[1]);
10845 gcc_assert (GET_CODE (operands[1]) == MEM);
10846 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10848 operands[1] = XEXP (operands[1], 0);
10850 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10852 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10856 if (GET_CODE (operands[1]) != SYMBOL_REF
10857 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10859 if (INTVAL (operands[3]) & CALL_LONG)
10860 operands[1] = rs6000_longcall_ref (operands[1]);
10862 switch (DEFAULT_ABI)
10866 operands[1] = force_reg (Pmode, operands[1]);
10870 gcc_unreachable ();
10875 ;; Call to function in current module. No TOC pointer reload needed.
10876 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10877 ;; either the function was not prototyped, or it was prototyped as a
10878 ;; variable argument function. It is > 0 if FP registers were passed
10879 ;; and < 0 if they were not.
10881 (define_insn "*call_local32"
10882 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10883 (match_operand 1 "" "g,g"))
10884 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10885 (clobber (reg:SI LR_REGNO))]
10886 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10889 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10890 output_asm_insn (\"crxor 6,6,6\", operands);
10892 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10893 output_asm_insn (\"creqv 6,6,6\", operands);
10895 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10897 [(set_attr "type" "branch")
10898 (set_attr "length" "4,8")])
10900 (define_insn "*call_local64"
10901 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10902 (match_operand 1 "" "g,g"))
10903 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10904 (clobber (reg:SI LR_REGNO))]
10905 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10908 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10909 output_asm_insn (\"crxor 6,6,6\", operands);
10911 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10912 output_asm_insn (\"creqv 6,6,6\", operands);
10914 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10916 [(set_attr "type" "branch")
10917 (set_attr "length" "4,8")])
10919 (define_insn "*call_value_local32"
10920 [(set (match_operand 0 "" "")
10921 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10922 (match_operand 2 "" "g,g")))
10923 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10924 (clobber (reg:SI LR_REGNO))]
10925 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10928 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10929 output_asm_insn (\"crxor 6,6,6\", operands);
10931 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10932 output_asm_insn (\"creqv 6,6,6\", operands);
10934 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10936 [(set_attr "type" "branch")
10937 (set_attr "length" "4,8")])
10940 (define_insn "*call_value_local64"
10941 [(set (match_operand 0 "" "")
10942 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10943 (match_operand 2 "" "g,g")))
10944 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10945 (clobber (reg:SI LR_REGNO))]
10946 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10949 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10950 output_asm_insn (\"crxor 6,6,6\", operands);
10952 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10953 output_asm_insn (\"creqv 6,6,6\", operands);
10955 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10957 [(set_attr "type" "branch")
10958 (set_attr "length" "4,8")])
10961 ;; A function pointer under System V is just a normal pointer
10962 ;; operands[0] is the function pointer
10963 ;; operands[1] is the stack size to clean up
10964 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10965 ;; which indicates how to set cr1
10967 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10968 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10969 (match_operand 1 "" "g,g,g,g"))
10970 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10971 (clobber (reg:SI LR_REGNO))]
10972 "DEFAULT_ABI == ABI_V4
10973 || DEFAULT_ABI == ABI_DARWIN"
10975 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10976 output_asm_insn ("crxor 6,6,6", operands);
10978 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10979 output_asm_insn ("creqv 6,6,6", operands);
10983 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10984 (set_attr "length" "4,4,8,8")])
10986 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10987 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10988 (match_operand 1 "" "g,g"))
10989 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10990 (clobber (reg:SI LR_REGNO))]
10991 "(DEFAULT_ABI == ABI_DARWIN
10992 || (DEFAULT_ABI == ABI_V4
10993 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10995 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10996 output_asm_insn ("crxor 6,6,6", operands);
10998 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10999 output_asm_insn ("creqv 6,6,6", operands);
11002 return output_call(insn, operands, 0, 2);
11004 if (DEFAULT_ABI == ABI_V4 && flag_pic)
11006 gcc_assert (!TARGET_SECURE_PLT);
11007 return "bl %z0@plt";
11013 "DEFAULT_ABI == ABI_V4
11014 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11015 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11016 [(parallel [(call (mem:SI (match_dup 0))
11018 (use (match_dup 2))
11019 (use (match_dup 3))
11020 (clobber (reg:SI LR_REGNO))])]
11022 operands[3] = pic_offset_table_rtx;
11024 [(set_attr "type" "branch,branch")
11025 (set_attr "length" "4,8")])
11027 (define_insn "*call_nonlocal_sysv_secure<mode>"
11028 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11029 (match_operand 1 "" "g,g"))
11030 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11031 (use (match_operand:SI 3 "register_operand" "r,r"))
11032 (clobber (reg:SI LR_REGNO))]
11033 "(DEFAULT_ABI == ABI_V4
11034 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11035 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11037 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11038 output_asm_insn ("crxor 6,6,6", operands);
11040 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11041 output_asm_insn ("creqv 6,6,6", operands);
11044 /* The magic 32768 offset here and in the other sysv call insns
11045 corresponds to the offset of r30 in .got2, as given by LCTOC1.
11046 See sysv4.h:toc_section. */
11047 return "bl %z0+32768@plt";
11049 return "bl %z0@plt";
11051 [(set_attr "type" "branch,branch")
11052 (set_attr "length" "4,8")])
11054 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11055 [(set (match_operand 0 "" "")
11056 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11057 (match_operand 2 "" "g,g,g,g")))
11058 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11059 (clobber (reg:SI LR_REGNO))]
11060 "DEFAULT_ABI == ABI_V4
11061 || DEFAULT_ABI == ABI_DARWIN"
11063 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11064 output_asm_insn ("crxor 6,6,6", operands);
11066 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11067 output_asm_insn ("creqv 6,6,6", operands);
11071 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11072 (set_attr "length" "4,4,8,8")])
11074 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11075 [(set (match_operand 0 "" "")
11076 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11077 (match_operand 2 "" "g,g")))
11078 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11079 (clobber (reg:SI LR_REGNO))]
11080 "(DEFAULT_ABI == ABI_DARWIN
11081 || (DEFAULT_ABI == ABI_V4
11082 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11084 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11085 output_asm_insn ("crxor 6,6,6", operands);
11087 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11088 output_asm_insn ("creqv 6,6,6", operands);
11091 return output_call(insn, operands, 1, 3);
11093 if (DEFAULT_ABI == ABI_V4 && flag_pic)
11095 gcc_assert (!TARGET_SECURE_PLT);
11096 return "bl %z1@plt";
11102 "DEFAULT_ABI == ABI_V4
11103 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11104 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11105 [(parallel [(set (match_dup 0)
11106 (call (mem:SI (match_dup 1))
11108 (use (match_dup 3))
11109 (use (match_dup 4))
11110 (clobber (reg:SI LR_REGNO))])]
11112 operands[4] = pic_offset_table_rtx;
11114 [(set_attr "type" "branch,branch")
11115 (set_attr "length" "4,8")])
11117 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11118 [(set (match_operand 0 "" "")
11119 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11120 (match_operand 2 "" "g,g")))
11121 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11122 (use (match_operand:SI 4 "register_operand" "r,r"))
11123 (clobber (reg:SI LR_REGNO))]
11124 "(DEFAULT_ABI == ABI_V4
11125 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11126 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11128 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11129 output_asm_insn ("crxor 6,6,6", operands);
11131 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11132 output_asm_insn ("creqv 6,6,6", operands);
11135 return "bl %z1+32768@plt";
11137 return "bl %z1@plt";
11139 [(set_attr "type" "branch,branch")
11140 (set_attr "length" "4,8")])
11143 ;; Call to AIX abi function in the same module.
11145 (define_insn "*call_local_aix<mode>"
11146 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11147 (match_operand 1 "" "g"))
11148 (clobber (reg:P LR_REGNO))]
11149 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11151 [(set_attr "type" "branch")
11152 (set_attr "length" "4")])
11154 (define_insn "*call_value_local_aix<mode>"
11155 [(set (match_operand 0 "" "")
11156 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11157 (match_operand 2 "" "g")))
11158 (clobber (reg:P LR_REGNO))]
11159 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11161 [(set_attr "type" "branch")
11162 (set_attr "length" "4")])
11164 ;; Call to AIX abi function which may be in another module.
11165 ;; Restore the TOC pointer (r2) after the call.
11167 (define_insn "*call_nonlocal_aix<mode>"
11168 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11169 (match_operand 1 "" "g"))
11170 (clobber (reg:P LR_REGNO))]
11171 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11173 [(set_attr "type" "branch")
11174 (set_attr "length" "8")])
11176 (define_insn "*call_value_nonlocal_aix<mode>"
11177 [(set (match_operand 0 "" "")
11178 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11179 (match_operand 2 "" "g")))
11180 (clobber (reg:P LR_REGNO))]
11181 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11183 [(set_attr "type" "branch")
11184 (set_attr "length" "8")])
11186 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11187 ;; Operand0 is the addresss of the function to call
11188 ;; Operand2 is the location in the function descriptor to load r2 from
11189 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11191 (define_insn "*call_indirect_aix<mode>"
11192 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11193 (match_operand 1 "" "g,g"))
11194 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11195 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11196 (clobber (reg:P LR_REGNO))]
11197 "DEFAULT_ABI == ABI_AIX"
11198 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11199 [(set_attr "type" "jmpreg")
11200 (set_attr "length" "12")])
11202 (define_insn "*call_value_indirect_aix<mode>"
11203 [(set (match_operand 0 "" "")
11204 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11205 (match_operand 2 "" "g,g")))
11206 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11207 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11208 (clobber (reg:P LR_REGNO))]
11209 "DEFAULT_ABI == ABI_AIX"
11210 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11211 [(set_attr "type" "jmpreg")
11212 (set_attr "length" "12")])
11214 ;; Call to indirect functions with the ELFv2 ABI.
11215 ;; Operand0 is the addresss of the function to call
11216 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11218 (define_insn "*call_indirect_elfv2<mode>"
11219 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11220 (match_operand 1 "" "g,g"))
11221 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11222 (clobber (reg:P LR_REGNO))]
11223 "DEFAULT_ABI == ABI_ELFv2"
11224 "b%T0l\;<ptrload> 2,%2(1)"
11225 [(set_attr "type" "jmpreg")
11226 (set_attr "length" "8")])
11228 (define_insn "*call_value_indirect_elfv2<mode>"
11229 [(set (match_operand 0 "" "")
11230 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11231 (match_operand 2 "" "g,g")))
11232 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11233 (clobber (reg:P LR_REGNO))]
11234 "DEFAULT_ABI == ABI_ELFv2"
11235 "b%T1l\;<ptrload> 2,%3(1)"
11236 [(set_attr "type" "jmpreg")
11237 (set_attr "length" "8")])
11240 ;; Call subroutine returning any type.
11241 (define_expand "untyped_call"
11242 [(parallel [(call (match_operand 0 "" "")
11244 (match_operand 1 "" "")
11245 (match_operand 2 "" "")])]
11251 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11253 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11255 rtx set = XVECEXP (operands[2], 0, i);
11256 emit_move_insn (SET_DEST (set), SET_SRC (set));
11259 /* The optimizer does not know that the call sets the function value
11260 registers we stored in the result block. We avoid problems by
11261 claiming that all hard registers are used and clobbered at this
11263 emit_insn (gen_blockage ());
11268 ;; sibling call patterns
11269 (define_expand "sibcall"
11270 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11271 (match_operand 1 "" ""))
11272 (use (match_operand 2 "" ""))
11278 if (MACHOPIC_INDIRECT)
11279 operands[0] = machopic_indirect_call_target (operands[0]);
11282 gcc_assert (GET_CODE (operands[0]) == MEM);
11283 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11285 operands[0] = XEXP (operands[0], 0);
11287 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11289 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11294 (define_expand "sibcall_value"
11295 [(parallel [(set (match_operand 0 "register_operand" "")
11296 (call (mem:SI (match_operand 1 "address_operand" ""))
11297 (match_operand 2 "" "")))
11298 (use (match_operand 3 "" ""))
11304 if (MACHOPIC_INDIRECT)
11305 operands[1] = machopic_indirect_call_target (operands[1]);
11308 gcc_assert (GET_CODE (operands[1]) == MEM);
11309 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11311 operands[1] = XEXP (operands[1], 0);
11313 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11315 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11320 (define_insn "*sibcall_local32"
11321 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11322 (match_operand 1 "" "g,g"))
11323 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11325 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11328 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11329 output_asm_insn (\"crxor 6,6,6\", operands);
11331 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11332 output_asm_insn (\"creqv 6,6,6\", operands);
11334 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11336 [(set_attr "type" "branch")
11337 (set_attr "length" "4,8")])
11339 (define_insn "*sibcall_local64"
11340 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11341 (match_operand 1 "" "g,g"))
11342 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11344 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11347 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11348 output_asm_insn (\"crxor 6,6,6\", operands);
11350 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11351 output_asm_insn (\"creqv 6,6,6\", operands);
11353 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11355 [(set_attr "type" "branch")
11356 (set_attr "length" "4,8")])
11358 (define_insn "*sibcall_value_local32"
11359 [(set (match_operand 0 "" "")
11360 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11361 (match_operand 2 "" "g,g")))
11362 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11364 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11367 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11368 output_asm_insn (\"crxor 6,6,6\", operands);
11370 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11371 output_asm_insn (\"creqv 6,6,6\", operands);
11373 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11375 [(set_attr "type" "branch")
11376 (set_attr "length" "4,8")])
11378 (define_insn "*sibcall_value_local64"
11379 [(set (match_operand 0 "" "")
11380 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11381 (match_operand 2 "" "g,g")))
11382 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11384 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11387 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11388 output_asm_insn (\"crxor 6,6,6\", operands);
11390 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11391 output_asm_insn (\"creqv 6,6,6\", operands);
11393 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11395 [(set_attr "type" "branch")
11396 (set_attr "length" "4,8")])
11398 (define_insn "*sibcall_nonlocal_sysv<mode>"
11399 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11400 (match_operand 1 "" ""))
11401 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11403 "(DEFAULT_ABI == ABI_DARWIN
11404 || DEFAULT_ABI == ABI_V4)
11405 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11408 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11409 output_asm_insn (\"crxor 6,6,6\", operands);
11411 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11412 output_asm_insn (\"creqv 6,6,6\", operands);
11414 if (which_alternative >= 2)
11416 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11418 gcc_assert (!TARGET_SECURE_PLT);
11419 return \"b %z0@plt\";
11424 [(set_attr "type" "branch")
11425 (set_attr "length" "4,8,4,8")])
11427 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11428 [(set (match_operand 0 "" "")
11429 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11430 (match_operand 2 "" "")))
11431 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11433 "(DEFAULT_ABI == ABI_DARWIN
11434 || DEFAULT_ABI == ABI_V4)
11435 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11438 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11439 output_asm_insn (\"crxor 6,6,6\", operands);
11441 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11442 output_asm_insn (\"creqv 6,6,6\", operands);
11444 if (which_alternative >= 2)
11446 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11448 gcc_assert (!TARGET_SECURE_PLT);
11449 return \"b %z1@plt\";
11454 [(set_attr "type" "branch")
11455 (set_attr "length" "4,8,4,8")])
11457 ;; AIX ABI sibling call patterns.
11459 (define_insn "*sibcall_aix<mode>"
11460 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11461 (match_operand 1 "" "g,g"))
11463 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11467 [(set_attr "type" "branch")
11468 (set_attr "length" "4")])
11470 (define_insn "*sibcall_value_aix<mode>"
11471 [(set (match_operand 0 "" "")
11472 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11473 (match_operand 2 "" "g,g")))
11475 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11479 [(set_attr "type" "branch")
11480 (set_attr "length" "4")])
11482 (define_expand "sibcall_epilogue"
11483 [(use (const_int 0))]
11486 if (!TARGET_SCHED_PROLOG)
11487 emit_insn (gen_blockage ());
11488 rs6000_emit_epilogue (TRUE);
11492 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11493 ;; all of memory. This blocks insns from being moved across this point.
11495 (define_insn "blockage"
11496 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11500 (define_expand "probe_stack_address"
11501 [(use (match_operand 0 "address_operand"))]
11504 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11505 MEM_VOLATILE_P (operands[0]) = 1;
11508 emit_insn (gen_probe_stack_di (operands[0]));
11510 emit_insn (gen_probe_stack_si (operands[0]));
11514 (define_insn "probe_stack_<mode>"
11515 [(set (match_operand:P 0 "memory_operand" "=m")
11516 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11519 operands[1] = gen_rtx_REG (Pmode, 0);
11520 return "st<wd>%U0%X0 %1,%0";
11522 [(set_attr "type" "store")
11523 (set (attr "update")
11524 (if_then_else (match_operand 0 "update_address_mem")
11525 (const_string "yes")
11526 (const_string "no")))
11527 (set (attr "indexed")
11528 (if_then_else (match_operand 0 "indexed_address_mem")
11529 (const_string "yes")
11530 (const_string "no")))
11531 (set_attr "length" "4")])
11533 (define_insn "probe_stack_range<P:mode>"
11534 [(set (match_operand:P 0 "register_operand" "=r")
11535 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11536 (match_operand:P 2 "register_operand" "r")]
11537 UNSPECV_PROBE_STACK_RANGE))]
11539 "* return output_probe_stack_range (operands[0], operands[2]);"
11540 [(set_attr "type" "three")])
11542 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11543 ;; signed & unsigned, and one type of branch.
11545 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11546 ;; insns, and branches.
11548 (define_expand "cbranch<mode>4"
11549 [(use (match_operator 0 "rs6000_cbranch_operator"
11550 [(match_operand:GPR 1 "gpc_reg_operand" "")
11551 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11552 (use (match_operand 3 ""))]
11556 /* Take care of the possibility that operands[2] might be negative but
11557 this might be a logical operation. That insn doesn't exist. */
11558 if (GET_CODE (operands[2]) == CONST_INT
11559 && INTVAL (operands[2]) < 0)
11561 operands[2] = force_reg (<MODE>mode, operands[2]);
11562 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11563 GET_MODE (operands[0]),
11564 operands[1], operands[2]);
11567 rs6000_emit_cbranch (<MODE>mode, operands);
11571 (define_expand "cbranch<mode>4"
11572 [(use (match_operator 0 "rs6000_cbranch_operator"
11573 [(match_operand:FP 1 "gpc_reg_operand" "")
11574 (match_operand:FP 2 "gpc_reg_operand" "")]))
11575 (use (match_operand 3 ""))]
11579 rs6000_emit_cbranch (<MODE>mode, operands);
11583 (define_expand "cstore<mode>4_signed"
11584 [(use (match_operator 1 "signed_comparison_operator"
11585 [(match_operand:P 2 "gpc_reg_operand")
11586 (match_operand:P 3 "gpc_reg_operand")]))
11587 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11590 enum rtx_code cond_code = GET_CODE (operands[1]);
11592 rtx op0 = operands[0];
11593 rtx op1 = operands[2];
11594 rtx op2 = operands[3];
11596 if (cond_code == GE || cond_code == LT)
11598 cond_code = swap_condition (cond_code);
11599 std::swap (op1, op2);
11602 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11603 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11604 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11606 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11607 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11608 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11610 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11612 if (cond_code == LE)
11613 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11616 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11617 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11618 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11624 (define_expand "cstore<mode>4_unsigned"
11625 [(use (match_operator 1 "unsigned_comparison_operator"
11626 [(match_operand:P 2 "gpc_reg_operand")
11627 (match_operand:P 3 "reg_or_short_operand")]))
11628 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11631 enum rtx_code cond_code = GET_CODE (operands[1]);
11633 rtx op0 = operands[0];
11634 rtx op1 = operands[2];
11635 rtx op2 = operands[3];
11637 if (cond_code == GEU || cond_code == LTU)
11639 cond_code = swap_condition (cond_code);
11640 std::swap (op1, op2);
11643 if (!gpc_reg_operand (op1, <MODE>mode))
11644 op1 = force_reg (<MODE>mode, op1);
11645 if (!reg_or_short_operand (op2, <MODE>mode))
11646 op2 = force_reg (<MODE>mode, op2);
11648 rtx tmp = gen_reg_rtx (<MODE>mode);
11649 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11651 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11652 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11654 if (cond_code == LEU)
11655 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11657 emit_insn (gen_neg<mode>2 (op0, tmp2));
11662 (define_expand "cstore_si_as_di"
11663 [(use (match_operator 1 "unsigned_comparison_operator"
11664 [(match_operand:SI 2 "gpc_reg_operand")
11665 (match_operand:SI 3 "reg_or_short_operand")]))
11666 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11669 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11670 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11672 operands[2] = force_reg (SImode, operands[2]);
11673 operands[3] = force_reg (SImode, operands[3]);
11674 rtx op1 = gen_reg_rtx (DImode);
11675 rtx op2 = gen_reg_rtx (DImode);
11676 convert_move (op1, operands[2], uns_flag);
11677 convert_move (op2, operands[3], uns_flag);
11679 if (cond_code == GT || cond_code == LE)
11681 cond_code = swap_condition (cond_code);
11682 std::swap (op1, op2);
11685 rtx tmp = gen_reg_rtx (DImode);
11686 rtx tmp2 = gen_reg_rtx (DImode);
11687 emit_insn (gen_subdi3 (tmp, op1, op2));
11688 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11694 gcc_unreachable ();
11699 tmp3 = gen_reg_rtx (DImode);
11700 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11704 convert_move (operands[0], tmp3, 1);
11709 (define_expand "cstore<mode>4_signed_imm"
11710 [(use (match_operator 1 "signed_comparison_operator"
11711 [(match_operand:GPR 2 "gpc_reg_operand")
11712 (match_operand:GPR 3 "immediate_operand")]))
11713 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11716 bool invert = false;
11718 enum rtx_code cond_code = GET_CODE (operands[1]);
11720 rtx op0 = operands[0];
11721 rtx op1 = operands[2];
11722 HOST_WIDE_INT val = INTVAL (operands[3]);
11724 if (cond_code == GE || cond_code == GT)
11726 cond_code = reverse_condition (cond_code);
11730 if (cond_code == LE)
11733 rtx tmp = gen_reg_rtx (<MODE>mode);
11734 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11735 rtx x = gen_reg_rtx (<MODE>mode);
11737 emit_insn (gen_and<mode>3 (x, op1, tmp));
11739 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11743 rtx tmp = gen_reg_rtx (<MODE>mode);
11744 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11748 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11749 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11754 (define_expand "cstore<mode>4_unsigned_imm"
11755 [(use (match_operator 1 "unsigned_comparison_operator"
11756 [(match_operand:GPR 2 "gpc_reg_operand")
11757 (match_operand:GPR 3 "immediate_operand")]))
11758 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11761 bool invert = false;
11763 enum rtx_code cond_code = GET_CODE (operands[1]);
11765 rtx op0 = operands[0];
11766 rtx op1 = operands[2];
11767 HOST_WIDE_INT val = INTVAL (operands[3]);
11769 if (cond_code == GEU || cond_code == GTU)
11771 cond_code = reverse_condition (cond_code);
11775 if (cond_code == LEU)
11778 rtx tmp = gen_reg_rtx (<MODE>mode);
11779 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11780 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11781 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11782 rtx x = gen_reg_rtx (<MODE>mode);
11784 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11786 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11790 rtx tmp = gen_reg_rtx (<MODE>mode);
11791 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11795 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11796 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11801 (define_expand "cstore<mode>4"
11802 [(use (match_operator 1 "rs6000_cbranch_operator"
11803 [(match_operand:GPR 2 "gpc_reg_operand")
11804 (match_operand:GPR 3 "reg_or_short_operand")]))
11805 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11808 /* Use ISEL if the user asked for it. */
11810 rs6000_emit_sISEL (<MODE>mode, operands);
11812 /* Expanding EQ and NE directly to some machine instructions does not help
11813 but does hurt combine. So don't. */
11814 else if (GET_CODE (operands[1]) == EQ)
11815 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11816 else if (<MODE>mode == Pmode
11817 && GET_CODE (operands[1]) == NE)
11818 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11819 else if (GET_CODE (operands[1]) == NE)
11821 rtx tmp = gen_reg_rtx (<MODE>mode);
11822 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11823 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11826 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
11827 etc. combinations magically work out just right. */
11828 else if (<MODE>mode == Pmode
11829 && unsigned_comparison_operator (operands[1], VOIDmode))
11830 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11831 operands[2], operands[3]));
11833 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11834 else if (<MODE>mode == SImode && Pmode == DImode)
11835 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11836 operands[2], operands[3]));
11838 /* For signed comparisons against a constant, we can do some simple
11840 else if (signed_comparison_operator (operands[1], VOIDmode)
11841 && CONST_INT_P (operands[3]))
11842 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11843 operands[2], operands[3]));
11845 /* And similarly for unsigned comparisons. */
11846 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11847 && CONST_INT_P (operands[3]))
11848 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11849 operands[2], operands[3]));
11851 /* We also do not want to use mfcr for signed comparisons. */
11852 else if (<MODE>mode == Pmode
11853 && signed_comparison_operator (operands[1], VOIDmode))
11854 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11855 operands[2], operands[3]));
11857 /* Everything else, use the mfcr brute force. */
11859 rs6000_emit_sCOND (<MODE>mode, operands);
11864 (define_expand "cstore<mode>4"
11865 [(use (match_operator 1 "rs6000_cbranch_operator"
11866 [(match_operand:FP 2 "gpc_reg_operand")
11867 (match_operand:FP 3 "gpc_reg_operand")]))
11868 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11871 rs6000_emit_sCOND (<MODE>mode, operands);
11876 (define_expand "stack_protect_set"
11877 [(match_operand 0 "memory_operand")
11878 (match_operand 1 "memory_operand")]
11881 if (rs6000_stack_protector_guard == SSP_TLS)
11883 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11884 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11885 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11886 operands[1] = gen_rtx_MEM (Pmode, addr);
11890 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11892 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11897 (define_insn "stack_protect_setsi"
11898 [(set (match_operand:SI 0 "memory_operand" "=m")
11899 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11900 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11902 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11903 [(set_attr "type" "three")
11904 (set_attr "length" "12")])
11906 (define_insn "stack_protect_setdi"
11907 [(set (match_operand:DI 0 "memory_operand" "=Y")
11908 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11909 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11911 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11912 [(set_attr "type" "three")
11913 (set_attr "length" "12")])
11915 (define_expand "stack_protect_test"
11916 [(match_operand 0 "memory_operand")
11917 (match_operand 1 "memory_operand")
11918 (match_operand 2 "")]
11921 rtx guard = operands[1];
11923 if (rs6000_stack_protector_guard == SSP_TLS)
11925 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11926 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11927 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11928 guard = gen_rtx_MEM (Pmode, addr);
11931 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11932 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11933 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11934 emit_jump_insn (jump);
11939 (define_insn "stack_protect_testsi"
11940 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11941 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11942 (match_operand:SI 2 "memory_operand" "m,m")]
11944 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11945 (clobber (match_scratch:SI 3 "=&r,&r"))]
11948 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11949 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11950 [(set_attr "length" "16,20")])
11952 (define_insn "stack_protect_testdi"
11953 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11954 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11955 (match_operand:DI 2 "memory_operand" "Y,Y")]
11957 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11958 (clobber (match_scratch:DI 3 "=&r,&r"))]
11961 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11962 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11963 [(set_attr "length" "16,20")])
11966 ;; Here are the actual compare insns.
11967 (define_insn "*cmp<mode>_signed"
11968 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11969 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11970 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11972 "cmp<wd>%I2 %0,%1,%2"
11973 [(set_attr "type" "cmp")])
11975 (define_insn "*cmp<mode>_unsigned"
11976 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11977 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11978 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11980 "cmpl<wd>%I2 %0,%1,%2"
11981 [(set_attr "type" "cmp")])
11983 ;; If we are comparing a register for equality with a large constant,
11984 ;; we can do this with an XOR followed by a compare. But this is profitable
11985 ;; only if the large constant is only used for the comparison (and in this
11986 ;; case we already have a register to reuse as scratch).
11988 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11989 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11992 [(set (match_operand:SI 0 "register_operand")
11993 (match_operand:SI 1 "logical_const_operand" ""))
11994 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11996 (match_operand:SI 2 "logical_const_operand" "")]))
11997 (set (match_operand:CC 4 "cc_reg_operand" "")
11998 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
12001 (if_then_else (match_operator 6 "equality_operator"
12002 [(match_dup 4) (const_int 0)])
12003 (match_operand 7 "" "")
12004 (match_operand 8 "" "")))]
12005 "peep2_reg_dead_p (3, operands[0])
12006 && peep2_reg_dead_p (4, operands[4])
12007 && REGNO (operands[0]) != REGNO (operands[5])"
12008 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12009 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12010 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12013 /* Get the constant we are comparing against, and see what it looks like
12014 when sign-extended from 16 to 32 bits. Then see what constant we could
12015 XOR with SEXTC to get the sign-extended value. */
12016 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12018 operands[1], operands[2]);
12019 HOST_WIDE_INT c = INTVAL (cnst);
12020 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
12021 HOST_WIDE_INT xorv = c ^ sextc;
12023 operands[9] = GEN_INT (xorv);
12024 operands[10] = GEN_INT (sextc);
12027 ;; The following two insns don't exist as single insns, but if we provide
12028 ;; them, we can swap an add and compare, which will enable us to overlap more
12029 ;; of the required delay between a compare and branch. We generate code for
12030 ;; them by splitting.
12033 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12034 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
12035 (match_operand:SI 2 "short_cint_operand" "i")))
12036 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12037 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12040 [(set_attr "length" "8")])
12043 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
12044 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
12045 (match_operand:SI 2 "u_short_cint_operand" "i")))
12046 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12047 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12050 [(set_attr "length" "8")])
12053 [(set (match_operand:CC 3 "cc_reg_operand" "")
12054 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
12055 (match_operand:SI 2 "short_cint_operand" "")))
12056 (set (match_operand:SI 0 "gpc_reg_operand" "")
12057 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12059 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
12060 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12063 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
12064 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
12065 (match_operand:SI 2 "u_short_cint_operand" "")))
12066 (set (match_operand:SI 0 "gpc_reg_operand" "")
12067 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12069 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
12070 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12072 ;; Only need to compare second words if first words equal
12073 (define_insn "*cmp<mode>_internal1"
12074 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12075 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12076 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12077 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12078 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12079 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12080 [(set_attr "type" "fpcompare")
12081 (set_attr "length" "12")])
12083 (define_insn_and_split "*cmp<mode>_internal2"
12084 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12085 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12086 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12087 (clobber (match_scratch:DF 3 "=d"))
12088 (clobber (match_scratch:DF 4 "=d"))
12089 (clobber (match_scratch:DF 5 "=d"))
12090 (clobber (match_scratch:DF 6 "=d"))
12091 (clobber (match_scratch:DF 7 "=d"))
12092 (clobber (match_scratch:DF 8 "=d"))
12093 (clobber (match_scratch:DF 9 "=d"))
12094 (clobber (match_scratch:DF 10 "=d"))
12095 (clobber (match_scratch:GPR 11 "=b"))]
12096 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12097 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12099 "&& reload_completed"
12100 [(set (match_dup 3) (match_dup 14))
12101 (set (match_dup 4) (match_dup 15))
12102 (set (match_dup 9) (abs:DF (match_dup 5)))
12103 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12104 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12105 (label_ref (match_dup 12))
12107 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12108 (set (pc) (label_ref (match_dup 13)))
12110 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12111 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12112 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12113 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12116 REAL_VALUE_TYPE rv;
12117 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12118 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12120 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12121 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12122 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12123 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12124 operands[12] = gen_label_rtx ();
12125 operands[13] = gen_label_rtx ();
12127 operands[14] = force_const_mem (DFmode,
12128 const_double_from_real_value (rv, DFmode));
12129 operands[15] = force_const_mem (DFmode,
12130 const_double_from_real_value (dconst0,
12135 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12136 operands[14] = gen_const_mem (DFmode, tocref);
12137 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12138 operands[15] = gen_const_mem (DFmode, tocref);
12139 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12140 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12144 ;; Now we have the scc insns. We can do some combinations because of the
12145 ;; way the machine works.
12147 ;; Note that this is probably faster if we can put an insn between the
12148 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12149 ;; cases the insns below which don't use an intermediate CR field will
12150 ;; be used instead.
12152 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12153 (match_operator:SI 1 "scc_comparison_operator"
12154 [(match_operand 2 "cc_reg_operand" "y")
12157 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12158 [(set (attr "type")
12159 (cond [(match_test "TARGET_MFCRF")
12160 (const_string "mfcrf")
12162 (const_string "mfcr")))
12163 (set_attr "length" "8")])
12165 ;; Same as above, but get the GT bit.
12166 (define_insn "move_from_CR_gt_bit"
12167 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12168 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
12169 "TARGET_HARD_FLOAT && !TARGET_FPRS"
12170 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
12171 [(set_attr "type" "mfcr")
12172 (set_attr "length" "8")])
12174 ;; Same as above, but get the OV/ORDERED bit.
12175 (define_insn "move_from_CR_ov_bit"
12176 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12177 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12180 "mfcr %0\;rlwinm %0,%0,%t1,1"
12181 [(set_attr "type" "mfcr")
12182 (set_attr "length" "8")])
12185 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12186 (match_operator:DI 1 "scc_comparison_operator"
12187 [(match_operand 2 "cc_reg_operand" "y")
12190 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12191 [(set (attr "type")
12192 (cond [(match_test "TARGET_MFCRF")
12193 (const_string "mfcrf")
12195 (const_string "mfcr")))
12196 (set_attr "length" "8")])
12199 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12200 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12201 [(match_operand 2 "cc_reg_operand" "y,y")
12204 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12205 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12208 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12210 [(set_attr "type" "shift")
12211 (set_attr "dot" "yes")
12212 (set_attr "length" "8,16")])
12215 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12216 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12217 [(match_operand 2 "cc_reg_operand" "")
12220 (set (match_operand:SI 3 "gpc_reg_operand" "")
12221 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12222 "TARGET_32BIT && reload_completed"
12223 [(set (match_dup 3)
12224 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12226 (compare:CC (match_dup 3)
12231 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12232 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12233 [(match_operand 2 "cc_reg_operand" "y")
12235 (match_operand:SI 3 "const_int_operand" "n")))]
12239 int is_bit = ccr_bit (operands[1], 1);
12240 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12243 if (is_bit >= put_bit)
12244 count = is_bit - put_bit;
12246 count = 32 - (put_bit - is_bit);
12248 operands[4] = GEN_INT (count);
12249 operands[5] = GEN_INT (put_bit);
12251 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12253 [(set (attr "type")
12254 (cond [(match_test "TARGET_MFCRF")
12255 (const_string "mfcrf")
12257 (const_string "mfcr")))
12258 (set_attr "length" "8")])
12261 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12263 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12264 [(match_operand 2 "cc_reg_operand" "y,y")
12266 (match_operand:SI 3 "const_int_operand" "n,n"))
12268 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12269 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12274 int is_bit = ccr_bit (operands[1], 1);
12275 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12278 /* Force split for non-cc0 compare. */
12279 if (which_alternative == 1)
12282 if (is_bit >= put_bit)
12283 count = is_bit - put_bit;
12285 count = 32 - (put_bit - is_bit);
12287 operands[5] = GEN_INT (count);
12288 operands[6] = GEN_INT (put_bit);
12290 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12292 [(set_attr "type" "shift")
12293 (set_attr "dot" "yes")
12294 (set_attr "length" "8,16")])
12297 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
12299 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12300 [(match_operand 2 "cc_reg_operand" "")
12302 (match_operand:SI 3 "const_int_operand" ""))
12304 (set (match_operand:SI 4 "gpc_reg_operand" "")
12305 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12308 [(set (match_dup 4)
12309 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12312 (compare:CC (match_dup 4)
12317 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12320 (define_insn_and_split "eq<mode>3"
12321 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12322 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12323 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12324 (clobber (match_scratch:GPR 3 "=r"))
12325 (clobber (match_scratch:GPR 4 "=r"))]
12329 [(set (match_dup 4)
12330 (clz:GPR (match_dup 3)))
12332 (lshiftrt:GPR (match_dup 4)
12335 operands[3] = rs6000_emit_eqne (<MODE>mode,
12336 operands[1], operands[2], operands[3]);
12338 if (GET_CODE (operands[4]) == SCRATCH)
12339 operands[4] = gen_reg_rtx (<MODE>mode);
12341 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12343 [(set (attr "length")
12344 (if_then_else (match_test "operands[2] == const0_rtx")
12346 (const_string "12")))])
12348 (define_insn_and_split "ne<mode>3"
12349 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12350 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12351 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12352 (clobber (match_scratch:P 3 "=r"))
12353 (clobber (match_scratch:P 4 "=r"))
12354 (clobber (reg:P CA_REGNO))]
12358 [(parallel [(set (match_dup 4)
12359 (plus:P (match_dup 3)
12361 (set (reg:P CA_REGNO)
12362 (ne:P (match_dup 3)
12364 (parallel [(set (match_dup 0)
12365 (plus:P (plus:P (not:P (match_dup 4))
12368 (clobber (reg:P CA_REGNO))])]
12370 operands[3] = rs6000_emit_eqne (<MODE>mode,
12371 operands[1], operands[2], operands[3]);
12373 if (GET_CODE (operands[4]) == SCRATCH)
12374 operands[4] = gen_reg_rtx (<MODE>mode);
12376 [(set (attr "length")
12377 (if_then_else (match_test "operands[2] == const0_rtx")
12379 (const_string "12")))])
12381 (define_insn_and_split "*neg_eq_<mode>"
12382 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12383 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12384 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12385 (clobber (match_scratch:P 3 "=r"))
12386 (clobber (match_scratch:P 4 "=r"))
12387 (clobber (reg:P CA_REGNO))]
12391 [(parallel [(set (match_dup 4)
12392 (plus:P (match_dup 3)
12394 (set (reg:P CA_REGNO)
12395 (ne:P (match_dup 3)
12397 (parallel [(set (match_dup 0)
12398 (plus:P (reg:P CA_REGNO)
12400 (clobber (reg:P CA_REGNO))])]
12402 operands[3] = rs6000_emit_eqne (<MODE>mode,
12403 operands[1], operands[2], operands[3]);
12405 if (GET_CODE (operands[4]) == SCRATCH)
12406 operands[4] = gen_reg_rtx (<MODE>mode);
12408 [(set (attr "length")
12409 (if_then_else (match_test "operands[2] == const0_rtx")
12411 (const_string "12")))])
12413 (define_insn_and_split "*neg_ne_<mode>"
12414 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12415 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12416 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12417 (clobber (match_scratch:P 3 "=r"))
12418 (clobber (match_scratch:P 4 "=r"))
12419 (clobber (reg:P CA_REGNO))]
12423 [(parallel [(set (match_dup 4)
12424 (neg:P (match_dup 3)))
12425 (set (reg:P CA_REGNO)
12426 (eq:P (match_dup 3)
12428 (parallel [(set (match_dup 0)
12429 (plus:P (reg:P CA_REGNO)
12431 (clobber (reg:P CA_REGNO))])]
12433 operands[3] = rs6000_emit_eqne (<MODE>mode,
12434 operands[1], operands[2], operands[3]);
12436 if (GET_CODE (operands[4]) == SCRATCH)
12437 operands[4] = gen_reg_rtx (<MODE>mode);
12439 [(set (attr "length")
12440 (if_then_else (match_test "operands[2] == const0_rtx")
12442 (const_string "12")))])
12444 (define_insn_and_split "*plus_eq_<mode>"
12445 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12446 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12447 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12448 (match_operand:P 3 "gpc_reg_operand" "r")))
12449 (clobber (match_scratch:P 4 "=r"))
12450 (clobber (match_scratch:P 5 "=r"))
12451 (clobber (reg:P CA_REGNO))]
12455 [(parallel [(set (match_dup 5)
12456 (neg:P (match_dup 4)))
12457 (set (reg:P CA_REGNO)
12458 (eq:P (match_dup 4)
12460 (parallel [(set (match_dup 0)
12461 (plus:P (match_dup 3)
12463 (clobber (reg:P CA_REGNO))])]
12465 operands[4] = rs6000_emit_eqne (<MODE>mode,
12466 operands[1], operands[2], operands[4]);
12468 if (GET_CODE (operands[5]) == SCRATCH)
12469 operands[5] = gen_reg_rtx (<MODE>mode);
12471 [(set (attr "length")
12472 (if_then_else (match_test "operands[2] == const0_rtx")
12474 (const_string "12")))])
12476 (define_insn_and_split "*plus_ne_<mode>"
12477 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12478 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12479 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12480 (match_operand:P 3 "gpc_reg_operand" "r")))
12481 (clobber (match_scratch:P 4 "=r"))
12482 (clobber (match_scratch:P 5 "=r"))
12483 (clobber (reg:P CA_REGNO))]
12487 [(parallel [(set (match_dup 5)
12488 (plus:P (match_dup 4)
12490 (set (reg:P CA_REGNO)
12491 (ne:P (match_dup 4)
12493 (parallel [(set (match_dup 0)
12494 (plus:P (match_dup 3)
12496 (clobber (reg:P CA_REGNO))])]
12498 operands[4] = rs6000_emit_eqne (<MODE>mode,
12499 operands[1], operands[2], operands[4]);
12501 if (GET_CODE (operands[5]) == SCRATCH)
12502 operands[5] = gen_reg_rtx (<MODE>mode);
12504 [(set (attr "length")
12505 (if_then_else (match_test "operands[2] == const0_rtx")
12507 (const_string "12")))])
12509 (define_insn_and_split "*minus_eq_<mode>"
12510 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12511 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12512 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12513 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12514 (clobber (match_scratch:P 4 "=r"))
12515 (clobber (match_scratch:P 5 "=r"))
12516 (clobber (reg:P CA_REGNO))]
12520 [(parallel [(set (match_dup 5)
12521 (plus:P (match_dup 4)
12523 (set (reg:P CA_REGNO)
12524 (ne:P (match_dup 4)
12526 (parallel [(set (match_dup 0)
12527 (plus:P (plus:P (match_dup 3)
12530 (clobber (reg:P CA_REGNO))])]
12532 operands[4] = rs6000_emit_eqne (<MODE>mode,
12533 operands[1], operands[2], operands[4]);
12535 if (GET_CODE (operands[5]) == SCRATCH)
12536 operands[5] = gen_reg_rtx (<MODE>mode);
12538 [(set (attr "length")
12539 (if_then_else (match_test "operands[2] == const0_rtx")
12541 (const_string "12")))])
12543 (define_insn_and_split "*minus_ne_<mode>"
12544 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12545 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12546 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12547 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12548 (clobber (match_scratch:P 4 "=r"))
12549 (clobber (match_scratch:P 5 "=r"))
12550 (clobber (reg:P CA_REGNO))]
12554 [(parallel [(set (match_dup 5)
12555 (neg:P (match_dup 4)))
12556 (set (reg:P CA_REGNO)
12557 (eq:P (match_dup 4)
12559 (parallel [(set (match_dup 0)
12560 (plus:P (plus:P (match_dup 3)
12563 (clobber (reg:P CA_REGNO))])]
12565 operands[4] = rs6000_emit_eqne (<MODE>mode,
12566 operands[1], operands[2], operands[4]);
12568 if (GET_CODE (operands[5]) == SCRATCH)
12569 operands[5] = gen_reg_rtx (<MODE>mode);
12571 [(set (attr "length")
12572 (if_then_else (match_test "operands[2] == const0_rtx")
12574 (const_string "12")))])
12576 (define_insn_and_split "*eqsi3_ext<mode>"
12577 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12578 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12579 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12580 (clobber (match_scratch:SI 3 "=r"))
12581 (clobber (match_scratch:SI 4 "=r"))]
12585 [(set (match_dup 4)
12586 (clz:SI (match_dup 3)))
12589 (lshiftrt:SI (match_dup 4)
12592 operands[3] = rs6000_emit_eqne (SImode,
12593 operands[1], operands[2], operands[3]);
12595 if (GET_CODE (operands[4]) == SCRATCH)
12596 operands[4] = gen_reg_rtx (SImode);
12598 [(set (attr "length")
12599 (if_then_else (match_test "operands[2] == const0_rtx")
12601 (const_string "12")))])
12603 (define_insn_and_split "*nesi3_ext<mode>"
12604 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12605 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12606 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12607 (clobber (match_scratch:SI 3 "=r"))
12608 (clobber (match_scratch:SI 4 "=r"))
12609 (clobber (match_scratch:EXTSI 5 "=r"))]
12613 [(set (match_dup 4)
12614 (clz:SI (match_dup 3)))
12617 (lshiftrt:SI (match_dup 4)
12620 (xor:EXTSI (match_dup 5)
12623 operands[3] = rs6000_emit_eqne (SImode,
12624 operands[1], operands[2], operands[3]);
12626 if (GET_CODE (operands[4]) == SCRATCH)
12627 operands[4] = gen_reg_rtx (SImode);
12628 if (GET_CODE (operands[5]) == SCRATCH)
12629 operands[5] = gen_reg_rtx (<MODE>mode);
12631 [(set (attr "length")
12632 (if_then_else (match_test "operands[2] == const0_rtx")
12633 (const_string "12")
12634 (const_string "16")))])
12636 ;; Define both directions of branch and return. If we need a reload
12637 ;; register, we'd rather use CR0 since it is much easier to copy a
12638 ;; register CC value to there.
12642 (if_then_else (match_operator 1 "branch_comparison_operator"
12644 "cc_reg_operand" "y")
12646 (label_ref (match_operand 0 "" ""))
12651 return output_cbranch (operands[1], \"%l0\", 0, insn);
12653 [(set_attr "type" "branch")])
12657 (if_then_else (match_operator 0 "branch_comparison_operator"
12659 "cc_reg_operand" "y")
12666 return output_cbranch (operands[0], NULL, 0, insn);
12668 [(set_attr "type" "jmpreg")
12669 (set_attr "length" "4")])
12673 (if_then_else (match_operator 1 "branch_comparison_operator"
12675 "cc_reg_operand" "y")
12678 (label_ref (match_operand 0 "" ""))))]
12682 return output_cbranch (operands[1], \"%l0\", 1, insn);
12684 [(set_attr "type" "branch")])
12688 (if_then_else (match_operator 0 "branch_comparison_operator"
12690 "cc_reg_operand" "y")
12697 return output_cbranch (operands[0], NULL, 1, insn);
12699 [(set_attr "type" "jmpreg")
12700 (set_attr "length" "4")])
12702 ;; Logic on condition register values.
12704 ; This pattern matches things like
12705 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12706 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12708 ; which are generated by the branch logic.
12709 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12711 (define_insn "*cceq_ior_compare"
12712 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12713 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12714 [(match_operator:SI 2
12715 "branch_positive_comparison_operator"
12717 "cc_reg_operand" "y,y")
12719 (match_operator:SI 4
12720 "branch_positive_comparison_operator"
12722 "cc_reg_operand" "0,y")
12726 "cr%q1 %E0,%j2,%j4"
12727 [(set_attr "type" "cr_logical,delayed_cr")])
12729 ; Why is the constant -1 here, but 1 in the previous pattern?
12730 ; Because ~1 has all but the low bit set.
12732 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12733 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12734 [(not:SI (match_operator:SI 2
12735 "branch_positive_comparison_operator"
12737 "cc_reg_operand" "y,y")
12739 (match_operator:SI 4
12740 "branch_positive_comparison_operator"
12742 "cc_reg_operand" "0,y")
12746 "cr%q1 %E0,%j2,%j4"
12747 [(set_attr "type" "cr_logical,delayed_cr")])
12749 (define_insn "*cceq_rev_compare"
12750 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12751 (compare:CCEQ (match_operator:SI 1
12752 "branch_positive_comparison_operator"
12754 "cc_reg_operand" "0,y")
12759 [(set_attr "type" "cr_logical,delayed_cr")])
12761 ;; If we are comparing the result of two comparisons, this can be done
12762 ;; using creqv or crxor.
12764 (define_insn_and_split ""
12765 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12766 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12767 [(match_operand 2 "cc_reg_operand" "y")
12769 (match_operator 3 "branch_comparison_operator"
12770 [(match_operand 4 "cc_reg_operand" "y")
12775 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12779 int positive_1, positive_2;
12781 positive_1 = branch_positive_comparison_operator (operands[1],
12782 GET_MODE (operands[1]));
12783 positive_2 = branch_positive_comparison_operator (operands[3],
12784 GET_MODE (operands[3]));
12787 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12788 GET_CODE (operands[1])),
12790 operands[2], const0_rtx);
12791 else if (GET_MODE (operands[1]) != SImode)
12792 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12793 operands[2], const0_rtx);
12796 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12797 GET_CODE (operands[3])),
12799 operands[4], const0_rtx);
12800 else if (GET_MODE (operands[3]) != SImode)
12801 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12802 operands[4], const0_rtx);
12804 if (positive_1 == positive_2)
12806 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12807 operands[5] = constm1_rtx;
12811 operands[5] = const1_rtx;
12815 ;; Unconditional branch and return.
12817 (define_insn "jump"
12819 (label_ref (match_operand 0 "" "")))]
12822 [(set_attr "type" "branch")])
12824 (define_insn "<return_str>return"
12828 [(set_attr "type" "jmpreg")])
12830 (define_expand "indirect_jump"
12831 [(set (pc) (match_operand 0 "register_operand" ""))])
12833 (define_insn "*indirect_jump<mode>"
12834 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
12839 [(set_attr "type" "jmpreg")])
12841 ;; Table jump for switch statements:
12842 (define_expand "tablejump"
12843 [(use (match_operand 0 "" ""))
12844 (use (label_ref (match_operand 1 "" "")))]
12849 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12851 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12855 (define_expand "tablejumpsi"
12856 [(set (match_dup 3)
12857 (plus:SI (match_operand:SI 0 "" "")
12859 (parallel [(set (pc) (match_dup 3))
12860 (use (label_ref (match_operand 1 "" "")))])]
12863 { operands[0] = force_reg (SImode, operands[0]);
12864 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12865 operands[3] = gen_reg_rtx (SImode);
12868 (define_expand "tablejumpdi"
12869 [(set (match_dup 4)
12870 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
12872 (plus:DI (match_dup 4)
12874 (parallel [(set (pc) (match_dup 3))
12875 (use (label_ref (match_operand 1 "" "")))])]
12878 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12879 operands[3] = gen_reg_rtx (DImode);
12880 operands[4] = gen_reg_rtx (DImode);
12883 (define_insn "*tablejump<mode>_internal1"
12885 (match_operand:P 0 "register_operand" "c,*l"))
12886 (use (label_ref (match_operand 1 "" "")))]
12891 [(set_attr "type" "jmpreg")])
12894 [(unspec [(const_int 0)] UNSPEC_NOP)]
12898 (define_insn "group_ending_nop"
12899 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12903 if (rs6000_cpu_attr == CPU_POWER6)
12904 return \"ori 1,1,0\";
12905 return \"ori 2,2,0\";
12908 ;; Define the subtract-one-and-jump insns, starting with the template
12909 ;; so loop.c knows what to generate.
12911 (define_expand "doloop_end"
12912 [(use (match_operand 0 "" "")) ; loop pseudo
12913 (use (match_operand 1 "" ""))] ; label
12919 if (GET_MODE (operands[0]) != DImode)
12921 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12925 if (GET_MODE (operands[0]) != SImode)
12927 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12932 (define_expand "ctr<mode>"
12933 [(parallel [(set (pc)
12934 (if_then_else (ne (match_operand:P 0 "register_operand" "")
12936 (label_ref (match_operand 1 "" ""))
12939 (plus:P (match_dup 0)
12941 (clobber (match_scratch:CC 2 ""))
12942 (clobber (match_scratch:P 3 ""))])]
12946 ;; We need to be able to do this for any operand, including MEM, or we
12947 ;; will cause reload to blow up since we don't allow output reloads on
12949 ;; For the length attribute to be calculated correctly, the
12950 ;; label MUST be operand 0.
12951 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12952 ;; the ctr<mode> insns.
12954 (define_insn "ctr<mode>_internal1"
12956 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12958 (label_ref (match_operand 0 "" ""))
12960 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12961 (plus:P (match_dup 1)
12963 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12964 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12968 if (which_alternative != 0)
12970 else if (get_attr_length (insn) == 4)
12971 return \"bdnz %l0\";
12973 return \"bdz $+8\;b %l0\";
12975 [(set_attr "type" "branch")
12976 (set_attr "length" "*,16,20,20")])
12978 (define_insn "ctr<mode>_internal2"
12980 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12983 (label_ref (match_operand 0 "" ""))))
12984 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12985 (plus:P (match_dup 1)
12987 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12988 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12992 if (which_alternative != 0)
12994 else if (get_attr_length (insn) == 4)
12995 return \"bdz %l0\";
12997 return \"bdnz $+8\;b %l0\";
12999 [(set_attr "type" "branch")
13000 (set_attr "length" "*,16,20,20")])
13002 ;; Similar but use EQ
13004 (define_insn "ctr<mode>_internal3"
13006 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13008 (label_ref (match_operand 0 "" ""))
13010 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13011 (plus:P (match_dup 1)
13013 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13014 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13018 if (which_alternative != 0)
13020 else if (get_attr_length (insn) == 4)
13021 return \"bdz %l0\";
13023 return \"bdnz $+8\;b %l0\";
13025 [(set_attr "type" "branch")
13026 (set_attr "length" "*,16,20,20")])
13028 (define_insn "ctr<mode>_internal4"
13030 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13033 (label_ref (match_operand 0 "" ""))))
13034 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13035 (plus:P (match_dup 1)
13037 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13038 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13042 if (which_alternative != 0)
13044 else if (get_attr_length (insn) == 4)
13045 return \"bdnz %l0\";
13047 return \"bdz $+8\;b %l0\";
13049 [(set_attr "type" "branch")
13050 (set_attr "length" "*,16,20,20")])
13052 ;; Now the splitters if we could not allocate the CTR register
13056 (if_then_else (match_operator 2 "comparison_operator"
13057 [(match_operand:P 1 "gpc_reg_operand" "")
13059 (match_operand 5 "" "")
13060 (match_operand 6 "" "")))
13061 (set (match_operand:P 0 "int_reg_operand" "")
13062 (plus:P (match_dup 1) (const_int -1)))
13063 (clobber (match_scratch:CC 3 ""))
13064 (clobber (match_scratch:P 4 ""))]
13066 [(set (match_dup 3)
13067 (compare:CC (match_dup 1)
13070 (plus:P (match_dup 1)
13072 (set (pc) (if_then_else (match_dup 7)
13076 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13077 operands[3], const0_rtx); }")
13081 (if_then_else (match_operator 2 "comparison_operator"
13082 [(match_operand:P 1 "gpc_reg_operand" "")
13084 (match_operand 5 "" "")
13085 (match_operand 6 "" "")))
13086 (set (match_operand:P 0 "nonimmediate_operand" "")
13087 (plus:P (match_dup 1) (const_int -1)))
13088 (clobber (match_scratch:CC 3 ""))
13089 (clobber (match_scratch:P 4 ""))]
13090 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
13091 [(set (match_dup 3)
13092 (compare:CC (match_dup 1)
13095 (plus:P (match_dup 1)
13099 (set (pc) (if_then_else (match_dup 7)
13103 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13104 operands[3], const0_rtx); }")
13106 (define_insn "trap"
13107 [(trap_if (const_int 1) (const_int 0))]
13110 [(set_attr "type" "trap")])
13112 (define_expand "ctrap<mode>4"
13113 [(trap_if (match_operator 0 "ordered_comparison_operator"
13114 [(match_operand:GPR 1 "register_operand")
13115 (match_operand:GPR 2 "reg_or_short_operand")])
13116 (match_operand 3 "zero_constant" ""))]
13121 [(trap_if (match_operator 0 "ordered_comparison_operator"
13122 [(match_operand:GPR 1 "register_operand" "r")
13123 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13126 "t<wd>%V0%I2 %1,%2"
13127 [(set_attr "type" "trap")])
13129 ;; Insns related to generating the function prologue and epilogue.
13131 (define_expand "prologue"
13132 [(use (const_int 0))]
13135 rs6000_emit_prologue ();
13136 if (!TARGET_SCHED_PROLOG)
13137 emit_insn (gen_blockage ());
13141 (define_insn "*movesi_from_cr_one"
13142 [(match_parallel 0 "mfcr_operation"
13143 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13144 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13145 (match_operand 3 "immediate_operand" "n")]
13146 UNSPEC_MOVESI_FROM_CR))])]
13152 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13154 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13155 operands[4] = GEN_INT (mask);
13156 output_asm_insn (\"mfcr %1,%4\", operands);
13160 [(set_attr "type" "mfcrf")])
13162 (define_insn "movesi_from_cr"
13163 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13164 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
13165 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13166 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
13167 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
13168 UNSPEC_MOVESI_FROM_CR))]
13171 [(set_attr "type" "mfcr")])
13173 (define_insn "*crsave"
13174 [(match_parallel 0 "crsave_operation"
13175 [(set (match_operand:SI 1 "memory_operand" "=m")
13176 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13179 [(set_attr "type" "store")])
13181 (define_insn "*stmw"
13182 [(match_parallel 0 "stmw_operation"
13183 [(set (match_operand:SI 1 "memory_operand" "=m")
13184 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13187 [(set_attr "type" "store")
13188 (set_attr "update" "yes")
13189 (set_attr "indexed" "yes")])
13191 ; The following comment applies to:
13195 ; return_and_restore_gpregs*
13196 ; return_and_restore_fpregs*
13197 ; return_and_restore_fpregs_aix*
13199 ; The out-of-line save / restore functions expects one input argument.
13200 ; Since those are not standard call_insn's, we must avoid using
13201 ; MATCH_OPERAND for that argument. That way the register rename
13202 ; optimization will not try to rename this register.
13203 ; Each pattern is repeated for each possible register number used in
13204 ; various ABIs (r11, r1, and for some functions r12)
13206 (define_insn "*save_gpregs_<mode>_r11"
13207 [(match_parallel 0 "any_parallel_operand"
13208 [(clobber (reg:P LR_REGNO))
13209 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13211 (set (match_operand:P 2 "memory_operand" "=m")
13212 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13215 [(set_attr "type" "branch")
13216 (set_attr "length" "4")])
13218 (define_insn "*save_gpregs_<mode>_r12"
13219 [(match_parallel 0 "any_parallel_operand"
13220 [(clobber (reg:P LR_REGNO))
13221 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13223 (set (match_operand:P 2 "memory_operand" "=m")
13224 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13227 [(set_attr "type" "branch")
13228 (set_attr "length" "4")])
13230 (define_insn "*save_gpregs_<mode>_r1"
13231 [(match_parallel 0 "any_parallel_operand"
13232 [(clobber (reg:P LR_REGNO))
13233 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13235 (set (match_operand:P 2 "memory_operand" "=m")
13236 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13239 [(set_attr "type" "branch")
13240 (set_attr "length" "4")])
13242 (define_insn "*save_fpregs_<mode>_r11"
13243 [(match_parallel 0 "any_parallel_operand"
13244 [(clobber (reg:P LR_REGNO))
13245 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13247 (set (match_operand:DF 2 "memory_operand" "=m")
13248 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13251 [(set_attr "type" "branch")
13252 (set_attr "length" "4")])
13254 (define_insn "*save_fpregs_<mode>_r12"
13255 [(match_parallel 0 "any_parallel_operand"
13256 [(clobber (reg:P LR_REGNO))
13257 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13259 (set (match_operand:DF 2 "memory_operand" "=m")
13260 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13263 [(set_attr "type" "branch")
13264 (set_attr "length" "4")])
13266 (define_insn "*save_fpregs_<mode>_r1"
13267 [(match_parallel 0 "any_parallel_operand"
13268 [(clobber (reg:P LR_REGNO))
13269 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13271 (set (match_operand:DF 2 "memory_operand" "=m")
13272 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13275 [(set_attr "type" "branch")
13276 (set_attr "length" "4")])
13278 ; This is to explain that changes to the stack pointer should
13279 ; not be moved over loads from or stores to stack memory.
13280 (define_insn "stack_tie"
13281 [(match_parallel 0 "tie_operand"
13282 [(set (mem:BLK (reg 1)) (const_int 0))])]
13285 [(set_attr "length" "0")])
13287 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13288 ; stay behind all restores from the stack, it cannot be reordered to before
13289 ; one. See PR77687. This insn is an add or mr, and a stack_tie on the
13290 ; operands of that.
13291 (define_insn "stack_restore_tie"
13292 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13293 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13294 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13295 (set (mem:BLK (match_dup 0)) (const_int 0))
13296 (set (mem:BLK (match_dup 1)) (const_int 0))]
13301 [(set_attr "type" "*,add")])
13303 (define_expand "epilogue"
13304 [(use (const_int 0))]
13307 if (!TARGET_SCHED_PROLOG)
13308 emit_insn (gen_blockage ());
13309 rs6000_emit_epilogue (FALSE);
13313 ; On some processors, doing the mtcrf one CC register at a time is
13314 ; faster (like on the 604e). On others, doing them all at once is
13315 ; faster; for instance, on the 601 and 750.
13317 (define_expand "movsi_to_cr_one"
13318 [(set (match_operand:CC 0 "cc_reg_operand" "")
13319 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13320 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13322 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13324 (define_insn "*movsi_to_cr"
13325 [(match_parallel 0 "mtcrf_operation"
13326 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13327 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13328 (match_operand 3 "immediate_operand" "n")]
13329 UNSPEC_MOVESI_TO_CR))])]
13335 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13336 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13337 operands[4] = GEN_INT (mask);
13338 return \"mtcrf %4,%2\";
13340 [(set_attr "type" "mtcr")])
13342 (define_insn "*mtcrfsi"
13343 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13344 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13345 (match_operand 2 "immediate_operand" "n")]
13346 UNSPEC_MOVESI_TO_CR))]
13347 "GET_CODE (operands[0]) == REG
13348 && CR_REGNO_P (REGNO (operands[0]))
13349 && GET_CODE (operands[2]) == CONST_INT
13350 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13352 [(set_attr "type" "mtcr")])
13354 ; The load-multiple instructions have similar properties.
13355 ; Note that "load_multiple" is a name known to the machine-independent
13356 ; code that actually corresponds to the PowerPC load-string.
13358 (define_insn "*lmw"
13359 [(match_parallel 0 "lmw_operation"
13360 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13361 (match_operand:SI 2 "memory_operand" "m"))])]
13364 [(set_attr "type" "load")
13365 (set_attr "update" "yes")
13366 (set_attr "indexed" "yes")
13367 (set_attr "cell_micro" "always")])
13369 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13370 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13372 ; The following comment applies to:
13376 ; return_and_restore_gpregs*
13377 ; return_and_restore_fpregs*
13378 ; return_and_restore_fpregs_aix*
13380 ; The out-of-line save / restore functions expects one input argument.
13381 ; Since those are not standard call_insn's, we must avoid using
13382 ; MATCH_OPERAND for that argument. That way the register rename
13383 ; optimization will not try to rename this register.
13384 ; Each pattern is repeated for each possible register number used in
13385 ; various ABIs (r11, r1, and for some functions r12)
13387 (define_insn "*restore_gpregs_<mode>_r11"
13388 [(match_parallel 0 "any_parallel_operand"
13389 [(clobber (reg:P LR_REGNO))
13390 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13392 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13393 (match_operand:P 3 "memory_operand" "m"))])]
13396 [(set_attr "type" "branch")
13397 (set_attr "length" "4")])
13399 (define_insn "*restore_gpregs_<mode>_r12"
13400 [(match_parallel 0 "any_parallel_operand"
13401 [(clobber (reg:P LR_REGNO))
13402 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13404 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13405 (match_operand:P 3 "memory_operand" "m"))])]
13408 [(set_attr "type" "branch")
13409 (set_attr "length" "4")])
13411 (define_insn "*restore_gpregs_<mode>_r1"
13412 [(match_parallel 0 "any_parallel_operand"
13413 [(clobber (reg:P LR_REGNO))
13414 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13416 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13417 (match_operand:P 3 "memory_operand" "m"))])]
13420 [(set_attr "type" "branch")
13421 (set_attr "length" "4")])
13423 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13424 [(match_parallel 0 "any_parallel_operand"
13426 (clobber (reg:P LR_REGNO))
13427 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13429 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13430 (match_operand:P 3 "memory_operand" "m"))])]
13433 [(set_attr "type" "branch")
13434 (set_attr "length" "4")])
13436 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13437 [(match_parallel 0 "any_parallel_operand"
13439 (clobber (reg:P LR_REGNO))
13440 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13442 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13443 (match_operand:P 3 "memory_operand" "m"))])]
13446 [(set_attr "type" "branch")
13447 (set_attr "length" "4")])
13449 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13450 [(match_parallel 0 "any_parallel_operand"
13452 (clobber (reg:P LR_REGNO))
13453 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13455 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13456 (match_operand:P 3 "memory_operand" "m"))])]
13459 [(set_attr "type" "branch")
13460 (set_attr "length" "4")])
13462 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13463 [(match_parallel 0 "any_parallel_operand"
13465 (clobber (reg:P LR_REGNO))
13466 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13468 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13469 (match_operand:DF 3 "memory_operand" "m"))])]
13472 [(set_attr "type" "branch")
13473 (set_attr "length" "4")])
13475 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13476 [(match_parallel 0 "any_parallel_operand"
13478 (clobber (reg:P LR_REGNO))
13479 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13481 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13482 (match_operand:DF 3 "memory_operand" "m"))])]
13485 [(set_attr "type" "branch")
13486 (set_attr "length" "4")])
13488 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13489 [(match_parallel 0 "any_parallel_operand"
13491 (clobber (reg:P LR_REGNO))
13492 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13494 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13495 (match_operand:DF 3 "memory_operand" "m"))])]
13498 [(set_attr "type" "branch")
13499 (set_attr "length" "4")])
13501 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13502 [(match_parallel 0 "any_parallel_operand"
13504 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13506 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13507 (match_operand:DF 3 "memory_operand" "m"))])]
13510 [(set_attr "type" "branch")
13511 (set_attr "length" "4")])
13513 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13514 [(match_parallel 0 "any_parallel_operand"
13516 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13518 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13519 (match_operand:DF 3 "memory_operand" "m"))])]
13522 [(set_attr "type" "branch")
13523 (set_attr "length" "4")])
13525 ; This is used in compiling the unwind routines.
13526 (define_expand "eh_return"
13527 [(use (match_operand 0 "general_operand" ""))]
13532 emit_insn (gen_eh_set_lr_si (operands[0]));
13534 emit_insn (gen_eh_set_lr_di (operands[0]));
13538 ; We can't expand this before we know where the link register is stored.
13539 (define_insn "eh_set_lr_<mode>"
13540 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13542 (clobber (match_scratch:P 1 "=&b"))]
13547 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13548 (clobber (match_scratch 1 ""))]
13553 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13557 (define_insn "prefetch"
13558 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13559 (match_operand:SI 1 "const_int_operand" "n")
13560 (match_operand:SI 2 "const_int_operand" "n"))]
13564 if (GET_CODE (operands[0]) == REG)
13565 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13566 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13568 [(set_attr "type" "load")])
13570 ;; Handle -fsplit-stack.
13572 (define_expand "split_stack_prologue"
13576 rs6000_expand_split_stack_prologue ();
13580 (define_expand "load_split_stack_limit"
13581 [(set (match_operand 0)
13582 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13585 emit_insn (gen_rtx_SET (operands[0],
13586 gen_rtx_UNSPEC (Pmode,
13587 gen_rtvec (1, const0_rtx),
13588 UNSPEC_STACK_CHECK)));
13592 (define_insn "load_split_stack_limit_di"
13593 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13594 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13596 "ld %0,-0x7040(13)"
13597 [(set_attr "type" "load")
13598 (set_attr "update" "no")
13599 (set_attr "indexed" "no")])
13601 (define_insn "load_split_stack_limit_si"
13602 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13603 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13605 "lwz %0,-0x7020(2)"
13606 [(set_attr "type" "load")
13607 (set_attr "update" "no")
13608 (set_attr "indexed" "no")])
13610 ;; A return instruction which the middle-end doesn't see.
13611 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13612 ;; after the call to __morestack.
13613 (define_insn "split_stack_return"
13614 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13617 [(set_attr "type" "jmpreg")])
13619 ;; If there are operand 0 bytes available on the stack, jump to
13621 (define_expand "split_stack_space_check"
13622 [(set (match_dup 2)
13623 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13625 (minus (reg STACK_POINTER_REGNUM)
13626 (match_operand 0)))
13627 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13628 (set (pc) (if_then_else
13629 (geu (match_dup 4) (const_int 0))
13630 (label_ref (match_operand 1))
13634 rs6000_split_stack_space_check (operands[0], operands[1]);
13638 (define_insn "bpermd_<mode>"
13639 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13640 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13641 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13644 [(set_attr "type" "popcnt")])
13647 ;; Builtin fma support. Handle
13648 ;; Note that the conditions for expansion are in the FMA_F iterator.
13650 (define_expand "fma<mode>4"
13651 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13653 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13654 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13655 (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13659 (define_insn "*fma<mode>4_fpr"
13660 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13662 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13663 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13664 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13665 "TARGET_<MODE>_FPR"
13667 fmadd<Ftrad> %0,%1,%2,%3
13668 xsmadda<Fvsx> %x0,%x1,%x2
13669 xsmaddm<Fvsx> %x0,%x1,%x3"
13670 [(set_attr "type" "fp")
13671 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13673 ; Altivec only has fma and nfms.
13674 (define_expand "fms<mode>4"
13675 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13677 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13678 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13679 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13680 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13683 (define_insn "*fms<mode>4_fpr"
13684 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13686 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13687 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13688 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13689 "TARGET_<MODE>_FPR"
13691 fmsub<Ftrad> %0,%1,%2,%3
13692 xsmsuba<Fvsx> %x0,%x1,%x2
13693 xsmsubm<Fvsx> %x0,%x1,%x3"
13694 [(set_attr "type" "fp")
13695 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13697 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13698 (define_expand "fnma<mode>4"
13699 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13702 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13703 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13704 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13705 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13708 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13709 (define_expand "fnms<mode>4"
13710 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13713 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13714 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13715 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13716 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13719 ; Not an official optab name, but used from builtins.
13720 (define_expand "nfma<mode>4"
13721 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13724 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13725 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13726 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13727 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13730 (define_insn "*nfma<mode>4_fpr"
13731 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13734 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13735 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13736 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13737 "TARGET_<MODE>_FPR"
13739 fnmadd<Ftrad> %0,%1,%2,%3
13740 xsnmadda<Fvsx> %x0,%x1,%x2
13741 xsnmaddm<Fvsx> %x0,%x1,%x3"
13742 [(set_attr "type" "fp")
13743 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13745 ; Not an official optab name, but used from builtins.
13746 (define_expand "nfms<mode>4"
13747 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13750 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13751 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13752 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13756 (define_insn "*nfmssf4_fpr"
13757 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13760 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13761 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13763 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13764 "TARGET_<MODE>_FPR"
13766 fnmsub<Ftrad> %0,%1,%2,%3
13767 xsnmsuba<Fvsx> %x0,%x1,%x2
13768 xsnmsubm<Fvsx> %x0,%x1,%x3"
13769 [(set_attr "type" "fp")
13770 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13773 (define_expand "rs6000_get_timebase"
13774 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13777 if (TARGET_POWERPC64)
13778 emit_insn (gen_rs6000_mftb_di (operands[0]));
13780 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13784 (define_insn "rs6000_get_timebase_ppc32"
13785 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13786 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13787 (clobber (match_scratch:SI 1 "=r"))
13788 (clobber (match_scratch:CC 2 "=y"))]
13789 "!TARGET_POWERPC64"
13791 if (WORDS_BIG_ENDIAN)
13794 return "mfspr %0,269\;"
13802 return "mftbu %0\;"
13811 return "mfspr %L0,269\;"
13819 return "mftbu %L0\;"
13826 [(set_attr "length" "20")])
13828 (define_insn "rs6000_mftb_<mode>"
13829 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13830 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13834 return "mfspr %0,268";
13840 (define_insn "rs6000_mffs"
13841 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13842 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13843 "TARGET_HARD_FLOAT && TARGET_FPRS"
13846 (define_insn "rs6000_mtfsf"
13847 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13848 (match_operand:DF 1 "gpc_reg_operand" "d")]
13850 "TARGET_HARD_FLOAT && TARGET_FPRS"
13854 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13855 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13856 ;; register that is being loaded. The fused ops must be physically adjacent.
13858 ;; There are two parts to addis fusion. The support for fused TOCs occur
13859 ;; before register allocation, and is meant to reduce the lifetime for the
13860 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13861 ;; to use the register that is being load. The peephole2 then gathers any
13862 ;; other fused possibilities that it can find after register allocation. If
13863 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13865 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13866 ;; before register allocation, so that we can avoid allocating a temporary base
13867 ;; register that won't be used, and that we try to load into base registers,
13868 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13869 ;; (addis followed by load) even on power8.
13872 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13873 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13874 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13875 [(parallel [(set (match_dup 0) (match_dup 2))
13876 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13877 (use (match_dup 3))
13878 (clobber (scratch:DI))])]
13880 operands[2] = fusion_wrap_memory_address (operands[1]);
13881 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13884 (define_insn "*toc_fusionload_<mode>"
13885 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13886 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13887 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13888 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13889 (clobber (match_scratch:DI 3 "=X,&b"))]
13890 "TARGET_TOC_FUSION_INT"
13892 if (base_reg_operand (operands[0], <MODE>mode))
13893 return emit_fusion_gpr_load (operands[0], operands[1]);
13895 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13897 [(set_attr "type" "load")
13898 (set_attr "length" "8")])
13900 (define_insn "*toc_fusionload_di"
13901 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13902 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13903 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13904 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13905 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13906 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13907 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13909 if (base_reg_operand (operands[0], DImode))
13910 return emit_fusion_gpr_load (operands[0], operands[1]);
13912 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13914 [(set_attr "type" "load")
13915 (set_attr "length" "8")])
13918 ;; Find cases where the addis that feeds into a load instruction is either used
13919 ;; once or is the same as the target register, and replace it with the fusion
13923 [(set (match_operand:P 0 "base_reg_operand" "")
13924 (match_operand:P 1 "fusion_gpr_addis" ""))
13925 (set (match_operand:INT1 2 "base_reg_operand" "")
13926 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13928 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13932 expand_fusion_gpr_load (operands);
13936 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13939 (define_insn "fusion_gpr_load_<mode>"
13940 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13941 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13942 UNSPEC_FUSION_GPR))]
13945 return emit_fusion_gpr_load (operands[0], operands[1]);
13947 [(set_attr "type" "load")
13948 (set_attr "length" "8")])
13951 ;; ISA 3.0 (power9) fusion support
13952 ;; Merge addis with floating load/store to FPRs (or GPRs).
13954 [(set (match_operand:P 0 "base_reg_operand" "")
13955 (match_operand:P 1 "fusion_gpr_addis" ""))
13956 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13957 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13958 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13959 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13962 expand_fusion_p9_load (operands);
13967 [(set (match_operand:P 0 "base_reg_operand" "")
13968 (match_operand:P 1 "fusion_gpr_addis" ""))
13969 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
13970 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
13971 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13972 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13973 && !rtx_equal_p (operands[0], operands[3])"
13976 expand_fusion_p9_store (operands);
13981 [(set (match_operand:SDI 0 "int_reg_operand" "")
13982 (match_operand:SDI 1 "upper16_cint_operand" ""))
13984 (ior:SDI (match_dup 0)
13985 (match_operand:SDI 2 "u_short_cint_operand" "")))]
13987 [(set (match_dup 0)
13988 (unspec:SDI [(match_dup 1)
13989 (match_dup 2)] UNSPEC_FUSION_P9))])
13992 [(set (match_operand:SDI 0 "int_reg_operand" "")
13993 (match_operand:SDI 1 "upper16_cint_operand" ""))
13994 (set (match_operand:SDI 2 "int_reg_operand" "")
13995 (ior:SDI (match_dup 0)
13996 (match_operand:SDI 3 "u_short_cint_operand" "")))]
13998 && !rtx_equal_p (operands[0], operands[2])
13999 && peep2_reg_dead_p (2, operands[0])"
14000 [(set (match_dup 2)
14001 (unspec:SDI [(match_dup 1)
14002 (match_dup 3)] UNSPEC_FUSION_P9))])
14004 ;; Fusion insns, created by the define_peephole2 above (and eventually by
14005 ;; reload). Because we want to eventually have secondary_reload generate
14006 ;; these, they have to have a single alternative that gives the register
14007 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
14008 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
14009 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
14011 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14013 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14016 /* This insn is a secondary reload insn, which cannot have alternatives.
14017 If we are not loading up register 0, use the power8 fusion instead. */
14018 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
14019 return emit_fusion_gpr_load (operands[0], operands[1]);
14021 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14023 [(set_attr "type" "load")
14024 (set_attr "length" "8")])
14026 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
14027 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14029 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
14031 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14034 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14036 [(set_attr "type" "store")
14037 (set_attr "length" "8")])
14039 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
14040 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
14042 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14044 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14047 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14049 [(set_attr "type" "fpload")
14050 (set_attr "length" "8")])
14052 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
14053 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14055 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
14057 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14060 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14062 [(set_attr "type" "fpstore")
14063 (set_attr "length" "8")])
14065 (define_insn "*fusion_p9_<mode>_constant"
14066 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
14067 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
14068 (match_operand:SDI 2 "u_short_cint_operand" "K")]
14069 UNSPEC_FUSION_P9))]
14072 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
14073 return "ori %0,%0,%2";
14075 [(set_attr "type" "two")
14076 (set_attr "length" "8")])
14079 ;; Miscellaneous ISA 2.06 (power7) instructions
14080 (define_insn "addg6s"
14081 [(set (match_operand:SI 0 "register_operand" "=r")
14082 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14083 (match_operand:SI 2 "register_operand" "r")]
14087 [(set_attr "type" "integer")
14088 (set_attr "length" "4")])
14090 (define_insn "cdtbcd"
14091 [(set (match_operand:SI 0 "register_operand" "=r")
14092 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14096 [(set_attr "type" "integer")
14097 (set_attr "length" "4")])
14099 (define_insn "cbcdtd"
14100 [(set (match_operand:SI 0 "register_operand" "=r")
14101 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14105 [(set_attr "type" "integer")
14106 (set_attr "length" "4")])
14108 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14113 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14114 (UNSPEC_DIVEO "eo")
14115 (UNSPEC_DIVEU "eu")
14116 (UNSPEC_DIVEUO "euo")])
14118 (define_insn "div<div_extend>_<mode>"
14119 [(set (match_operand:GPR 0 "register_operand" "=r")
14120 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14121 (match_operand:GPR 2 "register_operand" "r")]
14122 UNSPEC_DIV_EXTEND))]
14124 "div<wd><div_extend> %0,%1,%2"
14125 [(set_attr "type" "div")
14126 (set_attr "size" "<bits>")])
14129 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14131 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14132 (define_mode_attr FP128_64 [(TF "DF")
14137 (define_expand "unpack<mode>"
14138 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14140 [(match_operand:FMOVE128 1 "register_operand" "")
14141 (match_operand:QI 2 "const_0_to_1_operand" "")]
14142 UNSPEC_UNPACK_128BIT))]
14143 "FLOAT128_2REG_P (<MODE>mode)"
14146 (define_insn_and_split "unpack<mode>_dm"
14147 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14149 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14150 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14151 UNSPEC_UNPACK_128BIT))]
14152 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14154 "&& reload_completed"
14155 [(set (match_dup 0) (match_dup 3))]
14157 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14159 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14161 emit_note (NOTE_INSN_DELETED);
14165 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14167 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14168 (set_attr "length" "4")])
14170 (define_insn_and_split "unpack<mode>_nodm"
14171 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14173 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14174 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14175 UNSPEC_UNPACK_128BIT))]
14176 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14178 "&& reload_completed"
14179 [(set (match_dup 0) (match_dup 3))]
14181 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14183 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14185 emit_note (NOTE_INSN_DELETED);
14189 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14191 [(set_attr "type" "fp,fpstore")
14192 (set_attr "length" "4")])
14194 (define_insn_and_split "pack<mode>"
14195 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14197 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14198 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14199 UNSPEC_PACK_128BIT))]
14200 "FLOAT128_2REG_P (<MODE>mode)"
14204 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14205 [(set (match_dup 3) (match_dup 1))
14206 (set (match_dup 4) (match_dup 2))]
14208 unsigned dest_hi = REGNO (operands[0]);
14209 unsigned dest_lo = dest_hi + 1;
14211 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14212 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14214 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14215 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14217 [(set_attr "type" "fpsimple,fp")
14218 (set_attr "length" "4,8")])
14220 (define_insn "unpack<mode>"
14221 [(set (match_operand:DI 0 "register_operand" "=d,d")
14222 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14223 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14224 UNSPEC_UNPACK_128BIT))]
14225 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14227 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14228 return ASM_COMMENT_START " xxpermdi to same register";
14230 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14231 return "xxpermdi %x0,%x1,%x1,%3";
14233 [(set_attr "type" "vecperm")])
14235 (define_insn "pack<mode>"
14236 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14237 (unspec:FMOVE128_VSX
14238 [(match_operand:DI 1 "register_operand" "d")
14239 (match_operand:DI 2 "register_operand" "d")]
14240 UNSPEC_PACK_128BIT))]
14242 "xxpermdi %x0,%x1,%x2,0"
14243 [(set_attr "type" "vecperm")])
14247 ;; ISA 2.08 IEEE 128-bit floating point support.
14249 (define_insn "add<mode>3"
14250 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14252 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14253 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14254 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14256 [(set_attr "type" "vecfloat")
14257 (set_attr "size" "128")])
14259 (define_insn "sub<mode>3"
14260 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14262 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14263 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14264 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14266 [(set_attr "type" "vecfloat")
14267 (set_attr "size" "128")])
14269 (define_insn "mul<mode>3"
14270 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14272 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14273 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14274 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14276 [(set_attr "type" "vecfloat")
14277 (set_attr "size" "128")])
14279 (define_insn "div<mode>3"
14280 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14282 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14283 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14284 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14286 [(set_attr "type" "vecdiv")
14287 (set_attr "size" "128")])
14289 (define_insn "sqrt<mode>2"
14290 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14292 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14293 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14295 [(set_attr "type" "vecdiv")
14296 (set_attr "size" "128")])
14298 (define_expand "copysign<mode>3"
14299 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14300 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14301 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14302 "FLOAT128_IEEE_P (<MODE>mode)"
14304 if (TARGET_FLOAT128_HW)
14305 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14309 rtx tmp = gen_reg_rtx (<MODE>mode);
14310 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14311 operands[2], tmp));
14316 (define_insn "copysign<mode>3_hard"
14317 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14319 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14320 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14322 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14323 "xscpsgnqp %0,%2,%1"
14324 [(set_attr "type" "vecmove")
14325 (set_attr "size" "128")])
14327 (define_insn "copysign<mode>3_soft"
14328 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14330 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14331 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14332 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14334 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14335 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14336 [(set_attr "type" "veccomplex")
14337 (set_attr "length" "8")])
14339 (define_insn "neg<mode>2_hw"
14340 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14342 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14343 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14345 [(set_attr "type" "vecmove")
14346 (set_attr "size" "128")])
14349 (define_insn "abs<mode>2_hw"
14350 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14352 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14353 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14355 [(set_attr "type" "vecmove")
14356 (set_attr "size" "128")])
14359 (define_insn "*nabs<mode>2_hw"
14360 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14363 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14364 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14366 [(set_attr "type" "vecmove")
14367 (set_attr "size" "128")])
14369 ;; Initially don't worry about doing fusion
14370 (define_insn "*fma<mode>4_hw"
14371 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14373 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14374 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14375 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14376 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14377 "xsmaddqp %0,%1,%2"
14378 [(set_attr "type" "vecfloat")
14379 (set_attr "size" "128")])
14381 (define_insn "*fms<mode>4_hw"
14382 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14384 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14385 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14387 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14388 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14389 "xsmsubqp %0,%1,%2"
14390 [(set_attr "type" "vecfloat")
14391 (set_attr "size" "128")])
14393 (define_insn "*nfma<mode>4_hw"
14394 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14397 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14398 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14399 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14400 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14401 "xsnmaddqp %0,%1,%2"
14402 [(set_attr "type" "vecfloat")
14403 (set_attr "size" "128")])
14405 (define_insn "*nfms<mode>4_hw"
14406 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14409 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14410 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14412 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14413 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14414 "xsnmsubqp %0,%1,%2"
14415 [(set_attr "type" "vecfloat")
14416 (set_attr "size" "128")])
14418 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14419 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14420 (float_extend:IEEE128
14421 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14422 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14424 [(set_attr "type" "vecfloat")
14425 (set_attr "size" "128")])
14427 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14428 ;; point is a simple copy.
14429 (define_insn_and_split "extendkftf2"
14430 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14431 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14432 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14436 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14439 emit_note (NOTE_INSN_DELETED);
14442 [(set_attr "type" "*,veclogical")
14443 (set_attr "length" "0,4")])
14445 (define_insn_and_split "trunctfkf2"
14446 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14447 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14448 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14452 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14455 emit_note (NOTE_INSN_DELETED);
14458 [(set_attr "type" "*,veclogical")
14459 (set_attr "length" "0,4")])
14461 (define_insn "trunc<mode>df2_hw"
14462 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14464 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14465 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14467 [(set_attr "type" "vecfloat")
14468 (set_attr "size" "128")])
14470 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14471 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14473 (define_insn_and_split "trunc<mode>sf2_hw"
14474 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14476 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14477 (clobber (match_scratch:DF 2 "=v"))]
14478 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14481 [(set (match_dup 2)
14482 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
14484 (float_truncate:SF (match_dup 2)))]
14486 if (GET_CODE (operands[2]) == SCRATCH)
14487 operands[2] = gen_reg_rtx (DFmode);
14489 [(set_attr "type" "vecfloat")
14490 (set_attr "length" "8")])
14492 ;; Conversion between IEEE 128-bit and integer types
14493 (define_insn "fix_<mode>di2_hw"
14494 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14495 (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14496 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14498 [(set_attr "type" "vecfloat")
14499 (set_attr "size" "128")])
14501 (define_insn "fixuns_<mode>di2_hw"
14502 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14503 (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14504 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14506 [(set_attr "type" "vecfloat")
14507 (set_attr "size" "128")])
14509 (define_insn "fix_<mode>si2_hw"
14510 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14511 (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14512 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14514 [(set_attr "type" "vecfloat")
14515 (set_attr "size" "128")])
14517 (define_insn "fixuns_<mode>si2_hw"
14518 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14519 (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14520 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14522 [(set_attr "type" "vecfloat")
14523 (set_attr "size" "128")])
14525 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14526 ;; floating point value to 32-bit integer to GPR in order to save it.
14527 (define_insn_and_split "*fix<uns>_<mode>_mem"
14528 [(set (match_operand:SI 0 "memory_operand" "=Z")
14529 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14530 (clobber (match_scratch:SI 2 "=v"))]
14531 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14533 "&& reload_completed"
14534 [(set (match_dup 2)
14535 (any_fix:SI (match_dup 1)))
14539 (define_insn "float_<mode>di2_hw"
14540 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14541 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14542 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14544 [(set_attr "type" "vecfloat")
14545 (set_attr "size" "128")])
14547 (define_insn_and_split "float_<mode>si2_hw"
14548 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14549 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14550 (clobber (match_scratch:DI 2 "=v"))]
14551 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14554 [(set (match_dup 2)
14555 (sign_extend:DI (match_dup 1)))
14557 (float:IEEE128 (match_dup 2)))]
14559 if (GET_CODE (operands[2]) == SCRATCH)
14560 operands[2] = gen_reg_rtx (DImode);
14563 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14564 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14565 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14566 (clobber (match_scratch:DI 2 "=X,r,X"))]
14567 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14569 "&& reload_completed"
14572 rtx dest = operands[0];
14573 rtx src = operands[1];
14574 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14576 if (altivec_register_operand (src, <QHI:MODE>mode))
14577 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14578 else if (int_reg_operand (src, <QHI:MODE>mode))
14580 rtx ext_di = operands[2];
14581 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14582 emit_move_insn (dest_di, ext_di);
14584 else if (MEM_P (src))
14586 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14587 emit_move_insn (dest_qhi, src);
14588 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14591 gcc_unreachable ();
14593 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14596 [(set_attr "length" "8,12,12")
14597 (set_attr "type" "vecfloat")
14598 (set_attr "size" "128")])
14600 (define_insn "floatuns_<mode>di2_hw"
14601 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14602 (unsigned_float:IEEE128
14603 (match_operand:DI 1 "altivec_register_operand" "v")))]
14604 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14606 [(set_attr "type" "vecfloat")
14607 (set_attr "size" "128")])
14609 (define_insn_and_split "floatuns_<mode>si2_hw"
14610 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14611 (unsigned_float:IEEE128
14612 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14613 (clobber (match_scratch:DI 2 "=v"))]
14614 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14617 [(set (match_dup 2)
14618 (zero_extend:DI (match_dup 1)))
14620 (float:IEEE128 (match_dup 2)))]
14622 if (GET_CODE (operands[2]) == SCRATCH)
14623 operands[2] = gen_reg_rtx (DImode);
14626 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14627 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14628 (unsigned_float:IEEE128
14629 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14630 (clobber (match_scratch:DI 2 "=X,r,X"))]
14631 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14633 "&& reload_completed"
14636 rtx dest = operands[0];
14637 rtx src = operands[1];
14638 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14640 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14641 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14642 else if (int_reg_operand (src, <QHI:MODE>mode))
14644 rtx ext_di = operands[2];
14645 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14646 emit_move_insn (dest_di, ext_di);
14649 gcc_unreachable ();
14651 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14654 [(set_attr "length" "8,12,8")
14655 (set_attr "type" "vecfloat")
14656 (set_attr "size" "128")])
14658 ;; IEEE 128-bit instructions with round to odd semantics
14659 (define_insn "*trunc<mode>df2_odd"
14660 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14661 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14662 UNSPEC_ROUND_TO_ODD))]
14663 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14665 [(set_attr "type" "vecfloat")
14666 (set_attr "size" "128")])
14668 ;; IEEE 128-bit comparisons
14669 (define_insn "*cmp<mode>_hw"
14670 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14671 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14672 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14673 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14674 "xscmpuqp %0,%1,%2"
14675 [(set_attr "type" "veccmp")
14676 (set_attr "size" "128")])
14680 (include "sync.md")
14681 (include "vector.md")
14683 (include "altivec.md")
14686 (include "paired.md")
14687 (include "crypto.md")