1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2019 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)
36 (FIRST_ALTIVEC_REGNO 64)
37 (LAST_ALTIVEC_REGNO 95)
41 (ARG_POINTER_REGNUM 99)
53 (FRAME_POINTER_REGNUM 110)
60 (define_c_enum "unspec"
61 [UNSPEC_PROBE_STACK ; probe stack memory reference
62 UNSPEC_TOCPTR ; address of a word pointing to the TOC
63 UNSPEC_TOC ; address of the TOC (more-or-less)
64 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
72 UNSPEC_LD_MPIC ; load_macho_picbase
73 UNSPEC_RELD_MPIC ; re-load_macho_picbase
74 UNSPEC_MPIC_CORRECT ; macho_correct_pic
90 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
108 UNSPEC_MACHOPIC_OFFSET
122 UNSPEC_P8V_RELOAD_FROM_GPR
125 UNSPEC_P8V_RELOAD_FROM_VSX
139 UNSPEC_ADD_ROUND_TO_ODD
140 UNSPEC_SUB_ROUND_TO_ODD
141 UNSPEC_MUL_ROUND_TO_ODD
142 UNSPEC_DIV_ROUND_TO_ODD
143 UNSPEC_FMA_ROUND_TO_ODD
144 UNSPEC_SQRT_ROUND_TO_ODD
145 UNSPEC_TRUNC_ROUND_TO_ODD
156 ;; UNSPEC_VOLATILE usage
159 (define_c_enum "unspecv"
161 UNSPECV_LL ; load-locked
162 UNSPECV_SC ; store-conditional
163 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
164 UNSPECV_EH_RR ; eh_reg_restore
165 UNSPECV_ISYNC ; isync instruction
166 UNSPECV_MFTB ; move from time base
167 UNSPECV_DARN ; darn 1 (deliver a random number)
168 UNSPECV_DARN_32 ; darn 2
169 UNSPECV_DARN_RAW ; darn 0
170 UNSPECV_NLGR ; non-local goto receiver
171 UNSPECV_MFFS ; Move from FPSCR
172 UNSPECV_MFFSL ; Move from FPSCR light instruction version
173 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
174 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
175 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
176 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
177 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
178 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
179 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
180 UNSPECV_SPEC_BARRIER ; Speculation barrier
183 ; The three different kinds of epilogue.
184 (define_enum "epilogue_type" [normal sibcall eh_return])
186 ;; Define an insn type attribute. This is used in function unit delay
190 add,logical,shift,insert,
192 exts,cntlz,popcnt,isel,
193 load,store,fpload,fpstore,vecload,vecstore,
195 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
196 cr_logical,mfcr,mfcrf,mtcr,
197 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
198 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
199 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
200 veclogical,veccmpfx,vecexts,vecmove,
202 (const_string "integer"))
204 ;; What data size does this instruction work on?
205 ;; This is used for insert, mul and others as necessary.
206 (define_attr "size" "8,16,32,64,128" (const_string "32"))
208 ;; What is the insn_cost for this insn? The target hook can still override
209 ;; this. For optimizing for size the "length" attribute is used instead.
210 (define_attr "cost" "" (const_int 0))
212 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
213 ;; This is used for add, logical, shift, exts, mul.
214 (define_attr "dot" "no,yes" (const_string "no"))
216 ;; Does this instruction sign-extend its result?
217 ;; This is used for load insns.
218 (define_attr "sign_extend" "no,yes" (const_string "no"))
220 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
221 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
223 ;; Does this instruction use indexed (that is, reg+reg) addressing?
224 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
225 ;; it is automatically set based on that. If a load or store instruction
226 ;; has fewer than two operands it needs to set this attribute manually
227 ;; or the compiler will crash.
228 (define_attr "indexed" "no,yes"
229 (if_then_else (ior (match_operand 0 "indexed_address_mem")
230 (match_operand 1 "indexed_address_mem"))
232 (const_string "no")))
234 ;; Does this instruction use update addressing?
235 ;; This is used for load and store insns. See the comments for "indexed".
236 (define_attr "update" "no,yes"
237 (if_then_else (ior (match_operand 0 "update_address_mem")
238 (match_operand 1 "update_address_mem"))
240 (const_string "no")))
242 ;; Is this instruction using operands[2] as shift amount, and can that be a
244 ;; This is used for shift insns.
245 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
247 ;; Is this instruction using a shift amount from a register?
248 ;; This is used for shift insns.
249 (define_attr "var_shift" "no,yes"
250 (if_then_else (and (eq_attr "type" "shift")
251 (eq_attr "maybe_var_shift" "yes"))
252 (if_then_else (match_operand 2 "gpc_reg_operand")
255 (const_string "no")))
257 ;; Is copying of this instruction disallowed?
258 (define_attr "cannot_copy" "no,yes" (const_string "no"))
261 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
262 ;; before the instruction. A prefixed instruction has a prefix instruction
263 ;; word that extends the immediate value of the instructions from 12-16 bits to
264 ;; 34 bits. The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
265 ;; insns. The default "length" attribute will also be adjusted by default to
267 (define_attr "prefixed" "no,yes"
268 (cond [(ior (match_test "!TARGET_PREFIXED_ADDR")
269 (match_test "!NONJUMP_INSN_P (insn)"))
272 (eq_attr "type" "load,fpload,vecload")
273 (if_then_else (match_test "prefixed_load_p (insn)")
277 (eq_attr "type" "store,fpstore,vecstore")
278 (if_then_else (match_test "prefixed_store_p (insn)")
282 (eq_attr "type" "integer,add")
283 (if_then_else (match_test "prefixed_paddi_p (insn)")
285 (const_string "no"))]
287 (const_string "no")))
289 ;; Return the number of real hardware instructions in a combined insn. If it
290 ;; is 0, just use the length / 4.
291 (define_attr "num_insns" "" (const_int 0))
293 ;; If an insn is prefixed, return the maximum number of prefixed instructions
294 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
296 (define_attr "max_prefixed_insns" "" (const_int 1))
298 ;; Length of the instruction (in bytes). This length does not consider the
299 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
300 ;; the length if there are prefixed instructions.
302 ;; While it might be tempting to use num_insns to calculate the length, it can
303 ;; be problematical unless all insn lengths are adjusted to use num_insns
304 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
305 ;; num_insns and recurse).
306 (define_attr "length" "" (const_int 4))
308 ;; Processor type -- this attribute must exactly match the processor_type
309 ;; enumeration in rs6000-opts.h.
311 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
312 ppc750,ppc7400,ppc7450,
313 ppc403,ppc405,ppc440,ppc476,
314 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
315 power4,power5,power6,power7,power8,power9,future,
316 rs64a,mpccore,cell,ppca2,titan"
317 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
319 ;; The ISA we implement.
320 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,fut"
321 (const_string "any"))
323 ;; Is this alternative enabled for the current CPU/ISA/etc.?
324 (define_attr "enabled" ""
326 [(eq_attr "isa" "any")
329 (and (eq_attr "isa" "p5")
330 (match_test "TARGET_POPCNTB"))
333 (and (eq_attr "isa" "p6")
334 (match_test "TARGET_CMPB"))
337 (and (eq_attr "isa" "p7")
338 (match_test "TARGET_POPCNTD"))
341 (and (eq_attr "isa" "p7v")
342 (match_test "TARGET_VSX"))
345 (and (eq_attr "isa" "p8v")
346 (match_test "TARGET_P8_VECTOR"))
349 (and (eq_attr "isa" "p9v")
350 (match_test "TARGET_P9_VECTOR"))
353 (and (eq_attr "isa" "p9kf")
354 (match_test "TARGET_FLOAT128_TYPE"))
357 (and (eq_attr "isa" "p9tf")
358 (match_test "FLOAT128_VECTOR_P (TFmode)"))
361 (and (eq_attr "isa" "fut")
362 (match_test "TARGET_FUTURE"))
366 ;; If this instruction is microcoded on the CELL processor
367 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
368 (define_attr "cell_micro" "not,conditional,always"
369 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
370 (eq_attr "dot" "yes"))
371 (and (eq_attr "type" "load")
372 (eq_attr "sign_extend" "yes"))
373 (and (eq_attr "type" "shift")
374 (eq_attr "var_shift" "yes")))
375 (const_string "always")
376 (const_string "not")))
378 (automata_option "ndfa")
391 (include "e300c2c3.md")
392 (include "e500mc.md")
393 (include "e500mc64.md")
396 (include "power4.md")
397 (include "power5.md")
398 (include "power6.md")
399 (include "power7.md")
400 (include "power8.md")
401 (include "power9.md")
402 (include "future.md")
407 (include "predicates.md")
408 (include "constraints.md")
413 ; This mode iterator allows :GPR to be used to indicate the allowable size
414 ; of whole values in GPRs.
415 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
417 ; And again, for patterns that need two (potentially) different integer modes.
418 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
420 ; Any supported integer mode.
421 (define_mode_iterator INT [QI HI SI DI TI PTI])
423 ; Any supported integer mode that fits in one register.
424 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
426 ; Integer modes supported in VSX registers with ISA 3.0 instructions
427 (define_mode_iterator INT_ISA3 [QI HI SI DI])
429 ; Everything we can extend QImode to.
430 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
432 ; Everything we can extend HImode to.
433 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
435 ; Everything we can extend SImode to.
436 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
438 ; QImode or HImode for small integer moves and small atomic ops
439 (define_mode_iterator QHI [QI HI])
441 ; QImode, HImode, SImode for fused ops only for GPR loads
442 (define_mode_iterator QHSI [QI HI SI])
444 ; HImode or SImode for sign extended fusion ops
445 (define_mode_iterator HSI [HI SI])
447 ; SImode or DImode, even if DImode doesn't fit in GPRs.
448 (define_mode_iterator SDI [SI DI])
450 ; The size of a pointer. Also, the size of the value that a record-condition
451 ; (one with a '.') will compare; and the size used for arithmetic carries.
452 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
454 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
455 ; PTImode is GPR only)
456 (define_mode_iterator TI2 [TI PTI])
458 ; Any hardware-supported floating-point mode
459 (define_mode_iterator FP [
460 (SF "TARGET_HARD_FLOAT")
461 (DF "TARGET_HARD_FLOAT")
462 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
463 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
464 (KF "TARGET_FLOAT128_TYPE")
468 ; Any fma capable floating-point mode.
469 (define_mode_iterator FMA_F [
470 (SF "TARGET_HARD_FLOAT")
471 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
472 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
473 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
474 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
475 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
478 ; Floating point move iterators to combine binary and decimal moves
479 (define_mode_iterator FMOVE32 [SF SD])
480 (define_mode_iterator FMOVE64 [DF DD])
481 (define_mode_iterator FMOVE64X [DI DF DD])
482 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
483 (IF "FLOAT128_IBM_P (IFmode)")
484 (TD "TARGET_HARD_FLOAT")])
486 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
487 (IF "FLOAT128_2REG_P (IFmode)")
488 (TD "TARGET_HARD_FLOAT")])
490 ; Iterators for 128 bit types for direct move
491 (define_mode_iterator FMOVE128_GPR [TI
499 (KF "FLOAT128_VECTOR_P (KFmode)")
500 (TF "FLOAT128_VECTOR_P (TFmode)")])
502 ; Iterator for 128-bit VSX types for pack/unpack
503 (define_mode_iterator FMOVE128_VSX [V1TI KF])
505 ; Iterators for converting to/from TFmode
506 (define_mode_iterator IFKF [IF KF])
508 ; Constraints for moving IF/KFmode.
509 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
511 ; Whether a floating point move is ok, don't allow SD without hardware FP
512 (define_mode_attr fmove_ok [(SF "")
514 (SD "TARGET_HARD_FLOAT")
517 ; Convert REAL_VALUE to the appropriate bits
518 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
519 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
520 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
521 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
523 ; Whether 0.0 has an all-zero bit pattern
524 (define_mode_attr zero_fp [(SF "j")
533 ; Definitions for 64-bit VSX
534 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
536 ; Definitions for 64-bit direct move
537 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
539 ; Definitions for 64-bit use of altivec registers
540 (define_mode_attr f64_av [(DF "v") (DD "wn")])
542 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
543 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
545 ; These modes do not fit in integer registers in 32-bit mode.
546 (define_mode_iterator DIFD [DI DF DD])
548 ; Iterator for reciprocal estimate instructions
549 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
552 (define_mode_iterator SFDF [SF DF])
554 ; And again, for when we need two FP modes in a pattern.
555 (define_mode_iterator SFDF2 [SF DF])
557 ; A generic s/d attribute, for sp/dp for example.
558 (define_mode_attr sd [(SF "s") (DF "d")
559 (V4SF "s") (V2DF "d")])
561 ; "s" or nothing, for fmuls/fmul for example.
562 (define_mode_attr s [(SF "s") (DF "")])
564 ; Iterator for 128-bit floating point that uses the IBM double-double format
565 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
566 (TF "FLOAT128_IBM_P (TFmode)")])
568 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
569 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
570 (TF "FLOAT128_IEEE_P (TFmode)")])
572 ; Iterator for 128-bit floating point
573 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
574 (IF "TARGET_FLOAT128_TYPE")
575 (TF "TARGET_LONG_DOUBLE_128")])
577 ; Iterator for signbit on 64-bit machines with direct move
578 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
579 (TF "FLOAT128_VECTOR_P (TFmode)")])
581 ; Iterator for ISA 3.0 supported floating point types
582 (define_mode_iterator FP_ISA3 [SF DF])
584 ; SF/DF constraint for arithmetic on traditional floating point registers
585 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
587 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
588 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
589 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
591 (define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")])
593 ; Which isa is needed for those float instructions?
594 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
597 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
599 ; Conditional returns.
600 (define_code_iterator any_return [return simple_return])
601 (define_code_attr return_pred [(return "direct_return ()")
602 (simple_return "1")])
603 (define_code_attr return_str [(return "") (simple_return "simple_")])
606 (define_code_iterator iorxor [ior xor])
607 (define_code_iterator and_ior_xor [and ior xor])
609 ; Signed/unsigned variants of ops.
610 (define_code_iterator any_extend [sign_extend zero_extend])
611 (define_code_iterator any_fix [fix unsigned_fix])
612 (define_code_iterator any_float [float unsigned_float])
614 (define_code_attr u [(sign_extend "")
619 (define_code_attr su [(sign_extend "s")
624 (unsigned_float "u")])
626 (define_code_attr az [(sign_extend "a")
631 (unsigned_float "z")])
633 (define_code_attr uns [(fix "")
636 (unsigned_float "uns")])
638 ; Various instructions that come in SI and DI forms.
639 ; A generic w/d attribute, for things like cmpw/cmpd.
640 (define_mode_attr wd [(QI "b")
651 ;; How many bits in this mode?
652 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
653 (SF "32") (DF "64")])
656 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
658 ;; Bitmask for shift instructions
659 (define_mode_attr hH [(SI "h") (DI "H")])
661 ;; A mode twice the size of the given mode
662 (define_mode_attr dmode [(SI "di") (DI "ti")])
663 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
665 ;; Suffix for reload patterns
666 (define_mode_attr ptrsize [(SI "32bit")
669 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
670 (DI "TARGET_64BIT")])
672 (define_mode_attr mptrsize [(SI "si")
675 (define_mode_attr ptrload [(SI "lwz")
678 (define_mode_attr ptrm [(SI "m")
681 (define_mode_attr rreg [(SF "f")
688 (define_mode_attr rreg2 [(SF "f")
691 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
692 (DF "TARGET_FCFID")])
694 ;; Mode iterator for logical operations on 128-bit types
695 (define_mode_iterator BOOL_128 [TI
697 (V16QI "TARGET_ALTIVEC")
698 (V8HI "TARGET_ALTIVEC")
699 (V4SI "TARGET_ALTIVEC")
700 (V4SF "TARGET_ALTIVEC")
701 (V2DI "TARGET_ALTIVEC")
702 (V2DF "TARGET_ALTIVEC")
703 (V1TI "TARGET_ALTIVEC")])
705 ;; For the GPRs we use 3 constraints for register outputs, two that are the
706 ;; same as the output register, and a third where the output register is an
707 ;; early clobber, so we don't have to deal with register overlaps. For the
708 ;; vector types, we prefer to use the vector registers. For TI mode, allow
711 ;; Mode attribute for boolean operation register constraints for output
712 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
714 (V16QI "wa,v,&?r,?r,?r")
715 (V8HI "wa,v,&?r,?r,?r")
716 (V4SI "wa,v,&?r,?r,?r")
717 (V4SF "wa,v,&?r,?r,?r")
718 (V2DI "wa,v,&?r,?r,?r")
719 (V2DF "wa,v,&?r,?r,?r")
720 (V1TI "wa,v,&?r,?r,?r")])
722 ;; Mode attribute for boolean operation register constraints for operand1
723 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
731 (V1TI "wa,v,r,0,r")])
733 ;; Mode attribute for boolean operation register constraints for operand2
734 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
742 (V1TI "wa,v,r,r,0")])
744 ;; Mode attribute for boolean operation register constraints for operand1
745 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
746 ;; is used for operand1 or operand2
747 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
755 (V1TI "wa,v,r,0,0")])
757 ;; Reload iterator for creating the function to allocate a base register to
758 ;; supplement addressing modes.
759 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
760 SF SD SI DF DD DI TI PTI KF IF TF])
762 ;; Iterate over smin, smax
763 (define_code_iterator fp_minmax [smin smax])
765 (define_code_attr minmax [(smin "min")
768 (define_code_attr SMINMAX [(smin "SMIN")
771 ;; Iterator to optimize the following cases:
772 ;; D-form load to FPR register & move to Altivec register
773 ;; Move Altivec register to FPR register and store
774 (define_mode_iterator ALTIVEC_DFORM [DF
775 (SF "TARGET_P8_VECTOR")
776 (DI "TARGET_POWERPC64")])
778 (include "darwin.md")
780 ;; Start with fixed-point load and store insns. Here we put only the more
781 ;; complex forms. Basic data transfer is done later.
783 (define_insn "zero_extendqi<mode>2"
784 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
785 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
792 [(set_attr "type" "load,shift,fpload,vecperm")
793 (set_attr "isa" "*,*,p9v,p9v")])
795 (define_insn_and_split "*zero_extendqi<mode>2_dot"
796 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
797 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
799 (clobber (match_scratch:EXTQI 0 "=r,r"))]
804 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
806 (zero_extend:EXTQI (match_dup 1)))
808 (compare:CC (match_dup 0)
811 [(set_attr "type" "logical")
812 (set_attr "dot" "yes")
813 (set_attr "length" "4,8")])
815 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
816 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
817 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
819 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
820 (zero_extend:EXTQI (match_dup 1)))]
825 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
827 (zero_extend:EXTQI (match_dup 1)))
829 (compare:CC (match_dup 0)
832 [(set_attr "type" "logical")
833 (set_attr "dot" "yes")
834 (set_attr "length" "4,8")])
837 (define_insn "zero_extendhi<mode>2"
838 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
839 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
843 rlwinm %0,%1,0,0xffff
846 [(set_attr "type" "load,shift,fpload,vecperm")
847 (set_attr "isa" "*,*,p9v,p9v")])
849 (define_insn_and_split "*zero_extendhi<mode>2_dot"
850 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
851 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
853 (clobber (match_scratch:EXTHI 0 "=r,r"))]
858 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
860 (zero_extend:EXTHI (match_dup 1)))
862 (compare:CC (match_dup 0)
865 [(set_attr "type" "logical")
866 (set_attr "dot" "yes")
867 (set_attr "length" "4,8")])
869 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
870 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
871 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
873 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
874 (zero_extend:EXTHI (match_dup 1)))]
879 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
881 (zero_extend:EXTHI (match_dup 1)))
883 (compare:CC (match_dup 0)
886 [(set_attr "type" "logical")
887 (set_attr "dot" "yes")
888 (set_attr "length" "4,8")])
891 (define_insn "zero_extendsi<mode>2"
892 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
893 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
902 xxextractuw %x0,%x1,4"
903 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
904 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
906 (define_insn_and_split "*zero_extendsi<mode>2_dot"
907 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
910 (clobber (match_scratch:EXTSI 0 "=r,r"))]
915 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
917 (zero_extend:DI (match_dup 1)))
919 (compare:CC (match_dup 0)
922 [(set_attr "type" "shift")
923 (set_attr "dot" "yes")
924 (set_attr "length" "4,8")])
926 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
927 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
928 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
930 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
931 (zero_extend:EXTSI (match_dup 1)))]
936 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
938 (zero_extend:EXTSI (match_dup 1)))
940 (compare:CC (match_dup 0)
943 [(set_attr "type" "shift")
944 (set_attr "dot" "yes")
945 (set_attr "length" "4,8")])
948 (define_insn "extendqi<mode>2"
949 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
950 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
955 [(set_attr "type" "exts,vecperm")
956 (set_attr "isa" "*,p9v")])
958 (define_insn_and_split "*extendqi<mode>2_dot"
959 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
960 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
962 (clobber (match_scratch:EXTQI 0 "=r,r"))]
967 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
969 (sign_extend:EXTQI (match_dup 1)))
971 (compare:CC (match_dup 0)
974 [(set_attr "type" "exts")
975 (set_attr "dot" "yes")
976 (set_attr "length" "4,8")])
978 (define_insn_and_split "*extendqi<mode>2_dot2"
979 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
982 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
983 (sign_extend:EXTQI (match_dup 1)))]
988 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
990 (sign_extend:EXTQI (match_dup 1)))
992 (compare:CC (match_dup 0)
995 [(set_attr "type" "exts")
996 (set_attr "dot" "yes")
997 (set_attr "length" "4,8")])
1000 (define_expand "extendhi<mode>2"
1001 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1002 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1006 (define_insn "*extendhi<mode>2"
1007 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1008 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1015 [(set_attr "type" "load,exts,fpload,vecperm")
1016 (set_attr "sign_extend" "yes")
1017 (set_attr "length" "*,*,8,*")
1018 (set_attr "isa" "*,*,p9v,p9v")])
1021 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1023 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1024 "TARGET_P9_VECTOR && reload_completed"
1028 (sign_extend:EXTHI (match_dup 2)))]
1030 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1033 (define_insn_and_split "*extendhi<mode>2_dot"
1034 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1035 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1037 (clobber (match_scratch:EXTHI 0 "=r,r"))]
1042 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1044 (sign_extend:EXTHI (match_dup 1)))
1046 (compare:CC (match_dup 0)
1049 [(set_attr "type" "exts")
1050 (set_attr "dot" "yes")
1051 (set_attr "length" "4,8")])
1053 (define_insn_and_split "*extendhi<mode>2_dot2"
1054 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1055 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1057 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1058 (sign_extend:EXTHI (match_dup 1)))]
1063 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1065 (sign_extend:EXTHI (match_dup 1)))
1067 (compare:CC (match_dup 0)
1070 [(set_attr "type" "exts")
1071 (set_attr "dot" "yes")
1072 (set_attr "length" "4,8")])
1075 (define_insn "extendsi<mode>2"
1076 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1077 "=r, r, d, wa, wa, v, v, wr")
1078 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1079 "YZ, r, Z, Z, r, v, v, ?wa")))]
1090 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1091 (set_attr "sign_extend" "yes")
1092 (set_attr "length" "*,*,*,*,*,*,8,8")
1093 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1096 [(set (match_operand:EXTSI 0 "int_reg_operand")
1097 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1098 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1102 (sign_extend:DI (match_dup 2)))]
1104 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1108 [(set (match_operand:DI 0 "altivec_register_operand")
1109 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1110 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1113 rtx dest = operands[0];
1114 rtx src = operands[1];
1115 int dest_regno = REGNO (dest);
1116 int src_regno = REGNO (src);
1117 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1118 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1120 if (BYTES_BIG_ENDIAN)
1122 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1123 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1127 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1128 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1133 (define_insn_and_split "*extendsi<mode>2_dot"
1134 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1135 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1137 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1142 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1144 (sign_extend:EXTSI (match_dup 1)))
1146 (compare:CC (match_dup 0)
1149 [(set_attr "type" "exts")
1150 (set_attr "dot" "yes")
1151 (set_attr "length" "4,8")])
1153 (define_insn_and_split "*extendsi<mode>2_dot2"
1154 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1155 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1157 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1158 (sign_extend:EXTSI (match_dup 1)))]
1163 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1165 (sign_extend:EXTSI (match_dup 1)))
1167 (compare:CC (match_dup 0)
1170 [(set_attr "type" "exts")
1171 (set_attr "dot" "yes")
1172 (set_attr "length" "4,8")])
1174 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1176 (define_insn "*macchwc"
1177 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1178 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1179 (match_operand:SI 2 "gpc_reg_operand" "r")
1182 (match_operand:HI 1 "gpc_reg_operand" "r")))
1183 (match_operand:SI 4 "gpc_reg_operand" "0"))
1185 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186 (plus:SI (mult:SI (ashiftrt:SI
1194 [(set_attr "type" "halfmul")])
1196 (define_insn "*macchw"
1197 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1198 (plus:SI (mult:SI (ashiftrt:SI
1199 (match_operand:SI 2 "gpc_reg_operand" "r")
1202 (match_operand:HI 1 "gpc_reg_operand" "r")))
1203 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1206 [(set_attr "type" "halfmul")])
1208 (define_insn "*macchwuc"
1209 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1210 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1211 (match_operand:SI 2 "gpc_reg_operand" "r")
1214 (match_operand:HI 1 "gpc_reg_operand" "r")))
1215 (match_operand:SI 4 "gpc_reg_operand" "0"))
1217 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1218 (plus:SI (mult:SI (lshiftrt:SI
1226 [(set_attr "type" "halfmul")])
1228 (define_insn "*macchwu"
1229 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1230 (plus:SI (mult:SI (lshiftrt:SI
1231 (match_operand:SI 2 "gpc_reg_operand" "r")
1234 (match_operand:HI 1 "gpc_reg_operand" "r")))
1235 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1238 [(set_attr "type" "halfmul")])
1240 (define_insn "*machhwc"
1241 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1242 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1243 (match_operand:SI 1 "gpc_reg_operand" "%r")
1246 (match_operand:SI 2 "gpc_reg_operand" "r")
1248 (match_operand:SI 4 "gpc_reg_operand" "0"))
1250 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1251 (plus:SI (mult:SI (ashiftrt:SI
1260 [(set_attr "type" "halfmul")])
1262 (define_insn "*machhw"
1263 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264 (plus:SI (mult:SI (ashiftrt:SI
1265 (match_operand:SI 1 "gpc_reg_operand" "%r")
1268 (match_operand:SI 2 "gpc_reg_operand" "r")
1270 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1273 [(set_attr "type" "halfmul")])
1275 (define_insn "*machhwuc"
1276 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1277 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1278 (match_operand:SI 1 "gpc_reg_operand" "%r")
1281 (match_operand:SI 2 "gpc_reg_operand" "r")
1283 (match_operand:SI 4 "gpc_reg_operand" "0"))
1285 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1286 (plus:SI (mult:SI (lshiftrt:SI
1295 [(set_attr "type" "halfmul")])
1297 (define_insn "*machhwu"
1298 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1299 (plus:SI (mult:SI (lshiftrt:SI
1300 (match_operand:SI 1 "gpc_reg_operand" "%r")
1303 (match_operand:SI 2 "gpc_reg_operand" "r")
1305 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1308 [(set_attr "type" "halfmul")])
1310 (define_insn "*maclhwc"
1311 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1312 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1313 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1315 (match_operand:HI 2 "gpc_reg_operand" "r")))
1316 (match_operand:SI 4 "gpc_reg_operand" "0"))
1318 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1319 (plus:SI (mult:SI (sign_extend:SI
1326 [(set_attr "type" "halfmul")])
1328 (define_insn "*maclhw"
1329 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330 (plus:SI (mult:SI (sign_extend:SI
1331 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1333 (match_operand:HI 2 "gpc_reg_operand" "r")))
1334 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1337 [(set_attr "type" "halfmul")])
1339 (define_insn "*maclhwuc"
1340 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1341 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1342 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1344 (match_operand:HI 2 "gpc_reg_operand" "r")))
1345 (match_operand:SI 4 "gpc_reg_operand" "0"))
1347 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1348 (plus:SI (mult:SI (zero_extend:SI
1355 [(set_attr "type" "halfmul")])
1357 (define_insn "*maclhwu"
1358 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1359 (plus:SI (mult:SI (zero_extend:SI
1360 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1362 (match_operand:HI 2 "gpc_reg_operand" "r")))
1363 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1366 [(set_attr "type" "halfmul")])
1368 (define_insn "*nmacchwc"
1369 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1370 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1371 (mult:SI (ashiftrt:SI
1372 (match_operand:SI 2 "gpc_reg_operand" "r")
1375 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1377 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1378 (minus:SI (match_dup 4)
1379 (mult:SI (ashiftrt:SI
1386 [(set_attr "type" "halfmul")])
1388 (define_insn "*nmacchw"
1389 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1391 (mult:SI (ashiftrt:SI
1392 (match_operand:SI 2 "gpc_reg_operand" "r")
1395 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1398 [(set_attr "type" "halfmul")])
1400 (define_insn "*nmachhwc"
1401 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1402 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1403 (mult:SI (ashiftrt:SI
1404 (match_operand:SI 1 "gpc_reg_operand" "%r")
1407 (match_operand:SI 2 "gpc_reg_operand" "r")
1410 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1411 (minus:SI (match_dup 4)
1412 (mult:SI (ashiftrt:SI
1420 [(set_attr "type" "halfmul")])
1422 (define_insn "*nmachhw"
1423 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1424 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1425 (mult:SI (ashiftrt:SI
1426 (match_operand:SI 1 "gpc_reg_operand" "%r")
1429 (match_operand:SI 2 "gpc_reg_operand" "r")
1433 [(set_attr "type" "halfmul")])
1435 (define_insn "*nmaclhwc"
1436 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1437 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1438 (mult:SI (sign_extend:SI
1439 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1441 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1443 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1444 (minus:SI (match_dup 4)
1445 (mult:SI (sign_extend:SI
1451 [(set_attr "type" "halfmul")])
1453 (define_insn "*nmaclhw"
1454 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1455 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1456 (mult:SI (sign_extend:SI
1457 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1459 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1462 [(set_attr "type" "halfmul")])
1464 (define_insn "*mulchwc"
1465 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1466 (compare:CC (mult:SI (ashiftrt:SI
1467 (match_operand:SI 2 "gpc_reg_operand" "r")
1470 (match_operand:HI 1 "gpc_reg_operand" "r")))
1472 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1473 (mult:SI (ashiftrt:SI
1480 [(set_attr "type" "halfmul")])
1482 (define_insn "*mulchw"
1483 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1484 (mult:SI (ashiftrt:SI
1485 (match_operand:SI 2 "gpc_reg_operand" "r")
1488 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1491 [(set_attr "type" "halfmul")])
1493 (define_insn "*mulchwuc"
1494 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1495 (compare:CC (mult:SI (lshiftrt:SI
1496 (match_operand:SI 2 "gpc_reg_operand" "r")
1499 (match_operand:HI 1 "gpc_reg_operand" "r")))
1501 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1502 (mult:SI (lshiftrt:SI
1509 [(set_attr "type" "halfmul")])
1511 (define_insn "*mulchwu"
1512 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1513 (mult:SI (lshiftrt:SI
1514 (match_operand:SI 2 "gpc_reg_operand" "r")
1517 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1520 [(set_attr "type" "halfmul")])
1522 (define_insn "*mulhhwc"
1523 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1524 (compare:CC (mult:SI (ashiftrt:SI
1525 (match_operand:SI 1 "gpc_reg_operand" "%r")
1528 (match_operand:SI 2 "gpc_reg_operand" "r")
1531 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1532 (mult:SI (ashiftrt:SI
1540 [(set_attr "type" "halfmul")])
1542 (define_insn "*mulhhw"
1543 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1544 (mult:SI (ashiftrt:SI
1545 (match_operand:SI 1 "gpc_reg_operand" "%r")
1548 (match_operand:SI 2 "gpc_reg_operand" "r")
1552 [(set_attr "type" "halfmul")])
1554 (define_insn "*mulhhwuc"
1555 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1556 (compare:CC (mult:SI (lshiftrt:SI
1557 (match_operand:SI 1 "gpc_reg_operand" "%r")
1560 (match_operand:SI 2 "gpc_reg_operand" "r")
1563 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1564 (mult:SI (lshiftrt:SI
1572 [(set_attr "type" "halfmul")])
1574 (define_insn "*mulhhwu"
1575 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1576 (mult:SI (lshiftrt:SI
1577 (match_operand:SI 1 "gpc_reg_operand" "%r")
1580 (match_operand:SI 2 "gpc_reg_operand" "r")
1584 [(set_attr "type" "halfmul")])
1586 (define_insn "*mullhwc"
1587 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1588 (compare:CC (mult:SI (sign_extend:SI
1589 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1591 (match_operand:HI 2 "gpc_reg_operand" "r")))
1593 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1594 (mult:SI (sign_extend:SI
1600 [(set_attr "type" "halfmul")])
1602 (define_insn "*mullhw"
1603 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1604 (mult:SI (sign_extend:SI
1605 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1607 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1610 [(set_attr "type" "halfmul")])
1612 (define_insn "*mullhwuc"
1613 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1614 (compare:CC (mult:SI (zero_extend:SI
1615 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1617 (match_operand:HI 2 "gpc_reg_operand" "r")))
1619 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1620 (mult:SI (zero_extend:SI
1626 [(set_attr "type" "halfmul")])
1628 (define_insn "*mullhwu"
1629 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1630 (mult:SI (zero_extend:SI
1631 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1633 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1636 [(set_attr "type" "halfmul")])
1638 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1639 (define_insn "dlmzb"
1640 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1641 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1642 (match_operand:SI 2 "gpc_reg_operand" "r")]
1644 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1645 (unspec:SI [(match_dup 1)
1651 (define_expand "strlensi"
1652 [(set (match_operand:SI 0 "gpc_reg_operand")
1653 (unspec:SI [(match_operand:BLK 1 "general_operand")
1654 (match_operand:QI 2 "const_int_operand")
1655 (match_operand 3 "const_int_operand")]
1656 UNSPEC_DLMZB_STRLEN))
1657 (clobber (match_scratch:CC 4))]
1658 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1660 rtx result = operands[0];
1661 rtx src = operands[1];
1662 rtx search_char = operands[2];
1663 rtx align = operands[3];
1664 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1665 rtx loop_label, end_label, mem, cr0, cond;
1666 if (search_char != const0_rtx
1667 || !CONST_INT_P (align)
1668 || INTVAL (align) < 8)
1670 word1 = gen_reg_rtx (SImode);
1671 word2 = gen_reg_rtx (SImode);
1672 scratch_dlmzb = gen_reg_rtx (SImode);
1673 scratch_string = gen_reg_rtx (Pmode);
1674 loop_label = gen_label_rtx ();
1675 end_label = gen_label_rtx ();
1676 addr = force_reg (Pmode, XEXP (src, 0));
1677 emit_move_insn (scratch_string, addr);
1678 emit_label (loop_label);
1679 mem = change_address (src, SImode, scratch_string);
1680 emit_move_insn (word1, mem);
1681 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1682 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1683 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1684 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1685 emit_jump_insn (gen_rtx_SET (pc_rtx,
1686 gen_rtx_IF_THEN_ELSE (VOIDmode,
1692 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1693 emit_jump_insn (gen_rtx_SET (pc_rtx,
1694 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1696 emit_label (end_label);
1697 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1698 emit_insn (gen_subsi3 (result, scratch_string, addr));
1699 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1703 ;; Fixed-point arithmetic insns.
1705 (define_expand "add<mode>3"
1706 [(set (match_operand:SDI 0 "gpc_reg_operand")
1707 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1708 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1711 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1713 rtx lo0 = gen_lowpart (SImode, operands[0]);
1714 rtx lo1 = gen_lowpart (SImode, operands[1]);
1715 rtx lo2 = gen_lowpart (SImode, operands[2]);
1716 rtx hi0 = gen_highpart (SImode, operands[0]);
1717 rtx hi1 = gen_highpart (SImode, operands[1]);
1718 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1720 if (!reg_or_short_operand (lo2, SImode))
1721 lo2 = force_reg (SImode, lo2);
1722 if (!adde_operand (hi2, SImode))
1723 hi2 = force_reg (SImode, hi2);
1725 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1726 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1730 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1732 rtx tmp = ((!can_create_pseudo_p ()
1733 || rtx_equal_p (operands[0], operands[1]))
1734 ? operands[0] : gen_reg_rtx (<MODE>mode));
1736 /* Adding a constant to r0 is not a valid insn, so use a different
1737 strategy in that case. */
1738 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1740 if (operands[0] == operands[1])
1742 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1743 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1747 HOST_WIDE_INT val = INTVAL (operands[2]);
1748 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1749 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1751 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1754 /* The ordering here is important for the prolog expander.
1755 When space is allocated from the stack, adding 'low' first may
1756 produce a temporary deallocation (which would be bad). */
1757 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1758 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1763 (define_insn "*add<mode>3"
1764 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1765 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1766 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1772 [(set_attr "type" "add")])
1774 (define_insn "*addsi3_high"
1775 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1776 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1777 (high:SI (match_operand 2 "" ""))))]
1778 "TARGET_MACHO && !TARGET_64BIT"
1779 "addis %0,%1,ha16(%2)"
1780 [(set_attr "type" "add")])
1782 (define_insn_and_split "*add<mode>3_dot"
1783 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1784 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1785 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1787 (clobber (match_scratch:GPR 0 "=r,r"))]
1788 "<MODE>mode == Pmode"
1792 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1794 (plus:GPR (match_dup 1)
1797 (compare:CC (match_dup 0)
1800 [(set_attr "type" "add")
1801 (set_attr "dot" "yes")
1802 (set_attr "length" "4,8")])
1804 (define_insn_and_split "*add<mode>3_dot2"
1805 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1806 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1807 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1809 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1810 (plus:GPR (match_dup 1)
1812 "<MODE>mode == Pmode"
1816 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1818 (plus:GPR (match_dup 1)
1821 (compare:CC (match_dup 0)
1824 [(set_attr "type" "add")
1825 (set_attr "dot" "yes")
1826 (set_attr "length" "4,8")])
1828 (define_insn_and_split "*add<mode>3_imm_dot"
1829 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1830 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1831 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1833 (clobber (match_scratch:GPR 0 "=r,r"))
1834 (clobber (reg:GPR CA_REGNO))]
1835 "<MODE>mode == Pmode"
1839 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1841 (plus:GPR (match_dup 1)
1844 (compare:CC (match_dup 0)
1847 [(set_attr "type" "add")
1848 (set_attr "dot" "yes")
1849 (set_attr "length" "4,8")])
1851 (define_insn_and_split "*add<mode>3_imm_dot2"
1852 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1853 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1854 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1856 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1857 (plus:GPR (match_dup 1)
1859 (clobber (reg:GPR CA_REGNO))]
1860 "<MODE>mode == Pmode"
1864 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1866 (plus:GPR (match_dup 1)
1869 (compare:CC (match_dup 0)
1872 [(set_attr "type" "add")
1873 (set_attr "dot" "yes")
1874 (set_attr "length" "4,8")])
1876 ;; Split an add that we can't do in one insn into two insns, each of which
1877 ;; does one 16-bit part. This is used by combine. Note that the low-order
1878 ;; add should be last in case the result gets used in an address.
1881 [(set (match_operand:GPR 0 "gpc_reg_operand")
1882 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1883 (match_operand:GPR 2 "non_add_cint_operand")))]
1885 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1886 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1888 HOST_WIDE_INT val = INTVAL (operands[2]);
1889 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1890 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1892 operands[4] = GEN_INT (low);
1893 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1894 operands[3] = GEN_INT (rest);
1895 else if (can_create_pseudo_p ())
1897 operands[3] = gen_reg_rtx (DImode);
1898 emit_move_insn (operands[3], operands[2]);
1899 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1907 (define_insn "add<mode>3_carry"
1908 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1909 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1910 (match_operand:P 2 "reg_or_short_operand" "rI")))
1911 (set (reg:P CA_REGNO)
1912 (ltu:P (plus:P (match_dup 1)
1917 [(set_attr "type" "add")])
1919 (define_insn "*add<mode>3_imm_carry_pos"
1920 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1921 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1922 (match_operand:P 2 "short_cint_operand" "n")))
1923 (set (reg:P CA_REGNO)
1924 (geu:P (match_dup 1)
1925 (match_operand:P 3 "const_int_operand" "n")))]
1926 "INTVAL (operands[2]) > 0
1927 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1929 [(set_attr "type" "add")])
1931 (define_insn "*add<mode>3_imm_carry_0"
1932 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1933 (match_operand:P 1 "gpc_reg_operand" "r"))
1934 (set (reg:P CA_REGNO)
1938 [(set_attr "type" "add")])
1940 (define_insn "*add<mode>3_imm_carry_m1"
1941 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1942 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1944 (set (reg:P CA_REGNO)
1949 [(set_attr "type" "add")])
1951 (define_insn "*add<mode>3_imm_carry_neg"
1952 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1953 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1954 (match_operand:P 2 "short_cint_operand" "n")))
1955 (set (reg:P CA_REGNO)
1956 (gtu:P (match_dup 1)
1957 (match_operand:P 3 "const_int_operand" "n")))]
1958 "INTVAL (operands[2]) < 0
1959 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1961 [(set_attr "type" "add")])
1964 (define_expand "add<mode>3_carry_in"
1966 (set (match_operand:GPR 0 "gpc_reg_operand")
1967 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1968 (match_operand:GPR 2 "adde_operand"))
1969 (reg:GPR CA_REGNO)))
1970 (clobber (reg:GPR CA_REGNO))])]
1973 if (operands[2] == const0_rtx)
1975 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1978 if (operands[2] == constm1_rtx)
1980 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1985 (define_insn "*add<mode>3_carry_in_internal"
1986 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1987 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1988 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1989 (reg:GPR CA_REGNO)))
1990 (clobber (reg:GPR CA_REGNO))]
1993 [(set_attr "type" "add")])
1995 (define_insn "*add<mode>3_carry_in_internal2"
1996 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1997 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1999 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2000 (clobber (reg:GPR CA_REGNO))]
2003 [(set_attr "type" "add")])
2005 (define_insn "add<mode>3_carry_in_0"
2006 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2007 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2008 (reg:GPR CA_REGNO)))
2009 (clobber (reg:GPR CA_REGNO))]
2012 [(set_attr "type" "add")])
2014 (define_insn "add<mode>3_carry_in_m1"
2015 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2016 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2019 (clobber (reg:GPR CA_REGNO))]
2022 [(set_attr "type" "add")])
2025 (define_expand "one_cmpl<mode>2"
2026 [(set (match_operand:SDI 0 "gpc_reg_operand")
2027 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2030 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2032 rs6000_split_logical (operands, NOT, false, false, false);
2037 (define_insn "*one_cmpl<mode>2"
2038 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2039 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2043 (define_insn_and_split "*one_cmpl<mode>2_dot"
2044 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2045 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2047 (clobber (match_scratch:GPR 0 "=r,r"))]
2048 "<MODE>mode == Pmode"
2052 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2054 (not:GPR (match_dup 1)))
2056 (compare:CC (match_dup 0)
2059 [(set_attr "type" "logical")
2060 (set_attr "dot" "yes")
2061 (set_attr "length" "4,8")])
2063 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2064 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2065 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2067 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2068 (not:GPR (match_dup 1)))]
2069 "<MODE>mode == Pmode"
2073 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2075 (not:GPR (match_dup 1)))
2077 (compare:CC (match_dup 0)
2080 [(set_attr "type" "logical")
2081 (set_attr "dot" "yes")
2082 (set_attr "length" "4,8")])
2085 (define_expand "sub<mode>3"
2086 [(set (match_operand:SDI 0 "gpc_reg_operand")
2087 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2088 (match_operand:SDI 2 "gpc_reg_operand")))]
2091 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2093 rtx lo0 = gen_lowpart (SImode, operands[0]);
2094 rtx lo1 = gen_lowpart (SImode, operands[1]);
2095 rtx lo2 = gen_lowpart (SImode, operands[2]);
2096 rtx hi0 = gen_highpart (SImode, operands[0]);
2097 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2098 rtx hi2 = gen_highpart (SImode, operands[2]);
2100 if (!reg_or_short_operand (lo1, SImode))
2101 lo1 = force_reg (SImode, lo1);
2102 if (!adde_operand (hi1, SImode))
2103 hi1 = force_reg (SImode, hi1);
2105 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2106 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2110 if (short_cint_operand (operands[1], <MODE>mode))
2112 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2117 (define_insn "*subf<mode>3"
2118 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2119 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2120 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2123 [(set_attr "type" "add")])
2125 (define_insn_and_split "*subf<mode>3_dot"
2126 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2127 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2128 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2130 (clobber (match_scratch:GPR 0 "=r,r"))]
2131 "<MODE>mode == Pmode"
2135 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2137 (minus:GPR (match_dup 2)
2140 (compare:CC (match_dup 0)
2143 [(set_attr "type" "add")
2144 (set_attr "dot" "yes")
2145 (set_attr "length" "4,8")])
2147 (define_insn_and_split "*subf<mode>3_dot2"
2148 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2149 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2150 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2152 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2153 (minus:GPR (match_dup 2)
2155 "<MODE>mode == Pmode"
2159 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2161 (minus:GPR (match_dup 2)
2164 (compare:CC (match_dup 0)
2167 [(set_attr "type" "add")
2168 (set_attr "dot" "yes")
2169 (set_attr "length" "4,8")])
2171 (define_insn "subf<mode>3_imm"
2172 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2173 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2174 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2175 (clobber (reg:GPR CA_REGNO))]
2178 [(set_attr "type" "add")])
2180 (define_insn_and_split "subf<mode>3_carry_dot2"
2181 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2182 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2183 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2185 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2186 (minus:P (match_dup 2)
2188 (set (reg:P CA_REGNO)
2189 (leu:P (match_dup 1)
2191 "<MODE>mode == Pmode"
2195 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2196 [(parallel [(set (match_dup 0)
2197 (minus:P (match_dup 2)
2199 (set (reg:P CA_REGNO)
2200 (leu:P (match_dup 1)
2203 (compare:CC (match_dup 0)
2206 [(set_attr "type" "add")
2207 (set_attr "dot" "yes")
2208 (set_attr "length" "4,8")])
2210 (define_insn "subf<mode>3_carry"
2211 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2212 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2213 (match_operand:P 1 "gpc_reg_operand" "r")))
2214 (set (reg:P CA_REGNO)
2215 (leu:P (match_dup 1)
2219 [(set_attr "type" "add")])
2221 (define_insn "*subf<mode>3_imm_carry_0"
2222 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2223 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2224 (set (reg:P CA_REGNO)
2229 [(set_attr "type" "add")])
2231 (define_insn "*subf<mode>3_imm_carry_m1"
2232 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2233 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2234 (set (reg:P CA_REGNO)
2238 [(set_attr "type" "add")])
2241 (define_expand "subf<mode>3_carry_in"
2243 (set (match_operand:GPR 0 "gpc_reg_operand")
2244 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2246 (match_operand:GPR 2 "adde_operand")))
2247 (clobber (reg:GPR CA_REGNO))])]
2250 if (operands[2] == const0_rtx)
2252 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2255 if (operands[2] == constm1_rtx)
2257 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2262 (define_insn "*subf<mode>3_carry_in_internal"
2263 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2264 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2266 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2267 (clobber (reg:GPR CA_REGNO))]
2270 [(set_attr "type" "add")])
2272 (define_insn "subf<mode>3_carry_in_0"
2273 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2274 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2275 (reg:GPR CA_REGNO)))
2276 (clobber (reg:GPR CA_REGNO))]
2279 [(set_attr "type" "add")])
2281 (define_insn "subf<mode>3_carry_in_m1"
2282 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2283 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2284 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2286 (clobber (reg:GPR CA_REGNO))]
2289 [(set_attr "type" "add")])
2291 (define_insn "subf<mode>3_carry_in_xx"
2292 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2293 (plus:GPR (reg:GPR CA_REGNO)
2295 (clobber (reg:GPR CA_REGNO))]
2298 [(set_attr "type" "add")])
2301 (define_insn "@neg<mode>2"
2302 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2303 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2306 [(set_attr "type" "add")])
2308 (define_insn_and_split "*neg<mode>2_dot"
2309 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2310 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2312 (clobber (match_scratch:GPR 0 "=r,r"))]
2313 "<MODE>mode == Pmode"
2317 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2319 (neg:GPR (match_dup 1)))
2321 (compare:CC (match_dup 0)
2324 [(set_attr "type" "add")
2325 (set_attr "dot" "yes")
2326 (set_attr "length" "4,8")])
2328 (define_insn_and_split "*neg<mode>2_dot2"
2329 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2330 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2332 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2333 (neg:GPR (match_dup 1)))]
2334 "<MODE>mode == Pmode"
2338 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2340 (neg:GPR (match_dup 1)))
2342 (compare:CC (match_dup 0)
2345 [(set_attr "type" "add")
2346 (set_attr "dot" "yes")
2347 (set_attr "length" "4,8")])
2350 (define_insn "clz<mode>2"
2351 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2352 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2355 [(set_attr "type" "cntlz")])
2357 (define_expand "ctz<mode>2"
2358 [(set (match_operand:GPR 0 "gpc_reg_operand")
2359 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2364 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2368 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2369 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2370 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2374 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2375 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2376 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2377 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2381 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2382 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2383 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2384 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2390 (define_insn "ctz<mode>2_hw"
2391 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2392 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2395 [(set_attr "type" "cntlz")])
2397 (define_expand "ffs<mode>2"
2398 [(set (match_operand:GPR 0 "gpc_reg_operand")
2399 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2402 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2403 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2404 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2405 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2406 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2407 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2408 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2413 (define_expand "popcount<mode>2"
2414 [(set (match_operand:GPR 0 "gpc_reg_operand")
2415 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2416 "TARGET_POPCNTB || TARGET_POPCNTD"
2418 rs6000_emit_popcount (operands[0], operands[1]);
2422 (define_insn "popcntb<mode>2"
2423 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2424 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2428 [(set_attr "type" "popcnt")])
2430 (define_insn "popcntd<mode>2"
2431 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2432 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2435 [(set_attr "type" "popcnt")])
2438 (define_expand "parity<mode>2"
2439 [(set (match_operand:GPR 0 "gpc_reg_operand")
2440 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2443 rs6000_emit_parity (operands[0], operands[1]);
2447 (define_insn "parity<mode>2_cmpb"
2448 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2449 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2450 "TARGET_CMPB && TARGET_POPCNTB"
2452 [(set_attr "type" "popcnt")])
2454 (define_insn "cmpb<mode>3"
2455 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2456 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2457 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2460 [(set_attr "type" "cmp")])
2462 ;; Since the hardware zeros the upper part of the register, save generating the
2463 ;; AND immediate if we are converting to unsigned
2464 (define_insn "*bswap<mode>2_extenddi"
2465 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2467 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2470 [(set_attr "type" "load")])
2472 (define_insn "*bswaphi2_extendsi"
2473 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2475 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2478 [(set_attr "type" "load")])
2480 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2481 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2482 ;; load with byte swap, which can be slower than doing it in the registers. It
2483 ;; also prevents certain failures with the RELOAD register allocator.
2485 (define_expand "bswap<mode>2"
2486 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2487 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2490 rtx dest = operands[0];
2491 rtx src = operands[1];
2493 if (!REG_P (dest) && !REG_P (src))
2494 src = force_reg (<MODE>mode, src);
2498 src = rs6000_force_indexed_or_indirect_mem (src);
2499 emit_insn (gen_bswap<mode>2_load (dest, src));
2501 else if (MEM_P (dest))
2503 dest = rs6000_force_indexed_or_indirect_mem (dest);
2504 emit_insn (gen_bswap<mode>2_store (dest, src));
2507 emit_insn (gen_bswap<mode>2_reg (dest, src));
2511 (define_insn "bswap<mode>2_load"
2512 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2513 (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2516 [(set_attr "type" "load")])
2518 (define_insn "bswap<mode>2_store"
2519 [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2520 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2523 [(set_attr "type" "store")])
2525 (define_insn_and_split "bswaphi2_reg"
2526 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2528 (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2529 (clobber (match_scratch:SI 2 "=&r,X"))]
2534 "reload_completed && int_reg_operand (operands[0], HImode)"
2536 (and:SI (lshiftrt:SI (match_dup 4)
2540 (and:SI (ashift:SI (match_dup 4)
2542 (const_int 65280))) ;; 0xff00
2544 (ior:SI (match_dup 3)
2547 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2548 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2550 [(set_attr "length" "12,4")
2551 (set_attr "type" "*,vecperm")
2552 (set_attr "isa" "*,p9v")])
2554 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2555 ;; zero_extract insns do not change for -mlittle.
2556 (define_insn_and_split "bswapsi2_reg"
2557 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2559 (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2564 "reload_completed && int_reg_operand (operands[0], SImode)"
2565 [(set (match_dup 0) ; DABC
2566 (rotate:SI (match_dup 1)
2568 (set (match_dup 0) ; DCBC
2569 (ior:SI (and:SI (ashift:SI (match_dup 1)
2571 (const_int 16711680))
2572 (and:SI (match_dup 0)
2573 (const_int -16711681))))
2574 (set (match_dup 0) ; DCBA
2575 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2578 (and:SI (match_dup 0)
2579 (const_int -256))))]
2581 [(set_attr "length" "12,4")
2582 (set_attr "type" "*,vecperm")
2583 (set_attr "isa" "*,p9v")])
2585 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2586 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2589 (define_expand "bswapdi2"
2590 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2592 (match_operand:DI 1 "reg_or_mem_operand")))
2593 (clobber (match_scratch:DI 2))
2594 (clobber (match_scratch:DI 3))])]
2597 rtx dest = operands[0];
2598 rtx src = operands[1];
2600 if (!REG_P (dest) && !REG_P (src))
2601 operands[1] = src = force_reg (DImode, src);
2603 if (TARGET_POWERPC64 && TARGET_LDBRX)
2607 src = rs6000_force_indexed_or_indirect_mem (src);
2608 emit_insn (gen_bswapdi2_load (dest, src));
2610 else if (MEM_P (dest))
2612 dest = rs6000_force_indexed_or_indirect_mem (dest);
2613 emit_insn (gen_bswapdi2_store (dest, src));
2615 else if (TARGET_P9_VECTOR)
2616 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2618 emit_insn (gen_bswapdi2_reg (dest, src));
2622 if (!TARGET_POWERPC64)
2624 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2625 that uses 64-bit registers needs the same scratch registers as 64-bit
2627 emit_insn (gen_bswapdi2_32bit (dest, src));
2632 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2633 (define_insn "bswapdi2_load"
2634 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2635 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2636 "TARGET_POWERPC64 && TARGET_LDBRX"
2638 [(set_attr "type" "load")])
2640 (define_insn "bswapdi2_store"
2641 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2642 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2643 "TARGET_POWERPC64 && TARGET_LDBRX"
2645 [(set_attr "type" "store")])
2647 (define_insn "bswapdi2_xxbrd"
2648 [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2649 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2652 [(set_attr "type" "vecperm")
2653 (set_attr "isa" "p9v")])
2655 (define_insn "bswapdi2_reg"
2656 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2657 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2658 (clobber (match_scratch:DI 2 "=&r"))
2659 (clobber (match_scratch:DI 3 "=&r"))]
2660 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2662 [(set_attr "length" "36")])
2664 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2665 (define_insn "*bswapdi2_64bit"
2666 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2667 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2668 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2669 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2670 "TARGET_POWERPC64 && !TARGET_LDBRX
2671 && (REG_P (operands[0]) || REG_P (operands[1]))
2672 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2673 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2675 [(set_attr "length" "16,12,36")])
2678 [(set (match_operand:DI 0 "gpc_reg_operand")
2679 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2680 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2681 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2682 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2685 rtx dest = operands[0];
2686 rtx src = operands[1];
2687 rtx op2 = operands[2];
2688 rtx op3 = operands[3];
2689 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2690 BYTES_BIG_ENDIAN ? 4 : 0);
2691 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2692 BYTES_BIG_ENDIAN ? 4 : 0);
2698 addr1 = XEXP (src, 0);
2699 if (GET_CODE (addr1) == PLUS)
2701 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2702 if (TARGET_AVOID_XFORM)
2704 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2708 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2710 else if (TARGET_AVOID_XFORM)
2712 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2717 emit_move_insn (op2, GEN_INT (4));
2718 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2721 word1 = change_address (src, SImode, addr1);
2722 word2 = change_address (src, SImode, addr2);
2724 if (BYTES_BIG_ENDIAN)
2726 emit_insn (gen_bswapsi2 (op3_32, word2));
2727 emit_insn (gen_bswapsi2 (dest_32, word1));
2731 emit_insn (gen_bswapsi2 (op3_32, word1));
2732 emit_insn (gen_bswapsi2 (dest_32, word2));
2735 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2736 emit_insn (gen_iordi3 (dest, dest, op3));
2741 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2742 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2743 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2744 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2745 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2748 rtx dest = operands[0];
2749 rtx src = operands[1];
2750 rtx op2 = operands[2];
2751 rtx op3 = operands[3];
2752 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2753 BYTES_BIG_ENDIAN ? 4 : 0);
2754 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2755 BYTES_BIG_ENDIAN ? 4 : 0);
2761 addr1 = XEXP (dest, 0);
2762 if (GET_CODE (addr1) == PLUS)
2764 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2765 if (TARGET_AVOID_XFORM)
2767 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2771 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2773 else if (TARGET_AVOID_XFORM)
2775 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2780 emit_move_insn (op2, GEN_INT (4));
2781 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2784 word1 = change_address (dest, SImode, addr1);
2785 word2 = change_address (dest, SImode, addr2);
2787 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2789 if (BYTES_BIG_ENDIAN)
2791 emit_insn (gen_bswapsi2 (word1, src_si));
2792 emit_insn (gen_bswapsi2 (word2, op3_si));
2796 emit_insn (gen_bswapsi2 (word2, src_si));
2797 emit_insn (gen_bswapsi2 (word1, op3_si));
2803 [(set (match_operand:DI 0 "gpc_reg_operand")
2804 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2805 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2806 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2807 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2810 rtx dest = operands[0];
2811 rtx src = operands[1];
2812 rtx op2 = operands[2];
2813 rtx op3 = operands[3];
2814 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2815 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2816 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2817 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2818 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2820 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2821 emit_insn (gen_bswapsi2 (dest_si, src_si));
2822 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2823 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2824 emit_insn (gen_iordi3 (dest, dest, op3));
2828 (define_insn "bswapdi2_32bit"
2829 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2830 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2831 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2832 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2834 [(set_attr "length" "16,12,36")])
2837 [(set (match_operand:DI 0 "gpc_reg_operand")
2838 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2839 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2840 "!TARGET_POWERPC64 && reload_completed"
2843 rtx dest = operands[0];
2844 rtx src = operands[1];
2845 rtx op2 = operands[2];
2846 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2847 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2853 addr1 = XEXP (src, 0);
2854 if (GET_CODE (addr1) == PLUS)
2856 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2857 if (TARGET_AVOID_XFORM
2858 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2860 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2864 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2866 else if (TARGET_AVOID_XFORM
2867 || REGNO (addr1) == REGNO (dest2))
2869 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2874 emit_move_insn (op2, GEN_INT (4));
2875 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2878 word1 = change_address (src, SImode, addr1);
2879 word2 = change_address (src, SImode, addr2);
2881 emit_insn (gen_bswapsi2 (dest2, word1));
2882 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2883 thus allowing us to omit an early clobber on the output. */
2884 emit_insn (gen_bswapsi2 (dest1, word2));
2889 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2890 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2891 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2892 "!TARGET_POWERPC64 && reload_completed"
2895 rtx dest = operands[0];
2896 rtx src = operands[1];
2897 rtx op2 = operands[2];
2898 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2899 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2905 addr1 = XEXP (dest, 0);
2906 if (GET_CODE (addr1) == PLUS)
2908 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2909 if (TARGET_AVOID_XFORM)
2911 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2915 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2917 else if (TARGET_AVOID_XFORM)
2919 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2924 emit_move_insn (op2, GEN_INT (4));
2925 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2928 word1 = change_address (dest, SImode, addr1);
2929 word2 = change_address (dest, SImode, addr2);
2931 emit_insn (gen_bswapsi2 (word2, src1));
2932 emit_insn (gen_bswapsi2 (word1, src2));
2937 [(set (match_operand:DI 0 "gpc_reg_operand")
2938 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2939 (clobber (match_operand:SI 2 ""))]
2940 "!TARGET_POWERPC64 && reload_completed"
2943 rtx dest = operands[0];
2944 rtx src = operands[1];
2945 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2946 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2947 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2948 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2950 emit_insn (gen_bswapsi2 (dest1, src2));
2951 emit_insn (gen_bswapsi2 (dest2, src1));
2956 (define_insn "mul<mode>3"
2957 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2958 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2959 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2964 [(set_attr "type" "mul")
2966 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2968 (match_operand:GPR 2 "short_cint_operand")
2969 (const_string "16")]
2970 (const_string "<bits>")))])
2972 (define_insn_and_split "*mul<mode>3_dot"
2973 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2974 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2975 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2977 (clobber (match_scratch:GPR 0 "=r,r"))]
2978 "<MODE>mode == Pmode"
2982 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2984 (mult:GPR (match_dup 1)
2987 (compare:CC (match_dup 0)
2990 [(set_attr "type" "mul")
2991 (set_attr "size" "<bits>")
2992 (set_attr "dot" "yes")
2993 (set_attr "length" "4,8")])
2995 (define_insn_and_split "*mul<mode>3_dot2"
2996 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2997 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2998 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3000 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3001 (mult:GPR (match_dup 1)
3003 "<MODE>mode == Pmode"
3007 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3009 (mult:GPR (match_dup 1)
3012 (compare:CC (match_dup 0)
3015 [(set_attr "type" "mul")
3016 (set_attr "size" "<bits>")
3017 (set_attr "dot" "yes")
3018 (set_attr "length" "4,8")])
3021 (define_expand "<su>mul<mode>3_highpart"
3022 [(set (match_operand:GPR 0 "gpc_reg_operand")
3024 (mult:<DMODE> (any_extend:<DMODE>
3025 (match_operand:GPR 1 "gpc_reg_operand"))
3027 (match_operand:GPR 2 "gpc_reg_operand")))
3031 if (<MODE>mode == SImode && TARGET_POWERPC64)
3033 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3038 if (!WORDS_BIG_ENDIAN)
3040 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3046 (define_insn "*<su>mul<mode>3_highpart"
3047 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3049 (mult:<DMODE> (any_extend:<DMODE>
3050 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3052 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3054 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3055 "mulh<wd><u> %0,%1,%2"
3056 [(set_attr "type" "mul")
3057 (set_attr "size" "<bits>")])
3059 (define_insn "<su>mulsi3_highpart_le"
3060 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3062 (mult:DI (any_extend:DI
3063 (match_operand:SI 1 "gpc_reg_operand" "r"))
3065 (match_operand:SI 2 "gpc_reg_operand" "r")))
3067 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3069 [(set_attr "type" "mul")])
3071 (define_insn "<su>muldi3_highpart_le"
3072 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3074 (mult:TI (any_extend:TI
3075 (match_operand:DI 1 "gpc_reg_operand" "r"))
3077 (match_operand:DI 2 "gpc_reg_operand" "r")))
3079 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3081 [(set_attr "type" "mul")
3082 (set_attr "size" "64")])
3084 (define_insn "<su>mulsi3_highpart_64"
3085 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3088 (mult:DI (any_extend:DI
3089 (match_operand:SI 1 "gpc_reg_operand" "r"))
3091 (match_operand:SI 2 "gpc_reg_operand" "r")))
3095 [(set_attr "type" "mul")])
3097 (define_expand "<u>mul<mode><dmode>3"
3098 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3099 (mult:<DMODE> (any_extend:<DMODE>
3100 (match_operand:GPR 1 "gpc_reg_operand"))
3102 (match_operand:GPR 2 "gpc_reg_operand"))))]
3103 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3105 rtx l = gen_reg_rtx (<MODE>mode);
3106 rtx h = gen_reg_rtx (<MODE>mode);
3107 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3108 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3109 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3110 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3114 (define_insn "*maddld<mode>4"
3115 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3116 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3117 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3118 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3120 "maddld %0,%1,%2,%3"
3121 [(set_attr "type" "mul")])
3123 (define_insn "udiv<mode>3"
3124 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3125 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3126 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3129 [(set_attr "type" "div")
3130 (set_attr "size" "<bits>")])
3133 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3134 ;; modulus. If it isn't a power of two, force operands into register and do
3136 (define_expand "div<mode>3"
3137 [(set (match_operand:GPR 0 "gpc_reg_operand")
3138 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3139 (match_operand:GPR 2 "reg_or_cint_operand")))]
3142 if (CONST_INT_P (operands[2])
3143 && INTVAL (operands[2]) > 0
3144 && exact_log2 (INTVAL (operands[2])) >= 0)
3146 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3150 operands[2] = force_reg (<MODE>mode, operands[2]);
3153 (define_insn "*div<mode>3"
3154 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3155 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3156 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3159 [(set_attr "type" "div")
3160 (set_attr "size" "<bits>")])
3162 (define_insn "div<mode>3_sra"
3163 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3164 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3165 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3166 (clobber (reg:GPR CA_REGNO))]
3168 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3169 [(set_attr "type" "two")
3170 (set_attr "length" "8")])
3172 (define_insn_and_split "*div<mode>3_sra_dot"
3173 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3174 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3175 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3177 (clobber (match_scratch:GPR 0 "=r,r"))
3178 (clobber (reg:GPR CA_REGNO))]
3179 "<MODE>mode == Pmode"
3181 sra<wd>i %0,%1,%p2\;addze. %0,%0
3183 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3184 [(parallel [(set (match_dup 0)
3185 (div:GPR (match_dup 1)
3187 (clobber (reg:GPR CA_REGNO))])
3189 (compare:CC (match_dup 0)
3192 [(set_attr "type" "two")
3193 (set_attr "length" "8,12")
3194 (set_attr "cell_micro" "not")])
3196 (define_insn_and_split "*div<mode>3_sra_dot2"
3197 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3198 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3199 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3201 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3202 (div:GPR (match_dup 1)
3204 (clobber (reg:GPR CA_REGNO))]
3205 "<MODE>mode == Pmode"
3207 sra<wd>i %0,%1,%p2\;addze. %0,%0
3209 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3210 [(parallel [(set (match_dup 0)
3211 (div:GPR (match_dup 1)
3213 (clobber (reg:GPR CA_REGNO))])
3215 (compare:CC (match_dup 0)
3218 [(set_attr "type" "two")
3219 (set_attr "length" "8,12")
3220 (set_attr "cell_micro" "not")])
3222 (define_expand "mod<mode>3"
3223 [(set (match_operand:GPR 0 "gpc_reg_operand")
3224 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3225 (match_operand:GPR 2 "reg_or_cint_operand")))]
3232 if (!CONST_INT_P (operands[2])
3233 || INTVAL (operands[2]) <= 0
3234 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3239 operands[2] = force_reg (<MODE>mode, operands[2]);
3243 temp1 = gen_reg_rtx (<MODE>mode);
3244 temp2 = gen_reg_rtx (<MODE>mode);
3246 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3247 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3248 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3253 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3254 ;; mod, prefer putting the result of mod into a different register
3255 (define_insn "*mod<mode>3"
3256 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3257 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3258 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3261 [(set_attr "type" "div")
3262 (set_attr "size" "<bits>")])
3265 (define_insn "umod<mode>3"
3266 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3267 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3268 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3271 [(set_attr "type" "div")
3272 (set_attr "size" "<bits>")])
3274 ;; On machines with modulo support, do a combined div/mod the old fashioned
3275 ;; method, since the multiply/subtract is faster than doing the mod instruction
3279 [(set (match_operand:GPR 0 "gpc_reg_operand")
3280 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3281 (match_operand:GPR 2 "gpc_reg_operand")))
3282 (set (match_operand:GPR 3 "gpc_reg_operand")
3283 (mod:GPR (match_dup 1)
3286 && ! reg_mentioned_p (operands[0], operands[1])
3287 && ! reg_mentioned_p (operands[0], operands[2])
3288 && ! reg_mentioned_p (operands[3], operands[1])
3289 && ! reg_mentioned_p (operands[3], operands[2])"
3291 (div:GPR (match_dup 1)
3294 (mult:GPR (match_dup 0)
3297 (minus:GPR (match_dup 1)
3301 [(set (match_operand:GPR 0 "gpc_reg_operand")
3302 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3303 (match_operand:GPR 2 "gpc_reg_operand")))
3304 (set (match_operand:GPR 3 "gpc_reg_operand")
3305 (umod:GPR (match_dup 1)
3308 && ! reg_mentioned_p (operands[0], operands[1])
3309 && ! reg_mentioned_p (operands[0], operands[2])
3310 && ! reg_mentioned_p (operands[3], operands[1])
3311 && ! reg_mentioned_p (operands[3], operands[2])"
3313 (udiv:GPR (match_dup 1)
3316 (mult:GPR (match_dup 0)
3319 (minus:GPR (match_dup 1)
3323 ;; Logical instructions
3324 ;; The logical instructions are mostly combined by using match_operator,
3325 ;; but the plain AND insns are somewhat different because there is no
3326 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3327 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3329 (define_expand "and<mode>3"
3330 [(set (match_operand:SDI 0 "gpc_reg_operand")
3331 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3332 (match_operand:SDI 2 "reg_or_cint_operand")))]
3335 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3337 rs6000_split_logical (operands, AND, false, false, false);
3341 if (CONST_INT_P (operands[2]))
3343 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3345 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3349 if (logical_const_operand (operands[2], <MODE>mode))
3351 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3355 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3357 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3361 operands[2] = force_reg (<MODE>mode, operands[2]);
3366 (define_insn "and<mode>3_imm"
3367 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3368 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3369 (match_operand:GPR 2 "logical_const_operand" "n")))
3370 (clobber (match_scratch:CC 3 "=x"))]
3371 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3372 "andi%e2. %0,%1,%u2"
3373 [(set_attr "type" "logical")
3374 (set_attr "dot" "yes")])
3376 (define_insn_and_split "*and<mode>3_imm_dot"
3377 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3378 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3379 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3381 (clobber (match_scratch:GPR 0 "=r,r"))
3382 (clobber (match_scratch:CC 4 "=X,x"))]
3383 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3384 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3388 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3389 [(parallel [(set (match_dup 0)
3390 (and:GPR (match_dup 1)
3392 (clobber (match_dup 4))])
3394 (compare:CC (match_dup 0)
3397 [(set_attr "type" "logical")
3398 (set_attr "dot" "yes")
3399 (set_attr "length" "4,8")])
3401 (define_insn_and_split "*and<mode>3_imm_dot2"
3402 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3403 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3404 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3406 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3407 (and:GPR (match_dup 1)
3409 (clobber (match_scratch:CC 4 "=X,x"))]
3410 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3411 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3415 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3416 [(parallel [(set (match_dup 0)
3417 (and:GPR (match_dup 1)
3419 (clobber (match_dup 4))])
3421 (compare:CC (match_dup 0)
3424 [(set_attr "type" "logical")
3425 (set_attr "dot" "yes")
3426 (set_attr "length" "4,8")])
3428 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3429 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3430 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3431 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3433 (clobber (match_scratch:GPR 0 "=r,r"))]
3434 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3435 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3439 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3441 (and:GPR (match_dup 1)
3444 (compare:CC (match_dup 0)
3447 [(set_attr "type" "logical")
3448 (set_attr "dot" "yes")
3449 (set_attr "length" "4,8")])
3451 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3452 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3453 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3454 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3456 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3457 (and:GPR (match_dup 1)
3459 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3460 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3464 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3466 (and:GPR (match_dup 1)
3469 (compare:CC (match_dup 0)
3472 [(set_attr "type" "logical")
3473 (set_attr "dot" "yes")
3474 (set_attr "length" "4,8")])
3476 (define_insn "*and<mode>3_imm_dot_shifted"
3477 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3480 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3481 (match_operand:SI 4 "const_int_operand" "n"))
3482 (match_operand:GPR 2 "const_int_operand" "n"))
3484 (clobber (match_scratch:GPR 0 "=r"))]
3485 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3486 << INTVAL (operands[4])),
3488 && (<MODE>mode == Pmode
3489 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3491 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3492 return "andi%e2. %0,%1,%u2";
3494 [(set_attr "type" "logical")
3495 (set_attr "dot" "yes")])
3498 (define_insn "and<mode>3_mask"
3499 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3500 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3501 (match_operand:GPR 2 "const_int_operand" "n")))]
3502 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3504 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3506 [(set_attr "type" "shift")])
3508 (define_insn_and_split "*and<mode>3_mask_dot"
3509 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3510 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3511 (match_operand:GPR 2 "const_int_operand" "n,n"))
3513 (clobber (match_scratch:GPR 0 "=r,r"))]
3514 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3515 && !logical_const_operand (operands[2], <MODE>mode)
3516 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3518 if (which_alternative == 0)
3519 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3523 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3525 (and:GPR (match_dup 1)
3528 (compare:CC (match_dup 0)
3531 [(set_attr "type" "shift")
3532 (set_attr "dot" "yes")
3533 (set_attr "length" "4,8")])
3535 (define_insn_and_split "*and<mode>3_mask_dot2"
3536 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3537 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3538 (match_operand:GPR 2 "const_int_operand" "n,n"))
3540 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3541 (and:GPR (match_dup 1)
3543 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3544 && !logical_const_operand (operands[2], <MODE>mode)
3545 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3547 if (which_alternative == 0)
3548 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3552 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3554 (and:GPR (match_dup 1)
3557 (compare:CC (match_dup 0)
3560 [(set_attr "type" "shift")
3561 (set_attr "dot" "yes")
3562 (set_attr "length" "4,8")])
3565 (define_insn_and_split "*and<mode>3_2insn"
3566 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3567 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3568 (match_operand:GPR 2 "const_int_operand" "n")))]
3569 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3570 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3571 || logical_const_operand (operands[2], <MODE>mode))"
3576 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3579 [(set_attr "type" "shift")
3580 (set_attr "length" "8")])
3582 (define_insn_and_split "*and<mode>3_2insn_dot"
3583 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3584 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3585 (match_operand:GPR 2 "const_int_operand" "n,n"))
3587 (clobber (match_scratch:GPR 0 "=r,r"))]
3588 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3589 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3590 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3591 || logical_const_operand (operands[2], <MODE>mode))"
3593 "&& reload_completed"
3596 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3599 [(set_attr "type" "shift")
3600 (set_attr "dot" "yes")
3601 (set_attr "length" "8,12")])
3603 (define_insn_and_split "*and<mode>3_2insn_dot2"
3604 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3605 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3606 (match_operand:GPR 2 "const_int_operand" "n,n"))
3608 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3609 (and:GPR (match_dup 1)
3611 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3612 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3613 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3614 || logical_const_operand (operands[2], <MODE>mode))"
3616 "&& reload_completed"
3619 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3622 [(set_attr "type" "shift")
3623 (set_attr "dot" "yes")
3624 (set_attr "length" "8,12")])
3627 (define_expand "<code><mode>3"
3628 [(set (match_operand:SDI 0 "gpc_reg_operand")
3629 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3630 (match_operand:SDI 2 "reg_or_cint_operand")))]
3633 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3635 rs6000_split_logical (operands, <CODE>, false, false, false);
3639 if (non_logical_cint_operand (operands[2], <MODE>mode))
3641 rtx tmp = ((!can_create_pseudo_p ()
3642 || rtx_equal_p (operands[0], operands[1]))
3643 ? operands[0] : gen_reg_rtx (<MODE>mode));
3645 HOST_WIDE_INT value = INTVAL (operands[2]);
3646 HOST_WIDE_INT lo = value & 0xffff;
3647 HOST_WIDE_INT hi = value - lo;
3649 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3650 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3654 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3655 operands[2] = force_reg (<MODE>mode, operands[2]);
3659 [(set (match_operand:GPR 0 "gpc_reg_operand")
3660 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3661 (match_operand:GPR 2 "non_logical_cint_operand")))]
3664 (iorxor:GPR (match_dup 1)
3667 (iorxor:GPR (match_dup 3)
3670 operands[3] = ((!can_create_pseudo_p ()
3671 || rtx_equal_p (operands[0], operands[1]))
3672 ? operands[0] : gen_reg_rtx (<MODE>mode));
3674 HOST_WIDE_INT value = INTVAL (operands[2]);
3675 HOST_WIDE_INT lo = value & 0xffff;
3676 HOST_WIDE_INT hi = value - lo;
3678 operands[4] = GEN_INT (hi);
3679 operands[5] = GEN_INT (lo);
3682 (define_insn "*bool<mode>3_imm"
3683 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3684 (match_operator:GPR 3 "boolean_or_operator"
3685 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3686 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3689 [(set_attr "type" "logical")])
3691 (define_insn "*bool<mode>3"
3692 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3693 (match_operator:GPR 3 "boolean_operator"
3694 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3695 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3698 [(set_attr "type" "logical")])
3700 (define_insn_and_split "*bool<mode>3_dot"
3701 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3702 (compare:CC (match_operator:GPR 3 "boolean_operator"
3703 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3704 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3706 (clobber (match_scratch:GPR 0 "=r,r"))]
3707 "<MODE>mode == Pmode"
3711 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3715 (compare:CC (match_dup 0)
3718 [(set_attr "type" "logical")
3719 (set_attr "dot" "yes")
3720 (set_attr "length" "4,8")])
3722 (define_insn_and_split "*bool<mode>3_dot2"
3723 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3724 (compare:CC (match_operator:GPR 3 "boolean_operator"
3725 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3726 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3728 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3730 "<MODE>mode == Pmode"
3734 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3738 (compare:CC (match_dup 0)
3741 [(set_attr "type" "logical")
3742 (set_attr "dot" "yes")
3743 (set_attr "length" "4,8")])
3746 (define_insn "*boolc<mode>3"
3747 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3748 (match_operator:GPR 3 "boolean_operator"
3749 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3750 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3753 [(set_attr "type" "logical")])
3755 (define_insn_and_split "*boolc<mode>3_dot"
3756 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3757 (compare:CC (match_operator:GPR 3 "boolean_operator"
3758 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3759 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3761 (clobber (match_scratch:GPR 0 "=r,r"))]
3762 "<MODE>mode == Pmode"
3766 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3770 (compare:CC (match_dup 0)
3773 [(set_attr "type" "logical")
3774 (set_attr "dot" "yes")
3775 (set_attr "length" "4,8")])
3777 (define_insn_and_split "*boolc<mode>3_dot2"
3778 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3779 (compare:CC (match_operator:GPR 3 "boolean_operator"
3780 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3781 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3783 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3785 "<MODE>mode == Pmode"
3789 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3793 (compare:CC (match_dup 0)
3796 [(set_attr "type" "logical")
3797 (set_attr "dot" "yes")
3798 (set_attr "length" "4,8")])
3801 (define_insn "*boolcc<mode>3"
3802 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3803 (match_operator:GPR 3 "boolean_operator"
3804 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3805 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3808 [(set_attr "type" "logical")])
3810 (define_insn_and_split "*boolcc<mode>3_dot"
3811 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3812 (compare:CC (match_operator:GPR 3 "boolean_operator"
3813 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3814 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3816 (clobber (match_scratch:GPR 0 "=r,r"))]
3817 "<MODE>mode == Pmode"
3821 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3825 (compare:CC (match_dup 0)
3828 [(set_attr "type" "logical")
3829 (set_attr "dot" "yes")
3830 (set_attr "length" "4,8")])
3832 (define_insn_and_split "*boolcc<mode>3_dot2"
3833 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3834 (compare:CC (match_operator:GPR 3 "boolean_operator"
3835 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3836 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3838 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3840 "<MODE>mode == Pmode"
3844 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3848 (compare:CC (match_dup 0)
3851 [(set_attr "type" "logical")
3852 (set_attr "dot" "yes")
3853 (set_attr "length" "4,8")])
3856 ;; TODO: Should have dots of this as well.
3857 (define_insn "*eqv<mode>3"
3858 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3859 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3860 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3863 [(set_attr "type" "logical")])
3865 ;; Rotate-and-mask and insert.
3867 (define_insn "*rotl<mode>3_mask"
3868 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3869 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3870 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3871 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3872 (match_operand:GPR 3 "const_int_operand" "n")))]
3873 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3875 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3877 [(set_attr "type" "shift")
3878 (set_attr "maybe_var_shift" "yes")])
3880 (define_insn_and_split "*rotl<mode>3_mask_dot"
3881 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3883 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3884 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3885 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3886 (match_operand:GPR 3 "const_int_operand" "n,n"))
3888 (clobber (match_scratch:GPR 0 "=r,r"))]
3889 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3890 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3892 if (which_alternative == 0)
3893 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3897 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3899 (and:GPR (match_dup 4)
3902 (compare:CC (match_dup 0)
3905 [(set_attr "type" "shift")
3906 (set_attr "maybe_var_shift" "yes")
3907 (set_attr "dot" "yes")
3908 (set_attr "length" "4,8")])
3910 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3911 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3913 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3914 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3915 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3916 (match_operand:GPR 3 "const_int_operand" "n,n"))
3918 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3919 (and:GPR (match_dup 4)
3921 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3922 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3924 if (which_alternative == 0)
3925 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3929 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3931 (and:GPR (match_dup 4)
3934 (compare:CC (match_dup 0)
3937 [(set_attr "type" "shift")
3938 (set_attr "maybe_var_shift" "yes")
3939 (set_attr "dot" "yes")
3940 (set_attr "length" "4,8")])
3942 ; Special case for less-than-0. We can do it with just one machine
3943 ; instruction, but the generic optimizers do not realise it is cheap.
3944 (define_insn "*lt0_<mode>di"
3945 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3946 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3950 [(set_attr "type" "shift")])
3952 (define_insn "*lt0_<mode>si"
3953 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3954 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3957 "rlwinm %0,%1,1,31,31"
3958 [(set_attr "type" "shift")])
3962 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3963 ; both are an AND so are the same precedence).
3964 (define_insn "*rotl<mode>3_insert"
3965 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3966 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3967 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3968 (match_operand:SI 2 "const_int_operand" "n")])
3969 (match_operand:GPR 3 "const_int_operand" "n"))
3970 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3971 (match_operand:GPR 6 "const_int_operand" "n"))))]
3972 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3973 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3975 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3977 [(set_attr "type" "insert")])
3978 ; FIXME: this needs an attr "size", so that the scheduler can see the
3979 ; difference between rlwimi and rldimi. We also might want dot forms,
3980 ; but not for rlwimi on POWER4 and similar processors.
3982 (define_insn "*rotl<mode>3_insert_2"
3983 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3984 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3985 (match_operand:GPR 6 "const_int_operand" "n"))
3986 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3987 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3988 (match_operand:SI 2 "const_int_operand" "n")])
3989 (match_operand:GPR 3 "const_int_operand" "n"))))]
3990 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3991 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3993 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3995 [(set_attr "type" "insert")])
3997 ; There are also some forms without one of the ANDs.
3998 (define_insn "*rotl<mode>3_insert_3"
3999 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4000 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4001 (match_operand:GPR 4 "const_int_operand" "n"))
4002 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4003 (match_operand:SI 2 "const_int_operand" "n"))))]
4004 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4006 if (<MODE>mode == SImode)
4007 return "rlwimi %0,%1,%h2,0,31-%h2";
4009 return "rldimi %0,%1,%H2,0";
4011 [(set_attr "type" "insert")])
4013 (define_insn "*rotl<mode>3_insert_4"
4014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4015 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4016 (match_operand:GPR 4 "const_int_operand" "n"))
4017 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4018 (match_operand:SI 2 "const_int_operand" "n"))))]
4019 "<MODE>mode == SImode &&
4020 GET_MODE_PRECISION (<MODE>mode)
4021 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4023 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4024 - INTVAL (operands[2]));
4025 if (<MODE>mode == SImode)
4026 return "rlwimi %0,%1,%h2,32-%h2,31";
4028 return "rldimi %0,%1,%H2,64-%H2";
4030 [(set_attr "type" "insert")])
4032 (define_insn "*rotlsi3_insert_5"
4033 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4034 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4035 (match_operand:SI 2 "const_int_operand" "n,n"))
4036 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4037 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4038 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4039 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4040 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4044 [(set_attr "type" "insert")])
4046 (define_insn "*rotldi3_insert_6"
4047 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4048 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4049 (match_operand:DI 2 "const_int_operand" "n"))
4050 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4051 (match_operand:DI 4 "const_int_operand" "n"))))]
4052 "exact_log2 (-UINTVAL (operands[2])) > 0
4053 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4055 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4056 return "rldimi %0,%3,0,%5";
4058 [(set_attr "type" "insert")
4059 (set_attr "size" "64")])
4061 (define_insn "*rotldi3_insert_7"
4062 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4063 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4064 (match_operand:DI 4 "const_int_operand" "n"))
4065 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4066 (match_operand:DI 2 "const_int_operand" "n"))))]
4067 "exact_log2 (-UINTVAL (operands[2])) > 0
4068 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4070 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4071 return "rldimi %0,%3,0,%5";
4073 [(set_attr "type" "insert")
4074 (set_attr "size" "64")])
4077 ; This handles the important case of multiple-precision shifts. There is
4078 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4080 [(set (match_operand:GPR 0 "gpc_reg_operand")
4081 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4082 (match_operand:SI 3 "const_int_operand"))
4083 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4084 (match_operand:SI 4 "const_int_operand"))))]
4085 "can_create_pseudo_p ()
4086 && INTVAL (operands[3]) + INTVAL (operands[4])
4087 >= GET_MODE_PRECISION (<MODE>mode)"
4089 (lshiftrt:GPR (match_dup 2)
4092 (ior:GPR (and:GPR (match_dup 5)
4094 (ashift:GPR (match_dup 1)
4097 unsigned HOST_WIDE_INT mask = 1;
4098 mask = (mask << INTVAL (operands[3])) - 1;
4099 operands[5] = gen_reg_rtx (<MODE>mode);
4100 operands[6] = GEN_INT (mask);
4104 [(set (match_operand:GPR 0 "gpc_reg_operand")
4105 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4106 (match_operand:SI 4 "const_int_operand"))
4107 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4108 (match_operand:SI 3 "const_int_operand"))))]
4109 "can_create_pseudo_p ()
4110 && INTVAL (operands[3]) + INTVAL (operands[4])
4111 >= GET_MODE_PRECISION (<MODE>mode)"
4113 (lshiftrt:GPR (match_dup 2)
4116 (ior:GPR (and:GPR (match_dup 5)
4118 (ashift:GPR (match_dup 1)
4121 unsigned HOST_WIDE_INT mask = 1;
4122 mask = (mask << INTVAL (operands[3])) - 1;
4123 operands[5] = gen_reg_rtx (<MODE>mode);
4124 operands[6] = GEN_INT (mask);
4128 ; Another important case is setting some bits to 1; we can do that with
4129 ; an insert instruction, in many cases.
4130 (define_insn_and_split "*ior<mode>_mask"
4131 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4132 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4133 (match_operand:GPR 2 "const_int_operand" "n")))
4134 (clobber (match_scratch:GPR 3 "=r"))]
4135 "!logical_const_operand (operands[2], <MODE>mode)
4136 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4142 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4145 (and:GPR (match_dup 1)
4149 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4150 if (GET_CODE (operands[3]) == SCRATCH)
4151 operands[3] = gen_reg_rtx (<MODE>mode);
4152 operands[4] = GEN_INT (ne);
4153 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4155 [(set_attr "type" "two")
4156 (set_attr "length" "8")])
4159 ; Yet another case is an rldimi with the second value coming from memory.
4160 ; The zero_extend that should become part of the rldimi is merged into the
4161 ; load from memory instead. Split things properly again.
4163 [(set (match_operand:DI 0 "gpc_reg_operand")
4164 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4165 (match_operand:SI 2 "const_int_operand"))
4166 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4167 "INTVAL (operands[2]) == <bits>"
4169 (zero_extend:DI (match_dup 3)))
4171 (ior:DI (and:DI (match_dup 4)
4173 (ashift:DI (match_dup 1)
4176 operands[4] = gen_reg_rtx (DImode);
4177 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4182 [(set (match_operand:SI 0 "gpc_reg_operand")
4183 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4184 (match_operand:SI 2 "const_int_operand"))
4185 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4186 "INTVAL (operands[2]) == <bits>"
4188 (zero_extend:SI (match_dup 3)))
4190 (ior:SI (and:SI (match_dup 4)
4192 (ashift:SI (match_dup 1)
4195 operands[4] = gen_reg_rtx (SImode);
4196 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4200 ;; Now the simple shifts.
4202 (define_insn "rotl<mode>3"
4203 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4204 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4205 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4207 "rotl<wd>%I2 %0,%1,%<hH>2"
4208 [(set_attr "type" "shift")
4209 (set_attr "maybe_var_shift" "yes")])
4211 (define_insn "*rotlsi3_64"
4212 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4214 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4215 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4217 "rotlw%I2 %0,%1,%h2"
4218 [(set_attr "type" "shift")
4219 (set_attr "maybe_var_shift" "yes")])
4221 (define_insn_and_split "*rotl<mode>3_dot"
4222 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4223 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4224 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4226 (clobber (match_scratch:GPR 0 "=r,r"))]
4227 "<MODE>mode == Pmode"
4229 rotl<wd>%I2. %0,%1,%<hH>2
4231 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4233 (rotate:GPR (match_dup 1)
4236 (compare:CC (match_dup 0)
4239 [(set_attr "type" "shift")
4240 (set_attr "maybe_var_shift" "yes")
4241 (set_attr "dot" "yes")
4242 (set_attr "length" "4,8")])
4244 (define_insn_and_split "*rotl<mode>3_dot2"
4245 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4246 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4247 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4249 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4250 (rotate:GPR (match_dup 1)
4252 "<MODE>mode == Pmode"
4254 rotl<wd>%I2. %0,%1,%<hH>2
4256 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4258 (rotate:GPR (match_dup 1)
4261 (compare:CC (match_dup 0)
4264 [(set_attr "type" "shift")
4265 (set_attr "maybe_var_shift" "yes")
4266 (set_attr "dot" "yes")
4267 (set_attr "length" "4,8")])
4270 (define_insn "ashl<mode>3"
4271 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4272 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4273 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4275 "sl<wd>%I2 %0,%1,%<hH>2"
4276 [(set_attr "type" "shift")
4277 (set_attr "maybe_var_shift" "yes")])
4279 (define_insn "*ashlsi3_64"
4280 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4282 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4283 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4286 [(set_attr "type" "shift")
4287 (set_attr "maybe_var_shift" "yes")])
4289 (define_insn_and_split "*ashl<mode>3_dot"
4290 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4291 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4292 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4294 (clobber (match_scratch:GPR 0 "=r,r"))]
4295 "<MODE>mode == Pmode"
4297 sl<wd>%I2. %0,%1,%<hH>2
4299 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4301 (ashift:GPR (match_dup 1)
4304 (compare:CC (match_dup 0)
4307 [(set_attr "type" "shift")
4308 (set_attr "maybe_var_shift" "yes")
4309 (set_attr "dot" "yes")
4310 (set_attr "length" "4,8")])
4312 (define_insn_and_split "*ashl<mode>3_dot2"
4313 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4314 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4315 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4317 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4318 (ashift:GPR (match_dup 1)
4320 "<MODE>mode == Pmode"
4322 sl<wd>%I2. %0,%1,%<hH>2
4324 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4326 (ashift: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 ;; Pretend we have a memory form of extswsli until register allocation is done
4338 ;; so that we use LWZ to load the value from memory, instead of LWA.
4339 (define_insn_and_split "ashdi3_extswsli"
4340 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4342 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4343 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4348 "&& reload_completed && MEM_P (operands[1])"
4352 (ashift:DI (sign_extend:DI (match_dup 3))
4355 operands[3] = gen_lowpart (SImode, operands[0]);
4357 [(set_attr "type" "shift")
4358 (set_attr "maybe_var_shift" "no")])
4361 (define_insn_and_split "ashdi3_extswsli_dot"
4362 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4365 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4366 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4368 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4375 "&& reload_completed
4376 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4377 || memory_operand (operands[1], SImode))"
4380 rtx dest = operands[0];
4381 rtx src = operands[1];
4382 rtx shift = operands[2];
4383 rtx cr = operands[3];
4390 src2 = gen_lowpart (SImode, dest);
4391 emit_move_insn (src2, src);
4394 if (REGNO (cr) == CR0_REGNO)
4396 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4400 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4401 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4404 [(set_attr "type" "shift")
4405 (set_attr "maybe_var_shift" "no")
4406 (set_attr "dot" "yes")
4407 (set_attr "length" "4,8,8,12")])
4409 (define_insn_and_split "ashdi3_extswsli_dot2"
4410 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4413 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4414 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4416 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4417 (ashift:DI (sign_extend:DI (match_dup 1))
4425 "&& reload_completed
4426 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4427 || memory_operand (operands[1], SImode))"
4430 rtx dest = operands[0];
4431 rtx src = operands[1];
4432 rtx shift = operands[2];
4433 rtx cr = operands[3];
4440 src2 = gen_lowpart (SImode, dest);
4441 emit_move_insn (src2, src);
4444 if (REGNO (cr) == CR0_REGNO)
4446 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4450 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4451 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4454 [(set_attr "type" "shift")
4455 (set_attr "maybe_var_shift" "no")
4456 (set_attr "dot" "yes")
4457 (set_attr "length" "4,8,8,12")])
4459 (define_insn "lshr<mode>3"
4460 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4461 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4462 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4464 "sr<wd>%I2 %0,%1,%<hH>2"
4465 [(set_attr "type" "shift")
4466 (set_attr "maybe_var_shift" "yes")])
4468 (define_insn "*lshrsi3_64"
4469 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4471 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4472 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4475 [(set_attr "type" "shift")
4476 (set_attr "maybe_var_shift" "yes")])
4478 (define_insn_and_split "*lshr<mode>3_dot"
4479 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4480 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4481 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4483 (clobber (match_scratch:GPR 0 "=r,r"))]
4484 "<MODE>mode == Pmode"
4486 sr<wd>%I2. %0,%1,%<hH>2
4488 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4490 (lshiftrt:GPR (match_dup 1)
4493 (compare:CC (match_dup 0)
4496 [(set_attr "type" "shift")
4497 (set_attr "maybe_var_shift" "yes")
4498 (set_attr "dot" "yes")
4499 (set_attr "length" "4,8")])
4501 (define_insn_and_split "*lshr<mode>3_dot2"
4502 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4503 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4504 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4506 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4507 (lshiftrt:GPR (match_dup 1)
4509 "<MODE>mode == Pmode"
4511 sr<wd>%I2. %0,%1,%<hH>2
4513 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4515 (lshiftrt:GPR (match_dup 1)
4518 (compare:CC (match_dup 0)
4521 [(set_attr "type" "shift")
4522 (set_attr "maybe_var_shift" "yes")
4523 (set_attr "dot" "yes")
4524 (set_attr "length" "4,8")])
4527 (define_insn "ashr<mode>3"
4528 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4529 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4530 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4531 (clobber (reg:GPR CA_REGNO))]
4533 "sra<wd>%I2 %0,%1,%<hH>2"
4534 [(set_attr "type" "shift")
4535 (set_attr "maybe_var_shift" "yes")])
4537 (define_insn "*ashrsi3_64"
4538 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4540 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4541 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4542 (clobber (reg:SI CA_REGNO))]
4545 [(set_attr "type" "shift")
4546 (set_attr "maybe_var_shift" "yes")])
4548 (define_insn_and_split "*ashr<mode>3_dot"
4549 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4550 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4551 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4553 (clobber (match_scratch:GPR 0 "=r,r"))
4554 (clobber (reg:GPR CA_REGNO))]
4555 "<MODE>mode == Pmode"
4557 sra<wd>%I2. %0,%1,%<hH>2
4559 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4560 [(parallel [(set (match_dup 0)
4561 (ashiftrt:GPR (match_dup 1)
4563 (clobber (reg:GPR CA_REGNO))])
4565 (compare:CC (match_dup 0)
4568 [(set_attr "type" "shift")
4569 (set_attr "maybe_var_shift" "yes")
4570 (set_attr "dot" "yes")
4571 (set_attr "length" "4,8")])
4573 (define_insn_and_split "*ashr<mode>3_dot2"
4574 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4575 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4576 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4578 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4579 (ashiftrt:GPR (match_dup 1)
4581 (clobber (reg:GPR CA_REGNO))]
4582 "<MODE>mode == Pmode"
4584 sra<wd>%I2. %0,%1,%<hH>2
4586 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4587 [(parallel [(set (match_dup 0)
4588 (ashiftrt:GPR (match_dup 1)
4590 (clobber (reg:GPR CA_REGNO))])
4592 (compare:CC (match_dup 0)
4595 [(set_attr "type" "shift")
4596 (set_attr "maybe_var_shift" "yes")
4597 (set_attr "dot" "yes")
4598 (set_attr "length" "4,8")])
4600 ;; Builtins to replace a division to generate FRE reciprocal estimate
4601 ;; instructions and the necessary fixup instructions
4602 (define_expand "recip<mode>3"
4603 [(match_operand:RECIPF 0 "gpc_reg_operand")
4604 (match_operand:RECIPF 1 "gpc_reg_operand")
4605 (match_operand:RECIPF 2 "gpc_reg_operand")]
4606 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4608 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4612 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4613 ;; hardware division. This is only done before register allocation and with
4614 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4615 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4616 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4618 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4619 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4620 (match_operand 2 "gpc_reg_operand")))]
4621 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4622 && can_create_pseudo_p () && flag_finite_math_only
4623 && !flag_trapping_math && flag_reciprocal_math"
4626 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4630 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4631 ;; appropriate fixup.
4632 (define_expand "rsqrt<mode>2"
4633 [(match_operand:RECIPF 0 "gpc_reg_operand")
4634 (match_operand:RECIPF 1 "gpc_reg_operand")]
4635 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4637 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4641 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4642 ;; modes here, and also add in conditional vsx/power8-vector support to access
4643 ;; values in the traditional Altivec registers if the appropriate
4644 ;; -mupper-regs-{df,sf} option is enabled.
4646 (define_expand "abs<mode>2"
4647 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4648 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4652 (define_insn "*abs<mode>2_fpr"
4653 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4654 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4659 [(set_attr "type" "fpsimple")])
4661 (define_insn "*nabs<mode>2_fpr"
4662 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4665 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4670 [(set_attr "type" "fpsimple")])
4672 (define_expand "neg<mode>2"
4673 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4674 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4678 (define_insn "*neg<mode>2_fpr"
4679 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4680 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4685 [(set_attr "type" "fpsimple")])
4687 (define_expand "add<mode>3"
4688 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4689 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4690 (match_operand:SFDF 2 "gpc_reg_operand")))]
4694 (define_insn "*add<mode>3_fpr"
4695 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4696 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4697 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4701 xsadd<sd>p %x0,%x1,%x2"
4702 [(set_attr "type" "fp")
4703 (set_attr "isa" "*,<Fisa>")])
4705 (define_expand "sub<mode>3"
4706 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4707 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4708 (match_operand:SFDF 2 "gpc_reg_operand")))]
4712 (define_insn "*sub<mode>3_fpr"
4713 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4714 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4715 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4719 xssub<sd>p %x0,%x1,%x2"
4720 [(set_attr "type" "fp")
4721 (set_attr "isa" "*,<Fisa>")])
4723 (define_expand "mul<mode>3"
4724 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4725 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4726 (match_operand:SFDF 2 "gpc_reg_operand")))]
4730 (define_insn "*mul<mode>3_fpr"
4731 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4732 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4733 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4737 xsmul<sd>p %x0,%x1,%x2"
4738 [(set_attr "type" "dmul")
4739 (set_attr "isa" "*,<Fisa>")])
4741 (define_expand "div<mode>3"
4742 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4743 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4744 (match_operand:SFDF 2 "gpc_reg_operand")))]
4747 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4748 && can_create_pseudo_p () && flag_finite_math_only
4749 && !flag_trapping_math && flag_reciprocal_math)
4751 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4756 (define_insn "*div<mode>3_fpr"
4757 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4758 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4759 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4763 xsdiv<sd>p %x0,%x1,%x2"
4764 [(set_attr "type" "<sd>div")
4765 (set_attr "isa" "*,<Fisa>")])
4767 (define_insn "*sqrt<mode>2_internal"
4768 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4769 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4770 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4773 xssqrt<sd>p %x0,%x1"
4774 [(set_attr "type" "<sd>sqrt")
4775 (set_attr "isa" "*,<Fisa>")])
4777 (define_expand "sqrt<mode>2"
4778 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4779 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4780 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4782 if (<MODE>mode == SFmode
4783 && TARGET_RECIP_PRECISION
4784 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4785 && !optimize_function_for_size_p (cfun)
4786 && flag_finite_math_only && !flag_trapping_math
4787 && flag_unsafe_math_optimizations)
4789 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4794 ;; Floating point reciprocal approximation
4795 (define_insn "fre<sd>"
4796 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4797 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4803 [(set_attr "type" "fp")
4804 (set_attr "isa" "*,<Fisa>")])
4806 (define_insn "*rsqrt<mode>2"
4807 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4808 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4810 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4813 xsrsqrte<sd>p %x0,%x1"
4814 [(set_attr "type" "fp")
4815 (set_attr "isa" "*,<Fisa>")])
4817 ;; Floating point comparisons
4818 (define_insn "*cmp<mode>_fpr"
4819 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4820 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4821 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4825 xscmpudp %0,%x1,%x2"
4826 [(set_attr "type" "fpcompare")
4827 (set_attr "isa" "*,<Fisa>")])
4829 ;; Floating point conversions
4830 (define_expand "extendsfdf2"
4831 [(set (match_operand:DF 0 "gpc_reg_operand")
4832 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4835 if (HONOR_SNANS (SFmode))
4836 operands[1] = force_reg (SFmode, operands[1]);
4839 (define_insn_and_split "*extendsfdf2_fpr"
4840 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4841 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4842 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4848 xscpsgndp %x0,%x1,%x1
4851 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4854 emit_note (NOTE_INSN_DELETED);
4857 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4858 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4860 (define_insn "*extendsfdf2_snan"
4861 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4862 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4863 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4867 [(set_attr "type" "fp")
4868 (set_attr "isa" "*,p8v")])
4870 (define_expand "truncdfsf2"
4871 [(set (match_operand:SF 0 "gpc_reg_operand")
4872 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4876 (define_insn "*truncdfsf2_fpr"
4877 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4878 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4883 [(set_attr "type" "fp")
4884 (set_attr "isa" "*,p8v")])
4886 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4887 ;; builtins.c and optabs.c that are not correct for IBM long double
4888 ;; when little-endian.
4889 (define_expand "signbit<mode>2"
4891 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4893 (subreg:DI (match_dup 2) 0))
4896 (set (match_operand:SI 0 "gpc_reg_operand")
4899 && (!FLOAT128_IEEE_P (<MODE>mode)
4900 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4902 if (FLOAT128_IEEE_P (<MODE>mode))
4904 rtx dest = operands[0];
4905 rtx src = operands[1];
4906 rtx tmp = gen_reg_rtx (DImode);
4907 rtx dest_di = gen_lowpart (DImode, dest);
4909 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4910 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4913 operands[2] = gen_reg_rtx (DFmode);
4914 operands[3] = gen_reg_rtx (DImode);
4915 if (TARGET_POWERPC64)
4917 operands[4] = gen_reg_rtx (DImode);
4918 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4919 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4920 WORDS_BIG_ENDIAN ? 4 : 0);
4924 operands[4] = gen_reg_rtx (SImode);
4925 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4926 WORDS_BIG_ENDIAN ? 0 : 4);
4927 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4931 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4932 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4933 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4934 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4936 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4937 ;; split allows the post reload phases to eliminate the move, and do the shift
4938 ;; directly with the register that contains the signbit.
4939 (define_insn_and_split "@signbit<mode>2_dm"
4940 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4941 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4943 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4947 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4951 operands[2] = gen_highpart (DImode, operands[1]);
4953 [(set_attr "type" "mftgpr,*")])
4955 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4956 ;; register and then doing a direct move if the value comes from memory. On
4957 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4958 (define_insn_and_split "*signbit<mode>2_dm_mem"
4959 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4960 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4962 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4968 rtx dest = operands[0];
4969 rtx src = operands[1];
4970 rtx addr = XEXP (src, 0);
4972 if (WORDS_BIG_ENDIAN)
4973 operands[2] = adjust_address (src, DImode, 0);
4975 else if (REG_P (addr) || SUBREG_P (addr))
4976 operands[2] = adjust_address (src, DImode, 8);
4978 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4979 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4980 operands[2] = adjust_address (src, DImode, 8);
4984 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4985 emit_insn (gen_rtx_SET (tmp, addr));
4986 operands[2] = change_address (src, DImode,
4987 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4991 (define_expand "copysign<mode>3"
4993 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4995 (neg:SFDF (abs:SFDF (match_dup 1))))
4996 (set (match_operand:SFDF 0 "gpc_reg_operand")
4997 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5002 && ((TARGET_PPC_GFXOPT
5003 && !HONOR_NANS (<MODE>mode)
5004 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5006 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5008 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5010 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5015 operands[3] = gen_reg_rtx (<MODE>mode);
5016 operands[4] = gen_reg_rtx (<MODE>mode);
5017 operands[5] = CONST0_RTX (<MODE>mode);
5020 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5021 ;; compiler from optimizing -0.0
5022 (define_insn "copysign<mode>3_fcpsgn"
5023 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5024 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5025 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5027 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5030 xscpsgndp %x0,%x2,%x1"
5031 [(set_attr "type" "fpsimple")])
5033 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5034 ;; fsel instruction and some auxiliary computations. Then we just have a
5035 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5037 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5038 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5039 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5040 ;; define_splits to make them if made by combine. On VSX machines we have the
5041 ;; min/max instructions.
5043 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5044 ;; to allow either DF/SF to use only traditional registers.
5046 (define_expand "s<minmax><mode>3"
5047 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5048 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5049 (match_operand:SFDF 2 "gpc_reg_operand")))]
5052 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5056 (define_insn "*s<minmax><mode>3_vsx"
5057 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5058 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5059 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5060 "TARGET_VSX && TARGET_HARD_FLOAT"
5062 return (TARGET_P9_MINMAX
5063 ? "xs<minmax>cdp %x0,%x1,%x2"
5064 : "xs<minmax>dp %x0,%x1,%x2");
5066 [(set_attr "type" "fp")])
5068 ;; The conditional move instructions allow us to perform max and min operations
5069 ;; even when we don't have the appropriate max/min instruction using the FSEL
5072 (define_insn_and_split "*s<minmax><mode>3_fpr"
5073 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5074 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5075 (match_operand:SFDF 2 "gpc_reg_operand")))]
5076 "!TARGET_VSX && TARGET_MINMAX"
5081 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5085 (define_expand "mov<mode>cc"
5086 [(set (match_operand:GPR 0 "gpc_reg_operand")
5087 (if_then_else:GPR (match_operand 1 "comparison_operator")
5088 (match_operand:GPR 2 "gpc_reg_operand")
5089 (match_operand:GPR 3 "gpc_reg_operand")))]
5092 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5098 ;; We use the BASE_REGS for the isel input operands because, if rA is
5099 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5100 ;; because we may switch the operands and rB may end up being rA.
5102 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5103 ;; leave out the mode in operand 4 and use one pattern, but reload can
5104 ;; change the mode underneath our feet and then gets confused trying
5105 ;; to reload the value.
5106 (define_mode_iterator CCEITHER [CC CCUNS])
5107 (define_mode_attr un [(CC "") (CCUNS "un")])
5108 (define_insn "isel_<un>signed_<GPR:mode>"
5109 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5111 (match_operator 1 "scc_comparison_operator"
5112 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5114 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5115 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5118 [(set_attr "type" "isel")])
5120 ;; These patterns can be useful for combine; they let combine know that
5121 ;; isel can handle reversed comparisons so long as the operands are
5124 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5125 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5127 (match_operator 1 "scc_rev_comparison_operator"
5128 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5130 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5131 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5134 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5135 return "isel %0,%3,%2,%j1";
5137 [(set_attr "type" "isel")])
5139 ;; Floating point conditional move
5140 (define_expand "mov<mode>cc"
5141 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5142 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5143 (match_operand:SFDF 2 "gpc_reg_operand")
5144 (match_operand:SFDF 3 "gpc_reg_operand")))]
5145 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5147 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5153 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5154 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5156 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5157 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5158 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5159 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5160 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5162 [(set_attr "type" "fp")])
5164 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5165 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5167 (match_operator:CCFP 1 "fpmask_comparison_operator"
5168 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5169 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5170 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5171 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5172 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5177 (if_then_else:V2DI (match_dup 1)
5181 (if_then_else:SFDF (ne (match_dup 6)
5186 if (GET_CODE (operands[6]) == SCRATCH)
5187 operands[6] = gen_reg_rtx (V2DImode);
5189 operands[7] = CONSTM1_RTX (V2DImode);
5190 operands[8] = CONST0_RTX (V2DImode);
5192 [(set_attr "length" "8")
5193 (set_attr "type" "vecperm")])
5195 ;; Handle inverting the fpmask comparisons.
5196 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5197 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5199 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5200 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5201 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5202 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5203 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5204 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5209 (if_then_else:V2DI (match_dup 9)
5213 (if_then_else:SFDF (ne (match_dup 6)
5218 rtx op1 = operands[1];
5219 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5221 if (GET_CODE (operands[6]) == SCRATCH)
5222 operands[6] = gen_reg_rtx (V2DImode);
5224 operands[7] = CONSTM1_RTX (V2DImode);
5225 operands[8] = CONST0_RTX (V2DImode);
5227 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5229 [(set_attr "length" "8")
5230 (set_attr "type" "vecperm")])
5232 (define_insn "*fpmask<mode>"
5233 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5235 (match_operator:CCFP 1 "fpmask_comparison_operator"
5236 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5237 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5238 (match_operand:V2DI 4 "all_ones_constant" "")
5239 (match_operand:V2DI 5 "zero_constant" "")))]
5241 "xscmp%V1dp %x0,%x2,%x3"
5242 [(set_attr "type" "fpcompare")])
5244 (define_insn "*xxsel<mode>"
5245 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5246 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5247 (match_operand:V2DI 2 "zero_constant" ""))
5248 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5249 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5251 "xxsel %x0,%x4,%x3,%x1"
5252 [(set_attr "type" "vecmove")])
5255 ;; Conversions to and from floating-point.
5257 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5258 ; don't want to support putting SImode in FPR registers.
5259 (define_insn "lfiwax"
5260 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5261 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5263 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5269 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5270 (set_attr "isa" "*,p8v,p8v,p9v")])
5272 ; This split must be run before register allocation because it allocates the
5273 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5274 ; it earlier to allow for the combiner to merge insns together where it might
5275 ; not be needed and also in case the insns are deleted as dead code.
5277 (define_insn_and_split "floatsi<mode>2_lfiwax"
5278 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5279 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5280 (clobber (match_scratch:DI 2 "=d,wa"))]
5281 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5282 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5287 rtx dest = operands[0];
5288 rtx src = operands[1];
5291 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5292 tmp = convert_to_mode (DImode, src, false);
5296 if (GET_CODE (tmp) == SCRATCH)
5297 tmp = gen_reg_rtx (DImode);
5300 src = rs6000_force_indexed_or_indirect_mem (src);
5301 emit_insn (gen_lfiwax (tmp, src));
5305 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5306 emit_move_insn (stack, src);
5307 emit_insn (gen_lfiwax (tmp, stack));
5310 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5313 [(set_attr "length" "12")
5314 (set_attr "type" "fpload")])
5316 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5317 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5320 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5321 (clobber (match_scratch:DI 2 "=d,wa"))]
5322 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5327 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5328 if (GET_CODE (operands[2]) == SCRATCH)
5329 operands[2] = gen_reg_rtx (DImode);
5330 if (TARGET_P8_VECTOR)
5331 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5333 emit_insn (gen_lfiwax (operands[2], operands[1]));
5334 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5337 [(set_attr "length" "8")
5338 (set_attr "type" "fpload")])
5340 (define_insn "lfiwzx"
5341 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5342 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5344 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5349 xxextractuw %x0,%x1,4"
5350 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5351 (set_attr "isa" "*,p8v,p8v,p9v")])
5353 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5354 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5355 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5356 (clobber (match_scratch:DI 2 "=d,wa"))]
5357 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5362 rtx dest = operands[0];
5363 rtx src = operands[1];
5366 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5367 tmp = convert_to_mode (DImode, src, true);
5371 if (GET_CODE (tmp) == SCRATCH)
5372 tmp = gen_reg_rtx (DImode);
5375 src = rs6000_force_indexed_or_indirect_mem (src);
5376 emit_insn (gen_lfiwzx (tmp, src));
5380 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5381 emit_move_insn (stack, src);
5382 emit_insn (gen_lfiwzx (tmp, stack));
5385 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5388 [(set_attr "length" "12")
5389 (set_attr "type" "fpload")])
5391 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5392 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5393 (unsigned_float:SFDF
5395 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5396 (clobber (match_scratch:DI 2 "=d,wa"))]
5397 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5402 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5403 if (GET_CODE (operands[2]) == SCRATCH)
5404 operands[2] = gen_reg_rtx (DImode);
5405 if (TARGET_P8_VECTOR)
5406 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5408 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5409 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5412 [(set_attr "length" "8")
5413 (set_attr "type" "fpload")])
5415 ; For each of these conversions, there is a define_expand, a define_insn
5416 ; with a '#' template, and a define_split (with C code). The idea is
5417 ; to allow constant folding with the template of the define_insn,
5418 ; then to have the insns split later (between sched1 and final).
5420 (define_expand "floatsidf2"
5421 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5422 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5425 (clobber (match_dup 4))
5426 (clobber (match_dup 5))
5427 (clobber (match_dup 6))])]
5430 if (TARGET_LFIWAX && TARGET_FCFID)
5432 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5435 else if (TARGET_FCFID)
5437 rtx dreg = operands[1];
5439 dreg = force_reg (SImode, dreg);
5440 dreg = convert_to_mode (DImode, dreg, false);
5441 emit_insn (gen_floatdidf2 (operands[0], dreg));
5445 if (!REG_P (operands[1]))
5446 operands[1] = force_reg (SImode, operands[1]);
5447 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5448 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5449 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5450 operands[5] = gen_reg_rtx (DFmode);
5451 operands[6] = gen_reg_rtx (SImode);
5454 (define_insn_and_split "*floatsidf2_internal"
5455 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5456 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5457 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5458 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5459 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5460 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5461 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5462 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5467 rtx lowword, highword;
5468 gcc_assert (MEM_P (operands[4]));
5469 highword = adjust_address (operands[4], SImode, 0);
5470 lowword = adjust_address (operands[4], SImode, 4);
5471 if (! WORDS_BIG_ENDIAN)
5472 std::swap (lowword, highword);
5474 emit_insn (gen_xorsi3 (operands[6], operands[1],
5475 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5476 emit_move_insn (lowword, operands[6]);
5477 emit_move_insn (highword, operands[2]);
5478 emit_move_insn (operands[5], operands[4]);
5479 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5482 [(set_attr "length" "24")
5483 (set_attr "type" "fp")])
5485 ;; If we don't have a direct conversion to single precision, don't enable this
5486 ;; conversion for 32-bit without fast math, because we don't have the insn to
5487 ;; generate the fixup swizzle to avoid double rounding problems.
5488 (define_expand "floatunssisf2"
5489 [(set (match_operand:SF 0 "gpc_reg_operand")
5490 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5492 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5494 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5496 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5498 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5503 rtx dreg = operands[1];
5505 dreg = force_reg (SImode, dreg);
5506 dreg = convert_to_mode (DImode, dreg, true);
5507 emit_insn (gen_floatdisf2 (operands[0], dreg));
5512 (define_expand "floatunssidf2"
5513 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5514 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5517 (clobber (match_dup 4))
5518 (clobber (match_dup 5))])]
5521 if (TARGET_LFIWZX && TARGET_FCFID)
5523 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5526 else if (TARGET_FCFID)
5528 rtx dreg = operands[1];
5530 dreg = force_reg (SImode, dreg);
5531 dreg = convert_to_mode (DImode, dreg, true);
5532 emit_insn (gen_floatdidf2 (operands[0], dreg));
5536 if (!REG_P (operands[1]))
5537 operands[1] = force_reg (SImode, operands[1]);
5538 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5539 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5540 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5541 operands[5] = gen_reg_rtx (DFmode);
5544 (define_insn_and_split "*floatunssidf2_internal"
5545 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5546 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5547 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5548 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5549 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5550 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5551 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5552 && !(TARGET_FCFID && TARGET_POWERPC64)"
5557 rtx lowword, highword;
5558 gcc_assert (MEM_P (operands[4]));
5559 highword = adjust_address (operands[4], SImode, 0);
5560 lowword = adjust_address (operands[4], SImode, 4);
5561 if (! WORDS_BIG_ENDIAN)
5562 std::swap (lowword, highword);
5564 emit_move_insn (lowword, operands[1]);
5565 emit_move_insn (highword, operands[2]);
5566 emit_move_insn (operands[5], operands[4]);
5567 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5570 [(set_attr "length" "20")
5571 (set_attr "type" "fp")])
5573 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5574 ;; vector registers. These insns favor doing the sign/zero extension in
5575 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5576 ;; extension and then a direct move.
5578 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5579 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5581 (match_operand:QHI 1 "input_operand")))
5582 (clobber (match_scratch:DI 2))
5583 (clobber (match_scratch:DI 3))
5584 (clobber (match_scratch:<QHI:MODE> 4))])]
5585 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5587 if (MEM_P (operands[1]))
5588 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5591 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5592 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5594 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5595 (clobber (match_scratch:DI 2 "=v,wa,v"))
5596 (clobber (match_scratch:DI 3 "=X,r,X"))
5597 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5598 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5600 "&& reload_completed"
5603 rtx result = operands[0];
5604 rtx input = operands[1];
5605 rtx di = operands[2];
5609 rtx tmp = operands[3];
5610 if (altivec_register_operand (input, <QHI:MODE>mode))
5611 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5612 else if (GET_CODE (tmp) == SCRATCH)
5613 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5616 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5617 emit_move_insn (di, tmp);
5622 rtx tmp = operands[4];
5623 emit_move_insn (tmp, input);
5624 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5627 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5630 [(set_attr "isa" "p9v,*,p9v")])
5632 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5633 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5634 (unsigned_float:FP_ISA3
5635 (match_operand:QHI 1 "input_operand")))
5636 (clobber (match_scratch:DI 2))
5637 (clobber (match_scratch:DI 3))])]
5638 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5640 if (MEM_P (operands[1]))
5641 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5644 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5645 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5646 (unsigned_float:FP_ISA3
5647 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5648 (clobber (match_scratch:DI 2 "=v,wa,wa"))
5649 (clobber (match_scratch:DI 3 "=X,r,X"))]
5650 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5652 "&& reload_completed"
5655 rtx result = operands[0];
5656 rtx input = operands[1];
5657 rtx di = operands[2];
5659 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5660 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5663 rtx tmp = operands[3];
5664 if (GET_CODE (tmp) == SCRATCH)
5665 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5668 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5669 emit_move_insn (di, tmp);
5673 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5676 [(set_attr "isa" "p9v,*,p9v")])
5678 (define_expand "fix_trunc<mode>si2"
5679 [(set (match_operand:SI 0 "gpc_reg_operand")
5680 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5683 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5685 rtx src = force_reg (<MODE>mode, operands[1]);
5688 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5691 rtx tmp = gen_reg_rtx (DImode);
5692 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5693 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5700 ; Like the convert to float patterns, this insn must be split before
5701 ; register allocation so that it can allocate the memory slot if it
5703 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5704 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5705 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5706 (clobber (match_scratch:DI 2 "=d"))]
5707 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5708 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5713 rtx dest = operands[0];
5714 rtx src = operands[1];
5715 rtx tmp = operands[2];
5717 if (GET_CODE (tmp) == SCRATCH)
5718 tmp = gen_reg_rtx (DImode);
5720 emit_insn (gen_fctiwz_<mode> (tmp, src));
5721 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5723 dest = rs6000_force_indexed_or_indirect_mem (dest);
5724 emit_insn (gen_stfiwx (dest, tmp));
5727 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5729 dest = gen_lowpart (DImode, dest);
5730 emit_move_insn (dest, tmp);
5735 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5736 emit_insn (gen_stfiwx (stack, tmp));
5737 emit_move_insn (dest, stack);
5741 [(set_attr "length" "12")
5742 (set_attr "type" "fp")])
5744 (define_insn_and_split "fix_trunc<mode>si2_internal"
5745 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5746 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5747 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5748 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5750 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5756 gcc_assert (MEM_P (operands[3]));
5757 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5759 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5760 emit_move_insn (operands[3], operands[2]);
5761 emit_move_insn (operands[0], lowword);
5764 [(set_attr "length" "16")
5765 (set_attr "type" "fp")])
5767 (define_expand "fix_trunc<mode>di2"
5768 [(set (match_operand:DI 0 "gpc_reg_operand")
5769 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5770 "TARGET_HARD_FLOAT && TARGET_FCFID"
5773 (define_insn "*fix_trunc<mode>di2_fctidz"
5774 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5775 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5776 "TARGET_HARD_FLOAT && TARGET_FCFID"
5780 [(set_attr "type" "fp")])
5782 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5783 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5784 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5785 ;; values can go in VSX registers. Keeping the direct move part through
5786 ;; register allocation prevents the register allocator from doing a direct move
5787 ;; of the SImode value to a GPR, and then a store/load.
5788 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5789 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5790 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5791 (clobber (match_scratch:SI 2 "=X,X,wa"))]
5792 "TARGET_DIRECT_MOVE"
5795 xscvdp<su>xws %x0,%x1
5797 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5799 (any_fix:SI (match_dup 1)))
5803 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5805 [(set_attr "type" "fp")
5806 (set_attr "length" "4,4,8")
5807 (set_attr "isa" "p9v,p9v,*")])
5809 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5810 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5811 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5812 "TARGET_DIRECT_MOVE"
5815 xscvdp<su>xws %x0,%x1"
5816 [(set_attr "type" "fp")])
5818 ;; Keep the convert and store together through register allocation to prevent
5819 ;; the register allocator from getting clever and doing a direct move to a GPR
5820 ;; and then store for reg+offset stores.
5821 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5822 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5823 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5824 (clobber (match_scratch:SI 2 "=wa"))]
5825 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5827 "&& reload_completed"
5829 (any_fix:SI (match_dup 1)))
5833 operands[3] = (<QHSI:MODE>mode == SImode
5835 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5838 (define_expand "fixuns_trunc<mode>si2"
5839 [(set (match_operand:SI 0 "gpc_reg_operand")
5840 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5841 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5843 if (!TARGET_P8_VECTOR)
5845 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5850 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5851 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5852 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5853 (clobber (match_scratch:DI 2 "=d"))]
5854 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5855 && TARGET_STFIWX && can_create_pseudo_p ()
5856 && !TARGET_P8_VECTOR"
5861 rtx dest = operands[0];
5862 rtx src = operands[1];
5863 rtx tmp = operands[2];
5865 if (GET_CODE (tmp) == SCRATCH)
5866 tmp = gen_reg_rtx (DImode);
5868 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5871 dest = rs6000_force_indexed_or_indirect_mem (dest);
5872 emit_insn (gen_stfiwx (dest, tmp));
5875 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5877 dest = gen_lowpart (DImode, dest);
5878 emit_move_insn (dest, tmp);
5883 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5884 emit_insn (gen_stfiwx (stack, tmp));
5885 emit_move_insn (dest, stack);
5889 [(set_attr "length" "12")
5890 (set_attr "type" "fp")])
5892 (define_insn "fixuns_trunc<mode>di2"
5893 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5894 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5895 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5899 [(set_attr "type" "fp")])
5901 (define_insn "rs6000_mtfsb0"
5902 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5906 [(set_attr "type" "fp")])
5908 (define_insn "rs6000_mtfsb1"
5909 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5913 [(set_attr "type" "fp")])
5915 (define_insn "rs6000_mffscrn"
5916 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5917 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5921 [(set_attr "type" "fp")])
5923 (define_insn "rs6000_mffscdrn"
5924 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5925 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5926 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5929 [(set_attr "type" "fp")])
5931 (define_expand "rs6000_set_fpscr_rn"
5932 [(match_operand:DI 0 "reg_or_cint_operand")]
5935 rtx tmp_df = gen_reg_rtx (DFmode);
5937 /* The floating point rounding control bits are FPSCR[62:63]. Put the
5938 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
5941 rtx src_df = force_reg (DImode, operands[0]);
5942 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5943 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5947 if (CONST_INT_P (operands[0]))
5949 if ((INTVAL (operands[0]) & 0x1) == 0x1)
5950 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5952 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5954 if ((INTVAL (operands[0]) & 0x2) == 0x2)
5955 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5957 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5961 rtx tmp_rn = gen_reg_rtx (DImode);
5962 rtx tmp_di = gen_reg_rtx (DImode);
5964 /* Extract new RN mode from operand. */
5965 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5967 /* Insert new RN mode into FSCPR. */
5968 emit_insn (gen_rs6000_mffs (tmp_df));
5969 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5970 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5971 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5973 /* Need to write to field k=15. The fields are [0:15]. Hence with
5974 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
5975 8-bit field[0:7]. Need to set the bit that corresponds to the
5976 value of i that you want [0:7]. */
5977 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5978 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5983 (define_expand "rs6000_set_fpscr_drn"
5984 [(match_operand:DI 0 "gpc_reg_operand")]
5987 rtx tmp_df = gen_reg_rtx (DFmode);
5989 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5990 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
5993 rtx src_df = gen_reg_rtx (DFmode);
5995 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5996 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5997 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6001 rtx tmp_rn = gen_reg_rtx (DImode);
6002 rtx tmp_di = gen_reg_rtx (DImode);
6004 /* Extract new DRN mode from operand. */
6005 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6006 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6008 /* Insert new RN mode into FSCPR. */
6009 emit_insn (gen_rs6000_mffs (tmp_df));
6010 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6011 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
6012 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6014 /* Need to write to field 7. The fields are [0:15]. The equation to
6015 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6016 i to 0x1 to get field 7 where i selects the field. */
6017 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6018 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6023 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6024 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6025 ;; because the first makes it clear that operand 0 is not live
6026 ;; before the instruction.
6027 (define_insn "fctiwz_<mode>"
6028 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6030 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6036 [(set_attr "type" "fp")])
6038 (define_insn "fctiwuz_<mode>"
6039 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6040 (unspec:DI [(unsigned_fix:SI
6041 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6043 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6047 [(set_attr "type" "fp")])
6049 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6050 ;; since the friz instruction does not truncate the value if the floating
6051 ;; point value is < LONG_MIN or > LONG_MAX.
6052 (define_insn "*friz"
6053 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6054 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6055 "TARGET_HARD_FLOAT && TARGET_FPRND
6056 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6060 [(set_attr "type" "fp")])
6062 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6063 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6064 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6065 ;; extend it, store it back on the stack from the GPR, load it back into the
6066 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6067 ;; disable using store and load to sign/zero extend the value.
6068 (define_insn_and_split "*round32<mode>2_fprs"
6069 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6071 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6072 (clobber (match_scratch:DI 2 "=d"))
6073 (clobber (match_scratch:DI 3 "=d"))]
6075 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6076 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6081 rtx dest = operands[0];
6082 rtx src = operands[1];
6083 rtx tmp1 = operands[2];
6084 rtx tmp2 = operands[3];
6085 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6087 if (GET_CODE (tmp1) == SCRATCH)
6088 tmp1 = gen_reg_rtx (DImode);
6089 if (GET_CODE (tmp2) == SCRATCH)
6090 tmp2 = gen_reg_rtx (DImode);
6092 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6093 emit_insn (gen_stfiwx (stack, tmp1));
6094 emit_insn (gen_lfiwax (tmp2, stack));
6095 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6098 [(set_attr "type" "fpload")
6099 (set_attr "length" "16")])
6101 (define_insn_and_split "*roundu32<mode>2_fprs"
6102 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6103 (unsigned_float:SFDF
6104 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6105 (clobber (match_scratch:DI 2 "=d"))
6106 (clobber (match_scratch:DI 3 "=d"))]
6108 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6109 && can_create_pseudo_p ()"
6114 rtx dest = operands[0];
6115 rtx src = operands[1];
6116 rtx tmp1 = operands[2];
6117 rtx tmp2 = operands[3];
6118 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6120 if (GET_CODE (tmp1) == SCRATCH)
6121 tmp1 = gen_reg_rtx (DImode);
6122 if (GET_CODE (tmp2) == SCRATCH)
6123 tmp2 = gen_reg_rtx (DImode);
6125 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6126 emit_insn (gen_stfiwx (stack, tmp1));
6127 emit_insn (gen_lfiwzx (tmp2, stack));
6128 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6131 [(set_attr "type" "fpload")
6132 (set_attr "length" "16")])
6134 ;; No VSX equivalent to fctid
6135 (define_insn "lrint<mode>di2"
6136 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6137 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6139 "TARGET_HARD_FLOAT && TARGET_FPRND"
6141 [(set_attr "type" "fp")])
6143 (define_insn "btrunc<mode>2"
6144 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6145 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6147 "TARGET_HARD_FLOAT && TARGET_FPRND"
6151 [(set_attr "type" "fp")])
6153 (define_insn "ceil<mode>2"
6154 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6155 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6157 "TARGET_HARD_FLOAT && TARGET_FPRND"
6161 [(set_attr "type" "fp")])
6163 (define_insn "floor<mode>2"
6164 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6165 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6167 "TARGET_HARD_FLOAT && TARGET_FPRND"
6171 [(set_attr "type" "fp")])
6173 ;; No VSX equivalent to frin
6174 (define_insn "round<mode>2"
6175 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6176 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6178 "TARGET_HARD_FLOAT && TARGET_FPRND"
6180 [(set_attr "type" "fp")])
6182 (define_insn "*xsrdpi<mode>2"
6183 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6184 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6186 "TARGET_HARD_FLOAT && TARGET_VSX"
6188 [(set_attr "type" "fp")])
6190 (define_expand "lround<mode>di2"
6192 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6194 (set (match_operand:DI 0 "gpc_reg_operand")
6195 (unspec:DI [(match_dup 2)]
6197 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6199 operands[2] = gen_reg_rtx (<MODE>mode);
6202 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6203 (define_insn "stfiwx"
6204 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6205 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6211 [(set_attr "type" "fpstore")
6212 (set_attr "isa" "*,p8v")])
6214 ;; If we don't have a direct conversion to single precision, don't enable this
6215 ;; conversion for 32-bit without fast math, because we don't have the insn to
6216 ;; generate the fixup swizzle to avoid double rounding problems.
6217 (define_expand "floatsisf2"
6218 [(set (match_operand:SF 0 "gpc_reg_operand")
6219 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6221 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6223 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6225 if (TARGET_FCFIDS && TARGET_LFIWAX)
6227 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6230 else if (TARGET_FCFID && TARGET_LFIWAX)
6232 rtx dfreg = gen_reg_rtx (DFmode);
6233 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6234 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6239 rtx dreg = operands[1];
6241 dreg = force_reg (SImode, dreg);
6242 dreg = convert_to_mode (DImode, dreg, false);
6243 emit_insn (gen_floatdisf2 (operands[0], dreg));
6248 (define_insn "floatdidf2"
6249 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6250 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6251 "TARGET_FCFID && TARGET_HARD_FLOAT"
6255 [(set_attr "type" "fp")])
6257 ; Allow the combiner to merge source memory operands to the conversion so that
6258 ; the optimizer/register allocator doesn't try to load the value too early in a
6259 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6260 ; hit. We will split after reload to avoid the trip through the GPRs
6262 (define_insn_and_split "*floatdidf2_mem"
6263 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6264 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6265 (clobber (match_scratch:DI 2 "=d,wa"))]
6266 "TARGET_HARD_FLOAT && TARGET_FCFID"
6268 "&& reload_completed"
6269 [(set (match_dup 2) (match_dup 1))
6270 (set (match_dup 0) (float:DF (match_dup 2)))]
6272 [(set_attr "length" "8")
6273 (set_attr "type" "fpload")])
6275 (define_expand "floatunsdidf2"
6276 [(set (match_operand:DF 0 "gpc_reg_operand")
6278 (match_operand:DI 1 "gpc_reg_operand")))]
6279 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6282 (define_insn "*floatunsdidf2_fcfidu"
6283 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6284 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6285 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6289 [(set_attr "type" "fp")])
6291 (define_insn_and_split "*floatunsdidf2_mem"
6292 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6293 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6294 (clobber (match_scratch:DI 2 "=d,wa"))]
6295 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6297 "&& reload_completed"
6298 [(set (match_dup 2) (match_dup 1))
6299 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6301 [(set_attr "length" "8")
6302 (set_attr "type" "fpload")])
6304 (define_expand "floatdisf2"
6305 [(set (match_operand:SF 0 "gpc_reg_operand")
6306 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6307 "TARGET_FCFID && TARGET_HARD_FLOAT
6308 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6312 rtx val = operands[1];
6313 if (!flag_unsafe_math_optimizations)
6315 rtx label = gen_label_rtx ();
6316 val = gen_reg_rtx (DImode);
6317 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6320 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6325 (define_insn "floatdisf2_fcfids"
6326 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6327 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6328 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6332 [(set_attr "type" "fp")
6333 (set_attr "isa" "*,p8v")])
6335 (define_insn_and_split "*floatdisf2_mem"
6336 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6337 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6338 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6339 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6341 "&& reload_completed"
6344 emit_move_insn (operands[2], operands[1]);
6345 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6348 [(set_attr "length" "8")
6349 (set_attr "isa" "*,p8v,p8v")])
6351 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6352 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6353 ;; from double rounding.
6354 ;; Instead of creating a new cpu type for two FP operations, just use fp
6355 (define_insn_and_split "floatdisf2_internal1"
6356 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6357 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6358 (clobber (match_scratch:DF 2 "=d"))]
6359 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6361 "&& reload_completed"
6363 (float:DF (match_dup 1)))
6365 (float_truncate:SF (match_dup 2)))]
6367 [(set_attr "length" "8")
6368 (set_attr "type" "fp")])
6370 ;; Twiddles bits to avoid double rounding.
6371 ;; Bits that might be truncated when converting to DFmode are replaced
6372 ;; by a bit that won't be lost at that stage, but is below the SFmode
6373 ;; rounding position.
6374 (define_expand "floatdisf2_internal2"
6375 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6377 (clobber (reg:DI CA_REGNO))])
6378 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6380 (set (match_dup 3) (plus:DI (match_dup 3)
6382 (set (match_dup 0) (plus:DI (match_dup 0)
6384 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6386 (set (match_dup 0) (ior:DI (match_dup 0)
6388 (set (match_dup 0) (and:DI (match_dup 0)
6390 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6391 (label_ref (match_operand:DI 2 ""))
6393 (set (match_dup 0) (match_dup 1))]
6394 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6396 operands[3] = gen_reg_rtx (DImode);
6397 operands[4] = gen_reg_rtx (CCUNSmode);
6400 (define_expand "floatunsdisf2"
6401 [(set (match_operand:SF 0 "gpc_reg_operand")
6402 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6403 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6406 (define_insn "floatunsdisf2_fcfidus"
6407 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6408 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6409 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6413 [(set_attr "type" "fp")
6414 (set_attr "isa" "*,p8v")])
6416 (define_insn_and_split "*floatunsdisf2_mem"
6417 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6418 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6419 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6420 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6422 "&& reload_completed"
6425 emit_move_insn (operands[2], operands[1]);
6426 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6429 [(set_attr "type" "fpload")
6430 (set_attr "length" "8")
6431 (set_attr "isa" "*,p8v,p8v")])
6433 ;; Define the TImode operations that can be done in a small number
6434 ;; of instructions. The & constraints are to prevent the register
6435 ;; allocator from allocating registers that overlap with the inputs
6436 ;; (for example, having an input in 7,8 and an output in 6,7). We
6437 ;; also allow for the output being the same as one of the inputs.
6439 (define_expand "addti3"
6440 [(set (match_operand:TI 0 "gpc_reg_operand")
6441 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6442 (match_operand:TI 2 "reg_or_short_operand")))]
6445 rtx lo0 = gen_lowpart (DImode, operands[0]);
6446 rtx lo1 = gen_lowpart (DImode, operands[1]);
6447 rtx lo2 = gen_lowpart (DImode, operands[2]);
6448 rtx hi0 = gen_highpart (DImode, operands[0]);
6449 rtx hi1 = gen_highpart (DImode, operands[1]);
6450 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6452 if (!reg_or_short_operand (lo2, DImode))
6453 lo2 = force_reg (DImode, lo2);
6454 if (!adde_operand (hi2, DImode))
6455 hi2 = force_reg (DImode, hi2);
6457 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6458 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6462 (define_expand "subti3"
6463 [(set (match_operand:TI 0 "gpc_reg_operand")
6464 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6465 (match_operand:TI 2 "gpc_reg_operand")))]
6468 rtx lo0 = gen_lowpart (DImode, operands[0]);
6469 rtx lo1 = gen_lowpart (DImode, operands[1]);
6470 rtx lo2 = gen_lowpart (DImode, operands[2]);
6471 rtx hi0 = gen_highpart (DImode, operands[0]);
6472 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6473 rtx hi2 = gen_highpart (DImode, operands[2]);
6475 if (!reg_or_short_operand (lo1, DImode))
6476 lo1 = force_reg (DImode, lo1);
6477 if (!adde_operand (hi1, DImode))
6478 hi1 = force_reg (DImode, hi1);
6480 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6481 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6485 ;; 128-bit logical operations expanders
6487 (define_expand "and<mode>3"
6488 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6489 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6490 (match_operand:BOOL_128 2 "vlogical_operand")))]
6494 (define_expand "ior<mode>3"
6495 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6496 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6497 (match_operand:BOOL_128 2 "vlogical_operand")))]
6501 (define_expand "xor<mode>3"
6502 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6503 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6504 (match_operand:BOOL_128 2 "vlogical_operand")))]
6508 (define_expand "nor<mode>3"
6509 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6511 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6512 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6516 (define_expand "andc<mode>3"
6517 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6519 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6520 (match_operand:BOOL_128 1 "vlogical_operand")))]
6524 ;; Power8 vector logical instructions.
6525 (define_expand "eqv<mode>3"
6526 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6528 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6529 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6530 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6533 ;; Rewrite nand into canonical form
6534 (define_expand "nand<mode>3"
6535 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6537 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6538 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6539 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6542 ;; The canonical form is to have the negated element first, so we need to
6543 ;; reverse arguments.
6544 (define_expand "orc<mode>3"
6545 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6547 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6548 (match_operand:BOOL_128 1 "vlogical_operand")))]
6549 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6552 ;; 128-bit logical operations insns and split operations
6553 (define_insn_and_split "*and<mode>3_internal"
6554 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6556 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6557 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6560 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6561 return "xxland %x0,%x1,%x2";
6563 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6564 return "vand %0,%1,%2";
6568 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6571 rs6000_split_logical (operands, AND, false, false, false);
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"))))])
6589 (define_insn_and_split "*bool<mode>3_internal"
6590 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6591 (match_operator:BOOL_128 3 "boolean_or_operator"
6592 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6593 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6596 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6597 return "xxl%q3 %x0,%x1,%x2";
6599 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6600 return "v%q3 %0,%1,%2";
6604 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6607 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6612 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6613 (const_string "veclogical")
6614 (const_string "integer")))
6615 (set (attr "length")
6617 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6620 (match_test "TARGET_POWERPC64")
6622 (const_string "16"))))])
6625 (define_insn_and_split "*boolc<mode>3_internal1"
6626 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6627 (match_operator:BOOL_128 3 "boolean_operator"
6629 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6630 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6631 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6633 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6634 return "xxl%q3 %x0,%x1,%x2";
6636 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6637 return "v%q3 %0,%1,%2";
6641 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6642 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6645 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6650 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6651 (const_string "veclogical")
6652 (const_string "integer")))
6653 (set (attr "length")
6655 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6658 (match_test "TARGET_POWERPC64")
6660 (const_string "16"))))])
6662 (define_insn_and_split "*boolc<mode>3_internal2"
6663 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6664 (match_operator:TI2 3 "boolean_operator"
6666 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6667 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6668 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6670 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6673 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6676 [(set_attr "type" "integer")
6677 (set (attr "length")
6679 (match_test "TARGET_POWERPC64")
6681 (const_string "16")))])
6684 (define_insn_and_split "*boolcc<mode>3_internal1"
6685 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6686 (match_operator:BOOL_128 3 "boolean_operator"
6688 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6690 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6691 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6693 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6694 return "xxl%q3 %x0,%x1,%x2";
6696 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6697 return "v%q3 %0,%1,%2";
6701 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6702 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6705 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6710 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6711 (const_string "veclogical")
6712 (const_string "integer")))
6713 (set (attr "length")
6715 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6718 (match_test "TARGET_POWERPC64")
6720 (const_string "16"))))])
6722 (define_insn_and_split "*boolcc<mode>3_internal2"
6723 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6724 (match_operator:TI2 3 "boolean_operator"
6726 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6728 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6729 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6731 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6734 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6737 [(set_attr "type" "integer")
6738 (set (attr "length")
6740 (match_test "TARGET_POWERPC64")
6742 (const_string "16")))])
6746 (define_insn_and_split "*eqv<mode>3_internal1"
6747 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6750 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6751 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6754 if (vsx_register_operand (operands[0], <MODE>mode))
6755 return "xxleqv %x0,%x1,%x2";
6759 "TARGET_P8_VECTOR && reload_completed
6760 && int_reg_operand (operands[0], <MODE>mode)"
6763 rs6000_split_logical (operands, XOR, true, false, false);
6768 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6769 (const_string "veclogical")
6770 (const_string "integer")))
6771 (set (attr "length")
6773 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6776 (match_test "TARGET_POWERPC64")
6778 (const_string "16"))))])
6780 (define_insn_and_split "*eqv<mode>3_internal2"
6781 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6784 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6785 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6788 "reload_completed && !TARGET_P8_VECTOR"
6791 rs6000_split_logical (operands, XOR, true, false, false);
6794 [(set_attr "type" "integer")
6795 (set (attr "length")
6797 (match_test "TARGET_POWERPC64")
6799 (const_string "16")))])
6801 ;; 128-bit one's complement
6802 (define_insn_and_split "one_cmpl<mode>2"
6803 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6805 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6808 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6809 return "xxlnor %x0,%x1,%x1";
6811 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6812 return "vnor %0,%1,%1";
6816 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6819 rs6000_split_logical (operands, NOT, false, false, false);
6824 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6825 (const_string "veclogical")
6826 (const_string "integer")))
6827 (set (attr "length")
6829 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6832 (match_test "TARGET_POWERPC64")
6834 (const_string "16"))))])
6837 ;; Now define ways of moving data around.
6839 ;; Set up a register with a value from the GOT table
6841 (define_expand "movsi_got"
6842 [(set (match_operand:SI 0 "gpc_reg_operand")
6843 (unspec:SI [(match_operand:SI 1 "got_operand")
6844 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6845 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6847 if (GET_CODE (operands[1]) == CONST)
6849 rtx offset = const0_rtx;
6850 HOST_WIDE_INT value;
6852 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6853 value = INTVAL (offset);
6856 rtx tmp = (!can_create_pseudo_p ()
6858 : gen_reg_rtx (Pmode));
6859 emit_insn (gen_movsi_got (tmp, operands[1]));
6860 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6865 operands[2] = rs6000_got_register (operands[1]);
6868 (define_insn "*movsi_got_internal"
6869 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6870 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6871 (match_operand:SI 2 "gpc_reg_operand" "b")]
6873 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6874 "lwz %0,%a1@got(%2)"
6875 [(set_attr "type" "load")])
6877 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6878 ;; didn't get allocated to a hard register.
6880 [(set (match_operand:SI 0 "gpc_reg_operand")
6881 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6882 (match_operand:SI 2 "memory_operand")]
6884 "DEFAULT_ABI == ABI_V4
6886 && reload_completed"
6887 [(set (match_dup 0) (match_dup 2))
6888 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6892 ;; MR LA LWZ LFIWZX LXSIWZX
6893 ;; STW STFIWX STXSIWX LI LIS
6894 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6895 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6897 (define_insn "*movsi_internal1"
6898 [(set (match_operand:SI 0 "nonimmediate_operand"
6904 (match_operand:SI 1 "input_operand"
6910 "gpc_reg_operand (operands[0], SImode)
6911 || gpc_reg_operand (operands[1], SImode)"
6937 "*, *, load, fpload, fpload,
6938 store, fpstore, fpstore, *, *,
6939 *, veclogical, vecsimple, vecsimple, vecsimple,
6940 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6951 *, p8v, p9v, p9v, p8v,
6952 p9v, p8v, p9v, p8v, p8v,
6955 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6956 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6958 ;; Because SF values are actually stored as DF values within the vector
6959 ;; registers, we need to convert the value to the vector SF format when
6960 ;; we need to use the bits in a union or similar cases. We only need
6961 ;; to do this transformation when the value is a vector register. Loads,
6962 ;; stores, and transfers within GPRs are assumed to be safe.
6964 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6965 ;; no alternatives, because the call is created as part of secondary_reload,
6966 ;; and operand #2's register class is used to allocate the temporary register.
6967 ;; This function is called before reload, and it creates the temporary as
6970 ;; MR LWZ LFIWZX LXSIWZX STW
6971 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6974 (define_insn_and_split "movsi_from_sf"
6975 [(set (match_operand:SI 0 "nonimmediate_operand"
6976 "=r, r, ?*d, ?*v, m,
6979 (unspec:SI [(match_operand:SF 1 "input_operand"
6984 (clobber (match_scratch:V4SF 2
6988 "TARGET_NO_SF_SUBREG
6989 && (register_operand (operands[0], SImode)
6990 || register_operand (operands[1], SFmode))"
7003 "&& reload_completed
7004 && int_reg_operand (operands[0], SImode)
7005 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7008 rtx op0 = operands[0];
7009 rtx op1 = operands[1];
7010 rtx op2 = operands[2];
7011 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7012 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7014 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7015 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7019 "*, load, fpload, fpload, store,
7020 fpstore, fpstore, fpstore, mftgpr, fp,
7028 *, p9v, p8v, p8v, p8v,
7031 ;; movsi_from_sf with zero extension
7033 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7036 (define_insn_and_split "*movdi_from_sf_zero_ext"
7037 [(set (match_operand:DI 0 "gpc_reg_operand"
7038 "=r, r, ?*d, ?*v, r,
7041 (unspec:SI [(match_operand:SF 1 "input_operand"
7044 UNSPEC_SI_FROM_SF)))
7045 (clobber (match_scratch:V4SF 2
7048 "TARGET_DIRECT_MOVE_64BIT
7049 && (register_operand (operands[0], DImode)
7050 || register_operand (operands[1], SImode))"
7059 "&& reload_completed
7060 && register_operand (operands[0], DImode)
7061 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7064 rtx op0 = operands[0];
7065 rtx op1 = operands[1];
7066 rtx op2 = operands[2];
7067 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7069 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7070 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7074 "*, load, fpload, fpload, two,
7080 "*, *, p8v, p8v, p8v,
7083 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7084 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7085 ;; conversion explicitly since that doesn't work in most cases if the input
7086 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7087 ;; former handles cases where the input will not fit in a SFmode, and the
7088 ;; latter assumes the value has already been rounded.
7089 (define_insn "*movsi_from_df"
7090 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7091 (unspec:SI [(float_truncate:SF
7092 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7093 UNSPEC_SI_FROM_SF))]
7094 "TARGET_NO_SF_SUBREG"
7096 [(set_attr "type" "fp")])
7098 ;; Split a load of a large constant into the appropriate two-insn
7102 [(set (match_operand:SI 0 "gpc_reg_operand")
7103 (match_operand:SI 1 "const_int_operand"))]
7104 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7105 && (INTVAL (operands[1]) & 0xffff) != 0"
7109 (ior:SI (match_dup 0)
7112 if (rs6000_emit_set_const (operands[0], operands[1]))
7118 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7120 [(set (match_operand:DI 0 "altivec_register_operand")
7121 (match_operand:DI 1 "xxspltib_constant_split"))]
7122 "TARGET_P9_VECTOR && reload_completed"
7125 rtx op0 = operands[0];
7126 rtx op1 = operands[1];
7127 int r = REGNO (op0);
7128 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7130 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7131 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7135 (define_insn "*mov<mode>_internal2"
7136 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7137 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7139 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7145 [(set_attr "type" "cmp,logical,cmp")
7146 (set_attr "dot" "yes")
7147 (set_attr "length" "4,4,8")])
7150 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7151 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7153 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7155 [(set (match_dup 0) (match_dup 1))
7157 (compare:CC (match_dup 0)
7161 (define_expand "mov<mode>"
7162 [(set (match_operand:INT 0 "general_operand")
7163 (match_operand:INT 1 "any_operand"))]
7166 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7170 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7171 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7172 ;; MTVSRWZ MF%1 MT%1 NOP
7173 (define_insn "*mov<mode>_internal"
7174 [(set (match_operand:QHI 0 "nonimmediate_operand"
7175 "=r, r, wa, m, Z, r,
7176 wa, wa, wa, v, ?v, r,
7178 (match_operand:QHI 1 "input_operand"
7180 wa, O, wM, wB, wS, wa,
7182 "gpc_reg_operand (operands[0], <MODE>mode)
7183 || gpc_reg_operand (operands[1], <MODE>mode)"
7202 "*, load, fpload, store, fpstore, *,
7203 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7204 mffgpr, mfjmpr, mtjmpr, *")
7210 "*, *, p9v, *, p9v, *,
7211 p9v, p9v, p9v, p9v, p9v, p9v,
7215 ;; Here is how to move condition codes around. When we store CC data in
7216 ;; an integer register or memory, we store just the high-order 4 bits.
7217 ;; This lets us not shift in the most common case of CR0.
7218 (define_expand "movcc"
7219 [(set (match_operand:CC 0 "nonimmediate_operand")
7220 (match_operand:CC 1 "nonimmediate_operand"))]
7224 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7226 (define_insn "*movcc_<mode>"
7227 [(set (match_operand:CC_any 0 "nonimmediate_operand"
7228 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7229 (match_operand:CC_any 1 "general_operand"
7230 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7231 "register_operand (operands[0], <MODE>mode)
7232 || register_operand (operands[1], <MODE>mode)"
7236 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7239 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7246 [(set_attr_alternative "type"
7247 [(const_string "cr_logical")
7248 (const_string "mtcr")
7249 (const_string "mtcr")
7250 (const_string "cr_logical")
7251 (if_then_else (match_test "TARGET_MFCRF")
7252 (const_string "mfcrf") (const_string "mfcr"))
7253 (if_then_else (match_test "TARGET_MFCRF")
7254 (const_string "mfcrf") (const_string "mfcr"))
7255 (const_string "integer")
7256 (const_string "integer")
7257 (const_string "mfjmpr")
7258 (const_string "mtjmpr")
7259 (const_string "load")
7260 (const_string "store")])
7261 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7263 ;; For floating-point, we normally deal with the floating-point registers
7264 ;; unless -msoft-float is used. The sole exception is that parameter passing
7265 ;; can produce floating-point values in fixed-point registers. Unless the
7266 ;; value is a simple constant or already in memory, we deal with this by
7267 ;; allocating memory and copying the value explicitly via that memory location.
7269 ;; Move 32-bit binary/decimal floating point
7270 (define_expand "mov<mode>"
7271 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7272 (match_operand:FMOVE32 1 "any_operand"))]
7275 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7280 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7281 (match_operand:FMOVE32 1 "const_double_operand"))]
7283 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7284 || (SUBREG_P (operands[0])
7285 && REG_P (SUBREG_REG (operands[0]))
7286 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7287 [(set (match_dup 2) (match_dup 3))]
7291 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7293 if (! TARGET_POWERPC64)
7294 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7296 operands[2] = gen_lowpart (SImode, operands[0]);
7298 operands[3] = gen_int_mode (l, SImode);
7301 ;; Originally, we tried to keep movsf and movsd common, but the differences
7302 ;; addressing was making it rather difficult to hide with mode attributes. In
7303 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7304 ;; before the VSX stores meant that the register allocator would tend to do a
7305 ;; direct move to the GPR (which involves conversion from scalar to
7306 ;; vector/memory formats) to save values in the traditional Altivec registers,
7307 ;; while SDmode had problems on power6 if the GPR store was not first due to
7308 ;; the power6 not having an integer store operation.
7310 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7311 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7312 ;; MR MT<x> MF<x> NOP
7314 (define_insn "movsf_hardfloat"
7315 [(set (match_operand:SF 0 "nonimmediate_operand"
7316 "=!r, f, v, wa, m, wY,
7317 Z, m, wa, !r, f, wa,
7319 (match_operand:SF 1 "input_operand"
7323 "(register_operand (operands[0], SFmode)
7324 || register_operand (operands[1], SFmode))
7325 && TARGET_HARD_FLOAT
7326 && (TARGET_ALLOW_SF_SUBREG
7327 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7340 xscpsgndp %x0,%x1,%x1
7346 "load, fpload, fpload, fpload, fpstore, fpstore,
7347 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7348 *, mtjmpr, mfjmpr, *")
7350 "*, *, p9v, p8v, *, p9v,
7354 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7355 ;; FMR MR MT%0 MF%1 NOP
7356 (define_insn "movsd_hardfloat"
7357 [(set (match_operand:SD 0 "nonimmediate_operand"
7358 "=!r, d, m, Z, ?d, ?r,
7359 f, !r, *c*l, !r, *h")
7360 (match_operand:SD 1 "input_operand"
7363 "(register_operand (operands[0], SDmode)
7364 || register_operand (operands[1], SDmode))
7365 && TARGET_HARD_FLOAT"
7379 "load, fpload, store, fpstore, mffgpr, mftgpr,
7380 fpsimple, *, mtjmpr, mfjmpr, *")
7382 "*, p7, *, *, p8v, p8v,
7385 ;; MR MT%0 MF%0 LWZ STW LI
7386 ;; LIS G-const. F/n-const NOP
7387 (define_insn "*mov<mode>_softfloat"
7388 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7389 "=r, *c*l, r, r, m, r,
7392 (match_operand:FMOVE32 1 "input_operand"
7396 "(gpc_reg_operand (operands[0], <MODE>mode)
7397 || gpc_reg_operand (operands[1], <MODE>mode))
7398 && TARGET_SOFT_FLOAT"
7411 "*, mtjmpr, mfjmpr, load, store, *,
7418 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7419 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7421 ;; Because SF values are actually stored as DF values within the vector
7422 ;; registers, we need to convert the value to the vector SF format when
7423 ;; we need to use the bits in a union or similar cases. We only need
7424 ;; to do this transformation when the value is a vector register. Loads,
7425 ;; stores, and transfers within GPRs are assumed to be safe.
7427 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7428 ;; no alternatives, because the call is created as part of secondary_reload,
7429 ;; and operand #2's register class is used to allocate the temporary register.
7430 ;; This function is called before reload, and it creates the temporary as
7433 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7434 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7435 (define_insn_and_split "movsf_from_si"
7436 [(set (match_operand:SF 0 "nonimmediate_operand"
7437 "=!r, f, v, wa, m, Z,
7439 (unspec:SF [(match_operand:SI 1 "input_operand"
7443 (clobber (match_scratch:DI 2
7446 "TARGET_NO_SF_SUBREG
7447 && (register_operand (operands[0], SFmode)
7448 || register_operand (operands[1], SImode))"
7461 "&& reload_completed
7462 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7463 && int_reg_operand_not_pseudo (operands[1], SImode)"
7466 rtx op0 = operands[0];
7467 rtx op1 = operands[1];
7468 rtx op2 = operands[2];
7469 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7471 /* Move SF value to upper 32-bits for xscvspdpn. */
7472 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7473 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7474 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7481 "load, fpload, fpload, fpload, store, fpstore,
7482 fpstore, vecfloat, mffgpr, *")
7484 "*, *, p9v, p8v, *, *,
7485 p8v, p8v, p8v, *")])
7488 ;; Move 64-bit binary/decimal floating point
7489 (define_expand "mov<mode>"
7490 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7491 (match_operand:FMOVE64 1 "any_operand"))]
7494 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7499 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7500 (match_operand:FMOVE64 1 "const_int_operand"))]
7501 "! TARGET_POWERPC64 && reload_completed
7502 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7503 || (SUBREG_P (operands[0])
7504 && REG_P (SUBREG_REG (operands[0]))
7505 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7506 [(set (match_dup 2) (match_dup 4))
7507 (set (match_dup 3) (match_dup 1))]
7509 int endian = (WORDS_BIG_ENDIAN == 0);
7510 HOST_WIDE_INT value = INTVAL (operands[1]);
7512 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7513 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7514 operands[4] = GEN_INT (value >> 32);
7515 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7519 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7520 (match_operand:FMOVE64 1 "const_double_operand"))]
7521 "! TARGET_POWERPC64 && reload_completed
7522 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7523 || (SUBREG_P (operands[0])
7524 && REG_P (SUBREG_REG (operands[0]))
7525 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7526 [(set (match_dup 2) (match_dup 4))
7527 (set (match_dup 3) (match_dup 5))]
7529 int endian = (WORDS_BIG_ENDIAN == 0);
7532 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7534 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7535 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7536 operands[4] = gen_int_mode (l[endian], SImode);
7537 operands[5] = gen_int_mode (l[1 - endian], SImode);
7541 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7542 (match_operand:FMOVE64 1 "const_double_operand"))]
7543 "TARGET_POWERPC64 && reload_completed
7544 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7545 || (SUBREG_P (operands[0])
7546 && REG_P (SUBREG_REG (operands[0]))
7547 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7548 [(set (match_dup 2) (match_dup 3))]
7550 int endian = (WORDS_BIG_ENDIAN == 0);
7554 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7556 operands[2] = gen_lowpart (DImode, operands[0]);
7557 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7558 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7559 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7561 operands[3] = gen_int_mode (val, DImode);
7564 ;; Don't have reload use general registers to load a constant. It is
7565 ;; less efficient than loading the constant into an FP register, since
7566 ;; it will probably be used there.
7568 ;; The move constraints are ordered to prefer floating point registers before
7569 ;; general purpose registers to avoid doing a store and a load to get the value
7570 ;; into a floating point register when it is needed for a floating point
7571 ;; operation. Prefer traditional floating point registers over VSX registers,
7572 ;; since the D-form version of the memory instructions does not need a GPR for
7573 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7576 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7577 ;; except for 0.0 which can be created on VSX with an xor instruction.
7579 ;; STFD LFD FMR LXSD STXSD
7580 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7584 (define_insn "*mov<mode>_hardfloat32"
7585 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7586 "=m, d, d, <f64_p9>, wY,
7587 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7589 (match_operand:FMOVE64 1 "input_operand"
7590 "d, m, d, wY, <f64_p9>,
7591 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7593 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7594 && (gpc_reg_operand (operands[0], <MODE>mode)
7595 || gpc_reg_operand (operands[1], <MODE>mode))"
7611 "fpstore, fpload, fpsimple, fpload, fpstore,
7612 fpload, fpstore, veclogical, veclogical, two,
7614 (set_attr "size" "64")
7624 ;; STW LWZ MR G-const H-const F-const
7626 (define_insn "*mov<mode>_softfloat32"
7627 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7628 "=Y, r, r, r, r, r")
7630 (match_operand:FMOVE64 1 "input_operand"
7631 "r, Y, r, G, H, F"))]
7634 && (gpc_reg_operand (operands[0], <MODE>mode)
7635 || gpc_reg_operand (operands[1], <MODE>mode))"
7638 "store, load, two, *, *, *")
7641 "8, 8, 8, 8, 12, 16")])
7643 ; ld/std require word-aligned displacements -> 'Y' constraint.
7644 ; List Y->r and r->Y before r->r for reload.
7646 ;; STFD LFD FMR LXSD STXSD
7647 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7648 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7649 ;; NOP MFVSRD MTVSRD
7651 (define_insn "*mov<mode>_hardfloat64"
7652 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7653 "=m, d, d, <f64_p9>, wY,
7654 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7655 YZ, r, !r, *c*l, !r,
7657 (match_operand:FMOVE64 1 "input_operand"
7658 "d, m, d, wY, <f64_p9>,
7659 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7662 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7663 && (gpc_reg_operand (operands[0], <MODE>mode)
7664 || gpc_reg_operand (operands[1], <MODE>mode))"
7685 "fpstore, fpload, fpsimple, fpload, fpstore,
7686 fpload, fpstore, veclogical, veclogical, integer,
7687 store, load, *, mtjmpr, mfjmpr,
7689 (set_attr "size" "64")
7696 ;; STD LD MR MT<SPR> MF<SPR> G-const
7697 ;; H-const F-const Special
7699 (define_insn "*mov<mode>_softfloat64"
7700 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7701 "=Y, r, r, *c*l, r, r,
7704 (match_operand:FMOVE64 1 "input_operand"
7708 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7709 && (gpc_reg_operand (operands[0], <MODE>mode)
7710 || gpc_reg_operand (operands[1], <MODE>mode))"
7722 "store, load, *, mtjmpr, mfjmpr, *,
7729 (define_expand "mov<mode>"
7730 [(set (match_operand:FMOVE128 0 "general_operand")
7731 (match_operand:FMOVE128 1 "any_operand"))]
7734 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7738 ;; It's important to list Y->r and r->Y before r->r because otherwise
7739 ;; reload, given m->r, will try to pick r->r and reload it, which
7740 ;; doesn't make progress.
7742 ;; We can't split little endian direct moves of TDmode, because the words are
7743 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7744 ;; problematical. Don't allow direct move for this case.
7746 ;; FPR load FPR store FPR move FPR zero GPR load
7747 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
7749 (define_insn_and_split "*mov<mode>_64bit_dm"
7750 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7754 (match_operand:FMOVE128_FPR 1 "input_operand"
7755 "d, m, d, <zero_fp>, r,
7756 <zero_fp>, Y, r, d, r"))]
7758 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7759 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7760 && (gpc_reg_operand (operands[0], <MODE>mode)
7761 || gpc_reg_operand (operands[1], <MODE>mode))"
7763 "&& reload_completed"
7766 rs6000_split_multireg_move (operands[0], operands[1]);
7769 [(set_attr "length" "8")
7770 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7771 (set_attr "max_prefixed_insns" "2")
7772 (set_attr "num_insns" "2")])
7774 (define_insn_and_split "*movtd_64bit_nodm"
7775 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7776 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7777 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7778 && (gpc_reg_operand (operands[0], TDmode)
7779 || gpc_reg_operand (operands[1], TDmode))"
7781 "&& reload_completed"
7784 rs6000_split_multireg_move (operands[0], operands[1]);
7787 [(set_attr "length" "8,8,8,12,12,8")
7788 (set_attr "max_prefixed_insns" "2")
7789 (set_attr "num_insns" "2,2,2,3,3,2")])
7791 (define_insn_and_split "*mov<mode>_32bit"
7792 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7793 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7794 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7795 && (FLOAT128_2REG_P (<MODE>mode)
7796 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7797 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7798 && (gpc_reg_operand (operands[0], <MODE>mode)
7799 || gpc_reg_operand (operands[1], <MODE>mode))"
7801 "&& reload_completed"
7804 rs6000_split_multireg_move (operands[0], operands[1]);
7807 [(set_attr "length" "8,8,8,8,20,20,16")])
7809 (define_insn_and_split "*mov<mode>_softfloat"
7810 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7811 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7813 && (gpc_reg_operand (operands[0], <MODE>mode)
7814 || gpc_reg_operand (operands[1], <MODE>mode))"
7816 "&& reload_completed"
7819 rs6000_split_multireg_move (operands[0], operands[1]);
7822 [(set_attr_alternative "length"
7823 [(if_then_else (match_test "TARGET_POWERPC64")
7825 (const_string "16"))
7826 (if_then_else (match_test "TARGET_POWERPC64")
7828 (const_string "16"))
7829 (if_then_else (match_test "TARGET_POWERPC64")
7831 (const_string "32"))
7832 (if_then_else (match_test "TARGET_POWERPC64")
7834 (const_string "16"))])])
7836 (define_expand "@extenddf<mode>2"
7837 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7838 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7839 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7841 if (FLOAT128_IEEE_P (<MODE>mode))
7842 rs6000_expand_float128_convert (operands[0], operands[1], false);
7843 else if (TARGET_VSX)
7844 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7847 rtx zero = gen_reg_rtx (DFmode);
7848 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7850 emit_insn (gen_extenddf2_fprs (<MODE>mode,
7851 operands[0], operands[1], zero));
7856 ;; Allow memory operands for the source to be created by the combiner.
7857 (define_insn_and_split "@extenddf<mode>2_fprs"
7858 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7859 (float_extend:IBM128
7860 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7861 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7862 "!TARGET_VSX && TARGET_HARD_FLOAT
7863 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7865 "&& reload_completed"
7866 [(set (match_dup 3) (match_dup 1))
7867 (set (match_dup 4) (match_dup 2))]
7869 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7870 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7872 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7873 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7876 (define_insn_and_split "@extenddf<mode>2_vsx"
7877 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7878 (float_extend:IBM128
7879 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7880 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7882 "&& reload_completed"
7883 [(set (match_dup 2) (match_dup 1))
7884 (set (match_dup 3) (match_dup 4))]
7886 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7887 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7889 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7890 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7891 operands[4] = CONST0_RTX (DFmode);
7894 (define_expand "extendsf<mode>2"
7895 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7896 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7897 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7899 if (FLOAT128_IEEE_P (<MODE>mode))
7900 rs6000_expand_float128_convert (operands[0], operands[1], false);
7903 rtx tmp = gen_reg_rtx (DFmode);
7904 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7905 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7910 (define_expand "trunc<mode>df2"
7911 [(set (match_operand:DF 0 "gpc_reg_operand")
7912 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7913 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7915 if (FLOAT128_IEEE_P (<MODE>mode))
7917 rs6000_expand_float128_convert (operands[0], operands[1], false);
7922 (define_insn_and_split "trunc<mode>df2_internal1"
7923 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7925 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7926 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7927 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7931 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7934 emit_note (NOTE_INSN_DELETED);
7937 [(set_attr "type" "fpsimple")])
7939 (define_insn "trunc<mode>df2_internal2"
7940 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7941 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7942 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7943 && TARGET_LONG_DOUBLE_128"
7945 [(set_attr "type" "fp")])
7947 (define_expand "trunc<mode>sf2"
7948 [(set (match_operand:SF 0 "gpc_reg_operand")
7949 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7950 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7952 if (FLOAT128_IEEE_P (<MODE>mode))
7953 rs6000_expand_float128_convert (operands[0], operands[1], false);
7956 rtx tmp = gen_reg_rtx (DFmode);
7957 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7958 emit_insn (gen_truncdfsf2 (operands[0], tmp));
7963 (define_expand "floatsi<mode>2"
7964 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7965 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7966 (clobber (match_scratch:DI 2))])]
7967 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7969 rtx op0 = operands[0];
7970 rtx op1 = operands[1];
7972 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7974 else if (FLOAT128_IEEE_P (<MODE>mode))
7976 rs6000_expand_float128_convert (op0, op1, false);
7981 rtx tmp = gen_reg_rtx (DFmode);
7982 expand_float (tmp, op1, false);
7983 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
7988 ; fadd, but rounding towards zero.
7989 ; This is probably not the optimal code sequence.
7990 (define_insn "fix_trunc_helper<mode>"
7991 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7992 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7993 UNSPEC_FIX_TRUNC_TF))
7994 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7995 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7996 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7997 [(set_attr "type" "fp")
7998 (set_attr "length" "20")])
8000 (define_expand "fix_trunc<mode>si2"
8001 [(set (match_operand:SI 0 "gpc_reg_operand")
8002 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8003 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8005 rtx op0 = operands[0];
8006 rtx op1 = operands[1];
8008 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8012 if (FLOAT128_IEEE_P (<MODE>mode))
8013 rs6000_expand_float128_convert (op0, op1, false);
8015 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8020 (define_expand "@fix_trunc<mode>si2_fprs"
8021 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8022 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8023 (clobber (match_dup 2))
8024 (clobber (match_dup 3))
8025 (clobber (match_dup 4))
8026 (clobber (match_dup 5))])]
8027 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8029 operands[2] = gen_reg_rtx (DFmode);
8030 operands[3] = gen_reg_rtx (DFmode);
8031 operands[4] = gen_reg_rtx (DImode);
8032 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8035 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8036 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8037 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8038 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8039 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8040 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8041 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8042 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8048 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8051 gcc_assert (MEM_P (operands[5]));
8052 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8054 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8055 emit_move_insn (operands[5], operands[4]);
8056 emit_move_insn (operands[0], lowword);
8060 (define_expand "fix_trunc<mode>di2"
8061 [(set (match_operand:DI 0 "gpc_reg_operand")
8062 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8063 "TARGET_FLOAT128_TYPE"
8065 if (!TARGET_FLOAT128_HW)
8067 rs6000_expand_float128_convert (operands[0], operands[1], false);
8072 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8073 [(set (match_operand:SDI 0 "gpc_reg_operand")
8074 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8075 "TARGET_FLOAT128_TYPE"
8077 rs6000_expand_float128_convert (operands[0], operands[1], true);
8081 (define_expand "floatdi<mode>2"
8082 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8083 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8084 "TARGET_FLOAT128_TYPE"
8086 if (!TARGET_FLOAT128_HW)
8088 rs6000_expand_float128_convert (operands[0], operands[1], false);
8093 (define_expand "floatunsdi<IEEE128:mode>2"
8094 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8095 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8096 "TARGET_FLOAT128_TYPE"
8098 if (!TARGET_FLOAT128_HW)
8100 rs6000_expand_float128_convert (operands[0], operands[1], true);
8105 (define_expand "floatuns<IEEE128:mode>2"
8106 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8107 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8108 "TARGET_FLOAT128_TYPE"
8110 rtx op0 = operands[0];
8111 rtx op1 = operands[1];
8113 if (TARGET_FLOAT128_HW)
8114 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8116 rs6000_expand_float128_convert (op0, op1, true);
8120 (define_expand "neg<mode>2"
8121 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8122 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8123 "FLOAT128_IEEE_P (<MODE>mode)
8124 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8126 if (FLOAT128_IEEE_P (<MODE>mode))
8128 if (TARGET_FLOAT128_HW)
8129 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8130 else if (TARGET_FLOAT128_TYPE)
8131 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8132 operands[0], operands[1]));
8135 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8136 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8138 operands[1], <MODE>mode);
8140 if (target && !rtx_equal_p (target, operands[0]))
8141 emit_move_insn (operands[0], target);
8147 (define_insn "neg<mode>2_internal"
8148 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8149 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8150 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8152 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8153 return "fneg %L0,%L1\;fneg %0,%1";
8155 return "fneg %0,%1\;fneg %L0,%L1";
8157 [(set_attr "type" "fpsimple")
8158 (set_attr "length" "8")])
8160 (define_expand "abs<mode>2"
8161 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8162 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8163 "FLOAT128_IEEE_P (<MODE>mode)
8164 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8168 if (FLOAT128_IEEE_P (<MODE>mode))
8170 if (TARGET_FLOAT128_HW)
8172 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8175 else if (TARGET_FLOAT128_TYPE)
8177 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8178 operands[0], operands[1]));
8185 label = gen_label_rtx ();
8186 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8191 (define_expand "@abs<mode>2_internal"
8192 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8193 (match_operand:IBM128 1 "gpc_reg_operand"))
8194 (set (match_dup 3) (match_dup 5))
8195 (set (match_dup 5) (abs:DF (match_dup 5)))
8196 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8197 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8198 (label_ref (match_operand 2 ""))
8200 (set (match_dup 6) (neg:DF (match_dup 6)))]
8201 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8203 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8204 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8205 operands[3] = gen_reg_rtx (DFmode);
8206 operands[4] = gen_reg_rtx (CCFPmode);
8207 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8208 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8212 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8215 (define_expand "ieee_128bit_negative_zero"
8216 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8217 "TARGET_FLOAT128_TYPE"
8219 rtvec v = rtvec_alloc (16);
8222 for (i = 0; i < 16; i++)
8223 RTVEC_ELT (v, i) = const0_rtx;
8225 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8226 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8228 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8232 ;; IEEE 128-bit negate
8234 ;; We have 2 insns here for negate and absolute value. The first uses
8235 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8236 ;; insns, and second insn after the first split pass loads up the bit to
8237 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8238 ;; neg/abs to create the constant just once.
8240 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8241 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8242 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8243 (clobber (match_scratch:V16QI 2 "=v"))]
8244 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8247 [(parallel [(set (match_dup 0)
8248 (neg:IEEE128 (match_dup 1)))
8249 (use (match_dup 2))])]
8251 if (GET_CODE (operands[2]) == SCRATCH)
8252 operands[2] = gen_reg_rtx (V16QImode);
8254 operands[3] = gen_reg_rtx (V16QImode);
8255 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8257 [(set_attr "length" "8")
8258 (set_attr "type" "vecsimple")])
8260 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8261 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8262 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8263 (use (match_operand:V16QI 2 "register_operand" "v"))]
8264 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8265 "xxlxor %x0,%x1,%x2"
8266 [(set_attr "type" "veclogical")])
8268 ;; IEEE 128-bit absolute value
8269 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8270 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8271 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8272 (clobber (match_scratch:V16QI 2 "=v"))]
8273 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8276 [(parallel [(set (match_dup 0)
8277 (abs:IEEE128 (match_dup 1)))
8278 (use (match_dup 2))])]
8280 if (GET_CODE (operands[2]) == SCRATCH)
8281 operands[2] = gen_reg_rtx (V16QImode);
8283 operands[3] = gen_reg_rtx (V16QImode);
8284 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8286 [(set_attr "length" "8")
8287 (set_attr "type" "vecsimple")])
8289 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8290 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8291 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8292 (use (match_operand:V16QI 2 "register_operand" "v"))]
8293 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8294 "xxlandc %x0,%x1,%x2"
8295 [(set_attr "type" "veclogical")])
8297 ;; IEEE 128-bit negative absolute value
8298 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8299 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8302 (match_operand:IEEE128 1 "register_operand" "wa"))))
8303 (clobber (match_scratch:V16QI 2 "=v"))]
8304 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8305 && FLOAT128_IEEE_P (<MODE>mode)"
8308 [(parallel [(set (match_dup 0)
8309 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8310 (use (match_dup 2))])]
8312 if (GET_CODE (operands[2]) == SCRATCH)
8313 operands[2] = gen_reg_rtx (V16QImode);
8315 operands[3] = gen_reg_rtx (V16QImode);
8316 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8318 [(set_attr "length" "8")
8319 (set_attr "type" "vecsimple")])
8321 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8322 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8325 (match_operand:IEEE128 1 "register_operand" "wa"))))
8326 (use (match_operand:V16QI 2 "register_operand" "v"))]
8327 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8329 [(set_attr "type" "veclogical")])
8331 ;; Float128 conversion functions. These expand to library function calls.
8332 ;; We use expand to convert from IBM double double to IEEE 128-bit
8333 ;; and trunc for the opposite.
8334 (define_expand "extendiftf2"
8335 [(set (match_operand:TF 0 "gpc_reg_operand")
8336 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8337 "TARGET_FLOAT128_TYPE"
8339 rs6000_expand_float128_convert (operands[0], operands[1], false);
8343 (define_expand "extendifkf2"
8344 [(set (match_operand:KF 0 "gpc_reg_operand")
8345 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8346 "TARGET_FLOAT128_TYPE"
8348 rs6000_expand_float128_convert (operands[0], operands[1], false);
8352 (define_expand "extendtfkf2"
8353 [(set (match_operand:KF 0 "gpc_reg_operand")
8354 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8355 "TARGET_FLOAT128_TYPE"
8357 rs6000_expand_float128_convert (operands[0], operands[1], false);
8361 (define_expand "extendtfif2"
8362 [(set (match_operand:IF 0 "gpc_reg_operand")
8363 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8364 "TARGET_FLOAT128_TYPE"
8366 rs6000_expand_float128_convert (operands[0], operands[1], false);
8370 (define_expand "trunciftf2"
8371 [(set (match_operand:TF 0 "gpc_reg_operand")
8372 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8373 "TARGET_FLOAT128_TYPE"
8375 rs6000_expand_float128_convert (operands[0], operands[1], false);
8379 (define_expand "truncifkf2"
8380 [(set (match_operand:KF 0 "gpc_reg_operand")
8381 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8382 "TARGET_FLOAT128_TYPE"
8384 rs6000_expand_float128_convert (operands[0], operands[1], false);
8388 (define_expand "trunckftf2"
8389 [(set (match_operand:TF 0 "gpc_reg_operand")
8390 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8391 "TARGET_FLOAT128_TYPE"
8393 rs6000_expand_float128_convert (operands[0], operands[1], false);
8397 (define_expand "trunctfif2"
8398 [(set (match_operand:IF 0 "gpc_reg_operand")
8399 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8400 "TARGET_FLOAT128_TYPE"
8402 rs6000_expand_float128_convert (operands[0], operands[1], false);
8406 (define_insn_and_split "*extend<mode>tf2_internal"
8407 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8409 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8410 "TARGET_FLOAT128_TYPE
8411 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8413 "&& reload_completed"
8414 [(set (match_dup 0) (match_dup 2))]
8416 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8419 (define_insn_and_split "*extendtf<mode>2_internal"
8420 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8422 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8423 "TARGET_FLOAT128_TYPE
8424 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8426 "&& reload_completed"
8427 [(set (match_dup 0) (match_dup 2))]
8429 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8433 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8434 ;; must have 3 arguments, and scratch register constraint must be a single
8437 ;; Reload patterns to support gpr load/store with misaligned mem.
8438 ;; and multiple gpr load/store at offset >= 0xfffc
8439 (define_expand "reload_<mode>_store"
8440 [(parallel [(match_operand 0 "memory_operand" "=m")
8441 (match_operand 1 "gpc_reg_operand" "r")
8442 (match_operand:GPR 2 "register_operand" "=&b")])]
8445 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8449 (define_expand "reload_<mode>_load"
8450 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8451 (match_operand 1 "memory_operand" "m")
8452 (match_operand:GPR 2 "register_operand" "=b")])]
8455 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8460 ;; Reload patterns for various types using the vector registers. We may need
8461 ;; an additional base register to convert the reg+offset addressing to reg+reg
8462 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8463 ;; index register for gpr registers.
8464 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8465 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8466 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8467 (match_operand:P 2 "register_operand" "=b")])]
8470 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8474 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8475 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8476 (match_operand:RELOAD 1 "memory_operand" "m")
8477 (match_operand:P 2 "register_operand" "=b")])]
8480 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8485 ;; Reload sometimes tries to move the address to a GPR, and can generate
8486 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8487 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8489 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8490 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8491 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8492 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8494 "TARGET_ALTIVEC && reload_completed"
8496 "&& reload_completed"
8498 (plus:P (match_dup 1)
8501 (and:P (match_dup 0)
8504 ;; Power8 merge instructions to allow direct move to/from floating point
8505 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8506 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8507 ;; value, since it is allocated in reload and not all of the flow information
8508 ;; is setup for it. We have two patterns to do the two moves between gprs and
8509 ;; fprs. There isn't a dependancy between the two, but we could potentially
8510 ;; schedule other instructions between the two instructions.
8512 (define_insn "p8_fmrgow_<mode>"
8513 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8515 (match_operand:DF 1 "register_operand" "d")
8516 (match_operand:DF 2 "register_operand" "d")]
8517 UNSPEC_P8V_FMRGOW))]
8518 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8520 [(set_attr "type" "fpsimple")])
8522 (define_insn "p8_mtvsrwz"
8523 [(set (match_operand:DF 0 "register_operand" "=d")
8524 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8525 UNSPEC_P8V_MTVSRWZ))]
8526 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8528 [(set_attr "type" "mftgpr")])
8530 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8531 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8532 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8533 UNSPEC_P8V_RELOAD_FROM_GPR))
8534 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8535 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8537 "&& reload_completed"
8540 rtx dest = operands[0];
8541 rtx src = operands[1];
8542 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8543 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8544 rtx gpr_hi_reg = gen_highpart (SImode, src);
8545 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8547 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8548 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8549 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8552 [(set_attr "length" "12")
8553 (set_attr "type" "three")])
8555 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8556 (define_insn "p8_mtvsrd_df"
8557 [(set (match_operand:DF 0 "register_operand" "=wa")
8558 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8559 UNSPEC_P8V_MTVSRD))]
8560 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8562 [(set_attr "type" "mftgpr")])
8564 (define_insn "p8_xxpermdi_<mode>"
8565 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8566 (unspec:FMOVE128_GPR [
8567 (match_operand:DF 1 "register_operand" "wa")
8568 (match_operand:DF 2 "register_operand" "wa")]
8569 UNSPEC_P8V_XXPERMDI))]
8570 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8571 "xxpermdi %x0,%x1,%x2,0"
8572 [(set_attr "type" "vecperm")])
8574 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8575 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8576 (unspec:FMOVE128_GPR
8577 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8578 UNSPEC_P8V_RELOAD_FROM_GPR))
8579 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8580 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8582 "&& reload_completed"
8585 rtx dest = operands[0];
8586 rtx src = operands[1];
8587 /* You might think that we could use op0 as one temp and a DF clobber
8588 as op2, but you'd be wrong. Secondary reload move patterns don't
8589 check for overlap of the clobber and the destination. */
8590 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8591 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8592 rtx gpr_hi_reg = gen_highpart (DImode, src);
8593 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8595 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8596 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8597 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8600 [(set_attr "length" "12")
8601 (set_attr "type" "three")])
8604 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8605 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8607 && (int_reg_operand (operands[0], <MODE>mode)
8608 || int_reg_operand (operands[1], <MODE>mode))
8609 && (!TARGET_DIRECT_MOVE_128
8610 || (!vsx_register_operand (operands[0], <MODE>mode)
8611 && !vsx_register_operand (operands[1], <MODE>mode)))"
8614 rs6000_split_multireg_move (operands[0], operands[1]);
8618 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8619 ;; type is stored internally as double precision in the VSX registers, we have
8620 ;; to convert it from the vector format.
8621 (define_insn "p8_mtvsrd_sf"
8622 [(set (match_operand:SF 0 "register_operand" "=wa")
8623 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8624 UNSPEC_P8V_MTVSRD))]
8625 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8627 [(set_attr "type" "mftgpr")])
8629 (define_insn_and_split "reload_vsx_from_gprsf"
8630 [(set (match_operand:SF 0 "register_operand" "=wa")
8631 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8632 UNSPEC_P8V_RELOAD_FROM_GPR))
8633 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8634 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8636 "&& reload_completed"
8639 rtx op0 = operands[0];
8640 rtx op1 = operands[1];
8641 rtx op2 = operands[2];
8642 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8644 /* Move SF value to upper 32-bits for xscvspdpn. */
8645 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8646 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8647 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8650 [(set_attr "length" "8")
8651 (set_attr "type" "two")])
8653 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8654 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8655 ;; and then doing a move of that.
8656 (define_insn "p8_mfvsrd_3_<mode>"
8657 [(set (match_operand:DF 0 "register_operand" "=r")
8658 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8659 UNSPEC_P8V_RELOAD_FROM_VSX))]
8660 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8662 [(set_attr "type" "mftgpr")])
8664 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8665 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8666 (unspec:FMOVE128_GPR
8667 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8668 UNSPEC_P8V_RELOAD_FROM_VSX))
8669 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8670 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8672 "&& reload_completed"
8675 rtx dest = operands[0];
8676 rtx src = operands[1];
8677 rtx tmp = operands[2];
8678 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8679 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8681 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8682 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8683 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8686 [(set_attr "length" "12")
8687 (set_attr "type" "three")])
8689 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8690 ;; type is stored internally as double precision, we have to convert it to the
8693 (define_insn_and_split "reload_gpr_from_vsxsf"
8694 [(set (match_operand:SF 0 "register_operand" "=r")
8695 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8696 UNSPEC_P8V_RELOAD_FROM_VSX))
8697 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8698 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8700 "&& reload_completed"
8703 rtx op0 = operands[0];
8704 rtx op1 = operands[1];
8705 rtx op2 = operands[2];
8706 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8707 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8709 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8710 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8713 [(set_attr "length" "8")
8714 (set_attr "type" "two")
8715 (set_attr "isa" "p8v")])
8717 ;; Next come the multi-word integer load and store and the load and store
8720 ;; List r->r after r->Y, otherwise reload will try to reload a
8721 ;; non-offsettable address by using r->r which won't make progress.
8722 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8723 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8725 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8726 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8727 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8730 (define_insn "*movdi_internal32"
8731 [(set (match_operand:DI 0 "nonimmediate_operand"
8732 "=Y, r, r, m, ^d, ^d,
8733 r, wY, Z, ^v, $v, ^wa,
8734 wa, wa, v, wa, *i, v,
8736 (match_operand:DI 1 "input_operand"
8737 "r, Y, r, ^d, m, ^d,
8738 IJKnF, ^v, $v, wY, Z, ^wa,
8739 Oj, wM, OjwM, Oj, wM, wS,
8742 && (gpc_reg_operand (operands[0], DImode)
8743 || gpc_reg_operand (operands[1], DImode))"
8765 "store, load, *, fpstore, fpload, fpsimple,
8766 *, fpstore, fpstore, fpload, fpload, veclogical,
8767 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8769 (set_attr "size" "64")
8777 *, p9v, p7v, p9v, p7v, *,
8778 p9v, p9v, p7v, *, *, p7v,
8782 [(set (match_operand:DI 0 "gpc_reg_operand")
8783 (match_operand:DI 1 "const_int_operand"))]
8784 "! TARGET_POWERPC64 && reload_completed
8785 && gpr_or_gpr_p (operands[0], operands[1])
8786 && !direct_move_p (operands[0], operands[1])"
8787 [(set (match_dup 2) (match_dup 4))
8788 (set (match_dup 3) (match_dup 1))]
8790 HOST_WIDE_INT value = INTVAL (operands[1]);
8791 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8793 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8795 operands[4] = GEN_INT (value >> 32);
8796 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8800 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8801 (match_operand:DIFD 1 "input_operand"))]
8802 "reload_completed && !TARGET_POWERPC64
8803 && gpr_or_gpr_p (operands[0], operands[1])
8804 && !direct_move_p (operands[0], operands[1])"
8807 rs6000_split_multireg_move (operands[0], operands[1]);
8811 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8812 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8813 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8814 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8815 ;; VSX->GPR GPR->VSX
8816 (define_insn "*movdi_internal64"
8817 [(set (match_operand:DI 0 "nonimmediate_operand"
8818 "=YZ, r, r, r, r, r,
8819 m, ^d, ^d, wY, Z, $v,
8820 $v, ^wa, wa, wa, v, wa,
8821 wa, v, v, r, *h, *h,
8823 (match_operand:DI 1 "input_operand"
8824 "r, YZ, r, I, L, nF,
8825 ^d, m, ^d, ^v, $v, wY,
8826 Z, ^wa, Oj, wM, OjwM, Oj,
8827 wM, wS, wB, *h, r, 0,
8830 && (gpc_reg_operand (operands[0], DImode)
8831 || gpc_reg_operand (operands[1], DImode))"
8860 "store, load, *, *, *, *,
8861 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8862 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8863 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8865 (set_attr "size" "64")
8874 *, *, *, p9v, p7v, p9v,
8875 p7v, *, p9v, p9v, p7v, *,
8876 *, p7v, p7v, *, *, *,
8879 ; Some DImode loads are best done as a load of -1 followed by a mask
8882 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8883 (match_operand:DI 1 "const_int_operand"))]
8885 && num_insns_constant (operands[1], DImode) > 1
8886 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8887 && rs6000_is_valid_and_mask (operands[1], DImode)"
8891 (and:DI (match_dup 0)
8895 ;; Split a load of a large constant into the appropriate five-instruction
8896 ;; sequence. Handle anything in a constant number of insns.
8897 ;; When non-easy constants can go in the TOC, this should use
8898 ;; easy_fp_constant predicate.
8900 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8901 (match_operand:DI 1 "const_int_operand"))]
8902 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8903 [(set (match_dup 0) (match_dup 2))
8904 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8906 if (rs6000_emit_set_const (operands[0], operands[1]))
8913 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8914 (match_operand:DI 1 "const_scalar_int_operand"))]
8915 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8916 [(set (match_dup 0) (match_dup 2))
8917 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8919 if (rs6000_emit_set_const (operands[0], operands[1]))
8926 [(set (match_operand:DI 0 "altivec_register_operand")
8927 (match_operand:DI 1 "s5bit_cint_operand"))]
8928 "TARGET_VSX && reload_completed"
8931 rtx op0 = operands[0];
8932 rtx op1 = operands[1];
8933 int r = REGNO (op0);
8934 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8936 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8937 if (op1 != const0_rtx && op1 != constm1_rtx)
8939 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8940 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8945 ;; Split integer constants that can be loaded with XXSPLTIB and a
8946 ;; sign extend operation.
8948 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8949 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8950 "TARGET_P9_VECTOR && reload_completed"
8953 rtx op0 = operands[0];
8954 rtx op1 = operands[1];
8955 int r = REGNO (op0);
8956 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8958 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8959 if (<MODE>mode == DImode)
8960 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8961 else if (<MODE>mode == SImode)
8962 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8963 else if (<MODE>mode == HImode)
8965 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8966 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8972 ;; TImode/PTImode is similar, except that we usually want to compute the
8973 ;; address into a register and use lsi/stsi (the exception is during reload).
8975 (define_insn "*mov<mode>_string"
8976 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8977 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8979 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8980 && (gpc_reg_operand (operands[0], <MODE>mode)
8981 || gpc_reg_operand (operands[1], <MODE>mode))"
8983 [(set_attr "type" "store,store,load,load,*,*")
8984 (set_attr "update" "yes")
8985 (set_attr "indexed" "yes")
8986 (set_attr "cell_micro" "conditional")])
8988 (define_insn "*mov<mode>_ppc64"
8989 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8990 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8991 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8992 && (gpc_reg_operand (operands[0], <MODE>mode)
8993 || gpc_reg_operand (operands[1], <MODE>mode)))"
8995 return rs6000_output_move_128bit (operands);
8997 [(set_attr "type" "store,store,load,load,*,*")
8998 (set_attr "length" "8")
8999 (set_attr "max_prefixed_insns" "2")])
9002 [(set (match_operand:TI2 0 "int_reg_operand")
9003 (match_operand:TI2 1 "const_scalar_int_operand"))]
9005 && (VECTOR_MEM_NONE_P (<MODE>mode)
9006 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9007 [(set (match_dup 2) (match_dup 4))
9008 (set (match_dup 3) (match_dup 5))]
9010 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9012 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9014 if (CONST_WIDE_INT_P (operands[1]))
9016 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9017 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9019 else if (CONST_INT_P (operands[1]))
9021 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9022 operands[5] = operands[1];
9029 [(set (match_operand:TI2 0 "nonimmediate_operand")
9030 (match_operand:TI2 1 "input_operand"))]
9032 && gpr_or_gpr_p (operands[0], operands[1])
9033 && !direct_move_p (operands[0], operands[1])
9034 && !quad_load_store_p (operands[0], operands[1])"
9037 rs6000_split_multireg_move (operands[0], operands[1]);
9041 (define_expand "setmemsi"
9042 [(parallel [(set (match_operand:BLK 0 "")
9043 (match_operand 2 "const_int_operand"))
9044 (use (match_operand:SI 1 ""))
9045 (use (match_operand:SI 3 ""))])]
9048 /* If value to set is not zero, use the library routine. */
9049 if (operands[2] != const0_rtx)
9052 if (expand_block_clear (operands))
9058 ;; String compare N insn.
9059 ;; Argument 0 is the target (result)
9060 ;; Argument 1 is the destination
9061 ;; Argument 2 is the source
9062 ;; Argument 3 is the length
9063 ;; Argument 4 is the alignment
9065 (define_expand "cmpstrnsi"
9066 [(parallel [(set (match_operand:SI 0)
9067 (compare:SI (match_operand:BLK 1)
9068 (match_operand:BLK 2)))
9069 (use (match_operand:SI 3))
9070 (use (match_operand:SI 4))])]
9071 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9073 if (optimize_insn_for_size_p ())
9076 if (expand_strn_compare (operands, 0))
9082 ;; String compare insn.
9083 ;; Argument 0 is the target (result)
9084 ;; Argument 1 is the destination
9085 ;; Argument 2 is the source
9086 ;; Argument 3 is the alignment
9088 (define_expand "cmpstrsi"
9089 [(parallel [(set (match_operand:SI 0)
9090 (compare:SI (match_operand:BLK 1)
9091 (match_operand:BLK 2)))
9092 (use (match_operand:SI 3))])]
9093 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9095 if (optimize_insn_for_size_p ())
9098 if (expand_strn_compare (operands, 1))
9104 ;; Block compare insn.
9105 ;; Argument 0 is the target (result)
9106 ;; Argument 1 is the destination
9107 ;; Argument 2 is the source
9108 ;; Argument 3 is the length
9109 ;; Argument 4 is the alignment
9111 (define_expand "cmpmemsi"
9112 [(parallel [(set (match_operand:SI 0)
9113 (compare:SI (match_operand:BLK 1)
9114 (match_operand:BLK 2)))
9115 (use (match_operand:SI 3))
9116 (use (match_operand:SI 4))])]
9119 if (expand_block_compare (operands))
9125 ;; String/block copy insn (source and destination must not overlap).
9126 ;; Argument 0 is the destination
9127 ;; Argument 1 is the source
9128 ;; Argument 2 is the length
9129 ;; Argument 3 is the alignment
9131 (define_expand "cpymemsi"
9132 [(parallel [(set (match_operand:BLK 0 "")
9133 (match_operand:BLK 1 ""))
9134 (use (match_operand:SI 2 ""))
9135 (use (match_operand:SI 3 ""))])]
9138 if (expand_block_move (operands, false))
9144 ;; String/block move insn (source and destination may overlap).
9145 ;; Argument 0 is the destination
9146 ;; Argument 1 is the source
9147 ;; Argument 2 is the length
9148 ;; Argument 3 is the alignment
9150 (define_expand "movmemsi"
9151 [(parallel [(set (match_operand:BLK 0 "")
9152 (match_operand:BLK 1 ""))
9153 (use (match_operand:SI 2 ""))
9154 (use (match_operand:SI 3 ""))])]
9157 if (expand_block_move (operands, true))
9164 ;; Define insns that do load or store with update. Some of these we can
9165 ;; get by using pre-decrement or pre-increment, but the hardware can also
9166 ;; do cases where the increment is not the size of the object.
9168 ;; In all these cases, we use operands 0 and 1 for the register being
9169 ;; incremented because those are the operands that local-alloc will
9170 ;; tie and these are the pair most likely to be tieable (and the ones
9171 ;; that will benefit the most).
9173 (define_insn "*movdi_update1"
9174 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9175 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9176 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9177 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9178 (plus:P (match_dup 1) (match_dup 2)))]
9179 "TARGET_POWERPC64 && TARGET_UPDATE
9180 && (!avoiding_indexed_address_p (DImode)
9181 || !gpc_reg_operand (operands[2], Pmode))"
9185 [(set_attr "type" "load")
9186 (set_attr "update" "yes")
9187 (set_attr "indexed" "yes,no")])
9189 (define_insn "movdi_<mode>_update"
9190 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9191 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9192 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9193 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9194 (plus:P (match_dup 1) (match_dup 2)))]
9195 "TARGET_POWERPC64 && TARGET_UPDATE
9196 && (!avoiding_indexed_address_p (DImode)
9197 || !gpc_reg_operand (operands[2], Pmode)
9198 || (REG_P (operands[0])
9199 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9203 [(set_attr "type" "store")
9204 (set_attr "update" "yes")
9205 (set_attr "indexed" "yes,no")])
9207 ;; This pattern is only conditional on TARGET_64BIT, as it is
9208 ;; needed for stack allocation, even if the user passes -mno-update.
9209 (define_insn "movdi_update_stack"
9210 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9211 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9212 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9213 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9214 (plus:DI (match_dup 1) (match_dup 2)))]
9219 [(set_attr "type" "store")
9220 (set_attr "update" "yes")
9221 (set_attr "indexed" "yes,no")])
9223 (define_insn "*movsi_update1"
9224 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9225 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9226 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9227 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9228 (plus:P (match_dup 1) (match_dup 2)))]
9230 && (!avoiding_indexed_address_p (SImode)
9231 || !gpc_reg_operand (operands[2], Pmode))"
9235 [(set_attr "type" "load")
9236 (set_attr "update" "yes")
9237 (set_attr "indexed" "yes,no")])
9239 (define_insn "*movsi_update2"
9240 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9242 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9243 (match_operand:P 2 "gpc_reg_operand" "r")))))
9244 (set (match_operand:P 0 "gpc_reg_operand" "=b")
9245 (plus:P (match_dup 1) (match_dup 2)))]
9246 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9248 [(set_attr "type" "load")
9249 (set_attr "sign_extend" "yes")
9250 (set_attr "update" "yes")
9251 (set_attr "indexed" "yes")])
9253 (define_insn "movsi_<mode>_update"
9254 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9255 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9256 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9257 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9258 (plus:P (match_dup 1) (match_dup 2)))]
9260 && (!avoiding_indexed_address_p (SImode)
9261 || !gpc_reg_operand (operands[2], Pmode)
9262 || (REG_P (operands[0])
9263 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9267 [(set_attr "type" "store")
9268 (set_attr "update" "yes")
9269 (set_attr "indexed" "yes,no")])
9271 ;; This is an unconditional pattern; needed for stack allocation, even
9272 ;; if the user passes -mno-update.
9273 (define_insn "movsi_update_stack"
9274 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9275 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9276 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9277 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9278 (plus:SI (match_dup 1) (match_dup 2)))]
9283 [(set_attr "type" "store")
9284 (set_attr "update" "yes")
9285 (set_attr "indexed" "yes,no")])
9287 (define_insn "*movhi_update1"
9288 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9289 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9290 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9291 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9292 (plus:P (match_dup 1) (match_dup 2)))]
9294 && (!avoiding_indexed_address_p (HImode)
9295 || !gpc_reg_operand (operands[2], SImode))"
9299 [(set_attr "type" "load")
9300 (set_attr "update" "yes")
9301 (set_attr "indexed" "yes,no")])
9303 (define_insn "*movhi_update2"
9304 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9306 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9307 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9308 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9309 (plus:P (match_dup 1) (match_dup 2)))]
9311 && (!avoiding_indexed_address_p (HImode)
9312 || !gpc_reg_operand (operands[2], Pmode))"
9316 [(set_attr "type" "load")
9317 (set_attr "update" "yes")
9318 (set_attr "indexed" "yes,no")])
9320 (define_insn "*movhi_update3"
9321 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9323 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9324 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9325 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9326 (plus:P (match_dup 1) (match_dup 2)))]
9328 && !(avoiding_indexed_address_p (HImode)
9329 && gpc_reg_operand (operands[2], Pmode))"
9333 [(set_attr "type" "load")
9334 (set_attr "sign_extend" "yes")
9335 (set_attr "update" "yes")
9336 (set_attr "indexed" "yes,no")])
9338 (define_insn "*movhi_update4"
9339 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9340 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9341 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9342 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9343 (plus:P (match_dup 1) (match_dup 2)))]
9345 && (!avoiding_indexed_address_p (HImode)
9346 || !gpc_reg_operand (operands[2], Pmode))"
9350 [(set_attr "type" "store")
9351 (set_attr "update" "yes")
9352 (set_attr "indexed" "yes,no")])
9354 (define_insn "*movqi_update1"
9355 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9356 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9357 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9358 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9359 (plus:P (match_dup 1) (match_dup 2)))]
9361 && (!avoiding_indexed_address_p (QImode)
9362 || !gpc_reg_operand (operands[2], Pmode))"
9366 [(set_attr "type" "load")
9367 (set_attr "update" "yes")
9368 (set_attr "indexed" "yes,no")])
9370 (define_insn "*movqi_update2"
9371 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9373 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9374 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9375 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9376 (plus:P (match_dup 1) (match_dup 2)))]
9378 && (!avoiding_indexed_address_p (QImode)
9379 || !gpc_reg_operand (operands[2], Pmode))"
9383 [(set_attr "type" "load")
9384 (set_attr "update" "yes")
9385 (set_attr "indexed" "yes,no")])
9387 (define_insn "*movqi_update3"
9388 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9389 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9390 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9391 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9392 (plus:P (match_dup 1) (match_dup 2)))]
9394 && (!avoiding_indexed_address_p (QImode)
9395 || !gpc_reg_operand (operands[2], Pmode))"
9399 [(set_attr "type" "store")
9400 (set_attr "update" "yes")
9401 (set_attr "indexed" "yes,no")])
9403 (define_insn "*mov<SFDF:mode>_update1"
9404 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9405 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9406 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9407 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9408 (plus:P (match_dup 1) (match_dup 2)))]
9409 "TARGET_HARD_FLOAT && TARGET_UPDATE
9410 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9411 || !gpc_reg_operand (operands[2], Pmode))"
9415 [(set_attr "type" "fpload")
9416 (set_attr "update" "yes")
9417 (set_attr "indexed" "yes,no")
9418 (set_attr "size" "<SFDF:bits>")])
9420 (define_insn "*mov<SFDF:mode>_update2"
9421 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9422 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9423 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9424 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9425 (plus:P (match_dup 1) (match_dup 2)))]
9426 "TARGET_HARD_FLOAT && TARGET_UPDATE
9427 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9428 || !gpc_reg_operand (operands[2], Pmode))"
9432 [(set_attr "type" "fpstore")
9433 (set_attr "update" "yes")
9434 (set_attr "indexed" "yes,no")
9435 (set_attr "size" "<SFDF:bits>")])
9437 (define_insn "*movsf_update3"
9438 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9439 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9440 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9441 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9442 (plus:P (match_dup 1) (match_dup 2)))]
9443 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9444 && (!avoiding_indexed_address_p (SFmode)
9445 || !gpc_reg_operand (operands[2], Pmode))"
9449 [(set_attr "type" "load")
9450 (set_attr "update" "yes")
9451 (set_attr "indexed" "yes,no")])
9453 (define_insn "*movsf_update4"
9454 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9455 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9456 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9457 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9458 (plus:P (match_dup 1) (match_dup 2)))]
9459 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9460 && (!avoiding_indexed_address_p (SFmode)
9461 || !gpc_reg_operand (operands[2], Pmode))"
9465 [(set_attr "type" "store")
9466 (set_attr "update" "yes")
9467 (set_attr "indexed" "yes,no")])
9470 ;; After inserting conditional returns we can sometimes have
9471 ;; unnecessary register moves. Unfortunately we cannot have a
9472 ;; modeless peephole here, because some single SImode sets have early
9473 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9474 ;; sequences, using get_attr_length here will smash the operands
9475 ;; array. Neither is there an early_cobbler_p predicate.
9476 ;; Also this optimization interferes with scalars going into
9477 ;; altivec registers (the code does reloading through the FPRs).
9479 [(set (match_operand:DF 0 "gpc_reg_operand")
9480 (match_operand:DF 1 "any_operand"))
9481 (set (match_operand:DF 2 "gpc_reg_operand")
9484 && peep2_reg_dead_p (2, operands[0])"
9485 [(set (match_dup 2) (match_dup 1))])
9488 [(set (match_operand:SF 0 "gpc_reg_operand")
9489 (match_operand:SF 1 "any_operand"))
9490 (set (match_operand:SF 2 "gpc_reg_operand")
9493 && peep2_reg_dead_p (2, operands[0])"
9494 [(set (match_dup 2) (match_dup 1))])
9499 (define_insn "*tls_gd_pcrel<bits>"
9500 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9501 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9504 "HAVE_AS_TLS && TARGET_ELF"
9505 "la %0,%1@got@tlsgd@pcrel"
9506 [(set_attr "prefixed" "yes")])
9508 (define_insn_and_split "*tls_gd<bits>"
9509 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9510 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9511 (match_operand:P 2 "gpc_reg_operand" "b")]
9513 "HAVE_AS_TLS && TARGET_ELF"
9514 "addi %0,%2,%1@got@tlsgd"
9515 "&& TARGET_CMODEL != CMODEL_SMALL"
9518 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9520 (lo_sum:P (match_dup 3)
9521 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9523 operands[3] = gen_reg_rtx (<MODE>mode);
9525 [(set (attr "length")
9526 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9530 (define_insn "*tls_gd_high<bits>"
9531 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9533 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9534 (match_operand:P 2 "gpc_reg_operand" "b")]
9536 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9537 "addis %0,%2,%1@got@tlsgd@ha")
9539 (define_insn "*tls_gd_low<bits>"
9540 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9541 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9542 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9543 (match_operand:P 3 "gpc_reg_operand" "b")]
9545 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9546 "addi %0,%1,%2@got@tlsgd@l")
9548 (define_insn "*tls_ld_pcrel<bits>"
9549 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9550 (unspec:P [(const_int 0)]
9552 "HAVE_AS_TLS && TARGET_ELF"
9553 "la %0,%&@got@tlsld@pcrel"
9554 [(set_attr "prefixed" "yes")])
9556 (define_insn_and_split "*tls_ld<bits>"
9557 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9558 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9560 "HAVE_AS_TLS && TARGET_ELF"
9561 "addi %0,%1,%&@got@tlsld"
9562 "&& TARGET_CMODEL != CMODEL_SMALL"
9565 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9567 (lo_sum:P (match_dup 2)
9568 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9570 operands[2] = gen_reg_rtx (<MODE>mode);
9572 [(set (attr "length")
9573 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9577 (define_insn "*tls_ld_high<bits>"
9578 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9580 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9582 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9583 "addis %0,%1,%&@got@tlsld@ha")
9585 (define_insn "*tls_ld_low<bits>"
9586 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9587 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9588 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9590 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9591 "addi %0,%1,%&@got@tlsld@l")
9593 (define_insn "tls_dtprel_<bits>"
9594 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9595 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9596 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9599 "addi %0,%1,%2@dtprel"
9600 [(set (attr "prefixed")
9601 (if_then_else (match_test "rs6000_tls_size == 16")
9603 (const_string "yes")))])
9605 (define_insn "tls_dtprel_ha_<bits>"
9606 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9607 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9608 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9609 UNSPEC_TLSDTPRELHA))]
9611 "addis %0,%1,%2@dtprel@ha")
9613 (define_insn "tls_dtprel_lo_<bits>"
9614 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9615 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9616 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9617 UNSPEC_TLSDTPRELLO))]
9619 "addi %0,%1,%2@dtprel@l")
9621 (define_insn_and_split "tls_got_dtprel_<bits>"
9622 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9623 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9624 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9625 UNSPEC_TLSGOTDTPREL))]
9627 "<ptrload> %0,%2@got@dtprel(%1)"
9628 "&& TARGET_CMODEL != CMODEL_SMALL"
9631 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9633 (lo_sum:P (match_dup 3)
9634 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9636 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9638 [(set (attr "length")
9639 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9643 (define_insn "*tls_got_dtprel_high<bits>"
9644 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9646 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9647 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9648 UNSPEC_TLSGOTDTPREL)))]
9649 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9650 "addis %0,%1,%2@got@dtprel@ha")
9652 (define_insn "*tls_got_dtprel_low<bits>"
9653 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9654 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9655 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9656 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9657 UNSPEC_TLSGOTDTPREL)))]
9658 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9659 "<ptrload> %0,%2@got@dtprel@l(%1)")
9661 (define_insn "tls_tprel_<bits>"
9662 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9663 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9664 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9667 "addi %0,%1,%2@tprel"
9668 [(set (attr "prefixed")
9669 (if_then_else (match_test "rs6000_tls_size == 16")
9671 (const_string "yes")))])
9673 (define_insn "tls_tprel_ha_<bits>"
9674 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9675 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9676 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9677 UNSPEC_TLSTPRELHA))]
9679 "addis %0,%1,%2@tprel@ha")
9681 (define_insn "tls_tprel_lo_<bits>"
9682 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9683 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9684 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9685 UNSPEC_TLSTPRELLO))]
9687 "addi %0,%1,%2@tprel@l")
9689 (define_insn "*tls_got_tprel_pcrel_<bits>"
9690 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9691 (unspec:P [(const_int 0)
9692 (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9693 UNSPEC_TLSGOTTPREL))]
9695 "<ptrload> %0,%1@got@tprel@pcrel"
9696 [(set_attr "prefixed" "yes")])
9698 ;; "b" output constraint here and on tls_tls input to support linker tls
9699 ;; optimization. The linker may edit the instructions emitted by a
9700 ;; tls_got_tprel/tls_tls pair to addis,addi.
9701 (define_insn_and_split "tls_got_tprel_<bits>"
9702 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9703 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9704 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9705 UNSPEC_TLSGOTTPREL))]
9707 "<ptrload> %0,%2@got@tprel(%1)"
9708 "&& TARGET_CMODEL != CMODEL_SMALL"
9711 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9713 (lo_sum:P (match_dup 3)
9714 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9716 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9718 [(set (attr "length")
9719 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9723 (define_insn "*tls_got_tprel_high<bits>"
9724 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9726 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9727 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9728 UNSPEC_TLSGOTTPREL)))]
9729 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9730 "addis %0,%1,%2@got@tprel@ha")
9732 (define_insn "*tls_got_tprel_low<bits>"
9733 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9734 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9735 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9736 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9737 UNSPEC_TLSGOTTPREL)))]
9738 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9739 "<ptrload> %0,%2@got@tprel@l(%1)")
9741 (define_insn "tls_tls_pcrel_<bits>"
9742 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9743 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9744 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9745 UNSPEC_TLSTLS_PCREL))]
9746 "TARGET_ELF && HAVE_AS_TLS"
9747 "add %0,%1,%2@tls@pcrel")
9749 (define_insn "tls_tls_<bits>"
9750 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9751 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9752 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9754 "TARGET_ELF && HAVE_AS_TLS"
9757 (define_expand "tls_get_tpointer"
9758 [(set (match_operand:SI 0 "gpc_reg_operand")
9759 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9760 "TARGET_XCOFF && HAVE_AS_TLS"
9762 emit_insn (gen_tls_get_tpointer_internal ());
9763 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9767 (define_insn "tls_get_tpointer_internal"
9769 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9770 (clobber (reg:SI LR_REGNO))]
9771 "TARGET_XCOFF && HAVE_AS_TLS"
9772 "bla __get_tpointer")
9774 (define_expand "tls_get_addr<mode>"
9775 [(set (match_operand:P 0 "gpc_reg_operand")
9776 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9777 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9778 "TARGET_XCOFF && HAVE_AS_TLS"
9780 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9781 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9782 emit_insn (gen_tls_get_addr_internal<mode> ());
9783 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9787 (define_insn "tls_get_addr_internal<mode>"
9789 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9793 (clobber (reg:P 11))
9794 (clobber (reg:CC CR0_REGNO))
9795 (clobber (reg:P LR_REGNO))]
9796 "TARGET_XCOFF && HAVE_AS_TLS"
9797 "bla __tls_get_addr")
9799 ;; Next come insns related to the calling sequence.
9801 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9802 ;; We move the back-chain and decrement the stack pointer.
9804 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9805 ;; constant alloca, using that predicate will force the generic code to put
9806 ;; the constant size into a register before calling the expander.
9808 ;; As a result the expander would not have the constant size information
9809 ;; in those cases and would have to generate less efficient code.
9811 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9812 ;; the constant size. The value is forced into a register if necessary.
9814 (define_expand "allocate_stack"
9815 [(set (match_operand 0 "gpc_reg_operand")
9816 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9818 (minus (reg 1) (match_dup 1)))]
9821 rtx chain = gen_reg_rtx (Pmode);
9822 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9824 rtx insn, par, set, mem;
9826 /* By allowing reg_or_cint_operand as the predicate we can get
9827 better code for stack-clash-protection because we do not lose
9828 size information. But the rest of the code expects the operand
9829 to be reg_or_short_operand. If it isn't, then force it into
9831 rtx orig_op1 = operands[1];
9832 if (!reg_or_short_operand (operands[1], Pmode))
9833 operands[1] = force_reg (Pmode, operands[1]);
9835 emit_move_insn (chain, stack_bot);
9837 /* Check stack bounds if necessary. */
9838 if (crtl->limit_stack)
9841 available = expand_binop (Pmode, sub_optab,
9842 stack_pointer_rtx, stack_limit_rtx,
9843 NULL_RTX, 1, OPTAB_WIDEN);
9844 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9847 /* Allocate and probe if requested.
9848 This may look similar to the loop we use for prologue allocations,
9849 but it is critically different. For the former we know the loop
9850 will iterate, but do not know that generally here. The former
9851 uses that knowledge to rotate the loop. Combining them would be
9852 possible with some performance cost. */
9853 if (flag_stack_clash_protection)
9855 rtx rounded_size, last_addr, residual;
9856 HOST_WIDE_INT probe_interval;
9857 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9858 &residual, &probe_interval,
9861 /* We do occasionally get in here with constant sizes, we might
9862 as well do a reasonable job when we obviously can. */
9863 if (rounded_size != const0_rtx)
9865 rtx loop_lab, end_loop;
9866 bool rotated = CONST_INT_P (rounded_size);
9867 rtx update = GEN_INT (-probe_interval);
9868 if (probe_interval > 32768)
9869 update = force_reg (Pmode, update);
9871 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9872 last_addr, rotated);
9875 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9879 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9882 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9883 last_addr, rotated);
9886 /* Now handle residuals. We just have to set operands[1] correctly
9887 and let the rest of the expander run. */
9888 operands[1] = residual;
9891 if (!(CONST_INT_P (operands[1])
9892 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9894 operands[1] = force_reg (Pmode, operands[1]);
9895 neg_op0 = gen_reg_rtx (Pmode);
9896 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9899 neg_op0 = GEN_INT (-INTVAL (operands[1]));
9901 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9902 : gen_movdi_update_stack))
9903 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9905 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9906 it now and set the alias set/attributes. The above gen_*_update
9907 calls will generate a PARALLEL with the MEM set being the first
9909 par = PATTERN (insn);
9910 gcc_assert (GET_CODE (par) == PARALLEL);
9911 set = XVECEXP (par, 0, 0);
9912 gcc_assert (GET_CODE (set) == SET);
9913 mem = SET_DEST (set);
9914 gcc_assert (MEM_P (mem));
9915 MEM_NOTRAP_P (mem) = 1;
9916 set_mem_alias_set (mem, get_frame_alias_set ());
9918 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9922 ;; These patterns say how to save and restore the stack pointer. We need not
9923 ;; save the stack pointer at function level since we are careful to
9924 ;; preserve the backchain. At block level, we have to restore the backchain
9925 ;; when we restore the stack pointer.
9927 ;; For nonlocal gotos, we must save both the stack pointer and its
9928 ;; backchain and restore both. Note that in the nonlocal case, the
9929 ;; save area is a memory location.
9931 (define_expand "save_stack_function"
9932 [(match_operand 0 "any_operand")
9933 (match_operand 1 "any_operand")]
9937 (define_expand "restore_stack_function"
9938 [(match_operand 0 "any_operand")
9939 (match_operand 1 "any_operand")]
9943 ;; Adjust stack pointer (op0) to a new value (op1).
9944 ;; First copy old stack backchain to new location, and ensure that the
9945 ;; scheduler won't reorder the sp assignment before the backchain write.
9946 (define_expand "restore_stack_block"
9947 [(set (match_dup 2) (match_dup 3))
9948 (set (match_dup 4) (match_dup 2))
9950 (set (match_operand 0 "register_operand")
9951 (match_operand 1 "register_operand"))]
9956 operands[1] = force_reg (Pmode, operands[1]);
9957 operands[2] = gen_reg_rtx (Pmode);
9958 operands[3] = gen_frame_mem (Pmode, operands[0]);
9959 operands[4] = gen_frame_mem (Pmode, operands[1]);
9960 p = rtvec_alloc (1);
9961 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9963 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9966 (define_expand "save_stack_nonlocal"
9967 [(set (match_dup 3) (match_dup 4))
9968 (set (match_operand 0 "memory_operand") (match_dup 3))
9969 (set (match_dup 2) (match_operand 1 "register_operand"))]
9972 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9974 /* Copy the backchain to the first word, sp to the second. */
9975 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9976 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9977 operands[3] = gen_reg_rtx (Pmode);
9978 operands[4] = gen_frame_mem (Pmode, operands[1]);
9981 (define_expand "restore_stack_nonlocal"
9982 [(set (match_dup 2) (match_operand 1 "memory_operand"))
9983 (set (match_dup 3) (match_dup 4))
9984 (set (match_dup 5) (match_dup 2))
9986 (set (match_operand 0 "register_operand") (match_dup 3))]
9989 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9992 /* Restore the backchain from the first word, sp from the second. */
9993 operands[2] = gen_reg_rtx (Pmode);
9994 operands[3] = gen_reg_rtx (Pmode);
9995 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9996 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9997 operands[5] = gen_frame_mem (Pmode, operands[3]);
9998 p = rtvec_alloc (1);
9999 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10001 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10004 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10005 ;; to the symbol or label.
10006 (define_insn "*pcrel_local_addr"
10007 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10008 (match_operand:DI 1 "pcrel_local_address"))]
10011 [(set_attr "prefixed" "yes")])
10013 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10014 ;; program are both defined in the main program, the linker will optimize this
10015 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10016 ;; the dynamic linker and loaded up. Print_operand_address will append a
10017 ;; @got@pcrel to the symbol.
10018 (define_insn "*pcrel_extern_addr"
10019 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10020 (match_operand:DI 1 "pcrel_external_address"))]
10023 [(set_attr "prefixed" "yes")
10024 (set_attr "type" "load")])
10026 ;; TOC register handling.
10028 ;; Code to initialize the TOC register...
10030 (define_insn "load_toc_aix_si"
10031 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10032 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10033 (use (reg:SI 2))])]
10034 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10037 extern int need_toc_init;
10039 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10040 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10041 operands[2] = gen_rtx_REG (Pmode, 2);
10042 return "lwz %0,%1(%2)";
10044 [(set_attr "type" "load")
10045 (set_attr "update" "no")
10046 (set_attr "indexed" "no")])
10048 (define_insn "load_toc_aix_di"
10049 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10050 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10051 (use (reg:DI 2))])]
10052 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10055 extern int need_toc_init;
10057 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10058 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10060 strcat (buf, "@toc");
10061 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10062 operands[2] = gen_rtx_REG (Pmode, 2);
10063 return "ld %0,%1(%2)";
10065 [(set_attr "type" "load")
10066 (set_attr "update" "no")
10067 (set_attr "indexed" "no")])
10069 (define_insn "load_toc_v4_pic_si"
10070 [(set (reg:SI LR_REGNO)
10071 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10072 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10073 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10074 [(set_attr "type" "branch")])
10076 (define_expand "load_toc_v4_PIC_1"
10077 [(parallel [(set (reg:SI LR_REGNO)
10078 (match_operand:SI 0 "immediate_operand" "s"))
10079 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10080 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10081 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10084 (define_insn "load_toc_v4_PIC_1_normal"
10085 [(set (reg:SI LR_REGNO)
10086 (match_operand:SI 0 "immediate_operand" "s"))
10087 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10088 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10089 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10090 "bcl 20,31,%0\n%0:"
10091 [(set_attr "type" "branch")
10092 (set_attr "cannot_copy" "yes")])
10094 (define_insn "load_toc_v4_PIC_1_476"
10095 [(set (reg:SI LR_REGNO)
10096 (match_operand:SI 0 "immediate_operand" "s"))
10097 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10098 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10099 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10102 static char templ[32];
10104 get_ppc476_thunk_name (name);
10105 sprintf (templ, "bl %s\n%%0:", name);
10108 [(set_attr "type" "branch")
10109 (set_attr "cannot_copy" "yes")])
10111 (define_expand "load_toc_v4_PIC_1b"
10112 [(parallel [(set (reg:SI LR_REGNO)
10113 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10114 (label_ref (match_operand 1 ""))]
10117 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10120 (define_insn "load_toc_v4_PIC_1b_normal"
10121 [(set (reg:SI LR_REGNO)
10122 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10123 (label_ref (match_operand 1 "" ""))]
10126 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10127 "bcl 20,31,$+8\;.long %0-$"
10128 [(set_attr "type" "branch")
10129 (set_attr "length" "8")])
10131 (define_insn "load_toc_v4_PIC_1b_476"
10132 [(set (reg:SI LR_REGNO)
10133 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10134 (label_ref (match_operand 1 "" ""))]
10137 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10140 static char templ[32];
10142 get_ppc476_thunk_name (name);
10143 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10146 [(set_attr "type" "branch")
10147 (set_attr "length" "16")])
10149 (define_insn "load_toc_v4_PIC_2"
10150 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10152 (match_operand:SI 1 "gpc_reg_operand" "b")
10154 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10155 (match_operand:SI 3 "immediate_operand" "s"))))))]
10156 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10158 [(set_attr "type" "load")])
10160 (define_insn "load_toc_v4_PIC_3b"
10161 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10163 (match_operand:SI 1 "gpc_reg_operand" "b")
10166 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10167 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10168 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10169 "addis %0,%1,%2-%3@ha")
10171 (define_insn "load_toc_v4_PIC_3c"
10172 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10174 (match_operand:SI 1 "gpc_reg_operand" "b")
10176 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10177 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10178 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10179 "addi %0,%1,%2-%3@l")
10181 ;; If the TOC is shared over a translation unit, as happens with all
10182 ;; the kinds of PIC that we support, we need to restore the TOC
10183 ;; pointer only when jumping over units of translation.
10184 ;; On Darwin, we need to reload the picbase.
10186 (define_expand "builtin_setjmp_receiver"
10187 [(use (label_ref (match_operand 0 "")))]
10188 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10189 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10190 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10193 if (DEFAULT_ABI == ABI_DARWIN)
10195 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10196 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10200 crtl->uses_pic_offset_table = 1;
10201 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10202 CODE_LABEL_NUMBER (operands[0]));
10203 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10205 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10206 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10207 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10208 picrtx, tmplabrtx));
10212 rs6000_emit_load_toc_table (FALSE);
10216 ;; Largetoc support
10217 (define_insn "*largetoc_high"
10218 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10220 (unspec [(match_operand:DI 1 "" "")
10221 (match_operand:DI 2 "gpc_reg_operand" "b")]
10223 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10224 "addis %0,%2,%1@toc@ha")
10226 (define_insn "*largetoc_high_aix<mode>"
10227 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10229 (unspec [(match_operand:P 1 "" "")
10230 (match_operand:P 2 "gpc_reg_operand" "b")]
10232 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10233 "addis %0,%1@u(%2)")
10235 (define_insn "*largetoc_high_plus"
10236 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10239 (unspec [(match_operand:DI 1 "" "")
10240 (match_operand:DI 2 "gpc_reg_operand" "b")]
10242 (match_operand:DI 3 "add_cint_operand" "n"))))]
10243 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10244 "addis %0,%2,%1+%3@toc@ha")
10246 (define_insn "*largetoc_high_plus_aix<mode>"
10247 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10250 (unspec [(match_operand:P 1 "" "")
10251 (match_operand:P 2 "gpc_reg_operand" "b")]
10253 (match_operand:P 3 "add_cint_operand" "n"))))]
10254 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10255 "addis %0,%1+%3@u(%2)")
10257 (define_insn "*largetoc_low"
10258 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10259 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10260 (match_operand:DI 2 "" "")))]
10261 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10264 (define_insn "*largetoc_low_aix<mode>"
10265 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10266 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10267 (match_operand:P 2 "" "")))]
10268 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10271 (define_insn_and_split "*tocref<mode>"
10272 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10273 (match_operand:P 1 "small_toc_ref" "R"))]
10276 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10277 [(set (match_dup 0) (high:P (match_dup 1)))
10278 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10280 ;; Elf specific ways of loading addresses for non-PIC code.
10281 ;; The output of this could be r0, but we make a very strong
10282 ;; preference for a base register because it will usually
10283 ;; be needed there.
10284 (define_insn "elf_high"
10285 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10286 (high:SI (match_operand 1 "" "")))]
10287 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10290 (define_insn "elf_low"
10291 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10292 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10293 (match_operand 2 "" "")))]
10294 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10297 (define_insn "*pltseq_tocsave_<mode>"
10298 [(set (match_operand:P 0 "memory_operand" "=m")
10299 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10300 (match_operand:P 2 "symbol_ref_operand" "s")
10301 (match_operand:P 3 "" "")]
10304 && DEFAULT_ABI == ABI_ELFv2"
10306 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10309 (define_insn "*pltseq_plt16_ha_<mode>"
10310 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10311 (unspec:P [(match_operand:P 1 "" "")
10312 (match_operand:P 2 "symbol_ref_operand" "s")
10313 (match_operand:P 3 "" "")]
10317 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10320 (define_insn "*pltseq_plt16_lo_<mode>"
10321 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10322 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10323 (match_operand:P 2 "symbol_ref_operand" "s")
10324 (match_operand:P 3 "" "")]
10328 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10330 [(set_attr "type" "load")])
10332 (define_insn "*pltseq_mtctr_<mode>"
10333 [(set (match_operand:P 0 "register_operand" "=c")
10334 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10335 (match_operand:P 2 "symbol_ref_operand" "s")
10336 (match_operand:P 3 "" "")]
10340 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10343 (define_insn "*pltseq_plt_pcrel<mode>"
10344 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10345 (unspec:P [(match_operand:P 1 "" "")
10346 (match_operand:P 2 "symbol_ref_operand" "s")
10347 (match_operand:P 3 "" "")]
10348 UNSPEC_PLT_PCREL))]
10349 "HAVE_AS_PLTSEQ && TARGET_ELF
10350 && rs6000_pcrel_p (cfun)"
10352 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10354 [(set_attr "type" "load")
10355 (set_attr "length" "12")])
10357 ;; Call and call_value insns
10358 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10359 (define_expand "call"
10360 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10361 (match_operand 1 ""))
10362 (use (match_operand 2 ""))
10363 (clobber (reg:SI LR_REGNO))])]
10367 if (MACHOPIC_INDIRECT)
10368 operands[0] = machopic_indirect_call_target (operands[0]);
10371 gcc_assert (MEM_P (operands[0]));
10373 operands[0] = XEXP (operands[0], 0);
10375 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10376 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10377 else if (DEFAULT_ABI == ABI_V4)
10378 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10379 else if (DEFAULT_ABI == ABI_DARWIN)
10380 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10382 gcc_unreachable ();
10387 (define_expand "call_value"
10388 [(parallel [(set (match_operand 0 "")
10389 (call (mem:SI (match_operand 1 "address_operand"))
10390 (match_operand 2 "")))
10391 (use (match_operand 3 ""))
10392 (clobber (reg:SI LR_REGNO))])]
10396 if (MACHOPIC_INDIRECT)
10397 operands[1] = machopic_indirect_call_target (operands[1]);
10400 gcc_assert (MEM_P (operands[1]));
10402 operands[1] = XEXP (operands[1], 0);
10404 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10405 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10406 else if (DEFAULT_ABI == ABI_V4)
10407 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10408 else if (DEFAULT_ABI == ABI_DARWIN)
10409 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10411 gcc_unreachable ();
10416 ;; Call to function in current module. No TOC pointer reload needed.
10417 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10418 ;; either the function was not prototyped, or it was prototyped as a
10419 ;; variable argument function. It is > 0 if FP registers were passed
10420 ;; and < 0 if they were not.
10422 (define_insn "*call_local32"
10423 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10425 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10426 (clobber (reg:SI LR_REGNO))]
10427 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10429 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10430 output_asm_insn ("crxor 6,6,6", operands);
10432 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10433 output_asm_insn ("creqv 6,6,6", operands);
10435 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10437 [(set_attr "type" "branch")
10438 (set_attr "length" "4,8")])
10440 (define_insn "*call_local64"
10441 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10443 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10444 (clobber (reg:DI LR_REGNO))]
10445 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10447 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10448 output_asm_insn ("crxor 6,6,6", operands);
10450 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10451 output_asm_insn ("creqv 6,6,6", operands);
10453 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10455 [(set_attr "type" "branch")
10456 (set_attr "length" "4,8")])
10458 (define_insn "*call_value_local32"
10459 [(set (match_operand 0 "" "")
10460 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10461 (match_operand 2)))
10462 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10463 (clobber (reg:SI LR_REGNO))]
10464 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10466 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10467 output_asm_insn ("crxor 6,6,6", operands);
10469 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10470 output_asm_insn ("creqv 6,6,6", operands);
10472 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10474 [(set_attr "type" "branch")
10475 (set_attr "length" "4,8")])
10478 (define_insn "*call_value_local64"
10479 [(set (match_operand 0 "" "")
10480 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10481 (match_operand 2)))
10482 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10483 (clobber (reg:DI LR_REGNO))]
10484 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10486 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10487 output_asm_insn ("crxor 6,6,6", operands);
10489 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10490 output_asm_insn ("creqv 6,6,6", operands);
10492 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10494 [(set_attr "type" "branch")
10495 (set_attr "length" "4,8")])
10498 ;; A function pointer under System V is just a normal pointer
10499 ;; operands[0] is the function pointer
10500 ;; operands[1] is the tls call arg
10501 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10502 ;; which indicates how to set cr1
10504 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10505 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10507 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10508 (clobber (reg:P LR_REGNO))]
10509 "DEFAULT_ABI == ABI_V4
10510 || DEFAULT_ABI == ABI_DARWIN"
10512 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10513 output_asm_insn ("crxor 6,6,6", operands);
10515 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10516 output_asm_insn ("creqv 6,6,6", operands);
10518 return rs6000_indirect_call_template (operands, 0);
10520 [(set_attr "type" "jmpreg")
10521 (set (attr "length")
10522 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10523 (match_test "which_alternative != 1"))
10524 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10525 (const_string "12")
10526 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10527 (match_test "which_alternative != 1"))
10528 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10529 (const_string "8")]
10530 (const_string "4")))])
10532 (define_insn "*call_nonlocal_sysv<mode>"
10533 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10535 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10536 (clobber (reg:P LR_REGNO))]
10537 "(DEFAULT_ABI == ABI_DARWIN
10538 || (DEFAULT_ABI == ABI_V4
10539 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10541 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10542 output_asm_insn ("crxor 6,6,6", operands);
10544 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10545 output_asm_insn ("creqv 6,6,6", operands);
10547 return rs6000_call_template (operands, 0);
10549 [(set_attr "type" "branch,branch")
10550 (set_attr "length" "4,8")])
10552 (define_insn "*call_nonlocal_sysv_secure<mode>"
10553 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10555 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10556 (use (match_operand:SI 3 "register_operand" "r,r"))
10557 (clobber (reg:P LR_REGNO))]
10558 "(DEFAULT_ABI == ABI_V4
10559 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10560 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10562 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10563 output_asm_insn ("crxor 6,6,6", operands);
10565 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10566 output_asm_insn ("creqv 6,6,6", operands);
10568 return rs6000_call_template (operands, 0);
10570 [(set_attr "type" "branch,branch")
10571 (set_attr "length" "4,8")])
10573 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10574 [(set (match_operand 0 "" "")
10575 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10576 (match_operand:P 2 "unspec_tls" "")))
10577 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10578 (clobber (reg:P LR_REGNO))]
10579 "DEFAULT_ABI == ABI_V4
10580 || DEFAULT_ABI == ABI_DARWIN"
10582 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10583 output_asm_insn ("crxor 6,6,6", operands);
10585 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10586 output_asm_insn ("creqv 6,6,6", operands);
10588 return rs6000_indirect_call_template (operands, 1);
10590 [(set_attr "type" "jmpreg")
10591 (set (attr "length")
10593 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10596 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10597 (match_test "which_alternative != 1"))
10601 (define_insn "*call_value_nonlocal_sysv<mode>"
10602 [(set (match_operand 0 "" "")
10603 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10604 (match_operand:P 2 "unspec_tls" "")))
10605 (use (match_operand:SI 3 "immediate_operand" "n"))
10606 (clobber (reg:P LR_REGNO))]
10607 "(DEFAULT_ABI == ABI_DARWIN
10608 || (DEFAULT_ABI == ABI_V4
10609 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10611 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10612 output_asm_insn ("crxor 6,6,6", operands);
10614 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10615 output_asm_insn ("creqv 6,6,6", operands);
10617 return rs6000_call_template (operands, 1);
10619 [(set_attr "type" "branch")
10620 (set (attr "length")
10621 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10625 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10626 [(set (match_operand 0 "" "")
10627 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10628 (match_operand:P 2 "unspec_tls" "")))
10629 (use (match_operand:SI 3 "immediate_operand" "n"))
10630 (use (match_operand:SI 4 "register_operand" "r"))
10631 (clobber (reg:P LR_REGNO))]
10632 "(DEFAULT_ABI == ABI_V4
10633 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10634 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10636 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10637 output_asm_insn ("crxor 6,6,6", operands);
10639 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10640 output_asm_insn ("creqv 6,6,6", operands);
10642 return rs6000_call_template (operands, 1);
10644 [(set_attr "type" "branch")
10645 (set (attr "length")
10646 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10650 ;; Call to AIX abi function in the same module.
10652 (define_insn "*call_local_aix<mode>"
10653 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10655 (clobber (reg:P LR_REGNO))]
10656 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10658 if (rs6000_pcrel_p (cfun))
10659 return "bl %z0@notoc";
10662 [(set_attr "type" "branch")])
10664 (define_insn "*call_value_local_aix<mode>"
10665 [(set (match_operand 0 "" "")
10666 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10667 (match_operand 2)))
10668 (clobber (reg:P LR_REGNO))]
10669 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10671 if (rs6000_pcrel_p (cfun))
10672 return "bl %z1@notoc";
10675 [(set_attr "type" "branch")])
10677 ;; Call to AIX abi function which may be in another module.
10678 ;; Restore the TOC pointer (r2) after the call.
10680 (define_insn "*call_nonlocal_aix<mode>"
10681 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10683 (clobber (reg:P LR_REGNO))]
10684 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10686 return rs6000_call_template (operands, 0);
10688 [(set_attr "type" "branch")
10689 (set (attr "length")
10690 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10694 (define_insn "*call_value_nonlocal_aix<mode>"
10695 [(set (match_operand 0 "" "")
10696 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10697 (match_operand:P 2 "unspec_tls" "")))
10698 (clobber (reg:P LR_REGNO))]
10699 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10701 return rs6000_call_template (operands, 1);
10703 [(set_attr "type" "branch")
10704 (set (attr "length")
10705 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10709 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10710 ;; Operand0 is the addresss of the function to call
10711 ;; Operand2 is the location in the function descriptor to load r2 from
10712 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10714 (define_insn "*call_indirect_aix<mode>"
10715 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10717 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10718 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10719 (clobber (reg:P LR_REGNO))]
10720 "DEFAULT_ABI == ABI_AIX"
10722 return rs6000_indirect_call_template (operands, 0);
10724 [(set_attr "type" "jmpreg")
10725 (set (attr "length")
10726 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10727 (match_test "which_alternative != 1"))
10728 (const_string "16")
10729 (const_string "12")))])
10731 (define_insn "*call_value_indirect_aix<mode>"
10732 [(set (match_operand 0 "" "")
10733 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10734 (match_operand:P 2 "unspec_tls" "")))
10735 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10736 (set (reg:P TOC_REGNUM)
10737 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10739 (clobber (reg:P LR_REGNO))]
10740 "DEFAULT_ABI == ABI_AIX"
10742 return rs6000_indirect_call_template (operands, 1);
10744 [(set_attr "type" "jmpreg")
10745 (set (attr "length")
10746 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10747 (match_test "which_alternative != 1"))
10748 (const_string "16")
10749 (const_string "12")))])
10751 ;; Call to indirect functions with the ELFv2 ABI.
10752 ;; Operand0 is the addresss of the function to call
10753 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10755 (define_insn "*call_indirect_elfv2<mode>"
10756 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10758 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10759 (clobber (reg:P LR_REGNO))]
10760 "DEFAULT_ABI == ABI_ELFv2"
10762 return rs6000_indirect_call_template (operands, 0);
10764 [(set_attr "type" "jmpreg")
10765 (set (attr "length")
10766 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10767 (match_test "which_alternative != 1"))
10768 (const_string "12")
10769 (const_string "8")))])
10771 (define_insn "*call_indirect_pcrel<mode>"
10772 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10774 (clobber (reg:P LR_REGNO))]
10775 "rs6000_pcrel_p (cfun)"
10777 return rs6000_indirect_call_template (operands, 0);
10779 [(set_attr "type" "jmpreg")
10780 (set (attr "length")
10781 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10782 (match_test "which_alternative != 1"))
10784 (const_string "4")))])
10786 (define_insn "*call_value_indirect_elfv2<mode>"
10787 [(set (match_operand 0 "" "")
10788 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10789 (match_operand:P 2 "unspec_tls" "")))
10790 (set (reg:P TOC_REGNUM)
10791 (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")]
10793 (clobber (reg:P LR_REGNO))]
10794 "DEFAULT_ABI == ABI_ELFv2"
10796 return rs6000_indirect_call_template (operands, 1);
10798 [(set_attr "type" "jmpreg")
10799 (set (attr "length")
10800 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10801 (match_test "which_alternative != 1"))
10802 (const_string "12")
10803 (const_string "8")))])
10805 (define_insn "*call_value_indirect_pcrel<mode>"
10806 [(set (match_operand 0 "" "")
10807 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10808 (match_operand:P 2 "unspec_tls" "")))
10809 (clobber (reg:P LR_REGNO))]
10810 "rs6000_pcrel_p (cfun)"
10812 return rs6000_indirect_call_template (operands, 1);
10814 [(set_attr "type" "jmpreg")
10815 (set (attr "length")
10816 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10817 (match_test "which_alternative != 1"))
10819 (const_string "4")))])
10821 ;; Call subroutine returning any type.
10822 (define_expand "untyped_call"
10823 [(parallel [(call (match_operand 0 "")
10825 (match_operand 1 "")
10826 (match_operand 2 "")])]
10831 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10833 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10835 rtx set = XVECEXP (operands[2], 0, i);
10836 emit_move_insn (SET_DEST (set), SET_SRC (set));
10839 /* The optimizer does not know that the call sets the function value
10840 registers we stored in the result block. We avoid problems by
10841 claiming that all hard registers are used and clobbered at this
10843 emit_insn (gen_blockage ());
10848 ;; sibling call patterns
10849 (define_expand "sibcall"
10850 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10851 (match_operand 1 ""))
10852 (use (match_operand 2 ""))
10857 if (MACHOPIC_INDIRECT)
10858 operands[0] = machopic_indirect_call_target (operands[0]);
10861 gcc_assert (MEM_P (operands[0]));
10862 gcc_assert (CONST_INT_P (operands[1]));
10864 operands[0] = XEXP (operands[0], 0);
10866 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10867 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10868 else if (DEFAULT_ABI == ABI_V4)
10869 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10870 else if (DEFAULT_ABI == ABI_DARWIN)
10871 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10873 gcc_unreachable ();
10878 (define_expand "sibcall_value"
10879 [(parallel [(set (match_operand 0 "register_operand")
10880 (call (mem:SI (match_operand 1 "address_operand"))
10881 (match_operand 2 "")))
10882 (use (match_operand 3 ""))
10887 if (MACHOPIC_INDIRECT)
10888 operands[1] = machopic_indirect_call_target (operands[1]);
10891 gcc_assert (MEM_P (operands[1]));
10892 gcc_assert (CONST_INT_P (operands[2]));
10894 operands[1] = XEXP (operands[1], 0);
10896 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10897 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10898 else if (DEFAULT_ABI == ABI_V4)
10899 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10900 else if (DEFAULT_ABI == ABI_DARWIN)
10901 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10903 gcc_unreachable ();
10908 (define_insn "*sibcall_local32"
10909 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10911 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10913 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10915 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10916 output_asm_insn ("crxor 6,6,6", operands);
10918 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10919 output_asm_insn ("creqv 6,6,6", operands);
10921 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10923 [(set_attr "type" "branch")
10924 (set_attr "length" "4,8")])
10926 (define_insn "*sibcall_local64"
10927 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10929 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10931 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10933 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10934 output_asm_insn ("crxor 6,6,6", operands);
10936 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10937 output_asm_insn ("creqv 6,6,6", operands);
10939 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10941 [(set_attr "type" "branch")
10942 (set_attr "length" "4,8")])
10944 (define_insn "*sibcall_value_local32"
10945 [(set (match_operand 0 "" "")
10946 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10947 (match_operand 2)))
10948 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10950 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10952 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10953 output_asm_insn ("crxor 6,6,6", operands);
10955 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10956 output_asm_insn ("creqv 6,6,6", operands);
10958 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10960 [(set_attr "type" "branch")
10961 (set_attr "length" "4,8")])
10963 (define_insn "*sibcall_value_local64"
10964 [(set (match_operand 0 "" "")
10965 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10966 (match_operand 2)))
10967 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10969 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10971 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10972 output_asm_insn ("crxor 6,6,6", operands);
10974 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10975 output_asm_insn ("creqv 6,6,6", operands);
10977 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10979 [(set_attr "type" "branch")
10980 (set_attr "length" "4,8")])
10982 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10983 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10985 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10987 "DEFAULT_ABI == ABI_V4
10988 || DEFAULT_ABI == ABI_DARWIN"
10990 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10991 output_asm_insn ("crxor 6,6,6", operands);
10993 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10994 output_asm_insn ("creqv 6,6,6", operands);
10996 return rs6000_indirect_sibcall_template (operands, 0);
10998 [(set_attr "type" "jmpreg")
10999 (set (attr "length")
11000 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11001 (match_test "which_alternative != 1"))
11002 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11003 (const_string "12")
11004 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11005 (match_test "which_alternative != 1"))
11006 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11007 (const_string "8")]
11008 (const_string "4")))])
11010 (define_insn "*sibcall_nonlocal_sysv<mode>"
11011 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11013 (use (match_operand 2 "immediate_operand" "O,n"))
11015 "(DEFAULT_ABI == ABI_DARWIN
11016 || DEFAULT_ABI == ABI_V4)
11017 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11019 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11020 output_asm_insn ("crxor 6,6,6", operands);
11022 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11023 output_asm_insn ("creqv 6,6,6", operands);
11025 return rs6000_sibcall_template (operands, 0);
11027 [(set_attr "type" "branch")
11028 (set_attr "length" "4,8")])
11030 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11031 [(set (match_operand 0 "" "")
11032 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11033 (match_operand 2)))
11034 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11036 "DEFAULT_ABI == ABI_V4
11037 || DEFAULT_ABI == ABI_DARWIN"
11039 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11040 output_asm_insn ("crxor 6,6,6", operands);
11042 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11043 output_asm_insn ("creqv 6,6,6", operands);
11045 return rs6000_indirect_sibcall_template (operands, 1);
11047 [(set_attr "type" "jmpreg")
11048 (set (attr "length")
11049 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11050 (match_test "which_alternative != 1"))
11051 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11052 (const_string "12")
11053 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11054 (match_test "which_alternative != 1"))
11055 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11056 (const_string "8")]
11057 (const_string "4")))])
11059 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11060 [(set (match_operand 0 "" "")
11061 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11062 (match_operand 2)))
11063 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11065 "(DEFAULT_ABI == ABI_DARWIN
11066 || DEFAULT_ABI == ABI_V4)
11067 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11069 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11070 output_asm_insn ("crxor 6,6,6", operands);
11072 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11073 output_asm_insn ("creqv 6,6,6", operands);
11075 return rs6000_sibcall_template (operands, 1);
11077 [(set_attr "type" "branch")
11078 (set_attr "length" "4,8")])
11080 ;; AIX ABI sibling call patterns.
11082 (define_insn "*sibcall_aix<mode>"
11083 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11086 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11088 if (which_alternative == 0)
11089 return rs6000_sibcall_template (operands, 0);
11093 [(set_attr "type" "branch")])
11095 (define_insn "*sibcall_value_aix<mode>"
11096 [(set (match_operand 0 "" "")
11097 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11098 (match_operand 2)))
11100 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11102 if (which_alternative == 0)
11103 return rs6000_sibcall_template (operands, 1);
11107 [(set_attr "type" "branch")])
11109 (define_expand "sibcall_epilogue"
11110 [(use (const_int 0))]
11113 if (!TARGET_SCHED_PROLOG)
11114 emit_insn (gen_blockage ());
11115 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11119 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11120 ;; all of memory. This blocks insns from being moved across this point.
11122 (define_insn "blockage"
11123 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11126 [(set_attr "length" "0")])
11128 (define_expand "probe_stack_address"
11129 [(use (match_operand 0 "address_operand"))]
11132 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11133 MEM_VOLATILE_P (operands[0]) = 1;
11136 emit_insn (gen_probe_stack_di (operands[0]));
11138 emit_insn (gen_probe_stack_si (operands[0]));
11142 (define_insn "probe_stack_<mode>"
11143 [(set (match_operand:P 0 "memory_operand" "=m")
11144 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11147 operands[1] = gen_rtx_REG (Pmode, 0);
11148 return "st<wd>%U0%X0 %1,%0";
11150 [(set_attr "type" "store")
11151 (set (attr "update")
11152 (if_then_else (match_operand 0 "update_address_mem")
11153 (const_string "yes")
11154 (const_string "no")))
11155 (set (attr "indexed")
11156 (if_then_else (match_operand 0 "indexed_address_mem")
11157 (const_string "yes")
11158 (const_string "no")))])
11160 (define_insn "probe_stack_range<P:mode>"
11161 [(set (match_operand:P 0 "register_operand" "=&r")
11162 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11163 (match_operand:P 2 "register_operand" "r")
11164 (match_operand:P 3 "register_operand" "r")]
11165 UNSPECV_PROBE_STACK_RANGE))]
11167 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11168 [(set_attr "type" "three")])
11170 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11171 ;; signed & unsigned, and one type of branch.
11173 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11174 ;; insns, and branches.
11176 (define_expand "cbranch<mode>4"
11177 [(use (match_operator 0 "comparison_operator"
11178 [(match_operand:GPR 1 "gpc_reg_operand")
11179 (match_operand:GPR 2 "reg_or_short_operand")]))
11180 (use (match_operand 3))]
11183 /* Take care of the possibility that operands[2] might be negative but
11184 this might be a logical operation. That insn doesn't exist. */
11185 if (CONST_INT_P (operands[2])
11186 && INTVAL (operands[2]) < 0)
11188 operands[2] = force_reg (<MODE>mode, operands[2]);
11189 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11190 GET_MODE (operands[0]),
11191 operands[1], operands[2]);
11194 rs6000_emit_cbranch (<MODE>mode, operands);
11198 (define_expand "cbranch<mode>4"
11199 [(use (match_operator 0 "comparison_operator"
11200 [(match_operand:FP 1 "gpc_reg_operand")
11201 (match_operand:FP 2 "gpc_reg_operand")]))
11202 (use (match_operand 3))]
11205 rs6000_emit_cbranch (<MODE>mode, operands);
11209 (define_expand "cstore<mode>4_signed"
11210 [(use (match_operator 1 "signed_comparison_operator"
11211 [(match_operand:P 2 "gpc_reg_operand")
11212 (match_operand:P 3 "gpc_reg_operand")]))
11213 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11216 enum rtx_code cond_code = GET_CODE (operands[1]);
11218 rtx op0 = operands[0];
11219 rtx op1 = operands[2];
11220 rtx op2 = operands[3];
11222 if (cond_code == GE || cond_code == LT)
11224 cond_code = swap_condition (cond_code);
11225 std::swap (op1, op2);
11228 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11229 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11230 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11232 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11233 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11234 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11236 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11238 if (cond_code == LE)
11239 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11242 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11243 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11244 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11250 (define_expand "cstore<mode>4_unsigned"
11251 [(use (match_operator 1 "unsigned_comparison_operator"
11252 [(match_operand:P 2 "gpc_reg_operand")
11253 (match_operand:P 3 "reg_or_short_operand")]))
11254 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11257 enum rtx_code cond_code = GET_CODE (operands[1]);
11259 rtx op0 = operands[0];
11260 rtx op1 = operands[2];
11261 rtx op2 = operands[3];
11263 if (cond_code == GEU || cond_code == LTU)
11265 cond_code = swap_condition (cond_code);
11266 std::swap (op1, op2);
11269 if (!gpc_reg_operand (op1, <MODE>mode))
11270 op1 = force_reg (<MODE>mode, op1);
11271 if (!reg_or_short_operand (op2, <MODE>mode))
11272 op2 = force_reg (<MODE>mode, op2);
11274 rtx tmp = gen_reg_rtx (<MODE>mode);
11275 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11277 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11278 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11280 if (cond_code == LEU)
11281 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11283 emit_insn (gen_neg<mode>2 (op0, tmp2));
11288 (define_expand "cstore_si_as_di"
11289 [(use (match_operator 1 "unsigned_comparison_operator"
11290 [(match_operand:SI 2 "gpc_reg_operand")
11291 (match_operand:SI 3 "reg_or_short_operand")]))
11292 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11295 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11296 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11298 operands[2] = force_reg (SImode, operands[2]);
11299 operands[3] = force_reg (SImode, operands[3]);
11300 rtx op1 = gen_reg_rtx (DImode);
11301 rtx op2 = gen_reg_rtx (DImode);
11302 convert_move (op1, operands[2], uns_flag);
11303 convert_move (op2, operands[3], uns_flag);
11305 if (cond_code == GT || cond_code == LE)
11307 cond_code = swap_condition (cond_code);
11308 std::swap (op1, op2);
11311 rtx tmp = gen_reg_rtx (DImode);
11312 rtx tmp2 = gen_reg_rtx (DImode);
11313 emit_insn (gen_subdi3 (tmp, op1, op2));
11314 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11320 gcc_unreachable ();
11325 tmp3 = gen_reg_rtx (DImode);
11326 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11330 convert_move (operands[0], tmp3, 1);
11335 (define_expand "cstore<mode>4_signed_imm"
11336 [(use (match_operator 1 "signed_comparison_operator"
11337 [(match_operand:GPR 2 "gpc_reg_operand")
11338 (match_operand:GPR 3 "immediate_operand")]))
11339 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11342 bool invert = false;
11344 enum rtx_code cond_code = GET_CODE (operands[1]);
11346 rtx op0 = operands[0];
11347 rtx op1 = operands[2];
11348 HOST_WIDE_INT val = INTVAL (operands[3]);
11350 if (cond_code == GE || cond_code == GT)
11352 cond_code = reverse_condition (cond_code);
11356 if (cond_code == LE)
11359 rtx tmp = gen_reg_rtx (<MODE>mode);
11360 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11361 rtx x = gen_reg_rtx (<MODE>mode);
11363 emit_insn (gen_and<mode>3 (x, op1, tmp));
11365 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11369 rtx tmp = gen_reg_rtx (<MODE>mode);
11370 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11374 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11375 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11380 (define_expand "cstore<mode>4_unsigned_imm"
11381 [(use (match_operator 1 "unsigned_comparison_operator"
11382 [(match_operand:GPR 2 "gpc_reg_operand")
11383 (match_operand:GPR 3 "immediate_operand")]))
11384 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11387 bool invert = false;
11389 enum rtx_code cond_code = GET_CODE (operands[1]);
11391 rtx op0 = operands[0];
11392 rtx op1 = operands[2];
11393 HOST_WIDE_INT val = INTVAL (operands[3]);
11395 if (cond_code == GEU || cond_code == GTU)
11397 cond_code = reverse_condition (cond_code);
11401 if (cond_code == LEU)
11404 rtx tmp = gen_reg_rtx (<MODE>mode);
11405 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11406 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11407 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11408 rtx x = gen_reg_rtx (<MODE>mode);
11410 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11412 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11416 rtx tmp = gen_reg_rtx (<MODE>mode);
11417 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11421 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11422 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11427 (define_expand "cstore<mode>4"
11428 [(use (match_operator 1 "comparison_operator"
11429 [(match_operand:GPR 2 "gpc_reg_operand")
11430 (match_operand:GPR 3 "reg_or_short_operand")]))
11431 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11434 /* Expanding EQ and NE directly to some machine instructions does not help
11435 but does hurt combine. So don't. */
11436 if (GET_CODE (operands[1]) == EQ)
11437 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11438 else if (<MODE>mode == Pmode
11439 && GET_CODE (operands[1]) == NE)
11440 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11441 else if (GET_CODE (operands[1]) == NE)
11443 rtx tmp = gen_reg_rtx (<MODE>mode);
11444 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11445 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11448 /* If ISEL is fast, expand to it. */
11449 else if (TARGET_ISEL)
11450 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11452 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11453 etc. combinations magically work out just right. */
11454 else if (<MODE>mode == Pmode
11455 && unsigned_comparison_operator (operands[1], VOIDmode))
11456 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11457 operands[2], operands[3]));
11459 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11460 else if (<MODE>mode == SImode && Pmode == DImode)
11461 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11462 operands[2], operands[3]));
11464 /* For signed comparisons against a constant, we can do some simple
11466 else if (signed_comparison_operator (operands[1], VOIDmode)
11467 && CONST_INT_P (operands[3]))
11468 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11469 operands[2], operands[3]));
11471 /* And similarly for unsigned comparisons. */
11472 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11473 && CONST_INT_P (operands[3]))
11474 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11475 operands[2], operands[3]));
11477 /* We also do not want to use mfcr for signed comparisons. */
11478 else if (<MODE>mode == Pmode
11479 && signed_comparison_operator (operands[1], VOIDmode))
11480 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11481 operands[2], operands[3]));
11483 /* Everything else, use the mfcr brute force. */
11485 rs6000_emit_sCOND (<MODE>mode, operands);
11490 (define_expand "cstore<mode>4"
11491 [(use (match_operator 1 "comparison_operator"
11492 [(match_operand:FP 2 "gpc_reg_operand")
11493 (match_operand:FP 3 "gpc_reg_operand")]))
11494 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11497 rs6000_emit_sCOND (<MODE>mode, operands);
11502 (define_expand "stack_protect_set"
11503 [(match_operand 0 "memory_operand")
11504 (match_operand 1 "memory_operand")]
11507 if (rs6000_stack_protector_guard == SSP_TLS)
11509 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11510 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11511 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11512 operands[1] = gen_rtx_MEM (Pmode, addr);
11516 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11518 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11523 (define_insn "stack_protect_setsi"
11524 [(set (match_operand:SI 0 "memory_operand" "=m")
11525 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11526 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11528 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11529 [(set_attr "type" "three")
11530 (set_attr "length" "12")])
11532 ;; We can't use the prefixed attribute here because there are two memory
11533 ;; instructions. We can't split the insn due to the fact that this operation
11534 ;; needs to be done in one piece.
11535 (define_insn "stack_protect_setdi"
11536 [(set (match_operand:DI 0 "memory_operand" "=Y")
11537 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11538 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11541 if (prefixed_memory (operands[1], DImode))
11542 output_asm_insn ("pld %2,%1", operands);
11544 output_asm_insn ("ld%U1%X1 %2,%1", operands);
11546 if (prefixed_memory (operands[0], DImode))
11547 output_asm_insn ("pstd %2,%0", operands);
11549 output_asm_insn ("std%U0%X0 %2,%0", operands);
11553 [(set_attr "type" "three")
11555 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11556 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
11557 ;; the LI 0 at the end.
11558 (set_attr "prefixed" "no")
11559 (set_attr "num_insns" "3")
11560 (set (attr "length")
11561 (cond [(and (match_operand 0 "prefixed_memory")
11562 (match_operand 1 "prefixed_memory"))
11565 (ior (match_operand 0 "prefixed_memory")
11566 (match_operand 1 "prefixed_memory"))
11571 (define_expand "stack_protect_test"
11572 [(match_operand 0 "memory_operand")
11573 (match_operand 1 "memory_operand")
11574 (match_operand 2 "")]
11577 rtx guard = operands[1];
11579 if (rs6000_stack_protector_guard == SSP_TLS)
11581 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11582 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11583 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11584 guard = gen_rtx_MEM (Pmode, addr);
11587 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11588 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11589 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11590 emit_jump_insn (jump);
11595 (define_insn "stack_protect_testsi"
11596 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11597 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11598 (match_operand:SI 2 "memory_operand" "m,m")]
11600 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11601 (clobber (match_scratch:SI 3 "=&r,&r"))]
11604 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11605 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11606 [(set_attr "length" "16,20")])
11608 ;; We can't use the prefixed attribute here because there are two memory
11609 ;; instructions. We can't split the insn due to the fact that this operation
11610 ;; needs to be done in one piece.
11611 (define_insn "stack_protect_testdi"
11612 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11613 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11614 (match_operand:DI 2 "memory_operand" "Y,Y")]
11616 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11617 (clobber (match_scratch:DI 3 "=&r,&r"))]
11620 if (prefixed_memory (operands[1], DImode))
11621 output_asm_insn ("pld %3,%1", operands);
11623 output_asm_insn ("ld%U1%X1 %3,%1", operands);
11625 if (prefixed_memory (operands[2], DImode))
11626 output_asm_insn ("pld %4,%2", operands);
11628 output_asm_insn ("ld%U2%X2 %4,%2", operands);
11630 if (which_alternative == 0)
11631 output_asm_insn ("xor. %3,%3,%4", operands);
11633 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11637 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11638 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
11639 ;; 8 bytes to do the test.
11640 [(set_attr "prefixed" "no")
11641 (set_attr "num_insns" "4,5")
11642 (set (attr "length")
11643 (cond [(and (match_operand 1 "prefixed_memory")
11644 (match_operand 2 "prefixed_memory"))
11645 (if_then_else (eq_attr "alternative" "0")
11649 (ior (match_operand 1 "prefixed_memory")
11650 (match_operand 2 "prefixed_memory"))
11651 (if_then_else (eq_attr "alternative" "0")
11655 (if_then_else (eq_attr "alternative" "0")
11657 (const_int 20))))])
11660 ;; Here are the actual compare insns.
11661 (define_insn "*cmp<mode>_signed"
11662 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11663 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11664 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11666 "cmp<wd>%I2 %0,%1,%2"
11667 [(set_attr "type" "cmp")])
11669 (define_insn "*cmp<mode>_unsigned"
11670 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11671 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11672 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11674 "cmpl<wd>%I2 %0,%1,%2"
11675 [(set_attr "type" "cmp")])
11677 ;; If we are comparing a register for equality with a large constant,
11678 ;; we can do this with an XOR followed by a compare. But this is profitable
11679 ;; only if the large constant is only used for the comparison (and in this
11680 ;; case we already have a register to reuse as scratch).
11682 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11683 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11686 [(set (match_operand:SI 0 "register_operand")
11687 (match_operand:SI 1 "logical_const_operand"))
11688 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11690 (match_operand:SI 2 "logical_const_operand")]))
11691 (set (match_operand:CC 4 "cc_reg_operand")
11692 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11695 (if_then_else (match_operator 6 "equality_operator"
11696 [(match_dup 4) (const_int 0)])
11697 (match_operand 7 "")
11698 (match_operand 8 "")))]
11699 "peep2_reg_dead_p (3, operands[0])
11700 && peep2_reg_dead_p (4, operands[4])
11701 && REGNO (operands[0]) != REGNO (operands[5])"
11702 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11703 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11704 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11707 /* Get the constant we are comparing against, and see what it looks like
11708 when sign-extended from 16 to 32 bits. Then see what constant we could
11709 XOR with SEXTC to get the sign-extended value. */
11710 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11712 operands[1], operands[2]);
11713 HOST_WIDE_INT c = INTVAL (cnst);
11714 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11715 HOST_WIDE_INT xorv = c ^ sextc;
11717 operands[9] = GEN_INT (xorv);
11718 operands[10] = GEN_INT (sextc);
11721 ;; Only need to compare second words if first words equal
11722 (define_insn "*cmp<mode>_internal1"
11723 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11724 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11725 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11726 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11727 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11728 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11729 [(set_attr "type" "fpcompare")
11730 (set_attr "length" "12")])
11732 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11733 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11734 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11735 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11736 (clobber (match_scratch:DF 3 "=d"))
11737 (clobber (match_scratch:DF 4 "=d"))
11738 (clobber (match_scratch:DF 5 "=d"))
11739 (clobber (match_scratch:DF 6 "=d"))
11740 (clobber (match_scratch:DF 7 "=d"))
11741 (clobber (match_scratch:DF 8 "=d"))
11742 (clobber (match_scratch:DF 9 "=d"))
11743 (clobber (match_scratch:DF 10 "=d"))
11744 (clobber (match_scratch:GPR 11 "=b"))]
11745 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11746 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11748 "&& reload_completed"
11749 [(set (match_dup 3) (match_dup 14))
11750 (set (match_dup 4) (match_dup 15))
11751 (set (match_dup 9) (abs:DF (match_dup 5)))
11752 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11753 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11754 (label_ref (match_dup 12))
11756 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11757 (set (pc) (label_ref (match_dup 13)))
11759 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11760 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11761 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11762 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11765 REAL_VALUE_TYPE rv;
11766 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11767 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11769 operands[5] = simplify_gen_subreg (DFmode, operands[1],
11770 <IBM128:MODE>mode, hi_word);
11771 operands[6] = simplify_gen_subreg (DFmode, operands[1],
11772 <IBM128:MODE>mode, lo_word);
11773 operands[7] = simplify_gen_subreg (DFmode, operands[2],
11774 <IBM128:MODE>mode, hi_word);
11775 operands[8] = simplify_gen_subreg (DFmode, operands[2],
11776 <IBM128:MODE>mode, lo_word);
11777 operands[12] = gen_label_rtx ();
11778 operands[13] = gen_label_rtx ();
11780 operands[14] = force_const_mem (DFmode,
11781 const_double_from_real_value (rv, DFmode));
11782 operands[15] = force_const_mem (DFmode,
11783 const_double_from_real_value (dconst0,
11788 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11789 operands[14] = gen_const_mem (DFmode, tocref);
11790 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11791 operands[15] = gen_const_mem (DFmode, tocref);
11792 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11793 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11797 ;; Now we have the scc insns. We can do some combinations because of the
11798 ;; way the machine works.
11800 ;; Note that this is probably faster if we can put an insn between the
11801 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11802 ;; cases the insns below which don't use an intermediate CR field will
11803 ;; be used instead.
11805 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11806 (match_operator:GPR 1 "scc_comparison_operator"
11807 [(match_operand 2 "cc_reg_operand" "y")
11810 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11811 [(set (attr "type")
11812 (cond [(match_test "TARGET_MFCRF")
11813 (const_string "mfcrf")
11815 (const_string "mfcr")))
11816 (set_attr "length" "8")])
11818 (define_insn_and_split ""
11819 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11820 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11821 [(match_operand 2 "cc_reg_operand" "y,y")
11824 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11825 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11828 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11830 "&& reload_completed"
11831 [(set (match_dup 3)
11832 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11834 (compare:CC (match_dup 3)
11837 [(set_attr "type" "shift")
11838 (set_attr "dot" "yes")
11839 (set_attr "length" "8,16")])
11842 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11843 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11844 [(match_operand 2 "cc_reg_operand" "y")
11846 (match_operand:SI 3 "const_int_operand" "n")))]
11849 int is_bit = ccr_bit (operands[1], 1);
11850 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11853 gcc_assert (is_bit != -1);
11854 if (is_bit >= put_bit)
11855 count = is_bit - put_bit;
11857 count = 32 - (put_bit - is_bit);
11859 operands[4] = GEN_INT (count);
11860 operands[5] = GEN_INT (put_bit);
11862 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11864 [(set (attr "type")
11865 (cond [(match_test "TARGET_MFCRF")
11866 (const_string "mfcrf")
11868 (const_string "mfcr")))
11869 (set_attr "length" "8")])
11872 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11874 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11875 [(match_operand 2 "cc_reg_operand" "y,y")
11877 (match_operand:SI 3 "const_int_operand" "n,n"))
11879 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11880 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11884 int is_bit = ccr_bit (operands[1], 1);
11885 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11888 gcc_assert (is_bit != -1);
11889 /* Force split for non-cc0 compare. */
11890 if (which_alternative == 1)
11893 if (is_bit >= put_bit)
11894 count = is_bit - put_bit;
11896 count = 32 - (put_bit - is_bit);
11898 operands[5] = GEN_INT (count);
11899 operands[6] = GEN_INT (put_bit);
11901 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11903 [(set_attr "type" "shift")
11904 (set_attr "dot" "yes")
11905 (set_attr "length" "8,16")])
11908 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11910 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11911 [(match_operand 2 "cc_reg_operand")
11913 (match_operand:SI 3 "const_int_operand"))
11915 (set (match_operand:SI 4 "gpc_reg_operand")
11916 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11919 [(set (match_dup 4)
11920 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11923 (compare:CC (match_dup 4)
11928 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11929 (define_code_attr UNS [(eq "CC")
11931 (lt "CC") (ltu "CCUNS")
11932 (gt "CC") (gtu "CCUNS")
11933 (le "CC") (leu "CCUNS")
11934 (ge "CC") (geu "CCUNS")])
11935 (define_code_attr UNSu_ [(eq "")
11940 (ge "") (geu "u_")])
11941 (define_code_attr UNSIK [(eq "I")
11946 (ge "I") (geu "K")])
11948 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11949 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11950 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11951 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11952 (clobber (match_scratch:GPR 3 "=r"))
11953 (clobber (match_scratch:GPR 4 "=r"))
11954 (clobber (match_scratch:<UNS> 5 "=y"))]
11956 && !(<CODE> == EQ && operands[2] == const0_rtx)
11957 && !(<CODE> == NE && operands[2] == const0_rtx
11958 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11963 rtx_code code = <CODE>;
11964 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11966 HOST_WIDE_INT val = INTVAL (operands[2]);
11967 if (code == LT && val != -0x8000)
11972 if (code == GT && val != 0x7fff)
11977 if (code == LTU && val != 0)
11982 if (code == GTU && val != 0xffff)
11987 operands[2] = GEN_INT (val);
11990 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11991 operands[3] = const0_rtx;
11994 if (GET_CODE (operands[3]) == SCRATCH)
11995 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11996 emit_move_insn (operands[3], const0_rtx);
11999 if (GET_CODE (operands[4]) == SCRATCH)
12000 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12001 emit_move_insn (operands[4], const1_rtx);
12003 if (GET_CODE (operands[5]) == SCRATCH)
12004 operands[5] = gen_reg_rtx (<UNS>mode);
12006 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12007 emit_insn (gen_rtx_SET (operands[5], c1));
12009 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12010 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12011 emit_move_insn (operands[0], x);
12015 [(set (attr "cost")
12016 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12018 || <CODE> == LE || <CODE> == GE
12019 || <CODE> == LEU || <CODE> == GEU")
12021 (const_string "10")))])
12023 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12026 (define_expand "eq<mode>3"
12028 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12029 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12030 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12031 (clobber (match_scratch:GPR 3 "=r"))
12032 (clobber (match_scratch:GPR 4 "=r"))])]
12035 if (TARGET_ISEL && operands[2] != const0_rtx)
12037 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12043 (define_insn_and_split "*eq<mode>3"
12044 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12045 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12046 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12047 (clobber (match_scratch:GPR 3 "=r"))
12048 (clobber (match_scratch:GPR 4 "=r"))]
12049 "!(TARGET_ISEL && operands[2] != const0_rtx)"
12052 [(set (match_dup 4)
12053 (clz:GPR (match_dup 3)))
12055 (lshiftrt:GPR (match_dup 4)
12058 operands[3] = rs6000_emit_eqne (<MODE>mode,
12059 operands[1], operands[2], operands[3]);
12061 if (GET_CODE (operands[4]) == SCRATCH)
12062 operands[4] = gen_reg_rtx (<MODE>mode);
12064 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12066 [(set (attr "length")
12067 (if_then_else (match_test "operands[2] == const0_rtx")
12069 (const_string "12")))])
12071 (define_expand "ne<mode>3"
12073 (set (match_operand:P 0 "gpc_reg_operand" "=r")
12074 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12075 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12076 (clobber (match_scratch:P 3 "=r"))
12077 (clobber (match_scratch:P 4 "=r"))
12078 (clobber (reg:P CA_REGNO))])]
12081 if (TARGET_ISEL && operands[2] != const0_rtx)
12083 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12089 (define_insn_and_split "*ne<mode>3"
12090 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12091 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12092 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12093 (clobber (match_scratch:P 3 "=r"))
12094 (clobber (match_scratch:P 4 "=r"))
12095 (clobber (reg:P CA_REGNO))]
12096 "!(TARGET_ISEL && operands[2] != const0_rtx)"
12099 [(parallel [(set (match_dup 4)
12100 (plus:P (match_dup 3)
12102 (set (reg:P CA_REGNO)
12103 (ne:P (match_dup 3)
12105 (parallel [(set (match_dup 0)
12106 (plus:P (plus:P (not:P (match_dup 4))
12109 (clobber (reg:P CA_REGNO))])]
12111 operands[3] = rs6000_emit_eqne (<MODE>mode,
12112 operands[1], operands[2], operands[3]);
12114 if (GET_CODE (operands[4]) == SCRATCH)
12115 operands[4] = gen_reg_rtx (<MODE>mode);
12117 [(set (attr "length")
12118 (if_then_else (match_test "operands[2] == const0_rtx")
12120 (const_string "12")))])
12122 (define_insn_and_split "*neg_eq_<mode>"
12123 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12124 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12125 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12126 (clobber (match_scratch:P 3 "=r"))
12127 (clobber (match_scratch:P 4 "=r"))
12128 (clobber (reg:P CA_REGNO))]
12132 [(parallel [(set (match_dup 4)
12133 (plus:P (match_dup 3)
12135 (set (reg:P CA_REGNO)
12136 (ne:P (match_dup 3)
12138 (parallel [(set (match_dup 0)
12139 (plus:P (reg:P CA_REGNO)
12141 (clobber (reg:P CA_REGNO))])]
12143 operands[3] = rs6000_emit_eqne (<MODE>mode,
12144 operands[1], operands[2], operands[3]);
12146 if (GET_CODE (operands[4]) == SCRATCH)
12147 operands[4] = gen_reg_rtx (<MODE>mode);
12149 [(set (attr "length")
12150 (if_then_else (match_test "operands[2] == const0_rtx")
12152 (const_string "12")))])
12154 (define_insn_and_split "*neg_ne_<mode>"
12155 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12156 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12157 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12158 (clobber (match_scratch:P 3 "=r"))
12159 (clobber (match_scratch:P 4 "=r"))
12160 (clobber (reg:P CA_REGNO))]
12164 [(parallel [(set (match_dup 4)
12165 (neg:P (match_dup 3)))
12166 (set (reg:P CA_REGNO)
12167 (eq:P (match_dup 3)
12169 (parallel [(set (match_dup 0)
12170 (plus:P (reg:P CA_REGNO)
12172 (clobber (reg:P CA_REGNO))])]
12174 operands[3] = rs6000_emit_eqne (<MODE>mode,
12175 operands[1], operands[2], operands[3]);
12177 if (GET_CODE (operands[4]) == SCRATCH)
12178 operands[4] = gen_reg_rtx (<MODE>mode);
12180 [(set (attr "length")
12181 (if_then_else (match_test "operands[2] == const0_rtx")
12183 (const_string "12")))])
12185 (define_insn_and_split "*plus_eq_<mode>"
12186 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12187 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12188 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12189 (match_operand:P 3 "gpc_reg_operand" "r")))
12190 (clobber (match_scratch:P 4 "=r"))
12191 (clobber (match_scratch:P 5 "=r"))
12192 (clobber (reg:P CA_REGNO))]
12196 [(parallel [(set (match_dup 5)
12197 (neg:P (match_dup 4)))
12198 (set (reg:P CA_REGNO)
12199 (eq:P (match_dup 4)
12201 (parallel [(set (match_dup 0)
12202 (plus:P (match_dup 3)
12204 (clobber (reg:P CA_REGNO))])]
12206 operands[4] = rs6000_emit_eqne (<MODE>mode,
12207 operands[1], operands[2], operands[4]);
12209 if (GET_CODE (operands[5]) == SCRATCH)
12210 operands[5] = gen_reg_rtx (<MODE>mode);
12212 [(set (attr "length")
12213 (if_then_else (match_test "operands[2] == const0_rtx")
12215 (const_string "12")))])
12217 (define_insn_and_split "*plus_ne_<mode>"
12218 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12219 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12220 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12221 (match_operand:P 3 "gpc_reg_operand" "r")))
12222 (clobber (match_scratch:P 4 "=r"))
12223 (clobber (match_scratch:P 5 "=r"))
12224 (clobber (reg:P CA_REGNO))]
12228 [(parallel [(set (match_dup 5)
12229 (plus:P (match_dup 4)
12231 (set (reg:P CA_REGNO)
12232 (ne:P (match_dup 4)
12234 (parallel [(set (match_dup 0)
12235 (plus:P (match_dup 3)
12237 (clobber (reg:P CA_REGNO))])]
12239 operands[4] = rs6000_emit_eqne (<MODE>mode,
12240 operands[1], operands[2], operands[4]);
12242 if (GET_CODE (operands[5]) == SCRATCH)
12243 operands[5] = gen_reg_rtx (<MODE>mode);
12245 [(set (attr "length")
12246 (if_then_else (match_test "operands[2] == const0_rtx")
12248 (const_string "12")))])
12250 (define_insn_and_split "*minus_eq_<mode>"
12251 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12252 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12253 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12254 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12255 (clobber (match_scratch:P 4 "=r"))
12256 (clobber (match_scratch:P 5 "=r"))
12257 (clobber (reg:P CA_REGNO))]
12261 [(parallel [(set (match_dup 5)
12262 (plus:P (match_dup 4)
12264 (set (reg:P CA_REGNO)
12265 (ne:P (match_dup 4)
12267 (parallel [(set (match_dup 0)
12268 (plus:P (plus:P (match_dup 3)
12271 (clobber (reg:P CA_REGNO))])]
12273 operands[4] = rs6000_emit_eqne (<MODE>mode,
12274 operands[1], operands[2], operands[4]);
12276 if (GET_CODE (operands[5]) == SCRATCH)
12277 operands[5] = gen_reg_rtx (<MODE>mode);
12279 [(set (attr "length")
12280 (if_then_else (match_test "operands[2] == const0_rtx")
12282 (const_string "12")))])
12284 (define_insn_and_split "*minus_ne_<mode>"
12285 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12286 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12287 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12288 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12289 (clobber (match_scratch:P 4 "=r"))
12290 (clobber (match_scratch:P 5 "=r"))
12291 (clobber (reg:P CA_REGNO))]
12295 [(parallel [(set (match_dup 5)
12296 (neg:P (match_dup 4)))
12297 (set (reg:P CA_REGNO)
12298 (eq:P (match_dup 4)
12300 (parallel [(set (match_dup 0)
12301 (plus:P (plus:P (match_dup 3)
12304 (clobber (reg:P CA_REGNO))])]
12306 operands[4] = rs6000_emit_eqne (<MODE>mode,
12307 operands[1], operands[2], operands[4]);
12309 if (GET_CODE (operands[5]) == SCRATCH)
12310 operands[5] = gen_reg_rtx (<MODE>mode);
12312 [(set (attr "length")
12313 (if_then_else (match_test "operands[2] == const0_rtx")
12315 (const_string "12")))])
12317 (define_insn_and_split "*eqsi3_ext<mode>"
12318 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12319 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12320 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12321 (clobber (match_scratch:SI 3 "=r"))
12322 (clobber (match_scratch:SI 4 "=r"))]
12326 [(set (match_dup 4)
12327 (clz:SI (match_dup 3)))
12330 (lshiftrt:SI (match_dup 4)
12333 operands[3] = rs6000_emit_eqne (SImode,
12334 operands[1], operands[2], operands[3]);
12336 if (GET_CODE (operands[4]) == SCRATCH)
12337 operands[4] = gen_reg_rtx (SImode);
12339 [(set (attr "length")
12340 (if_then_else (match_test "operands[2] == const0_rtx")
12342 (const_string "12")))])
12344 (define_insn_and_split "*nesi3_ext<mode>"
12345 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12346 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12347 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12348 (clobber (match_scratch:SI 3 "=r"))
12349 (clobber (match_scratch:SI 4 "=r"))
12350 (clobber (match_scratch:EXTSI 5 "=r"))]
12354 [(set (match_dup 4)
12355 (clz:SI (match_dup 3)))
12358 (lshiftrt:SI (match_dup 4)
12361 (xor:EXTSI (match_dup 5)
12364 operands[3] = rs6000_emit_eqne (SImode,
12365 operands[1], operands[2], operands[3]);
12367 if (GET_CODE (operands[4]) == SCRATCH)
12368 operands[4] = gen_reg_rtx (SImode);
12369 if (GET_CODE (operands[5]) == SCRATCH)
12370 operands[5] = gen_reg_rtx (<MODE>mode);
12372 [(set (attr "length")
12373 (if_then_else (match_test "operands[2] == const0_rtx")
12374 (const_string "12")
12375 (const_string "16")))])
12377 ;; Conditional branches.
12378 ;; These either are a single bc insn, or a bc around a b.
12380 (define_insn "*cbranch"
12382 (if_then_else (match_operator 1 "branch_comparison_operator"
12383 [(match_operand 2 "cc_reg_operand" "y")
12385 (label_ref (match_operand 0))
12389 return output_cbranch (operands[1], "%l0", 0, insn);
12391 [(set_attr "type" "branch")
12392 (set (attr "length")
12393 (if_then_else (and (ge (minus (match_dup 0) (pc))
12394 (const_int -32768))
12395 (lt (minus (match_dup 0) (pc))
12396 (const_int 32764)))
12400 ;; Conditional return.
12401 (define_insn "*creturn"
12403 (if_then_else (match_operator 0 "branch_comparison_operator"
12404 [(match_operand 1 "cc_reg_operand" "y")
12410 return output_cbranch (operands[0], NULL, 0, insn);
12412 [(set_attr "type" "jmpreg")])
12414 ;; Logic on condition register values.
12416 ; This pattern matches things like
12417 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12418 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12420 ; which are generated by the branch logic.
12421 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12423 (define_insn "cceq_ior_compare"
12424 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12425 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12426 [(match_operator:SI 2
12427 "branch_positive_comparison_operator"
12429 "cc_reg_operand" "y,y")
12431 (match_operator:SI 4
12432 "branch_positive_comparison_operator"
12434 "cc_reg_operand" "0,y")
12438 "cr%q1 %E0,%j2,%j4"
12439 [(set_attr "type" "cr_logical")
12440 (set_attr "cr_logical_3op" "no,yes")])
12442 ; Why is the constant -1 here, but 1 in the previous pattern?
12443 ; Because ~1 has all but the low bit set.
12444 (define_insn "cceq_ior_compare_complement"
12445 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12446 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12447 [(not:SI (match_operator:SI 2
12448 "branch_positive_comparison_operator"
12450 "cc_reg_operand" "y,y")
12452 (match_operator:SI 4
12453 "branch_positive_comparison_operator"
12455 "cc_reg_operand" "0,y")
12459 "cr%q1 %E0,%j2,%j4"
12460 [(set_attr "type" "cr_logical")
12461 (set_attr "cr_logical_3op" "no,yes")])
12463 (define_insn "*cceq_rev_compare"
12464 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12465 (compare:CCEQ (match_operator:SI 1
12466 "branch_positive_comparison_operator"
12468 "cc_reg_operand" "0,y")
12473 [(set_attr "type" "cr_logical")
12474 (set_attr "cr_logical_3op" "no,yes")])
12476 ;; If we are comparing the result of two comparisons, this can be done
12477 ;; using creqv or crxor.
12479 (define_insn_and_split ""
12480 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12481 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12482 [(match_operand 2 "cc_reg_operand" "y")
12484 (match_operator 3 "branch_comparison_operator"
12485 [(match_operand 4 "cc_reg_operand" "y")
12490 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12493 int positive_1, positive_2;
12495 positive_1 = branch_positive_comparison_operator (operands[1],
12496 GET_MODE (operands[1]));
12497 positive_2 = branch_positive_comparison_operator (operands[3],
12498 GET_MODE (operands[3]));
12501 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12502 GET_CODE (operands[1])),
12504 operands[2], const0_rtx);
12505 else if (GET_MODE (operands[1]) != SImode)
12506 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12507 operands[2], const0_rtx);
12510 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12511 GET_CODE (operands[3])),
12513 operands[4], const0_rtx);
12514 else if (GET_MODE (operands[3]) != SImode)
12515 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12516 operands[4], const0_rtx);
12518 if (positive_1 == positive_2)
12520 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12521 operands[5] = constm1_rtx;
12525 operands[5] = const1_rtx;
12529 ;; Unconditional branch and return.
12531 (define_insn "jump"
12533 (label_ref (match_operand 0)))]
12536 [(set_attr "type" "branch")])
12538 (define_insn "<return_str>return"
12542 [(set_attr "type" "jmpreg")])
12544 (define_expand "indirect_jump"
12545 [(set (pc) (match_operand 0 "register_operand"))]
12548 if (!rs6000_speculate_indirect_jumps) {
12549 rtx ccreg = gen_reg_rtx (CCmode);
12550 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12555 (define_insn "*indirect_jump<mode>"
12557 (match_operand:P 0 "register_operand" "c,*l"))]
12558 "rs6000_speculate_indirect_jumps"
12560 [(set_attr "type" "jmpreg")])
12562 (define_insn "@indirect_jump<mode>_nospec"
12563 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12564 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12565 "!rs6000_speculate_indirect_jumps"
12566 "crset %E1\;beq%T0- %1\;b $"
12567 [(set_attr "type" "jmpreg")
12568 (set_attr "length" "12")])
12570 ;; Table jump for switch statements:
12571 (define_expand "tablejump"
12572 [(use (match_operand 0))
12573 (use (label_ref (match_operand 1)))]
12576 if (rs6000_speculate_indirect_jumps)
12579 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12581 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12585 rtx ccreg = gen_reg_rtx (CCmode);
12588 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12590 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12591 emit_jump_insn (jump);
12596 (define_expand "tablejumpsi"
12597 [(set (match_dup 3)
12598 (plus:SI (match_operand:SI 0)
12600 (parallel [(set (pc)
12602 (use (label_ref (match_operand 1)))])]
12603 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12605 operands[0] = force_reg (SImode, operands[0]);
12606 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12607 operands[3] = gen_reg_rtx (SImode);
12610 (define_expand "tablejumpsi_nospec"
12611 [(set (match_dup 4)
12612 (plus:SI (match_operand:SI 0)
12614 (parallel [(set (pc)
12616 (use (label_ref (match_operand 1)))
12617 (clobber (match_operand 2))])]
12618 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12620 operands[0] = force_reg (SImode, operands[0]);
12621 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12622 operands[4] = gen_reg_rtx (SImode);
12625 (define_expand "tablejumpdi"
12626 [(set (match_dup 4)
12627 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12629 (plus:DI (match_dup 4)
12631 (parallel [(set (pc)
12633 (use (label_ref (match_operand 1)))])]
12634 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12636 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12637 operands[3] = gen_reg_rtx (DImode);
12638 operands[4] = gen_reg_rtx (DImode);
12641 (define_expand "tablejumpdi_nospec"
12642 [(set (match_dup 5)
12643 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12645 (plus:DI (match_dup 5)
12647 (parallel [(set (pc)
12649 (use (label_ref (match_operand 1)))
12650 (clobber (match_operand 2))])]
12651 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12653 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12654 operands[4] = gen_reg_rtx (DImode);
12655 operands[5] = gen_reg_rtx (DImode);
12658 (define_insn "*tablejump<mode>_internal1"
12660 (match_operand:P 0 "register_operand" "c,*l"))
12661 (use (label_ref (match_operand 1)))]
12662 "rs6000_speculate_indirect_jumps"
12664 [(set_attr "type" "jmpreg")])
12666 (define_insn "*tablejump<mode>_internal1_nospec"
12668 (match_operand:P 0 "register_operand" "c,*l"))
12669 (use (label_ref (match_operand 1)))
12670 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12671 "!rs6000_speculate_indirect_jumps"
12672 "crset %E2\;beq%T0- %2\;b $"
12673 [(set_attr "type" "jmpreg")
12674 (set_attr "length" "12")])
12677 [(unspec [(const_int 0)] UNSPEC_NOP)]
12681 (define_insn "group_ending_nop"
12682 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12685 operands[0] = gen_rtx_REG (Pmode,
12686 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12687 return "ori %0,%0,0";
12690 (define_insn "speculation_barrier"
12691 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12694 operands[0] = gen_rtx_REG (Pmode, 31);
12695 return "ori %0,%0,0";
12698 ;; Define the subtract-one-and-jump insns, starting with the template
12699 ;; so loop.c knows what to generate.
12701 (define_expand "doloop_end"
12702 [(use (match_operand 0)) ; loop pseudo
12703 (use (match_operand 1))] ; label
12706 if (GET_MODE (operands[0]) != Pmode)
12709 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12713 (define_expand "@ctr<mode>"
12714 [(parallel [(set (pc)
12715 (if_then_else (ne (match_operand:P 0 "register_operand")
12717 (label_ref (match_operand 1))
12720 (plus:P (match_dup 0)
12722 (clobber (match_scratch:CC 2))
12723 (clobber (match_scratch:P 3))])]
12727 ;; We need to be able to do this for any operand, including MEM, or we
12728 ;; will cause reload to blow up since we don't allow output reloads on
12730 ;; For the length attribute to be calculated correctly, the
12731 ;; label MUST be operand 0.
12732 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12733 ;; the ctr<mode> insns.
12735 (define_code_iterator eqne [eq ne])
12736 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12737 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12739 (define_insn "<bd>_<mode>"
12741 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12743 (label_ref (match_operand 0))
12745 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12746 (plus:P (match_dup 1)
12748 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12749 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12752 if (which_alternative != 0)
12754 else if (get_attr_length (insn) == 4)
12757 return "<bd_neg> $+8\;b %l0";
12759 [(set_attr "type" "branch")
12760 (set_attr_alternative "length"
12761 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12762 (const_int -32768))
12763 (lt (minus (match_dup 0) (pc))
12764 (const_int 32764)))
12767 (const_string "16")
12768 (const_string "20")
12769 (const_string "20")])])
12771 ;; Now the splitter if we could not allocate the CTR register
12774 (if_then_else (match_operator 2 "comparison_operator"
12775 [(match_operand:P 1 "gpc_reg_operand")
12778 (match_operand 6)))
12779 (set (match_operand:P 0 "nonimmediate_operand")
12780 (plus:P (match_dup 1)
12782 (clobber (match_scratch:CC 3))
12783 (clobber (match_scratch:P 4))]
12786 (if_then_else (match_dup 7)
12790 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12792 emit_insn (gen_rtx_SET (operands[3],
12793 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12794 if (int_reg_operand (operands[0], <MODE>mode))
12795 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12798 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12799 emit_move_insn (operands[0], operands[4]);
12801 /* No DONE so branch comes from the pattern. */
12804 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12805 ;; Note that in the case of long branches we have to decompose this into
12806 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12807 ;; and the CR bit, which means there is no way to conveniently invert the
12808 ;; comparison as is done with plain bdnz/bdz.
12810 (define_insn "<bd>tf_<mode>"
12814 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12816 (match_operator 3 "branch_comparison_operator"
12817 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12819 (label_ref (match_operand 0))
12821 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12822 (plus:P (match_dup 1)
12824 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12825 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12826 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12829 if (which_alternative != 0)
12831 else if (get_attr_length (insn) == 4)
12833 if (branch_positive_comparison_operator (operands[3],
12834 GET_MODE (operands[3])))
12835 return "<bd>t %j3,%l0";
12837 return "<bd>f %j3,%l0";
12841 static char seq[96];
12842 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12843 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12847 [(set_attr "type" "branch")
12848 (set_attr_alternative "length"
12849 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12850 (const_int -32768))
12851 (lt (minus (match_dup 0) (pc))
12852 (const_int 32764)))
12855 (const_string "16")
12856 (const_string "20")
12857 (const_string "20")])])
12859 ;; Now the splitter if we could not allocate the CTR register
12864 (match_operator 1 "comparison_operator"
12865 [(match_operand:P 0 "gpc_reg_operand")
12867 (match_operator 3 "branch_comparison_operator"
12868 [(match_operand 2 "cc_reg_operand")
12871 (match_operand 5)))
12872 (set (match_operand:P 6 "nonimmediate_operand")
12873 (plus:P (match_dup 0)
12875 (clobber (match_scratch:P 7))
12876 (clobber (match_scratch:CC 8))
12877 (clobber (match_scratch:CCEQ 9))]
12881 rtx ctr = operands[0];
12882 rtx ctrcmp = operands[1];
12883 rtx ccin = operands[2];
12884 rtx cccmp = operands[3];
12885 rtx dst1 = operands[4];
12886 rtx dst2 = operands[5];
12887 rtx ctrout = operands[6];
12888 rtx ctrtmp = operands[7];
12889 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12890 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12892 cmpcode = reverse_condition (cmpcode);
12893 /* Generate crand/crandc here. */
12894 emit_insn (gen_rtx_SET (operands[8],
12895 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12896 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12898 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12900 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12901 operands[8], cccmp, ccin));
12903 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12904 operands[8], cccmp, ccin));
12905 if (int_reg_operand (ctrout, <MODE>mode))
12906 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12909 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12910 emit_move_insn (ctrout, ctrtmp);
12912 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12913 emit_jump_insn (gen_rtx_SET (pc_rtx,
12914 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12920 (define_insn "trap"
12921 [(trap_if (const_int 1) (const_int 0))]
12924 [(set_attr "type" "trap")])
12926 (define_expand "ctrap<mode>4"
12927 [(trap_if (match_operator 0 "ordered_comparison_operator"
12928 [(match_operand:GPR 1 "register_operand")
12929 (match_operand:GPR 2 "reg_or_short_operand")])
12930 (match_operand 3 "zero_constant" ""))]
12935 [(trap_if (match_operator 0 "ordered_comparison_operator"
12936 [(match_operand:GPR 1 "register_operand" "r")
12937 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12940 "t<wd>%V0%I2 %1,%2"
12941 [(set_attr "type" "trap")])
12943 ;; Insns related to generating the function prologue and epilogue.
12945 (define_expand "prologue"
12946 [(use (const_int 0))]
12949 rs6000_emit_prologue ();
12950 if (!TARGET_SCHED_PROLOG)
12951 emit_insn (gen_blockage ());
12955 (define_insn "*movesi_from_cr_one"
12956 [(match_parallel 0 "mfcr_operation"
12957 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12958 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12959 (match_operand 3 "immediate_operand" "n")]
12960 UNSPEC_MOVESI_FROM_CR))])]
12965 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12967 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12968 operands[4] = GEN_INT (mask);
12969 output_asm_insn ("mfcr %1,%4", operands);
12973 [(set_attr "type" "mfcrf")])
12975 ;; Don't include the volatile CRs since their values are not used wrt CR save
12976 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12977 ;; prologue past an insn (early exit test) that defines a register used in the
12979 (define_insn "prologue_movesi_from_cr"
12980 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12981 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12982 (reg:CC CR4_REGNO)]
12983 UNSPEC_MOVESI_FROM_CR))]
12986 [(set_attr "type" "mfcr")])
12988 (define_insn "*crsave"
12989 [(match_parallel 0 "crsave_operation"
12990 [(set (match_operand:SI 1 "memory_operand" "=m")
12991 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12994 [(set_attr "type" "store")])
12996 (define_insn "*stmw"
12997 [(match_parallel 0 "stmw_operation"
12998 [(set (match_operand:SI 1 "memory_operand" "=m")
12999 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13002 [(set_attr "type" "store")
13003 (set_attr "update" "yes")
13004 (set_attr "indexed" "yes")])
13006 ; The following comment applies to:
13010 ; return_and_restore_gpregs*
13011 ; return_and_restore_fpregs*
13012 ; return_and_restore_fpregs_aix*
13014 ; The out-of-line save / restore functions expects one input argument.
13015 ; Since those are not standard call_insn's, we must avoid using
13016 ; MATCH_OPERAND for that argument. That way the register rename
13017 ; optimization will not try to rename this register.
13018 ; Each pattern is repeated for each possible register number used in
13019 ; various ABIs (r11, r1, and for some functions r12)
13021 (define_insn "*save_gpregs_<mode>_r11"
13022 [(match_parallel 0 "any_parallel_operand"
13023 [(clobber (reg:P LR_REGNO))
13024 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13026 (set (match_operand:P 2 "memory_operand" "=m")
13027 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13030 [(set_attr "type" "branch")])
13032 (define_insn "*save_gpregs_<mode>_r12"
13033 [(match_parallel 0 "any_parallel_operand"
13034 [(clobber (reg:P LR_REGNO))
13035 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13037 (set (match_operand:P 2 "memory_operand" "=m")
13038 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13041 [(set_attr "type" "branch")])
13043 (define_insn "*save_gpregs_<mode>_r1"
13044 [(match_parallel 0 "any_parallel_operand"
13045 [(clobber (reg:P LR_REGNO))
13046 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13048 (set (match_operand:P 2 "memory_operand" "=m")
13049 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13052 [(set_attr "type" "branch")])
13054 (define_insn "*save_fpregs_<mode>_r11"
13055 [(match_parallel 0 "any_parallel_operand"
13056 [(clobber (reg:P LR_REGNO))
13057 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13059 (set (match_operand:DF 2 "memory_operand" "=m")
13060 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13063 [(set_attr "type" "branch")])
13065 (define_insn "*save_fpregs_<mode>_r12"
13066 [(match_parallel 0 "any_parallel_operand"
13067 [(clobber (reg:P LR_REGNO))
13068 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13070 (set (match_operand:DF 2 "memory_operand" "=m")
13071 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13074 [(set_attr "type" "branch")])
13076 (define_insn "*save_fpregs_<mode>_r1"
13077 [(match_parallel 0 "any_parallel_operand"
13078 [(clobber (reg:P LR_REGNO))
13079 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13081 (set (match_operand:DF 2 "memory_operand" "=m")
13082 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13085 [(set_attr "type" "branch")])
13087 ; This is to explain that changes to the stack pointer should
13088 ; not be moved over loads from or stores to stack memory.
13089 (define_insn "stack_tie"
13090 [(match_parallel 0 "tie_operand"
13091 [(set (mem:BLK (reg 1)) (const_int 0))])]
13094 [(set_attr "length" "0")])
13096 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13097 ; stay behind all restores from the stack, it cannot be reordered to before
13098 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13099 (define_insn "stack_restore_tie"
13100 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13101 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13102 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13103 (set (mem:BLK (scratch)) (const_int 0))]
13108 [(set_attr "type" "*,add")])
13110 (define_expand "epilogue"
13111 [(use (const_int 0))]
13114 if (!TARGET_SCHED_PROLOG)
13115 emit_insn (gen_blockage ());
13116 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13120 ; On some processors, doing the mtcrf one CC register at a time is
13121 ; faster (like on the 604e). On others, doing them all at once is
13122 ; faster; for instance, on the 601 and 750.
13124 (define_expand "movsi_to_cr_one"
13125 [(set (match_operand:CC 0 "cc_reg_operand")
13126 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13127 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13129 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13131 (define_insn "*movsi_to_cr"
13132 [(match_parallel 0 "mtcrf_operation"
13133 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13134 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13135 (match_operand 3 "immediate_operand" "n")]
13136 UNSPEC_MOVESI_TO_CR))])]
13141 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13142 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13143 operands[4] = GEN_INT (mask);
13144 return "mtcrf %4,%2";
13146 [(set_attr "type" "mtcr")])
13148 (define_insn "*mtcrfsi"
13149 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13150 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13151 (match_operand 2 "immediate_operand" "n")]
13152 UNSPEC_MOVESI_TO_CR))]
13153 "REG_P (operands[0])
13154 && CR_REGNO_P (REGNO (operands[0]))
13155 && CONST_INT_P (operands[2])
13156 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13158 [(set_attr "type" "mtcr")])
13160 ; The load-multiple instructions have similar properties.
13161 ; Note that "load_multiple" is a name known to the machine-independent
13162 ; code that actually corresponds to the PowerPC load-string.
13164 (define_insn "*lmw"
13165 [(match_parallel 0 "lmw_operation"
13166 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13167 (match_operand:SI 2 "memory_operand" "m"))])]
13170 [(set_attr "type" "load")
13171 (set_attr "update" "yes")
13172 (set_attr "indexed" "yes")
13173 (set_attr "cell_micro" "always")])
13175 ; FIXME: "any_parallel_operand" is a bit flexible...
13177 ; The following comment applies to:
13181 ; return_and_restore_gpregs*
13182 ; return_and_restore_fpregs*
13183 ; return_and_restore_fpregs_aix*
13185 ; The out-of-line save / restore functions expects one input argument.
13186 ; Since those are not standard call_insn's, we must avoid using
13187 ; MATCH_OPERAND for that argument. That way the register rename
13188 ; optimization will not try to rename this register.
13189 ; Each pattern is repeated for each possible register number used in
13190 ; various ABIs (r11, r1, and for some functions r12)
13192 (define_insn "*restore_gpregs_<mode>_r11"
13193 [(match_parallel 0 "any_parallel_operand"
13194 [(clobber (reg:P LR_REGNO))
13195 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13197 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13198 (match_operand:P 3 "memory_operand" "m"))])]
13201 [(set_attr "type" "branch")])
13203 (define_insn "*restore_gpregs_<mode>_r12"
13204 [(match_parallel 0 "any_parallel_operand"
13205 [(clobber (reg:P LR_REGNO))
13206 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13208 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13209 (match_operand:P 3 "memory_operand" "m"))])]
13212 [(set_attr "type" "branch")])
13214 (define_insn "*restore_gpregs_<mode>_r1"
13215 [(match_parallel 0 "any_parallel_operand"
13216 [(clobber (reg:P LR_REGNO))
13217 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13219 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13220 (match_operand:P 3 "memory_operand" "m"))])]
13223 [(set_attr "type" "branch")])
13225 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13226 [(match_parallel 0 "any_parallel_operand"
13228 (clobber (reg:P LR_REGNO))
13229 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13231 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13232 (match_operand:P 3 "memory_operand" "m"))])]
13235 [(set_attr "type" "branch")])
13237 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13238 [(match_parallel 0 "any_parallel_operand"
13240 (clobber (reg:P LR_REGNO))
13241 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13243 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13244 (match_operand:P 3 "memory_operand" "m"))])]
13247 [(set_attr "type" "branch")])
13249 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13250 [(match_parallel 0 "any_parallel_operand"
13252 (clobber (reg:P LR_REGNO))
13253 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13255 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13256 (match_operand:P 3 "memory_operand" "m"))])]
13259 [(set_attr "type" "branch")])
13261 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13262 [(match_parallel 0 "any_parallel_operand"
13264 (clobber (reg:P LR_REGNO))
13265 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13267 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13268 (match_operand:DF 3 "memory_operand" "m"))])]
13271 [(set_attr "type" "branch")])
13273 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13274 [(match_parallel 0 "any_parallel_operand"
13276 (clobber (reg:P LR_REGNO))
13277 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13279 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13280 (match_operand:DF 3 "memory_operand" "m"))])]
13283 [(set_attr "type" "branch")])
13285 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13286 [(match_parallel 0 "any_parallel_operand"
13288 (clobber (reg:P LR_REGNO))
13289 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13291 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13292 (match_operand:DF 3 "memory_operand" "m"))])]
13295 [(set_attr "type" "branch")])
13297 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13298 [(match_parallel 0 "any_parallel_operand"
13300 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13302 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13303 (match_operand:DF 3 "memory_operand" "m"))])]
13306 [(set_attr "type" "branch")])
13308 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13309 [(match_parallel 0 "any_parallel_operand"
13311 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13313 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13314 (match_operand:DF 3 "memory_operand" "m"))])]
13317 [(set_attr "type" "branch")])
13319 ; This is used in compiling the unwind routines.
13320 (define_expand "eh_return"
13321 [(use (match_operand 0 "general_operand"))]
13324 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13328 ; We can't expand this before we know where the link register is stored.
13329 (define_insn_and_split "@eh_set_lr_<mode>"
13330 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13331 (clobber (match_scratch:P 1 "=&b"))]
13337 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13341 (define_insn "prefetch"
13342 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13343 (match_operand:SI 1 "const_int_operand" "n")
13344 (match_operand:SI 2 "const_int_operand" "n"))]
13349 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13350 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13351 The AIX assembler does not support the three operand form of dcbt
13352 and dcbtst on Power 7 (-mpwr7). */
13353 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13355 if (REG_P (operands[0]))
13357 if (INTVAL (operands[1]) == 0)
13358 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13360 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13364 if (INTVAL (operands[1]) == 0)
13365 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13367 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13370 [(set_attr "type" "load")])
13372 ;; Handle -fsplit-stack.
13374 (define_expand "split_stack_prologue"
13378 rs6000_expand_split_stack_prologue ();
13382 (define_expand "load_split_stack_limit"
13383 [(set (match_operand 0)
13384 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13387 emit_insn (gen_rtx_SET (operands[0],
13388 gen_rtx_UNSPEC (Pmode,
13389 gen_rtvec (1, const0_rtx),
13390 UNSPEC_STACK_CHECK)));
13394 (define_insn "load_split_stack_limit_di"
13395 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13396 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13398 "ld %0,-0x7040(13)"
13399 [(set_attr "type" "load")
13400 (set_attr "update" "no")
13401 (set_attr "indexed" "no")])
13403 (define_insn "load_split_stack_limit_si"
13404 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13405 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13407 "lwz %0,-0x7020(2)"
13408 [(set_attr "type" "load")
13409 (set_attr "update" "no")
13410 (set_attr "indexed" "no")])
13412 ;; A return instruction which the middle-end doesn't see.
13413 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13414 ;; after the call to __morestack.
13415 (define_insn "split_stack_return"
13416 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13419 [(set_attr "type" "jmpreg")])
13421 ;; If there are operand 0 bytes available on the stack, jump to
13423 (define_expand "split_stack_space_check"
13424 [(set (match_dup 2)
13425 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13427 (minus (reg STACK_POINTER_REGNUM)
13428 (match_operand 0)))
13429 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13430 (set (pc) (if_then_else
13431 (geu (match_dup 4) (const_int 0))
13432 (label_ref (match_operand 1))
13436 rs6000_split_stack_space_check (operands[0], operands[1]);
13440 (define_insn "bpermd_<mode>"
13441 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13442 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13443 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13446 [(set_attr "type" "popcnt")])
13449 ;; Builtin fma support. Handle
13450 ;; Note that the conditions for expansion are in the FMA_F iterator.
13452 (define_expand "fma<mode>4"
13453 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13455 (match_operand:FMA_F 1 "gpc_reg_operand")
13456 (match_operand:FMA_F 2 "gpc_reg_operand")
13457 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13461 (define_insn "*fma<mode>4_fpr"
13462 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13464 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13465 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13466 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13467 "TARGET_HARD_FLOAT"
13469 fmadd<s> %0,%1,%2,%3
13470 xsmadda<sd>p %x0,%x1,%x2
13471 xsmaddm<sd>p %x0,%x1,%x3"
13472 [(set_attr "type" "fp")
13473 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13475 ; Altivec only has fma and nfms.
13476 (define_expand "fms<mode>4"
13477 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13479 (match_operand:FMA_F 1 "gpc_reg_operand")
13480 (match_operand:FMA_F 2 "gpc_reg_operand")
13481 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13482 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13485 (define_insn "*fms<mode>4_fpr"
13486 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13488 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13489 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13490 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13491 "TARGET_HARD_FLOAT"
13493 fmsub<s> %0,%1,%2,%3
13494 xsmsuba<sd>p %x0,%x1,%x2
13495 xsmsubm<sd>p %x0,%x1,%x3"
13496 [(set_attr "type" "fp")
13497 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13499 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13500 (define_expand "fnma<mode>4"
13501 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13504 (match_operand:FMA_F 1 "gpc_reg_operand")
13505 (match_operand:FMA_F 2 "gpc_reg_operand")
13506 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13507 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13510 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13511 (define_expand "fnms<mode>4"
13512 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13515 (match_operand:FMA_F 1 "gpc_reg_operand")
13516 (match_operand:FMA_F 2 "gpc_reg_operand")
13517 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13518 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13521 ; Not an official optab name, but used from builtins.
13522 (define_expand "nfma<mode>4"
13523 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13526 (match_operand:FMA_F 1 "gpc_reg_operand")
13527 (match_operand:FMA_F 2 "gpc_reg_operand")
13528 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13529 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13532 (define_insn "*nfma<mode>4_fpr"
13533 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13536 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13537 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13538 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13539 "TARGET_HARD_FLOAT"
13541 fnmadd<s> %0,%1,%2,%3
13542 xsnmadda<sd>p %x0,%x1,%x2
13543 xsnmaddm<sd>p %x0,%x1,%x3"
13544 [(set_attr "type" "fp")
13545 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13547 ; Not an official optab name, but used from builtins.
13548 (define_expand "nfms<mode>4"
13549 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13552 (match_operand:FMA_F 1 "gpc_reg_operand")
13553 (match_operand:FMA_F 2 "gpc_reg_operand")
13554 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13558 (define_insn "*nfmssf4_fpr"
13559 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13562 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13563 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13565 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13566 "TARGET_HARD_FLOAT"
13568 fnmsub<s> %0,%1,%2,%3
13569 xsnmsuba<sd>p %x0,%x1,%x2
13570 xsnmsubm<sd>p %x0,%x1,%x3"
13571 [(set_attr "type" "fp")
13572 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13574 (define_expand "rs6000_get_timebase"
13575 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13578 if (TARGET_POWERPC64)
13579 emit_insn (gen_rs6000_mftb_di (operands[0]));
13581 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13585 (define_insn "rs6000_get_timebase_ppc32"
13586 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13587 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13588 (clobber (match_scratch:SI 1 "=r"))
13589 (clobber (match_scratch:CC 2 "=y"))]
13590 "!TARGET_POWERPC64"
13592 if (WORDS_BIG_ENDIAN)
13595 return "mfspr %0,269\;"
13603 return "mftbu %0\;"
13612 return "mfspr %L0,269\;"
13620 return "mftbu %L0\;"
13627 [(set_attr "length" "20")])
13629 (define_insn "rs6000_mftb_<mode>"
13630 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13631 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13635 return "mfspr %0,268";
13641 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13642 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13643 (define_insn "rs6000_mffsl_hw"
13644 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13645 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13646 "TARGET_HARD_FLOAT"
13649 (define_expand "rs6000_mffsl"
13650 [(set (match_operand:DF 0 "gpc_reg_operand")
13651 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13652 "TARGET_HARD_FLOAT"
13654 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13655 otherwise fall back to the older mffs instruction to emulate the mffsl
13658 if (!TARGET_P9_MISC)
13660 rtx tmp_di = gen_reg_rtx (DImode);
13661 rtx tmp_df = gen_reg_rtx (DFmode);
13663 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13664 instruction using the mffs instruction and masking off the bits
13665 the mmsl instruciton actually reads. */
13666 emit_insn (gen_rs6000_mffs (tmp_df));
13667 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13668 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13670 operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13674 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13678 (define_insn "rs6000_mffs"
13679 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13680 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13681 "TARGET_HARD_FLOAT"
13684 (define_insn "rs6000_mtfsf"
13685 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13686 (match_operand:DF 1 "gpc_reg_operand" "d")]
13688 "TARGET_HARD_FLOAT"
13691 (define_insn "rs6000_mtfsf_hi"
13692 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13693 (match_operand:DF 1 "gpc_reg_operand" "d")]
13695 "TARGET_HARD_FLOAT"
13699 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13700 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13701 ;; register that is being loaded. The fused ops must be physically adjacent.
13703 ;; On Power8 GPR loads, we try to use the register that is being load. The
13704 ;; peephole2 then gathers any other fused possibilities that it can find after
13705 ;; register allocation. If power9 fusion is selected, we also fuse floating
13706 ;; point loads/stores.
13708 ;; Find cases where the addis that feeds into a load instruction is either used
13709 ;; once or is the same as the target register, and replace it with the fusion
13713 [(set (match_operand:P 0 "base_reg_operand")
13714 (match_operand:P 1 "fusion_gpr_addis"))
13715 (set (match_operand:INT1 2 "base_reg_operand")
13716 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13718 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13722 expand_fusion_gpr_load (operands);
13726 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13729 (define_insn "*fusion_gpr_load_<mode>"
13730 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13731 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13732 UNSPEC_FUSION_GPR))]
13735 return emit_fusion_gpr_load (operands[0], operands[1]);
13737 [(set_attr "type" "load")
13738 (set_attr "length" "8")])
13741 ;; Optimize cases where we want to do a D-form load (register+offset) on
13742 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13747 ;; and we change this to:
13752 [(match_scratch:P 0 "b")
13753 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13754 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13755 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13757 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13758 [(set (match_dup 0)
13763 rtx tmp_reg = operands[0];
13764 rtx mem = operands[2];
13765 rtx addr = XEXP (mem, 0);
13766 rtx add_op0, add_op1, new_addr;
13768 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13769 add_op0 = XEXP (addr, 0);
13770 add_op1 = XEXP (addr, 1);
13771 gcc_assert (REG_P (add_op0));
13772 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13774 operands[4] = add_op1;
13775 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13778 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13779 ;; Altivec register, and the register allocator has generated:
13783 ;; and we change this to:
13788 [(match_scratch:P 0 "b")
13789 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13790 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13791 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13793 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13794 [(set (match_dup 0)
13799 rtx tmp_reg = operands[0];
13800 rtx mem = operands[3];
13801 rtx addr = XEXP (mem, 0);
13802 rtx add_op0, add_op1, new_addr;
13804 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13805 add_op0 = XEXP (addr, 0);
13806 add_op1 = XEXP (addr, 1);
13807 gcc_assert (REG_P (add_op0));
13808 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13810 operands[4] = add_op1;
13811 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13815 ;; Miscellaneous ISA 2.06 (power7) instructions
13816 (define_insn "addg6s"
13817 [(set (match_operand:SI 0 "register_operand" "=r")
13818 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13819 (match_operand:SI 2 "register_operand" "r")]
13823 [(set_attr "type" "integer")])
13825 (define_insn "cdtbcd"
13826 [(set (match_operand:SI 0 "register_operand" "=r")
13827 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13831 [(set_attr "type" "integer")])
13833 (define_insn "cbcdtd"
13834 [(set (match_operand:SI 0 "register_operand" "=r")
13835 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13839 [(set_attr "type" "integer")])
13841 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13844 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13845 (UNSPEC_DIVEU "eu")])
13847 (define_insn "div<div_extend>_<mode>"
13848 [(set (match_operand:GPR 0 "register_operand" "=r")
13849 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13850 (match_operand:GPR 2 "register_operand" "r")]
13851 UNSPEC_DIV_EXTEND))]
13853 "div<wd><div_extend> %0,%1,%2"
13854 [(set_attr "type" "div")
13855 (set_attr "size" "<bits>")])
13858 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13860 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13861 (define_mode_attr FP128_64 [(TF "DF")
13866 (define_expand "unpack<mode>"
13867 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13869 [(match_operand:FMOVE128 1 "register_operand")
13870 (match_operand:QI 2 "const_0_to_1_operand")]
13871 UNSPEC_UNPACK_128BIT))]
13872 "FLOAT128_2REG_P (<MODE>mode)"
13875 (define_insn_and_split "unpack<mode>_dm"
13876 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13878 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13879 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13880 UNSPEC_UNPACK_128BIT))]
13881 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13883 "&& reload_completed"
13884 [(set (match_dup 0) (match_dup 3))]
13886 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13888 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13890 emit_note (NOTE_INSN_DELETED);
13894 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13896 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13898 (define_insn_and_split "unpack<mode>_nodm"
13899 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13901 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13902 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13903 UNSPEC_UNPACK_128BIT))]
13904 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13906 "&& reload_completed"
13907 [(set (match_dup 0) (match_dup 3))]
13909 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13911 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13913 emit_note (NOTE_INSN_DELETED);
13917 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13919 [(set_attr "type" "fp,fpstore")])
13921 (define_insn_and_split "pack<mode>"
13922 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13924 [(match_operand:<FP128_64> 1 "register_operand" "d")
13925 (match_operand:<FP128_64> 2 "register_operand" "d")]
13926 UNSPEC_PACK_128BIT))]
13927 "FLOAT128_2REG_P (<MODE>mode)"
13929 "&& reload_completed"
13930 [(set (match_dup 3) (match_dup 1))
13931 (set (match_dup 4) (match_dup 2))]
13933 unsigned dest_hi = REGNO (operands[0]);
13934 unsigned dest_lo = dest_hi + 1;
13936 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13937 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13939 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13940 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13942 [(set_attr "type" "fp")
13943 (set_attr "length" "8")])
13945 (define_insn "unpack<mode>"
13946 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13947 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13948 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13949 UNSPEC_UNPACK_128BIT))]
13950 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13952 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13953 return ASM_COMMENT_START " xxpermdi to same register";
13955 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13956 return "xxpermdi %x0,%x1,%x1,%3";
13958 [(set_attr "type" "vecperm")])
13960 (define_insn "pack<mode>"
13961 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13962 (unspec:FMOVE128_VSX
13963 [(match_operand:DI 1 "register_operand" "wa")
13964 (match_operand:DI 2 "register_operand" "wa")]
13965 UNSPEC_PACK_128BIT))]
13967 "xxpermdi %x0,%x1,%x2,0"
13968 [(set_attr "type" "vecperm")])
13972 ;; ISA 2.08 IEEE 128-bit floating point support.
13974 (define_insn "add<mode>3"
13975 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13977 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13978 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13979 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13981 [(set_attr "type" "vecfloat")
13982 (set_attr "size" "128")])
13984 (define_insn "sub<mode>3"
13985 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13987 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13988 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13989 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13991 [(set_attr "type" "vecfloat")
13992 (set_attr "size" "128")])
13994 (define_insn "mul<mode>3"
13995 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13997 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13998 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13999 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14001 [(set_attr "type" "qmul")
14002 (set_attr "size" "128")])
14004 (define_insn "div<mode>3"
14005 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14007 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14008 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14009 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14011 [(set_attr "type" "vecdiv")
14012 (set_attr "size" "128")])
14014 (define_insn "sqrt<mode>2"
14015 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14017 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14018 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14020 [(set_attr "type" "vecdiv")
14021 (set_attr "size" "128")])
14023 (define_expand "copysign<mode>3"
14024 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14025 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14026 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14027 "FLOAT128_IEEE_P (<MODE>mode)"
14029 if (TARGET_FLOAT128_HW)
14030 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14033 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14038 (define_insn "copysign<mode>3_hard"
14039 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14041 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14042 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14044 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14045 "xscpsgnqp %0,%2,%1"
14046 [(set_attr "type" "vecmove")
14047 (set_attr "size" "128")])
14049 (define_insn "copysign<mode>3_soft"
14050 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14052 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14053 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14055 (clobber (match_scratch:IEEE128 3 "=&v"))]
14056 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14057 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14058 [(set_attr "type" "veccomplex")
14059 (set_attr "length" "8")])
14061 (define_insn "@neg<mode>2_hw"
14062 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14064 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14065 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14067 [(set_attr "type" "vecmove")
14068 (set_attr "size" "128")])
14071 (define_insn "@abs<mode>2_hw"
14072 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14074 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14075 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14077 [(set_attr "type" "vecmove")
14078 (set_attr "size" "128")])
14081 (define_insn "*nabs<mode>2_hw"
14082 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14085 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14086 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14088 [(set_attr "type" "vecmove")
14089 (set_attr "size" "128")])
14091 ;; Initially don't worry about doing fusion
14092 (define_insn "fma<mode>4_hw"
14093 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14095 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14096 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14097 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14098 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14099 "xsmaddqp %0,%1,%2"
14100 [(set_attr "type" "qmul")
14101 (set_attr "size" "128")])
14103 (define_insn "*fms<mode>4_hw"
14104 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14106 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14107 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14109 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14110 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14111 "xsmsubqp %0,%1,%2"
14112 [(set_attr "type" "qmul")
14113 (set_attr "size" "128")])
14115 (define_insn "*nfma<mode>4_hw"
14116 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14119 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14120 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14121 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14122 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14123 "xsnmaddqp %0,%1,%2"
14124 [(set_attr "type" "qmul")
14125 (set_attr "size" "128")])
14127 (define_insn "*nfms<mode>4_hw"
14128 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14131 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14132 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14134 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14135 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14136 "xsnmsubqp %0,%1,%2"
14137 [(set_attr "type" "qmul")
14138 (set_attr "size" "128")])
14140 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14141 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14142 (float_extend:IEEE128
14143 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14144 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14146 [(set_attr "type" "vecfloat")
14147 (set_attr "size" "128")])
14149 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14150 ;; point is a simple copy.
14151 (define_insn_and_split "extendkftf2"
14152 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14153 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14154 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14158 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14161 emit_note (NOTE_INSN_DELETED);
14164 [(set_attr "type" "*,veclogical")
14165 (set_attr "length" "0,4")])
14167 (define_insn_and_split "trunctfkf2"
14168 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14169 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14170 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14174 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14177 emit_note (NOTE_INSN_DELETED);
14180 [(set_attr "type" "*,veclogical")
14181 (set_attr "length" "0,4")])
14183 (define_insn "trunc<mode>df2_hw"
14184 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14186 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14187 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14189 [(set_attr "type" "vecfloat")
14190 (set_attr "size" "128")])
14192 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14193 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14195 (define_insn_and_split "trunc<mode>sf2_hw"
14196 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14198 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14199 (clobber (match_scratch:DF 2 "=v"))]
14200 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14203 [(set (match_dup 2)
14204 (unspec:DF [(match_dup 1)]
14205 UNSPEC_TRUNC_ROUND_TO_ODD))
14207 (float_truncate:SF (match_dup 2)))]
14209 if (GET_CODE (operands[2]) == SCRATCH)
14210 operands[2] = gen_reg_rtx (DFmode);
14212 [(set_attr "type" "vecfloat")
14213 (set_attr "length" "8")
14214 (set_attr "isa" "p8v")])
14216 ;; Conversion between IEEE 128-bit and integer types
14218 ;; The fix function for DImode and SImode was declared earlier as a
14219 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14220 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14221 ;; unless we have the IEEE 128-bit hardware.
14223 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14224 ;; to provide a GPR target that used direct move and a conversion in the GPR
14225 ;; which works around QImode/HImode not being allowed in vector registers in
14226 ;; ISA 2.07 (power8).
14227 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14228 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14229 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14230 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14231 "xscvqp<su><wd>z %0,%1"
14232 [(set_attr "type" "vecfloat")
14233 (set_attr "size" "128")])
14235 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14236 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14238 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14239 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14240 "xscvqp<su>wz %0,%1"
14241 [(set_attr "type" "vecfloat")
14242 (set_attr "size" "128")])
14244 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14245 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14246 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14247 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14249 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14250 (clobber (match_scratch:QHSI 2 "=v"))]
14251 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14253 "&& reload_completed"
14254 [(set (match_dup 2)
14255 (any_fix:QHSI (match_dup 1)))
14259 (define_insn "float_<mode>di2_hw"
14260 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14261 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14262 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14264 [(set_attr "type" "vecfloat")
14265 (set_attr "size" "128")])
14267 (define_insn_and_split "float_<mode>si2_hw"
14268 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14269 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14270 (clobber (match_scratch:DI 2 "=v"))]
14271 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14274 [(set (match_dup 2)
14275 (sign_extend:DI (match_dup 1)))
14277 (float:IEEE128 (match_dup 2)))]
14279 if (GET_CODE (operands[2]) == SCRATCH)
14280 operands[2] = gen_reg_rtx (DImode);
14282 if (MEM_P (operands[1]))
14283 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14286 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14287 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14288 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14289 (clobber (match_scratch:DI 2 "=X,r,X"))]
14290 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14292 "&& reload_completed"
14295 rtx dest = operands[0];
14296 rtx src = operands[1];
14297 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14299 if (altivec_register_operand (src, <QHI:MODE>mode))
14300 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14301 else if (int_reg_operand (src, <QHI:MODE>mode))
14303 rtx ext_di = operands[2];
14304 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14305 emit_move_insn (dest_di, ext_di);
14307 else if (MEM_P (src))
14309 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14310 emit_move_insn (dest_qhi, src);
14311 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14314 gcc_unreachable ();
14316 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14319 [(set_attr "length" "8,12,12")
14320 (set_attr "type" "vecfloat")
14321 (set_attr "size" "128")])
14323 (define_insn "floatuns_<mode>di2_hw"
14324 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14325 (unsigned_float:IEEE128
14326 (match_operand:DI 1 "altivec_register_operand" "v")))]
14327 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14329 [(set_attr "type" "vecfloat")
14330 (set_attr "size" "128")])
14332 (define_insn_and_split "floatuns_<mode>si2_hw"
14333 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14334 (unsigned_float:IEEE128
14335 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14336 (clobber (match_scratch:DI 2 "=v"))]
14337 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14340 [(set (match_dup 2)
14341 (zero_extend:DI (match_dup 1)))
14343 (float:IEEE128 (match_dup 2)))]
14345 if (GET_CODE (operands[2]) == SCRATCH)
14346 operands[2] = gen_reg_rtx (DImode);
14348 if (MEM_P (operands[1]))
14349 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14352 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14353 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14354 (unsigned_float:IEEE128
14355 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14356 (clobber (match_scratch:DI 2 "=X,r,X"))]
14357 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14359 "&& reload_completed"
14362 rtx dest = operands[0];
14363 rtx src = operands[1];
14364 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14366 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14367 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14368 else if (int_reg_operand (src, <QHI:MODE>mode))
14370 rtx ext_di = operands[2];
14371 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14372 emit_move_insn (dest_di, ext_di);
14375 gcc_unreachable ();
14377 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14380 [(set_attr "length" "8,12,8")
14381 (set_attr "type" "vecfloat")
14382 (set_attr "size" "128")])
14384 ;; IEEE 128-bit round to integer built-in functions
14385 (define_insn "floor<mode>2"
14386 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14388 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14390 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14392 [(set_attr "type" "vecfloat")
14393 (set_attr "size" "128")])
14395 (define_insn "ceil<mode>2"
14396 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14398 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14400 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14402 [(set_attr "type" "vecfloat")
14403 (set_attr "size" "128")])
14405 (define_insn "btrunc<mode>2"
14406 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14408 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14410 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14412 [(set_attr "type" "vecfloat")
14413 (set_attr "size" "128")])
14415 (define_insn "round<mode>2"
14416 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14418 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14420 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14422 [(set_attr "type" "vecfloat")
14423 (set_attr "size" "128")])
14425 ;; IEEE 128-bit instructions with round to odd semantics
14426 (define_insn "add<mode>3_odd"
14427 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14429 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14430 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14431 UNSPEC_ADD_ROUND_TO_ODD))]
14432 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14433 "xsaddqpo %0,%1,%2"
14434 [(set_attr "type" "vecfloat")
14435 (set_attr "size" "128")])
14437 (define_insn "sub<mode>3_odd"
14438 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14440 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14441 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14442 UNSPEC_SUB_ROUND_TO_ODD))]
14443 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14444 "xssubqpo %0,%1,%2"
14445 [(set_attr "type" "vecfloat")
14446 (set_attr "size" "128")])
14448 (define_insn "mul<mode>3_odd"
14449 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14451 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14452 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14453 UNSPEC_MUL_ROUND_TO_ODD))]
14454 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14455 "xsmulqpo %0,%1,%2"
14456 [(set_attr "type" "qmul")
14457 (set_attr "size" "128")])
14459 (define_insn "div<mode>3_odd"
14460 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14462 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14463 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14464 UNSPEC_DIV_ROUND_TO_ODD))]
14465 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14466 "xsdivqpo %0,%1,%2"
14467 [(set_attr "type" "vecdiv")
14468 (set_attr "size" "128")])
14470 (define_insn "sqrt<mode>2_odd"
14471 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14473 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14474 UNSPEC_SQRT_ROUND_TO_ODD))]
14475 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14477 [(set_attr "type" "vecdiv")
14478 (set_attr "size" "128")])
14480 (define_insn "fma<mode>4_odd"
14481 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14483 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14484 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14485 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14486 UNSPEC_FMA_ROUND_TO_ODD))]
14487 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14488 "xsmaddqpo %0,%1,%2"
14489 [(set_attr "type" "qmul")
14490 (set_attr "size" "128")])
14492 (define_insn "*fms<mode>4_odd"
14493 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14495 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14496 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14498 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14499 UNSPEC_FMA_ROUND_TO_ODD))]
14500 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14501 "xsmsubqpo %0,%1,%2"
14502 [(set_attr "type" "qmul")
14503 (set_attr "size" "128")])
14505 (define_insn "*nfma<mode>4_odd"
14506 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14509 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14510 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14511 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14512 UNSPEC_FMA_ROUND_TO_ODD)))]
14513 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14514 "xsnmaddqpo %0,%1,%2"
14515 [(set_attr "type" "qmul")
14516 (set_attr "size" "128")])
14518 (define_insn "*nfms<mode>4_odd"
14519 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14522 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14523 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14525 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14526 UNSPEC_FMA_ROUND_TO_ODD)))]
14527 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14528 "xsnmsubqpo %0,%1,%2"
14529 [(set_attr "type" "qmul")
14530 (set_attr "size" "128")])
14532 (define_insn "trunc<mode>df2_odd"
14533 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14534 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14535 UNSPEC_TRUNC_ROUND_TO_ODD))]
14536 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14538 [(set_attr "type" "vecfloat")
14539 (set_attr "size" "128")])
14541 ;; IEEE 128-bit comparisons
14542 (define_insn "*cmp<mode>_hw"
14543 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14544 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14545 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14546 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14547 "xscmpuqp %0,%1,%2"
14548 [(set_attr "type" "veccmp")
14549 (set_attr "size" "128")])
14551 ;; Miscellaneous ISA 3.0 (power9) instructions
14553 (define_insn "darn_32"
14554 [(set (match_operand:SI 0 "register_operand" "=r")
14555 (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14558 [(set_attr "type" "integer")])
14560 (define_insn "darn_raw"
14561 [(set (match_operand:DI 0 "register_operand" "=r")
14562 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14563 "TARGET_P9_MISC && TARGET_64BIT"
14565 [(set_attr "type" "integer")])
14567 (define_insn "darn"
14568 [(set (match_operand:DI 0 "register_operand" "=r")
14569 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14570 "TARGET_P9_MISC && TARGET_64BIT"
14572 [(set_attr "type" "integer")])
14574 ;; Test byte within range.
14576 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14577 ;; represents a byte whose value is ignored in this context and
14578 ;; vv, the least significant byte, holds the byte value that is to
14579 ;; be tested for membership within the range specified by operand 2.
14580 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14582 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14583 ;; vv <= hi. Otherwise, set register operand 0 to 0.
14585 ;; Though the instructions to which this expansion maps operate on
14586 ;; 64-bit registers, the current implementation only operates on
14587 ;; SI-mode operands as the high-order bits provide no information
14588 ;; that is not already available in the low-order bits. To avoid the
14589 ;; costs of data widening operations, future enhancements might allow
14590 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14591 (define_expand "cmprb"
14592 [(set (match_dup 3)
14593 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14594 (match_operand:SI 2 "gpc_reg_operand" "r")]
14596 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14597 (if_then_else:SI (lt (match_dup 3)
14600 (if_then_else (gt (match_dup 3)
14606 operands[3] = gen_reg_rtx (CCmode);
14609 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14610 ;; represents a byte whose value is ignored in this context and
14611 ;; vv, the least significant byte, holds the byte value that is to
14612 ;; be tested for membership within the range specified by operand 2.
14613 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14615 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14616 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
14617 ;; 3 bits of the target CR register are all set to 0.
14618 (define_insn "*cmprb_internal"
14619 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14620 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14621 (match_operand:SI 2 "gpc_reg_operand" "r")]
14625 [(set_attr "type" "logical")])
14627 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14628 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
14629 ;; if the GT bit (0x4) of condition register operand 1 is on.
14630 ;; Otherwise, set operand 0 to 0. Note that the result stored into
14631 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14632 ;; within condition register operand 1.
14633 (define_insn "setb_signed"
14634 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14635 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14638 (if_then_else (gt (match_dup 1)
14644 [(set_attr "type" "logical")])
14646 (define_insn "setb_unsigned"
14647 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14648 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14651 (if_then_else (gtu (match_dup 1)
14657 [(set_attr "type" "logical")])
14659 ;; Test byte within two ranges.
14661 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14662 ;; represents a byte whose value is ignored in this context and
14663 ;; vv, the least significant byte, holds the byte value that is to
14664 ;; be tested for membership within the range specified by operand 2.
14665 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14667 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14668 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
14671 ;; Though the instructions to which this expansion maps operate on
14672 ;; 64-bit registers, the current implementation only operates on
14673 ;; SI-mode operands as the high-order bits provide no information
14674 ;; that is not already available in the low-order bits. To avoid the
14675 ;; costs of data widening operations, future enhancements might allow
14676 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14677 (define_expand "cmprb2"
14678 [(set (match_dup 3)
14679 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14680 (match_operand:SI 2 "gpc_reg_operand" "r")]
14682 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14683 (if_then_else:SI (lt (match_dup 3)
14686 (if_then_else (gt (match_dup 3)
14692 operands[3] = gen_reg_rtx (CCmode);
14695 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14696 ;; represents a byte whose value is ignored in this context and
14697 ;; vv, the least significant byte, holds the byte value that is to
14698 ;; be tested for membership within the ranges specified by operand 2.
14699 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14701 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14702 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14703 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
14704 ;; CR register are all set to 0.
14705 (define_insn "*cmprb2_internal"
14706 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14707 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14708 (match_operand:SI 2 "gpc_reg_operand" "r")]
14712 [(set_attr "type" "logical")])
14714 ;; Test byte membership within set of 8 bytes.
14716 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14717 ;; represents a byte whose value is ignored in this context and
14718 ;; vv, the least significant byte, holds the byte value that is to
14719 ;; be tested for membership within the set specified by operand 2.
14720 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14722 ;; Return in target register operand 0 a value of 1 if vv equals one
14723 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
14724 ;; register operand 0 to 0. Note that the 8 byte values held within
14725 ;; operand 2 need not be unique.
14727 ;; Though the instructions to which this expansion maps operate on
14728 ;; 64-bit registers, the current implementation requires that operands
14729 ;; 0 and 1 have mode SI as the high-order bits provide no information
14730 ;; that is not already available in the low-order bits. To avoid the
14731 ;; costs of data widening operations, future enhancements might allow
14732 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14733 (define_expand "cmpeqb"
14734 [(set (match_dup 3)
14735 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14736 (match_operand:DI 2 "gpc_reg_operand" "r")]
14738 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14739 (if_then_else:SI (lt (match_dup 3)
14742 (if_then_else (gt (match_dup 3)
14746 "TARGET_P9_MISC && TARGET_64BIT"
14748 operands[3] = gen_reg_rtx (CCmode);
14751 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14752 ;; represents a byte whose value is ignored in this context and
14753 ;; vv, the least significant byte, holds the byte value that is to
14754 ;; be tested for membership within the set specified by operand 2.
14755 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14757 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14758 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
14759 ;; set the GT bit to zero. The other 3 bits of the target CR register
14760 ;; are all set to 0.
14761 (define_insn "*cmpeqb_internal"
14762 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14763 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14764 (match_operand:DI 2 "gpc_reg_operand" "r")]
14766 "TARGET_P9_MISC && TARGET_64BIT"
14768 [(set_attr "type" "logical")])
14771 (include "sync.md")
14772 (include "vector.md")
14774 (include "altivec.md")
14776 (include "crypto.md")