1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2020 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
91 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
109 UNSPEC_MACHOPIC_OFFSET
123 UNSPEC_P8V_RELOAD_FROM_GPR
126 UNSPEC_P8V_RELOAD_FROM_VSX
140 UNSPEC_ADD_ROUND_TO_ODD
141 UNSPEC_SUB_ROUND_TO_ODD
142 UNSPEC_MUL_ROUND_TO_ODD
143 UNSPEC_DIV_ROUND_TO_ODD
144 UNSPEC_FMA_ROUND_TO_ODD
145 UNSPEC_SQRT_ROUND_TO_ODD
146 UNSPEC_TRUNC_ROUND_TO_ODD
160 ;; UNSPEC_VOLATILE usage
163 (define_c_enum "unspecv"
165 UNSPECV_LL ; load-locked
166 UNSPECV_SC ; store-conditional
167 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
168 UNSPECV_EH_RR ; eh_reg_restore
169 UNSPECV_ISYNC ; isync instruction
170 UNSPECV_MFTB ; move from time base
171 UNSPECV_DARN ; darn 1 (deliver a random number)
172 UNSPECV_DARN_32 ; darn 2
173 UNSPECV_DARN_RAW ; darn 0
174 UNSPECV_NLGR ; non-local goto receiver
175 UNSPECV_MFFS ; Move from FPSCR
176 UNSPECV_MFFSL ; Move from FPSCR light instruction version
177 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
178 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
179 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
180 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
181 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
182 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
183 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
184 UNSPECV_SPEC_BARRIER ; Speculation barrier
189 ; The three different kinds of epilogue.
190 (define_enum "epilogue_type" [normal sibcall eh_return])
192 ;; Define an insn type attribute. This is used in function unit delay
196 add,logical,shift,insert,
198 exts,cntlz,popcnt,isel,
199 load,store,fpload,fpstore,vecload,vecstore,
201 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
202 cr_logical,mfcr,mfcrf,mtcr,
203 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
204 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
205 vecfloat,vecfdiv,vecdouble,mtvsr,mfvsr,crypto,
206 veclogical,veccmpfx,vecexts,vecmove,
207 htm,htmsimple,dfp,mma"
208 (const_string "integer"))
210 ;; What data size does this instruction work on?
211 ;; This is used for insert, mul and others as necessary.
212 (define_attr "size" "8,16,32,64,128" (const_string "32"))
214 ;; What is the insn_cost for this insn? The target hook can still override
215 ;; this. For optimizing for size the "length" attribute is used instead.
216 (define_attr "cost" "" (const_int 0))
218 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
219 ;; This is used for add, logical, shift, exts, mul.
220 (define_attr "dot" "no,yes" (const_string "no"))
222 ;; Does this instruction sign-extend its result?
223 ;; This is used for load insns.
224 (define_attr "sign_extend" "no,yes" (const_string "no"))
226 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
227 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
229 ;; Does this instruction use indexed (that is, reg+reg) addressing?
230 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
231 ;; it is automatically set based on that. If a load or store instruction
232 ;; has fewer than two operands it needs to set this attribute manually
233 ;; or the compiler will crash.
234 (define_attr "indexed" "no,yes"
235 (if_then_else (ior (match_operand 0 "indexed_address_mem")
236 (match_operand 1 "indexed_address_mem"))
238 (const_string "no")))
240 ;; Does this instruction use update addressing?
241 ;; This is used for load and store insns. See the comments for "indexed".
242 (define_attr "update" "no,yes"
243 (if_then_else (ior (match_operand 0 "update_address_mem")
244 (match_operand 1 "update_address_mem"))
246 (const_string "no")))
248 ;; Is this instruction using operands[2] as shift amount, and can that be a
250 ;; This is used for shift insns.
251 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
253 ;; Is this instruction using a shift amount from a register?
254 ;; This is used for shift insns.
255 (define_attr "var_shift" "no,yes"
256 (if_then_else (and (eq_attr "type" "shift")
257 (eq_attr "maybe_var_shift" "yes"))
258 (if_then_else (match_operand 2 "gpc_reg_operand")
261 (const_string "no")))
263 ;; Is copying of this instruction disallowed?
264 (define_attr "cannot_copy" "no,yes" (const_string "no"))
267 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
268 ;; before the instruction. A prefixed instruction has a prefix instruction
269 ;; word that extends the immediate value of the instructions from 12-16 bits to
270 ;; 34 bits. The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
271 ;; insns. The default "length" attribute will also be adjusted by default to
273 (define_attr "prefixed" "no,yes"
274 (cond [(ior (match_test "!TARGET_PREFIXED")
275 (match_test "!NONJUMP_INSN_P (insn)"))
278 (eq_attr "type" "load,fpload,vecload")
279 (if_then_else (match_test "prefixed_load_p (insn)")
283 (eq_attr "type" "store,fpstore,vecstore")
284 (if_then_else (match_test "prefixed_store_p (insn)")
288 (eq_attr "type" "integer,add")
289 (if_then_else (match_test "prefixed_paddi_p (insn)")
291 (const_string "no"))]
293 (const_string "no")))
295 ;; Return the number of real hardware instructions in a combined insn. If it
296 ;; is 0, just use the length / 4.
297 (define_attr "num_insns" "" (const_int 0))
299 ;; If an insn is prefixed, return the maximum number of prefixed instructions
300 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
302 (define_attr "max_prefixed_insns" "" (const_int 1))
304 ;; Length of the instruction (in bytes). This length does not consider the
305 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
306 ;; the length if there are prefixed instructions.
308 ;; While it might be tempting to use num_insns to calculate the length, it can
309 ;; be problematical unless all insn lengths are adjusted to use num_insns
310 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
311 ;; num_insns and recurse).
312 (define_attr "length" "" (const_int 4))
314 ;; Processor type -- this attribute must exactly match the processor_type
315 ;; enumeration in rs6000-opts.h.
317 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
318 ppc750,ppc7400,ppc7450,
319 ppc403,ppc405,ppc440,ppc476,
320 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
321 power4,power5,power6,power7,power8,power9,power10,
322 rs64a,mpccore,cell,ppca2,titan"
323 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
325 ;; The ISA we implement.
326 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10"
327 (const_string "any"))
329 ;; Is this alternative enabled for the current CPU/ISA/etc.?
330 (define_attr "enabled" ""
332 [(eq_attr "isa" "any")
335 (and (eq_attr "isa" "p5")
336 (match_test "TARGET_POPCNTB"))
339 (and (eq_attr "isa" "p6")
340 (match_test "TARGET_CMPB"))
343 (and (eq_attr "isa" "p7")
344 (match_test "TARGET_POPCNTD"))
347 (and (eq_attr "isa" "p7v")
348 (match_test "TARGET_VSX"))
351 (and (eq_attr "isa" "p8v")
352 (match_test "TARGET_P8_VECTOR"))
355 (and (eq_attr "isa" "p9")
356 (match_test "TARGET_MODULO"))
359 (and (eq_attr "isa" "p9v")
360 (match_test "TARGET_P9_VECTOR"))
363 (and (eq_attr "isa" "p9kf")
364 (match_test "TARGET_FLOAT128_TYPE"))
367 (and (eq_attr "isa" "p9tf")
368 (match_test "FLOAT128_VECTOR_P (TFmode)"))
371 (and (eq_attr "isa" "p10")
372 (match_test "TARGET_POWER10"))
376 ;; If this instruction is microcoded on the CELL processor
377 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
378 (define_attr "cell_micro" "not,conditional,always"
379 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
380 (eq_attr "dot" "yes"))
381 (and (eq_attr "type" "load")
382 (eq_attr "sign_extend" "yes"))
383 (and (eq_attr "type" "shift")
384 (eq_attr "var_shift" "yes")))
385 (const_string "always")
386 (const_string "not")))
388 (automata_option "ndfa")
401 (include "e300c2c3.md")
402 (include "e500mc.md")
403 (include "e500mc64.md")
406 (include "power4.md")
407 (include "power5.md")
408 (include "power6.md")
409 (include "power7.md")
410 (include "power8.md")
411 (include "power9.md")
412 (include "power10.md")
417 (include "predicates.md")
418 (include "constraints.md")
423 ; This mode iterator allows :GPR to be used to indicate the allowable size
424 ; of whole values in GPRs.
425 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
427 ; And again, for patterns that need two (potentially) different integer modes.
428 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
430 ; Any supported integer mode.
431 (define_mode_iterator INT [QI HI SI DI TI PTI])
433 ; Any supported integer mode that fits in one register.
434 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
436 ; Integer modes supported in VSX registers with ISA 3.0 instructions
437 (define_mode_iterator INT_ISA3 [QI HI SI DI])
439 ; Everything we can extend QImode to.
440 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
442 ; Everything we can extend HImode to.
443 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
445 ; Everything we can extend SImode to.
446 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
448 ; QImode or HImode for small integer moves and small atomic ops
449 (define_mode_iterator QHI [QI HI])
451 ; QImode, HImode, SImode for fused ops only for GPR loads
452 (define_mode_iterator QHSI [QI HI SI])
454 ; HImode or SImode for sign extended fusion ops
455 (define_mode_iterator HSI [HI SI])
457 ; SImode or DImode, even if DImode doesn't fit in GPRs.
458 (define_mode_iterator SDI [SI DI])
460 ; The size of a pointer. Also, the size of the value that a record-condition
461 ; (one with a '.') will compare; and the size used for arithmetic carries.
462 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
464 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
465 ; PTImode is GPR only)
466 (define_mode_iterator TI2 [TI PTI])
468 ; Any hardware-supported floating-point mode
469 (define_mode_iterator FP [
470 (SF "TARGET_HARD_FLOAT")
471 (DF "TARGET_HARD_FLOAT")
472 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
473 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
474 (KF "TARGET_FLOAT128_TYPE")
478 ; Any fma capable floating-point mode.
479 (define_mode_iterator FMA_F [
480 (SF "TARGET_HARD_FLOAT")
481 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
482 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
483 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
484 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
485 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
488 ; Floating point move iterators to combine binary and decimal moves
489 (define_mode_iterator FMOVE32 [SF SD])
490 (define_mode_iterator FMOVE64 [DF DD])
491 (define_mode_iterator FMOVE64X [DI DF DD])
492 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
493 (IF "FLOAT128_IBM_P (IFmode)")
494 (TD "TARGET_HARD_FLOAT")])
496 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
497 (IF "FLOAT128_2REG_P (IFmode)")
498 (TD "TARGET_HARD_FLOAT")])
500 ; Iterators for 128 bit types for direct move
501 (define_mode_iterator FMOVE128_GPR [TI
509 (KF "FLOAT128_VECTOR_P (KFmode)")
510 (TF "FLOAT128_VECTOR_P (TFmode)")])
512 ; Iterator for 128-bit VSX types for pack/unpack
513 (define_mode_iterator FMOVE128_VSX [V1TI KF])
515 ; Iterators for converting to/from TFmode
516 (define_mode_iterator IFKF [IF KF])
518 ; Constraints for moving IF/KFmode.
519 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
521 ; Whether a floating point move is ok, don't allow SD without hardware FP
522 (define_mode_attr fmove_ok [(SF "")
524 (SD "TARGET_HARD_FLOAT")
527 ; Convert REAL_VALUE to the appropriate bits
528 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
529 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
530 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
531 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
533 ; Whether 0.0 has an all-zero bit pattern
534 (define_mode_attr zero_fp [(SF "j")
543 ; Definitions for 64-bit VSX
544 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
546 ; Definitions for 64-bit direct move
547 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
549 ; Definitions for 64-bit use of altivec registers
550 (define_mode_attr f64_av [(DF "v") (DD "wn")])
552 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
553 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
555 ; These modes do not fit in integer registers in 32-bit mode.
556 (define_mode_iterator DIFD [DI DF DD])
558 ; Iterator for reciprocal estimate instructions
559 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
562 (define_mode_iterator SFDF [SF DF])
564 ; And again, for when we need two FP modes in a pattern.
565 (define_mode_iterator SFDF2 [SF DF])
567 ; A generic s/d attribute, for sp/dp for example.
568 (define_mode_attr sd [(SF "s") (DF "d")
569 (V4SF "s") (V2DF "d")])
571 ; "s" or nothing, for fmuls/fmul for example.
572 (define_mode_attr s [(SF "s") (DF "")])
574 ; Iterator for 128-bit floating point that uses the IBM double-double format
575 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
576 (TF "FLOAT128_IBM_P (TFmode)")])
578 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
579 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
580 (TF "FLOAT128_IEEE_P (TFmode)")])
582 ; Iterator for 128-bit floating point
583 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
584 (IF "TARGET_FLOAT128_TYPE")
585 (TF "TARGET_LONG_DOUBLE_128")])
587 ; Iterator for signbit on 64-bit machines with direct move
588 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
589 (TF "FLOAT128_VECTOR_P (TFmode)")])
591 ; Iterator for ISA 3.0 supported floating point types
592 (define_mode_iterator FP_ISA3 [SF DF])
594 ; SF/DF constraint for arithmetic on traditional floating point registers
595 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
597 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
598 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
599 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
601 (define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")])
603 ; Which isa is needed for those float instructions?
604 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
607 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
609 ; Conditional returns.
610 (define_code_iterator any_return [return simple_return])
611 (define_code_attr return_pred [(return "direct_return ()")
612 (simple_return "1")])
613 (define_code_attr return_str [(return "") (simple_return "simple_")])
616 (define_code_iterator iorxor [ior xor])
617 (define_code_iterator and_ior_xor [and ior xor])
619 ; Signed/unsigned variants of ops.
620 (define_code_iterator any_extend [sign_extend zero_extend])
621 (define_code_iterator any_fix [fix unsigned_fix])
622 (define_code_iterator any_float [float unsigned_float])
624 (define_code_attr u [(sign_extend "")
629 (define_code_attr su [(sign_extend "s")
634 (unsigned_float "u")])
636 (define_code_attr az [(sign_extend "a")
641 (unsigned_float "z")])
643 (define_code_attr uns [(fix "")
646 (unsigned_float "uns")])
648 ; Various instructions that come in SI and DI forms.
649 ; A generic w/d attribute, for things like cmpw/cmpd.
650 (define_mode_attr wd [(QI "b")
661 ; For double extract from different origin types
662 (define_mode_attr du_or_d [(QI "du")
671 ;; How many bits in this mode?
672 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
673 (SF "32") (DF "64")])
676 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
678 ;; Bitmask for shift instructions
679 (define_mode_attr hH [(SI "h") (DI "H")])
681 ;; A mode twice the size of the given mode
682 (define_mode_attr dmode [(SI "di") (DI "ti")])
683 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
685 ;; Suffix for reload patterns
686 (define_mode_attr ptrsize [(SI "32bit")
689 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
690 (DI "TARGET_64BIT")])
692 (define_mode_attr mptrsize [(SI "si")
695 (define_mode_attr ptrload [(SI "lwz")
698 (define_mode_attr ptrm [(SI "m")
701 (define_mode_attr rreg [(SF "f")
708 (define_mode_attr rreg2 [(SF "f")
711 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
712 (DF "TARGET_FCFID")])
714 ;; Mode iterator for logical operations on 128-bit types
715 (define_mode_iterator BOOL_128 [TI
717 (V16QI "TARGET_ALTIVEC")
718 (V8HI "TARGET_ALTIVEC")
719 (V4SI "TARGET_ALTIVEC")
720 (V4SF "TARGET_ALTIVEC")
721 (V2DI "TARGET_ALTIVEC")
722 (V2DF "TARGET_ALTIVEC")
723 (V1TI "TARGET_ALTIVEC")])
725 ;; For the GPRs we use 3 constraints for register outputs, two that are the
726 ;; same as the output register, and a third where the output register is an
727 ;; early clobber, so we don't have to deal with register overlaps. For the
728 ;; vector types, we prefer to use the vector registers. For TI mode, allow
731 ;; Mode attribute for boolean operation register constraints for output
732 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
734 (V16QI "wa,v,&?r,?r,?r")
735 (V8HI "wa,v,&?r,?r,?r")
736 (V4SI "wa,v,&?r,?r,?r")
737 (V4SF "wa,v,&?r,?r,?r")
738 (V2DI "wa,v,&?r,?r,?r")
739 (V2DF "wa,v,&?r,?r,?r")
740 (V1TI "wa,v,&?r,?r,?r")])
742 ;; Mode attribute for boolean operation register constraints for operand1
743 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
751 (V1TI "wa,v,r,0,r")])
753 ;; Mode attribute for boolean operation register constraints for operand2
754 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
762 (V1TI "wa,v,r,r,0")])
764 ;; Mode attribute for boolean operation register constraints for operand1
765 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
766 ;; is used for operand1 or operand2
767 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
775 (V1TI "wa,v,r,0,0")])
777 ;; Reload iterator for creating the function to allocate a base register to
778 ;; supplement addressing modes.
779 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
780 SF SD SI DF DD DI TI PTI KF IF TF
783 ;; Iterate over smin, smax
784 (define_code_iterator fp_minmax [smin smax])
786 (define_code_attr minmax [(smin "min")
789 (define_code_attr SMINMAX [(smin "SMIN")
792 ;; Iterator to optimize the following cases:
793 ;; D-form load to FPR register & move to Altivec register
794 ;; Move Altivec register to FPR register and store
795 (define_mode_iterator ALTIVEC_DFORM [DF
796 (SF "TARGET_P8_VECTOR")
797 (DI "TARGET_POWERPC64")])
799 (include "darwin.md")
801 ;; Start with fixed-point load and store insns. Here we put only the more
802 ;; complex forms. Basic data transfer is done later.
804 (define_insn "zero_extendqi<mode>2"
805 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
806 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
813 [(set_attr "type" "load,shift,fpload,vecperm")
814 (set_attr "isa" "*,*,p9v,p9v")])
816 (define_insn_and_split "*zero_extendqi<mode>2_dot"
817 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
818 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
820 (clobber (match_scratch:EXTQI 0 "=r,r"))]
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")])
836 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
837 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
838 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
840 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
841 (zero_extend:EXTQI (match_dup 1)))]
846 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
848 (zero_extend:EXTQI (match_dup 1)))
850 (compare:CC (match_dup 0)
853 [(set_attr "type" "logical")
854 (set_attr "dot" "yes")
855 (set_attr "length" "4,8")])
858 (define_insn "zero_extendhi<mode>2"
859 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
860 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
864 rlwinm %0,%1,0,0xffff
867 [(set_attr "type" "load,shift,fpload,vecperm")
868 (set_attr "isa" "*,*,p9v,p9v")])
870 (define_insn_and_split "*zero_extendhi<mode>2_dot"
871 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
872 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
874 (clobber (match_scratch:EXTHI 0 "=r,r"))]
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")])
890 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
891 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
892 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
894 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
895 (zero_extend:EXTHI (match_dup 1)))]
900 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
902 (zero_extend:EXTHI (match_dup 1)))
904 (compare:CC (match_dup 0)
907 [(set_attr "type" "logical")
908 (set_attr "dot" "yes")
909 (set_attr "length" "4,8")])
912 (define_insn "zero_extendsi<mode>2"
913 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
914 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
923 xxextractuw %x0,%x1,4"
924 [(set_attr "type" "load,shift,fpload,fpload,mtvsr,mfvsr,vecexts")
925 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
927 (define_insn_and_split "*zero_extendsi<mode>2_dot"
928 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
929 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
931 (clobber (match_scratch:EXTSI 0 "=r,r"))]
936 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
938 (zero_extend:DI (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")])
947 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
948 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
949 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
951 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
952 (zero_extend:EXTSI (match_dup 1)))]
957 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
959 (zero_extend:EXTSI (match_dup 1)))
961 (compare:CC (match_dup 0)
964 [(set_attr "type" "shift")
965 (set_attr "dot" "yes")
966 (set_attr "length" "4,8")])
969 (define_insn "extendqi<mode>2"
970 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
971 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
976 [(set_attr "type" "exts,vecperm")
977 (set_attr "isa" "*,p9v")])
979 (define_insn_and_split "*extendqi<mode>2_dot"
980 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
981 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
983 (clobber (match_scratch:EXTQI 0 "=r,r"))]
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")])
999 (define_insn_and_split "*extendqi<mode>2_dot2"
1000 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1001 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
1003 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
1004 (sign_extend:EXTQI (match_dup 1)))]
1009 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1011 (sign_extend:EXTQI (match_dup 1)))
1013 (compare:CC (match_dup 0)
1016 [(set_attr "type" "exts")
1017 (set_attr "dot" "yes")
1018 (set_attr "length" "4,8")])
1021 (define_expand "extendhi<mode>2"
1022 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1023 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1027 (define_insn "*extendhi<mode>2"
1028 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1029 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1036 [(set_attr "type" "load,exts,fpload,vecperm")
1037 (set_attr "sign_extend" "yes")
1038 (set_attr "length" "*,*,8,*")
1039 (set_attr "isa" "*,*,p9v,p9v")])
1042 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1044 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1045 "TARGET_P9_VECTOR && reload_completed"
1049 (sign_extend:EXTHI (match_dup 2)))]
1051 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1054 (define_insn_and_split "*extendhi<mode>2_dot"
1055 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1056 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1058 (clobber (match_scratch:EXTHI 0 "=r,r"))]
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")])
1074 (define_insn_and_split "*extendhi<mode>2_dot2"
1075 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1076 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1078 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1079 (sign_extend:EXTHI (match_dup 1)))]
1084 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1086 (sign_extend:EXTHI (match_dup 1)))
1088 (compare:CC (match_dup 0)
1091 [(set_attr "type" "exts")
1092 (set_attr "dot" "yes")
1093 (set_attr "length" "4,8")])
1096 (define_insn "extendsi<mode>2"
1097 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1098 "=r, r, d, wa, wa, v, v, wr")
1099 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1100 "YZ, r, Z, Z, r, v, v, ?wa")))]
1111 [(set_attr "type" "load,exts,fpload,fpload,mtvsr,vecexts,vecperm,mfvsr")
1112 (set_attr "sign_extend" "yes")
1113 (set_attr "length" "*,*,*,*,*,*,8,8")
1114 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1117 [(set (match_operand:EXTSI 0 "int_reg_operand")
1118 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1119 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1123 (sign_extend:DI (match_dup 2)))]
1125 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1129 [(set (match_operand:DI 0 "altivec_register_operand")
1130 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1131 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1134 rtx dest = operands[0];
1135 rtx src = operands[1];
1136 int dest_regno = REGNO (dest);
1137 int src_regno = REGNO (src);
1138 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1139 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1141 if (BYTES_BIG_ENDIAN)
1143 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1144 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1148 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1149 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1154 (define_insn_and_split "*extendsi<mode>2_dot"
1155 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1156 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1158 (clobber (match_scratch:EXTSI 0 "=r,r"))]
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 (define_insn_and_split "*extendsi<mode>2_dot2"
1175 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1176 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1178 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1179 (sign_extend:EXTSI (match_dup 1)))]
1184 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1186 (sign_extend:EXTSI (match_dup 1)))
1188 (compare:CC (match_dup 0)
1191 [(set_attr "type" "exts")
1192 (set_attr "dot" "yes")
1193 (set_attr "length" "4,8")])
1195 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1197 (define_insn "*macchwc"
1198 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1199 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1200 (match_operand:SI 2 "gpc_reg_operand" "r")
1203 (match_operand:HI 1 "gpc_reg_operand" "r")))
1204 (match_operand:SI 4 "gpc_reg_operand" "0"))
1206 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1207 (plus:SI (mult:SI (ashiftrt:SI
1215 [(set_attr "type" "halfmul")])
1217 (define_insn "*macchw"
1218 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1219 (plus:SI (mult:SI (ashiftrt:SI
1220 (match_operand:SI 2 "gpc_reg_operand" "r")
1223 (match_operand:HI 1 "gpc_reg_operand" "r")))
1224 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1227 [(set_attr "type" "halfmul")])
1229 (define_insn "*macchwuc"
1230 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1231 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1232 (match_operand:SI 2 "gpc_reg_operand" "r")
1235 (match_operand:HI 1 "gpc_reg_operand" "r")))
1236 (match_operand:SI 4 "gpc_reg_operand" "0"))
1238 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1239 (plus:SI (mult:SI (lshiftrt:SI
1247 [(set_attr "type" "halfmul")])
1249 (define_insn "*macchwu"
1250 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1251 (plus:SI (mult:SI (lshiftrt:SI
1252 (match_operand:SI 2 "gpc_reg_operand" "r")
1255 (match_operand:HI 1 "gpc_reg_operand" "r")))
1256 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1259 [(set_attr "type" "halfmul")])
1261 (define_insn "*machhwc"
1262 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1263 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1264 (match_operand:SI 1 "gpc_reg_operand" "%r")
1267 (match_operand:SI 2 "gpc_reg_operand" "r")
1269 (match_operand:SI 4 "gpc_reg_operand" "0"))
1271 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1272 (plus:SI (mult:SI (ashiftrt:SI
1281 [(set_attr "type" "halfmul")])
1283 (define_insn "*machhw"
1284 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1285 (plus:SI (mult:SI (ashiftrt:SI
1286 (match_operand:SI 1 "gpc_reg_operand" "%r")
1289 (match_operand:SI 2 "gpc_reg_operand" "r")
1291 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1294 [(set_attr "type" "halfmul")])
1296 (define_insn "*machhwuc"
1297 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1298 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1299 (match_operand:SI 1 "gpc_reg_operand" "%r")
1302 (match_operand:SI 2 "gpc_reg_operand" "r")
1304 (match_operand:SI 4 "gpc_reg_operand" "0"))
1306 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1307 (plus:SI (mult:SI (lshiftrt:SI
1316 [(set_attr "type" "halfmul")])
1318 (define_insn "*machhwu"
1319 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1320 (plus:SI (mult:SI (lshiftrt:SI
1321 (match_operand:SI 1 "gpc_reg_operand" "%r")
1324 (match_operand:SI 2 "gpc_reg_operand" "r")
1326 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1329 [(set_attr "type" "halfmul")])
1331 (define_insn "*maclhwc"
1332 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1333 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1334 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1336 (match_operand:HI 2 "gpc_reg_operand" "r")))
1337 (match_operand:SI 4 "gpc_reg_operand" "0"))
1339 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1340 (plus:SI (mult:SI (sign_extend:SI
1347 [(set_attr "type" "halfmul")])
1349 (define_insn "*maclhw"
1350 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1351 (plus:SI (mult:SI (sign_extend:SI
1352 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1354 (match_operand:HI 2 "gpc_reg_operand" "r")))
1355 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1358 [(set_attr "type" "halfmul")])
1360 (define_insn "*maclhwuc"
1361 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1362 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1363 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1365 (match_operand:HI 2 "gpc_reg_operand" "r")))
1366 (match_operand:SI 4 "gpc_reg_operand" "0"))
1368 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1369 (plus:SI (mult:SI (zero_extend:SI
1376 [(set_attr "type" "halfmul")])
1378 (define_insn "*maclhwu"
1379 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1380 (plus:SI (mult:SI (zero_extend:SI
1381 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1383 (match_operand:HI 2 "gpc_reg_operand" "r")))
1384 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1387 [(set_attr "type" "halfmul")])
1389 (define_insn "*nmacchwc"
1390 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1391 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1392 (mult:SI (ashiftrt:SI
1393 (match_operand:SI 2 "gpc_reg_operand" "r")
1396 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1398 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1399 (minus:SI (match_dup 4)
1400 (mult:SI (ashiftrt:SI
1407 [(set_attr "type" "halfmul")])
1409 (define_insn "*nmacchw"
1410 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1411 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1412 (mult:SI (ashiftrt:SI
1413 (match_operand:SI 2 "gpc_reg_operand" "r")
1416 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1419 [(set_attr "type" "halfmul")])
1421 (define_insn "*nmachhwc"
1422 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1423 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1424 (mult:SI (ashiftrt:SI
1425 (match_operand:SI 1 "gpc_reg_operand" "%r")
1428 (match_operand:SI 2 "gpc_reg_operand" "r")
1431 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1432 (minus:SI (match_dup 4)
1433 (mult:SI (ashiftrt:SI
1441 [(set_attr "type" "halfmul")])
1443 (define_insn "*nmachhw"
1444 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1445 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1446 (mult:SI (ashiftrt:SI
1447 (match_operand:SI 1 "gpc_reg_operand" "%r")
1450 (match_operand:SI 2 "gpc_reg_operand" "r")
1454 [(set_attr "type" "halfmul")])
1456 (define_insn "*nmaclhwc"
1457 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1458 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1459 (mult:SI (sign_extend:SI
1460 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1462 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1464 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1465 (minus:SI (match_dup 4)
1466 (mult:SI (sign_extend:SI
1472 [(set_attr "type" "halfmul")])
1474 (define_insn "*nmaclhw"
1475 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1476 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1477 (mult:SI (sign_extend:SI
1478 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1480 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1483 [(set_attr "type" "halfmul")])
1485 (define_insn "*mulchwc"
1486 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1487 (compare:CC (mult:SI (ashiftrt:SI
1488 (match_operand:SI 2 "gpc_reg_operand" "r")
1491 (match_operand:HI 1 "gpc_reg_operand" "r")))
1493 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1494 (mult:SI (ashiftrt:SI
1501 [(set_attr "type" "halfmul")])
1503 (define_insn "*mulchw"
1504 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1505 (mult:SI (ashiftrt:SI
1506 (match_operand:SI 2 "gpc_reg_operand" "r")
1509 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1512 [(set_attr "type" "halfmul")])
1514 (define_insn "*mulchwuc"
1515 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1516 (compare:CC (mult:SI (lshiftrt:SI
1517 (match_operand:SI 2 "gpc_reg_operand" "r")
1520 (match_operand:HI 1 "gpc_reg_operand" "r")))
1522 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1523 (mult:SI (lshiftrt:SI
1530 [(set_attr "type" "halfmul")])
1532 (define_insn "*mulchwu"
1533 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1534 (mult:SI (lshiftrt:SI
1535 (match_operand:SI 2 "gpc_reg_operand" "r")
1538 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1541 [(set_attr "type" "halfmul")])
1543 (define_insn "*mulhhwc"
1544 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1545 (compare:CC (mult:SI (ashiftrt:SI
1546 (match_operand:SI 1 "gpc_reg_operand" "%r")
1549 (match_operand:SI 2 "gpc_reg_operand" "r")
1552 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1553 (mult:SI (ashiftrt:SI
1561 [(set_attr "type" "halfmul")])
1563 (define_insn "*mulhhw"
1564 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1565 (mult:SI (ashiftrt:SI
1566 (match_operand:SI 1 "gpc_reg_operand" "%r")
1569 (match_operand:SI 2 "gpc_reg_operand" "r")
1573 [(set_attr "type" "halfmul")])
1575 (define_insn "*mulhhwuc"
1576 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1577 (compare:CC (mult:SI (lshiftrt:SI
1578 (match_operand:SI 1 "gpc_reg_operand" "%r")
1581 (match_operand:SI 2 "gpc_reg_operand" "r")
1584 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1585 (mult:SI (lshiftrt:SI
1593 [(set_attr "type" "halfmul")])
1595 (define_insn "*mulhhwu"
1596 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1597 (mult:SI (lshiftrt:SI
1598 (match_operand:SI 1 "gpc_reg_operand" "%r")
1601 (match_operand:SI 2 "gpc_reg_operand" "r")
1605 [(set_attr "type" "halfmul")])
1607 (define_insn "*mullhwc"
1608 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1609 (compare:CC (mult:SI (sign_extend:SI
1610 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1612 (match_operand:HI 2 "gpc_reg_operand" "r")))
1614 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1615 (mult:SI (sign_extend:SI
1621 [(set_attr "type" "halfmul")])
1623 (define_insn "*mullhw"
1624 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1625 (mult:SI (sign_extend:SI
1626 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1628 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1631 [(set_attr "type" "halfmul")])
1633 (define_insn "*mullhwuc"
1634 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1635 (compare:CC (mult:SI (zero_extend:SI
1636 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1638 (match_operand:HI 2 "gpc_reg_operand" "r")))
1640 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1641 (mult:SI (zero_extend:SI
1647 [(set_attr "type" "halfmul")])
1649 (define_insn "*mullhwu"
1650 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1651 (mult:SI (zero_extend:SI
1652 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1654 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1657 [(set_attr "type" "halfmul")])
1659 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1660 (define_insn "dlmzb"
1661 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1662 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1663 (match_operand:SI 2 "gpc_reg_operand" "r")]
1665 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1666 (unspec:SI [(match_dup 1)
1672 (define_expand "strlensi"
1673 [(set (match_operand:SI 0 "gpc_reg_operand")
1674 (unspec:SI [(match_operand:BLK 1 "general_operand")
1675 (match_operand:QI 2 "const_int_operand")
1676 (match_operand 3 "const_int_operand")]
1677 UNSPEC_DLMZB_STRLEN))
1678 (clobber (match_scratch:CC 4))]
1679 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1681 rtx result = operands[0];
1682 rtx src = operands[1];
1683 rtx search_char = operands[2];
1684 rtx align = operands[3];
1685 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1686 rtx loop_label, end_label, mem, cr0, cond;
1687 if (search_char != const0_rtx
1688 || !CONST_INT_P (align)
1689 || INTVAL (align) < 8)
1691 word1 = gen_reg_rtx (SImode);
1692 word2 = gen_reg_rtx (SImode);
1693 scratch_dlmzb = gen_reg_rtx (SImode);
1694 scratch_string = gen_reg_rtx (Pmode);
1695 loop_label = gen_label_rtx ();
1696 end_label = gen_label_rtx ();
1697 addr = force_reg (Pmode, XEXP (src, 0));
1698 emit_move_insn (scratch_string, addr);
1699 emit_label (loop_label);
1700 mem = change_address (src, SImode, scratch_string);
1701 emit_move_insn (word1, mem);
1702 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1703 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1704 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1705 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1706 emit_jump_insn (gen_rtx_SET (pc_rtx,
1707 gen_rtx_IF_THEN_ELSE (VOIDmode,
1713 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1714 emit_jump_insn (gen_rtx_SET (pc_rtx,
1715 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1717 emit_label (end_label);
1718 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1719 emit_insn (gen_subsi3 (result, scratch_string, addr));
1720 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1724 ;; Fixed-point arithmetic insns.
1726 (define_expand "add<mode>3"
1727 [(set (match_operand:SDI 0 "gpc_reg_operand")
1728 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1729 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1732 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1734 rtx lo0 = gen_lowpart (SImode, operands[0]);
1735 rtx lo1 = gen_lowpart (SImode, operands[1]);
1736 rtx lo2 = gen_lowpart (SImode, operands[2]);
1737 rtx hi0 = gen_highpart (SImode, operands[0]);
1738 rtx hi1 = gen_highpart (SImode, operands[1]);
1739 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1741 if (!reg_or_short_operand (lo2, SImode))
1742 lo2 = force_reg (SImode, lo2);
1743 if (!adde_operand (hi2, SImode))
1744 hi2 = force_reg (SImode, hi2);
1746 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1747 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1751 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1753 rtx tmp = ((!can_create_pseudo_p ()
1754 || rtx_equal_p (operands[0], operands[1]))
1755 ? operands[0] : gen_reg_rtx (<MODE>mode));
1757 /* Adding a constant to r0 is not a valid insn, so use a different
1758 strategy in that case. */
1759 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1761 if (operands[0] == operands[1])
1763 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1764 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1768 HOST_WIDE_INT val = INTVAL (operands[2]);
1769 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1770 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1772 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1775 /* The ordering here is important for the prolog expander.
1776 When space is allocated from the stack, adding 'low' first may
1777 produce a temporary deallocation (which would be bad). */
1778 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1779 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1784 (define_insn "*add<mode>3"
1785 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1786 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1787 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1794 [(set_attr "type" "add")
1795 (set_attr "isa" "*,*,*,p10")])
1797 (define_insn "*addsi3_high"
1798 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1799 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1800 (high:SI (match_operand 2 "" ""))))]
1801 "TARGET_MACHO && !TARGET_64BIT"
1802 "addis %0,%1,ha16(%2)"
1803 [(set_attr "type" "add")])
1805 (define_insn_and_split "*add<mode>3_dot"
1806 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1807 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1808 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1810 (clobber (match_scratch:GPR 0 "=r,r"))]
1811 "<MODE>mode == Pmode"
1815 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1817 (plus:GPR (match_dup 1)
1820 (compare:CC (match_dup 0)
1823 [(set_attr "type" "add")
1824 (set_attr "dot" "yes")
1825 (set_attr "length" "4,8")])
1827 (define_insn_and_split "*add<mode>3_dot2"
1828 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1829 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1830 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1832 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1833 (plus:GPR (match_dup 1)
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_dot"
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 (clobber (match_scratch:GPR 0 "=r,r"))
1857 (clobber (reg:GPR CA_REGNO))]
1858 "<MODE>mode == Pmode"
1862 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1864 (plus:GPR (match_dup 1)
1867 (compare:CC (match_dup 0)
1870 [(set_attr "type" "add")
1871 (set_attr "dot" "yes")
1872 (set_attr "length" "4,8")])
1874 (define_insn_and_split "*add<mode>3_imm_dot2"
1875 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1876 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1877 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1879 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1880 (plus:GPR (match_dup 1)
1882 (clobber (reg:GPR CA_REGNO))]
1883 "<MODE>mode == Pmode"
1887 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1889 (plus:GPR (match_dup 1)
1892 (compare:CC (match_dup 0)
1895 [(set_attr "type" "add")
1896 (set_attr "dot" "yes")
1897 (set_attr "length" "4,8")])
1899 ;; Split an add that we can't do in one insn into two insns, each of which
1900 ;; does one 16-bit part. This is used by combine. Note that the low-order
1901 ;; add should be last in case the result gets used in an address.
1904 [(set (match_operand:GPR 0 "gpc_reg_operand")
1905 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1906 (match_operand:GPR 2 "non_add_cint_operand")))]
1908 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1909 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1911 HOST_WIDE_INT val = INTVAL (operands[2]);
1912 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1913 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1915 operands[4] = GEN_INT (low);
1916 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1917 operands[3] = GEN_INT (rest);
1918 else if (can_create_pseudo_p ())
1920 operands[3] = gen_reg_rtx (DImode);
1921 emit_move_insn (operands[3], operands[2]);
1922 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1930 (define_insn "add<mode>3_carry"
1931 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1932 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1933 (match_operand:P 2 "reg_or_short_operand" "rI")))
1934 (set (reg:P CA_REGNO)
1935 (ltu:P (plus:P (match_dup 1)
1940 [(set_attr "type" "add")])
1942 (define_insn "*add<mode>3_imm_carry_pos"
1943 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1944 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1945 (match_operand:P 2 "short_cint_operand" "n")))
1946 (set (reg:P CA_REGNO)
1947 (geu:P (match_dup 1)
1948 (match_operand:P 3 "const_int_operand" "n")))]
1949 "INTVAL (operands[2]) > 0
1950 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1952 [(set_attr "type" "add")])
1954 (define_insn "*add<mode>3_imm_carry_0"
1955 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1956 (match_operand:P 1 "gpc_reg_operand" "r"))
1957 (set (reg:P CA_REGNO)
1961 [(set_attr "type" "add")])
1963 (define_insn "*add<mode>3_imm_carry_m1"
1964 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1965 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1967 (set (reg:P CA_REGNO)
1972 [(set_attr "type" "add")])
1974 (define_insn "*add<mode>3_imm_carry_neg"
1975 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1976 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1977 (match_operand:P 2 "short_cint_operand" "n")))
1978 (set (reg:P CA_REGNO)
1979 (gtu:P (match_dup 1)
1980 (match_operand:P 3 "const_int_operand" "n")))]
1981 "INTVAL (operands[2]) < 0
1982 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1984 [(set_attr "type" "add")])
1987 (define_expand "add<mode>3_carry_in"
1989 (set (match_operand:GPR 0 "gpc_reg_operand")
1990 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1991 (match_operand:GPR 2 "adde_operand"))
1992 (reg:GPR CA_REGNO)))
1993 (clobber (reg:GPR CA_REGNO))])]
1996 if (operands[2] == const0_rtx)
1998 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
2001 if (operands[2] == constm1_rtx)
2003 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
2008 (define_insn "*add<mode>3_carry_in_internal"
2009 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2010 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2011 (match_operand:GPR 2 "gpc_reg_operand" "r"))
2012 (reg:GPR CA_REGNO)))
2013 (clobber (reg:GPR CA_REGNO))]
2016 [(set_attr "type" "add")])
2018 (define_insn "*add<mode>3_carry_in_internal2"
2019 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2020 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2022 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2023 (clobber (reg:GPR CA_REGNO))]
2026 [(set_attr "type" "add")])
2028 (define_insn "add<mode>3_carry_in_0"
2029 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2030 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2031 (reg:GPR CA_REGNO)))
2032 (clobber (reg:GPR CA_REGNO))]
2035 [(set_attr "type" "add")])
2037 (define_insn "add<mode>3_carry_in_m1"
2038 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2039 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2042 (clobber (reg:GPR CA_REGNO))]
2045 [(set_attr "type" "add")])
2048 (define_expand "one_cmpl<mode>2"
2049 [(set (match_operand:SDI 0 "gpc_reg_operand")
2050 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2053 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2055 rs6000_split_logical (operands, NOT, false, false, false);
2060 (define_insn "*one_cmpl<mode>2"
2061 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2062 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2066 (define_insn_and_split "*one_cmpl<mode>2_dot"
2067 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2068 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2070 (clobber (match_scratch:GPR 0 "=r,r"))]
2071 "<MODE>mode == Pmode"
2075 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2077 (not:GPR (match_dup 1)))
2079 (compare:CC (match_dup 0)
2082 [(set_attr "type" "logical")
2083 (set_attr "dot" "yes")
2084 (set_attr "length" "4,8")])
2086 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2087 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2088 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2090 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2091 (not:GPR (match_dup 1)))]
2092 "<MODE>mode == Pmode"
2096 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2098 (not:GPR (match_dup 1)))
2100 (compare:CC (match_dup 0)
2103 [(set_attr "type" "logical")
2104 (set_attr "dot" "yes")
2105 (set_attr "length" "4,8")])
2108 (define_expand "sub<mode>3"
2109 [(set (match_operand:SDI 0 "gpc_reg_operand")
2110 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2111 (match_operand:SDI 2 "gpc_reg_operand")))]
2114 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2116 rtx lo0 = gen_lowpart (SImode, operands[0]);
2117 rtx lo1 = gen_lowpart (SImode, operands[1]);
2118 rtx lo2 = gen_lowpart (SImode, operands[2]);
2119 rtx hi0 = gen_highpart (SImode, operands[0]);
2120 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2121 rtx hi2 = gen_highpart (SImode, operands[2]);
2123 if (!reg_or_short_operand (lo1, SImode))
2124 lo1 = force_reg (SImode, lo1);
2125 if (!adde_operand (hi1, SImode))
2126 hi1 = force_reg (SImode, hi1);
2128 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2129 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2133 if (short_cint_operand (operands[1], <MODE>mode))
2135 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2140 (define_insn "*subf<mode>3"
2141 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2142 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2143 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2146 [(set_attr "type" "add")])
2148 (define_insn_and_split "*subf<mode>3_dot"
2149 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2150 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2151 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2153 (clobber (match_scratch:GPR 0 "=r,r"))]
2154 "<MODE>mode == Pmode"
2158 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2160 (minus:GPR (match_dup 2)
2163 (compare:CC (match_dup 0)
2166 [(set_attr "type" "add")
2167 (set_attr "dot" "yes")
2168 (set_attr "length" "4,8")])
2170 (define_insn_and_split "*subf<mode>3_dot2"
2171 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2172 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2173 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2175 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2176 (minus:GPR (match_dup 2)
2178 "<MODE>mode == Pmode"
2182 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2184 (minus:GPR (match_dup 2)
2187 (compare:CC (match_dup 0)
2190 [(set_attr "type" "add")
2191 (set_attr "dot" "yes")
2192 (set_attr "length" "4,8")])
2194 (define_insn "subf<mode>3_imm"
2195 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2196 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2197 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2198 (clobber (reg:GPR CA_REGNO))]
2201 [(set_attr "type" "add")])
2203 (define_insn_and_split "subf<mode>3_carry_dot2"
2204 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2205 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2206 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2208 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2209 (minus:P (match_dup 2)
2211 (set (reg:P CA_REGNO)
2212 (leu:P (match_dup 1)
2214 "<MODE>mode == Pmode"
2218 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2219 [(parallel [(set (match_dup 0)
2220 (minus:P (match_dup 2)
2222 (set (reg:P CA_REGNO)
2223 (leu:P (match_dup 1)
2226 (compare:CC (match_dup 0)
2229 [(set_attr "type" "add")
2230 (set_attr "dot" "yes")
2231 (set_attr "length" "4,8")])
2233 (define_insn "subf<mode>3_carry"
2234 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2235 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2236 (match_operand:P 1 "gpc_reg_operand" "r")))
2237 (set (reg:P CA_REGNO)
2238 (leu:P (match_dup 1)
2242 [(set_attr "type" "add")])
2244 (define_insn "*subf<mode>3_imm_carry_0"
2245 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2246 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2247 (set (reg:P CA_REGNO)
2252 [(set_attr "type" "add")])
2254 (define_insn "*subf<mode>3_imm_carry_m1"
2255 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2256 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2257 (set (reg:P CA_REGNO)
2261 [(set_attr "type" "add")])
2264 (define_expand "subf<mode>3_carry_in"
2266 (set (match_operand:GPR 0 "gpc_reg_operand")
2267 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2269 (match_operand:GPR 2 "adde_operand")))
2270 (clobber (reg:GPR CA_REGNO))])]
2273 if (operands[2] == const0_rtx)
2275 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2278 if (operands[2] == constm1_rtx)
2280 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2285 (define_insn "*subf<mode>3_carry_in_internal"
2286 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2287 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2289 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2290 (clobber (reg:GPR CA_REGNO))]
2293 [(set_attr "type" "add")])
2295 (define_insn "subf<mode>3_carry_in_0"
2296 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2297 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2298 (reg:GPR CA_REGNO)))
2299 (clobber (reg:GPR CA_REGNO))]
2302 [(set_attr "type" "add")])
2304 (define_insn "subf<mode>3_carry_in_m1"
2305 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2306 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2307 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2309 (clobber (reg:GPR CA_REGNO))]
2312 [(set_attr "type" "add")])
2314 (define_insn "subf<mode>3_carry_in_xx"
2315 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2316 (plus:GPR (reg:GPR CA_REGNO)
2318 (clobber (reg:GPR CA_REGNO))]
2321 [(set_attr "type" "add")])
2324 (define_insn "@neg<mode>2"
2325 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2326 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2329 [(set_attr "type" "add")])
2331 (define_insn_and_split "*neg<mode>2_dot"
2332 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2333 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2335 (clobber (match_scratch:GPR 0 "=r,r"))]
2336 "<MODE>mode == Pmode"
2340 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2342 (neg:GPR (match_dup 1)))
2344 (compare:CC (match_dup 0)
2347 [(set_attr "type" "add")
2348 (set_attr "dot" "yes")
2349 (set_attr "length" "4,8")])
2351 (define_insn_and_split "*neg<mode>2_dot2"
2352 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2353 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2355 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2356 (neg:GPR (match_dup 1)))]
2357 "<MODE>mode == Pmode"
2361 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2363 (neg:GPR (match_dup 1)))
2365 (compare:CC (match_dup 0)
2368 [(set_attr "type" "add")
2369 (set_attr "dot" "yes")
2370 (set_attr "length" "4,8")])
2373 (define_insn "clz<mode>2"
2374 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2375 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2378 [(set_attr "type" "cntlz")])
2380 (define_expand "ctz<mode>2"
2381 [(set (match_operand:GPR 0 "gpc_reg_operand")
2382 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2387 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2391 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2392 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2393 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2397 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2398 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2399 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2400 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2404 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2405 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2406 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2407 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2413 (define_insn "ctz<mode>2_hw"
2414 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2415 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2418 [(set_attr "type" "cntlz")])
2420 (define_expand "ffs<mode>2"
2421 [(set (match_operand:GPR 0 "gpc_reg_operand")
2422 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2425 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2426 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2427 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2428 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2429 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2430 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2431 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2436 (define_expand "popcount<mode>2"
2437 [(set (match_operand:GPR 0 "gpc_reg_operand")
2438 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2439 "TARGET_POPCNTB || TARGET_POPCNTD"
2441 rs6000_emit_popcount (operands[0], operands[1]);
2445 (define_insn "popcntb<mode>2"
2446 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2447 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2451 [(set_attr "type" "popcnt")])
2453 (define_insn "popcntd<mode>2"
2454 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2455 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2458 [(set_attr "type" "popcnt")])
2461 (define_expand "parity<mode>2"
2462 [(set (match_operand:GPR 0 "gpc_reg_operand")
2463 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2466 rs6000_emit_parity (operands[0], operands[1]);
2470 (define_insn "parity<mode>2_cmpb"
2471 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2472 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2473 "TARGET_CMPB && TARGET_POPCNTB"
2475 [(set_attr "type" "popcnt")])
2477 (define_insn "cfuged"
2478 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2479 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2480 (match_operand:DI 2 "gpc_reg_operand" "r")]
2482 "TARGET_POWER10 && TARGET_64BIT"
2484 [(set_attr "type" "integer")])
2486 (define_insn "cntlzdm"
2487 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2488 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2489 (match_operand:DI 2 "gpc_reg_operand" "r")]
2491 "TARGET_POWER10 && TARGET_POWERPC64"
2493 [(set_attr "type" "integer")])
2495 (define_insn "cnttzdm"
2496 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2497 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2498 (match_operand:DI 2 "gpc_reg_operand" "r")]
2500 "TARGET_POWER10 && TARGET_POWERPC64"
2502 [(set_attr "type" "integer")])
2504 (define_insn "pdepd"
2505 [(set (match_operand:DI 0 "register_operand" "=r")
2506 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2507 (match_operand:DI 2 "gpc_reg_operand" "r")]
2509 "TARGET_POWER10 && TARGET_POWERPC64"
2511 [(set_attr "type" "integer")])
2513 (define_insn "pextd"
2514 [(set (match_operand:DI 0 "register_operand" "=r")
2515 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2516 (match_operand:DI 2 "gpc_reg_operand" "r")]
2518 "TARGET_POWER10 && TARGET_POWERPC64"
2520 [(set_attr "type" "integer")])
2522 (define_insn "cmpb<mode>3"
2523 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2524 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2525 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2528 [(set_attr "type" "cmp")])
2530 ;; Since the hardware zeros the upper part of the register, save generating the
2531 ;; AND immediate if we are converting to unsigned
2532 (define_insn "*bswap<mode>2_extenddi"
2533 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2535 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2538 [(set_attr "type" "load")])
2540 (define_insn "*bswaphi2_extendsi"
2541 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2543 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2546 [(set_attr "type" "load")])
2548 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2549 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2550 ;; load with byte swap, which can be slower than doing it in the registers. It
2551 ;; also prevents certain failures with the RELOAD register allocator.
2553 (define_expand "bswap<mode>2"
2554 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2555 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2558 rtx dest = operands[0];
2559 rtx src = operands[1];
2561 if (!REG_P (dest) && !REG_P (src))
2562 src = force_reg (<MODE>mode, src);
2566 src = rs6000_force_indexed_or_indirect_mem (src);
2567 emit_insn (gen_bswap<mode>2_load (dest, src));
2569 else if (MEM_P (dest))
2571 dest = rs6000_force_indexed_or_indirect_mem (dest);
2572 emit_insn (gen_bswap<mode>2_store (dest, src));
2575 emit_insn (gen_bswap<mode>2_reg (dest, src));
2579 (define_insn "bswap<mode>2_load"
2580 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2581 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2584 [(set_attr "type" "load")])
2586 (define_insn "bswap<mode>2_store"
2587 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2588 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2591 [(set_attr "type" "store")])
2593 (define_insn_and_split "bswaphi2_reg"
2594 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,&r,wa")
2596 (match_operand:HI 1 "gpc_reg_operand" "r,r,wa")))
2597 (clobber (match_scratch:SI 2 "=X,&r,X"))]
2603 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], HImode)"
2605 (and:SI (lshiftrt:SI (match_dup 4)
2609 (and:SI (ashift:SI (match_dup 4)
2611 (const_int 65280))) ;; 0xff00
2613 (ior:SI (match_dup 3)
2616 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2617 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2619 [(set_attr "length" "*,12,*")
2620 (set_attr "type" "shift,*,vecperm")
2621 (set_attr "isa" "p10,*,p9v")])
2623 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2624 ;; zero_extract insns do not change for -mlittle.
2625 (define_insn_and_split "bswapsi2_reg"
2626 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,wa")
2628 (match_operand:SI 1 "gpc_reg_operand" "r,r,wa")))]
2634 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], SImode)"
2635 [(set (match_dup 0) ; DABC
2636 (rotate:SI (match_dup 1)
2638 (set (match_dup 0) ; DCBC
2639 (ior:SI (and:SI (ashift:SI (match_dup 1)
2641 (const_int 16711680))
2642 (and:SI (match_dup 0)
2643 (const_int -16711681))))
2644 (set (match_dup 0) ; DCBA
2645 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2648 (and:SI (match_dup 0)
2649 (const_int -256))))]
2651 [(set_attr "length" "4,12,4")
2652 (set_attr "type" "shift,*,vecperm")
2653 (set_attr "isa" "p10,*,p9v")])
2655 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2656 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2659 (define_expand "bswapdi2"
2660 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2662 (match_operand:DI 1 "reg_or_mem_operand")))
2663 (clobber (match_scratch:DI 2))
2664 (clobber (match_scratch:DI 3))])]
2667 rtx dest = operands[0];
2668 rtx src = operands[1];
2670 if (!REG_P (dest) && !REG_P (src))
2671 operands[1] = src = force_reg (DImode, src);
2673 if (TARGET_POWERPC64 && TARGET_LDBRX)
2677 src = rs6000_force_indexed_or_indirect_mem (src);
2678 emit_insn (gen_bswapdi2_load (dest, src));
2680 else if (MEM_P (dest))
2682 dest = rs6000_force_indexed_or_indirect_mem (dest);
2683 emit_insn (gen_bswapdi2_store (dest, src));
2685 else if (TARGET_P9_VECTOR)
2686 emit_insn (gen_bswapdi2_brd (dest, src));
2688 emit_insn (gen_bswapdi2_reg (dest, src));
2692 if (!TARGET_POWERPC64)
2694 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2695 that uses 64-bit registers needs the same scratch registers as 64-bit
2697 emit_insn (gen_bswapdi2_32bit (dest, src));
2702 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2703 (define_insn "bswapdi2_load"
2704 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2705 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2706 "TARGET_POWERPC64 && TARGET_LDBRX"
2708 [(set_attr "type" "load")])
2710 (define_insn "bswapdi2_store"
2711 [(set (match_operand:DI 0 "memory_operand" "=Z")
2712 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2713 "TARGET_POWERPC64 && TARGET_LDBRX"
2715 [(set_attr "type" "store")])
2717 (define_insn "bswapdi2_brd"
2718 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,wa")
2719 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r,wa")))]
2724 [(set_attr "type" "shift,vecperm")
2725 (set_attr "isa" "p10,p9v")])
2727 (define_insn "bswapdi2_reg"
2728 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2729 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2730 (clobber (match_scratch:DI 2 "=&r"))
2731 (clobber (match_scratch:DI 3 "=&r"))]
2732 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2734 [(set_attr "length" "36")])
2736 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2737 (define_insn "*bswapdi2_64bit"
2738 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2739 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2740 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2741 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2742 "TARGET_POWERPC64 && !TARGET_LDBRX
2743 && (REG_P (operands[0]) || REG_P (operands[1]))
2744 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2745 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2747 [(set_attr "length" "16,12,36")])
2750 [(set (match_operand:DI 0 "gpc_reg_operand")
2751 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2752 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2753 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2754 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2757 rtx dest = operands[0];
2758 rtx src = operands[1];
2759 rtx op2 = operands[2];
2760 rtx op3 = operands[3];
2761 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2762 BYTES_BIG_ENDIAN ? 4 : 0);
2763 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2764 BYTES_BIG_ENDIAN ? 4 : 0);
2770 addr1 = XEXP (src, 0);
2771 if (GET_CODE (addr1) == PLUS)
2773 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2774 if (TARGET_AVOID_XFORM)
2776 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2780 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2782 else if (TARGET_AVOID_XFORM)
2784 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2789 emit_move_insn (op2, GEN_INT (4));
2790 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2793 word1 = change_address (src, SImode, addr1);
2794 word2 = change_address (src, SImode, addr2);
2796 if (BYTES_BIG_ENDIAN)
2798 emit_insn (gen_bswapsi2 (op3_32, word2));
2799 emit_insn (gen_bswapsi2 (dest_32, word1));
2803 emit_insn (gen_bswapsi2 (op3_32, word1));
2804 emit_insn (gen_bswapsi2 (dest_32, word2));
2807 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2808 emit_insn (gen_iordi3 (dest, dest, op3));
2813 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2814 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2815 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2816 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2817 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2820 rtx dest = operands[0];
2821 rtx src = operands[1];
2822 rtx op2 = operands[2];
2823 rtx op3 = operands[3];
2824 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2825 BYTES_BIG_ENDIAN ? 4 : 0);
2826 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2827 BYTES_BIG_ENDIAN ? 4 : 0);
2833 addr1 = XEXP (dest, 0);
2834 if (GET_CODE (addr1) == PLUS)
2836 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2837 if (TARGET_AVOID_XFORM)
2839 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2843 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2845 else if (TARGET_AVOID_XFORM)
2847 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2852 emit_move_insn (op2, GEN_INT (4));
2853 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2856 word1 = change_address (dest, SImode, addr1);
2857 word2 = change_address (dest, SImode, addr2);
2859 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2861 if (BYTES_BIG_ENDIAN)
2863 emit_insn (gen_bswapsi2 (word1, src_si));
2864 emit_insn (gen_bswapsi2 (word2, op3_si));
2868 emit_insn (gen_bswapsi2 (word2, src_si));
2869 emit_insn (gen_bswapsi2 (word1, op3_si));
2875 [(set (match_operand:DI 0 "gpc_reg_operand")
2876 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2877 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2878 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2879 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2882 rtx dest = operands[0];
2883 rtx src = operands[1];
2884 rtx op2 = operands[2];
2885 rtx op3 = operands[3];
2886 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2887 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2888 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2889 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2890 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2892 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2893 emit_insn (gen_bswapsi2 (dest_si, src_si));
2894 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2895 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2896 emit_insn (gen_iordi3 (dest, dest, op3));
2900 (define_insn "bswapdi2_32bit"
2901 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2902 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2903 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2904 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2906 [(set_attr "length" "16,12,36")])
2909 [(set (match_operand:DI 0 "gpc_reg_operand")
2910 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2911 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2912 "!TARGET_POWERPC64 && reload_completed"
2915 rtx dest = operands[0];
2916 rtx src = operands[1];
2917 rtx op2 = operands[2];
2918 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2919 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2925 addr1 = XEXP (src, 0);
2926 if (GET_CODE (addr1) == PLUS)
2928 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2929 if (TARGET_AVOID_XFORM
2930 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2932 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2936 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2938 else if (TARGET_AVOID_XFORM
2939 || REGNO (addr1) == REGNO (dest2))
2941 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2946 emit_move_insn (op2, GEN_INT (4));
2947 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2950 word1 = change_address (src, SImode, addr1);
2951 word2 = change_address (src, SImode, addr2);
2953 emit_insn (gen_bswapsi2 (dest2, word1));
2954 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2955 thus allowing us to omit an early clobber on the output. */
2956 emit_insn (gen_bswapsi2 (dest1, word2));
2961 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2962 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2963 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2964 "!TARGET_POWERPC64 && reload_completed"
2967 rtx dest = operands[0];
2968 rtx src = operands[1];
2969 rtx op2 = operands[2];
2970 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2971 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2977 addr1 = XEXP (dest, 0);
2978 if (GET_CODE (addr1) == PLUS)
2980 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2981 if (TARGET_AVOID_XFORM)
2983 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2987 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2989 else if (TARGET_AVOID_XFORM)
2991 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2996 emit_move_insn (op2, GEN_INT (4));
2997 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
3000 word1 = change_address (dest, SImode, addr1);
3001 word2 = change_address (dest, SImode, addr2);
3003 emit_insn (gen_bswapsi2 (word2, src1));
3004 emit_insn (gen_bswapsi2 (word1, src2));
3009 [(set (match_operand:DI 0 "gpc_reg_operand")
3010 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
3011 (clobber (match_operand:SI 2 ""))]
3012 "!TARGET_POWERPC64 && reload_completed"
3015 rtx dest = operands[0];
3016 rtx src = operands[1];
3017 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3018 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3019 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
3020 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
3022 emit_insn (gen_bswapsi2 (dest1, src2));
3023 emit_insn (gen_bswapsi2 (dest2, src1));
3028 (define_insn "mul<mode>3"
3029 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3030 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3031 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
3036 [(set_attr "type" "mul")
3038 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
3040 (match_operand:GPR 2 "short_cint_operand")
3041 (const_string "16")]
3042 (const_string "<bits>")))])
3044 (define_insn_and_split "*mul<mode>3_dot"
3045 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3046 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3047 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3049 (clobber (match_scratch:GPR 0 "=r,r"))]
3050 "<MODE>mode == Pmode"
3054 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3056 (mult:GPR (match_dup 1)
3059 (compare:CC (match_dup 0)
3062 [(set_attr "type" "mul")
3063 (set_attr "size" "<bits>")
3064 (set_attr "dot" "yes")
3065 (set_attr "length" "4,8")])
3067 (define_insn_and_split "*mul<mode>3_dot2"
3068 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3069 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3070 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3072 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3073 (mult:GPR (match_dup 1)
3075 "<MODE>mode == Pmode"
3079 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3081 (mult:GPR (match_dup 1)
3084 (compare:CC (match_dup 0)
3087 [(set_attr "type" "mul")
3088 (set_attr "size" "<bits>")
3089 (set_attr "dot" "yes")
3090 (set_attr "length" "4,8")])
3093 (define_expand "<su>mul<mode>3_highpart"
3094 [(set (match_operand:GPR 0 "gpc_reg_operand")
3096 (mult:<DMODE> (any_extend:<DMODE>
3097 (match_operand:GPR 1 "gpc_reg_operand"))
3099 (match_operand:GPR 2 "gpc_reg_operand")))
3103 if (<MODE>mode == SImode && TARGET_POWERPC64)
3105 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3110 if (!WORDS_BIG_ENDIAN)
3112 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3118 (define_insn "*<su>mul<mode>3_highpart"
3119 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3121 (mult:<DMODE> (any_extend:<DMODE>
3122 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3124 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3126 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3127 "mulh<wd><u> %0,%1,%2"
3128 [(set_attr "type" "mul")
3129 (set_attr "size" "<bits>")])
3131 (define_insn "<su>mulsi3_highpart_le"
3132 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3134 (mult:DI (any_extend:DI
3135 (match_operand:SI 1 "gpc_reg_operand" "r"))
3137 (match_operand:SI 2 "gpc_reg_operand" "r")))
3139 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3141 [(set_attr "type" "mul")])
3143 (define_insn "<su>muldi3_highpart_le"
3144 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3146 (mult:TI (any_extend:TI
3147 (match_operand:DI 1 "gpc_reg_operand" "r"))
3149 (match_operand:DI 2 "gpc_reg_operand" "r")))
3151 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3153 [(set_attr "type" "mul")
3154 (set_attr "size" "64")])
3156 (define_insn "<su>mulsi3_highpart_64"
3157 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3160 (mult:DI (any_extend:DI
3161 (match_operand:SI 1 "gpc_reg_operand" "r"))
3163 (match_operand:SI 2 "gpc_reg_operand" "r")))
3167 [(set_attr "type" "mul")])
3169 (define_expand "<u>mul<mode><dmode>3"
3170 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3171 (mult:<DMODE> (any_extend:<DMODE>
3172 (match_operand:GPR 1 "gpc_reg_operand"))
3174 (match_operand:GPR 2 "gpc_reg_operand"))))]
3175 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3177 rtx l = gen_reg_rtx (<MODE>mode);
3178 rtx h = gen_reg_rtx (<MODE>mode);
3179 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3180 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3181 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3182 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3186 (define_insn "*maddld<mode>4"
3187 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3188 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3189 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3190 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3192 "maddld %0,%1,%2,%3"
3193 [(set_attr "type" "mul")])
3195 (define_insn "udiv<mode>3"
3196 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3197 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3198 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3201 [(set_attr "type" "div")
3202 (set_attr "size" "<bits>")])
3205 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3206 ;; modulus. If it isn't a power of two, force operands into register and do
3208 (define_expand "div<mode>3"
3209 [(set (match_operand:GPR 0 "gpc_reg_operand")
3210 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3211 (match_operand:GPR 2 "reg_or_cint_operand")))]
3214 if (CONST_INT_P (operands[2])
3215 && INTVAL (operands[2]) > 0
3216 && exact_log2 (INTVAL (operands[2])) >= 0)
3218 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3222 operands[2] = force_reg (<MODE>mode, operands[2]);
3225 (define_insn "*div<mode>3"
3226 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3227 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3228 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3231 [(set_attr "type" "div")
3232 (set_attr "size" "<bits>")])
3234 (define_insn "div<mode>3_sra"
3235 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3236 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3237 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3238 (clobber (reg:GPR CA_REGNO))]
3240 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3241 [(set_attr "type" "two")
3242 (set_attr "length" "8")])
3244 (define_insn_and_split "*div<mode>3_sra_dot"
3245 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3246 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3247 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3249 (clobber (match_scratch:GPR 0 "=r,r"))
3250 (clobber (reg:GPR CA_REGNO))]
3251 "<MODE>mode == Pmode"
3253 sra<wd>i %0,%1,%p2\;addze. %0,%0
3255 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3256 [(parallel [(set (match_dup 0)
3257 (div:GPR (match_dup 1)
3259 (clobber (reg:GPR CA_REGNO))])
3261 (compare:CC (match_dup 0)
3264 [(set_attr "type" "two")
3265 (set_attr "length" "8,12")
3266 (set_attr "cell_micro" "not")])
3268 (define_insn_and_split "*div<mode>3_sra_dot2"
3269 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3270 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3271 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3273 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3274 (div:GPR (match_dup 1)
3276 (clobber (reg:GPR CA_REGNO))]
3277 "<MODE>mode == Pmode"
3279 sra<wd>i %0,%1,%p2\;addze. %0,%0
3281 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3282 [(parallel [(set (match_dup 0)
3283 (div:GPR (match_dup 1)
3285 (clobber (reg:GPR CA_REGNO))])
3287 (compare:CC (match_dup 0)
3290 [(set_attr "type" "two")
3291 (set_attr "length" "8,12")
3292 (set_attr "cell_micro" "not")])
3294 (define_expand "mod<mode>3"
3295 [(set (match_operand:GPR 0 "gpc_reg_operand")
3296 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3297 (match_operand:GPR 2 "reg_or_cint_operand")))]
3304 if (!CONST_INT_P (operands[2])
3305 || INTVAL (operands[2]) <= 0
3306 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3311 operands[2] = force_reg (<MODE>mode, operands[2]);
3315 temp1 = gen_reg_rtx (<MODE>mode);
3316 temp2 = gen_reg_rtx (<MODE>mode);
3318 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3319 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3320 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3325 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3326 ;; mod, prefer putting the result of mod into a different register
3327 (define_insn "*mod<mode>3"
3328 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3329 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3330 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3333 [(set_attr "type" "div")
3334 (set_attr "size" "<bits>")])
3337 (define_insn "umod<mode>3"
3338 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3339 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3340 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3343 [(set_attr "type" "div")
3344 (set_attr "size" "<bits>")])
3346 ;; On machines with modulo support, do a combined div/mod the old fashioned
3347 ;; method, since the multiply/subtract is faster than doing the mod instruction
3351 [(set (match_operand:GPR 0 "gpc_reg_operand")
3352 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3353 (match_operand:GPR 2 "gpc_reg_operand")))
3354 (set (match_operand:GPR 3 "gpc_reg_operand")
3355 (mod:GPR (match_dup 1)
3358 && ! reg_mentioned_p (operands[0], operands[1])
3359 && ! reg_mentioned_p (operands[0], operands[2])
3360 && ! reg_mentioned_p (operands[3], operands[1])
3361 && ! reg_mentioned_p (operands[3], operands[2])"
3363 (div:GPR (match_dup 1)
3366 (mult:GPR (match_dup 0)
3369 (minus:GPR (match_dup 1)
3373 [(set (match_operand:GPR 0 "gpc_reg_operand")
3374 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3375 (match_operand:GPR 2 "gpc_reg_operand")))
3376 (set (match_operand:GPR 3 "gpc_reg_operand")
3377 (umod:GPR (match_dup 1)
3380 && ! reg_mentioned_p (operands[0], operands[1])
3381 && ! reg_mentioned_p (operands[0], operands[2])
3382 && ! reg_mentioned_p (operands[3], operands[1])
3383 && ! reg_mentioned_p (operands[3], operands[2])"
3385 (udiv:GPR (match_dup 1)
3388 (mult:GPR (match_dup 0)
3391 (minus:GPR (match_dup 1)
3395 ;; Logical instructions
3396 ;; The logical instructions are mostly combined by using match_operator,
3397 ;; but the plain AND insns are somewhat different because there is no
3398 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3399 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3401 (define_expand "and<mode>3"
3402 [(set (match_operand:SDI 0 "gpc_reg_operand")
3403 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3404 (match_operand:SDI 2 "reg_or_cint_operand")))]
3407 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3409 rs6000_split_logical (operands, AND, false, false, false);
3413 if (CONST_INT_P (operands[2]))
3415 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3417 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3421 if (logical_const_operand (operands[2], <MODE>mode))
3423 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3427 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3429 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3433 operands[2] = force_reg (<MODE>mode, operands[2]);
3438 (define_insn "and<mode>3_imm"
3439 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3440 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3441 (match_operand:GPR 2 "logical_const_operand" "n")))
3442 (clobber (match_scratch:CC 3 "=x"))]
3443 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3444 "andi%e2. %0,%1,%u2"
3445 [(set_attr "type" "logical")
3446 (set_attr "dot" "yes")])
3448 (define_insn_and_split "*and<mode>3_imm_dot"
3449 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3450 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3451 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3453 (clobber (match_scratch:GPR 0 "=r,r"))
3454 (clobber (match_scratch:CC 4 "=X,x"))]
3455 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3456 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3460 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3461 [(parallel [(set (match_dup 0)
3462 (and:GPR (match_dup 1)
3464 (clobber (match_dup 4))])
3466 (compare:CC (match_dup 0)
3469 [(set_attr "type" "logical")
3470 (set_attr "dot" "yes")
3471 (set_attr "length" "4,8")])
3473 (define_insn_and_split "*and<mode>3_imm_dot2"
3474 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3475 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3476 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3478 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3479 (and:GPR (match_dup 1)
3481 (clobber (match_scratch:CC 4 "=X,x"))]
3482 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3483 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3487 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3488 [(parallel [(set (match_dup 0)
3489 (and:GPR (match_dup 1)
3491 (clobber (match_dup 4))])
3493 (compare:CC (match_dup 0)
3496 [(set_attr "type" "logical")
3497 (set_attr "dot" "yes")
3498 (set_attr "length" "4,8")])
3500 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3501 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3502 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3503 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3505 (clobber (match_scratch:GPR 0 "=r,r"))]
3506 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3507 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3511 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3513 (and:GPR (match_dup 1)
3516 (compare:CC (match_dup 0)
3519 [(set_attr "type" "logical")
3520 (set_attr "dot" "yes")
3521 (set_attr "length" "4,8")])
3523 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3524 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3525 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3526 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3528 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3529 (and:GPR (match_dup 1)
3531 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3532 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3536 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3538 (and:GPR (match_dup 1)
3541 (compare:CC (match_dup 0)
3544 [(set_attr "type" "logical")
3545 (set_attr "dot" "yes")
3546 (set_attr "length" "4,8")])
3548 (define_insn "*and<mode>3_imm_dot_shifted"
3549 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3552 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3553 (match_operand:SI 4 "const_int_operand" "n"))
3554 (match_operand:GPR 2 "const_int_operand" "n"))
3556 (clobber (match_scratch:GPR 0 "=r"))]
3557 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3558 << INTVAL (operands[4])),
3560 && (<MODE>mode == Pmode
3561 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3563 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3564 return "andi%e2. %0,%1,%u2";
3566 [(set_attr "type" "logical")
3567 (set_attr "dot" "yes")])
3570 (define_insn "and<mode>3_mask"
3571 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3572 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3573 (match_operand:GPR 2 "const_int_operand" "n")))]
3574 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3576 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3578 [(set_attr "type" "shift")])
3580 (define_insn_and_split "*and<mode>3_mask_dot"
3581 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3582 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3583 (match_operand:GPR 2 "const_int_operand" "n,n"))
3585 (clobber (match_scratch:GPR 0 "=r,r"))]
3586 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3587 && !logical_const_operand (operands[2], <MODE>mode)
3588 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3590 if (which_alternative == 0)
3591 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3595 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3597 (and:GPR (match_dup 1)
3600 (compare:CC (match_dup 0)
3603 [(set_attr "type" "shift")
3604 (set_attr "dot" "yes")
3605 (set_attr "length" "4,8")])
3607 (define_insn_and_split "*and<mode>3_mask_dot2"
3608 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3609 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3610 (match_operand:GPR 2 "const_int_operand" "n,n"))
3612 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3613 (and:GPR (match_dup 1)
3615 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3616 && !logical_const_operand (operands[2], <MODE>mode)
3617 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3619 if (which_alternative == 0)
3620 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3624 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3626 (and:GPR (match_dup 1)
3629 (compare:CC (match_dup 0)
3632 [(set_attr "type" "shift")
3633 (set_attr "dot" "yes")
3634 (set_attr "length" "4,8")])
3637 (define_insn_and_split "*and<mode>3_2insn"
3638 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3639 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3640 (match_operand:GPR 2 "const_int_operand" "n")))]
3641 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3642 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3643 || logical_const_operand (operands[2], <MODE>mode))"
3648 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3651 [(set_attr "type" "shift")
3652 (set_attr "length" "8")])
3654 (define_insn_and_split "*and<mode>3_2insn_dot"
3655 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3656 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3657 (match_operand:GPR 2 "const_int_operand" "n,n"))
3659 (clobber (match_scratch:GPR 0 "=r,r"))]
3660 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3661 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3662 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3663 || logical_const_operand (operands[2], <MODE>mode))"
3665 "&& reload_completed"
3668 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3671 [(set_attr "type" "shift")
3672 (set_attr "dot" "yes")
3673 (set_attr "length" "8,12")])
3675 (define_insn_and_split "*and<mode>3_2insn_dot2"
3676 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3677 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3678 (match_operand:GPR 2 "const_int_operand" "n,n"))
3680 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3681 (and:GPR (match_dup 1)
3683 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3684 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3685 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3686 || logical_const_operand (operands[2], <MODE>mode))"
3688 "&& reload_completed"
3691 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3694 [(set_attr "type" "shift")
3695 (set_attr "dot" "yes")
3696 (set_attr "length" "8,12")])
3699 (define_expand "<code><mode>3"
3700 [(set (match_operand:SDI 0 "gpc_reg_operand")
3701 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3702 (match_operand:SDI 2 "reg_or_cint_operand")))]
3705 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3707 rs6000_split_logical (operands, <CODE>, false, false, false);
3711 if (non_logical_cint_operand (operands[2], <MODE>mode))
3713 rtx tmp = ((!can_create_pseudo_p ()
3714 || rtx_equal_p (operands[0], operands[1]))
3715 ? operands[0] : gen_reg_rtx (<MODE>mode));
3717 HOST_WIDE_INT value = INTVAL (operands[2]);
3718 HOST_WIDE_INT lo = value & 0xffff;
3719 HOST_WIDE_INT hi = value - lo;
3721 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3722 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3726 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3727 operands[2] = force_reg (<MODE>mode, operands[2]);
3731 [(set (match_operand:GPR 0 "gpc_reg_operand")
3732 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3733 (match_operand:GPR 2 "non_logical_cint_operand")))]
3736 (iorxor:GPR (match_dup 1)
3739 (iorxor:GPR (match_dup 3)
3742 operands[3] = ((!can_create_pseudo_p ()
3743 || rtx_equal_p (operands[0], operands[1]))
3744 ? operands[0] : gen_reg_rtx (<MODE>mode));
3746 HOST_WIDE_INT value = INTVAL (operands[2]);
3747 HOST_WIDE_INT lo = value & 0xffff;
3748 HOST_WIDE_INT hi = value - lo;
3750 operands[4] = GEN_INT (hi);
3751 operands[5] = GEN_INT (lo);
3754 (define_insn "*bool<mode>3_imm"
3755 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3756 (match_operator:GPR 3 "boolean_or_operator"
3757 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3758 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3761 [(set_attr "type" "logical")])
3763 (define_insn "*bool<mode>3"
3764 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3765 (match_operator:GPR 3 "boolean_operator"
3766 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3767 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3770 [(set_attr "type" "logical")])
3772 (define_insn_and_split "*bool<mode>3_dot"
3773 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3774 (compare:CC (match_operator:GPR 3 "boolean_operator"
3775 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3776 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3778 (clobber (match_scratch:GPR 0 "=r,r"))]
3779 "<MODE>mode == Pmode"
3783 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3787 (compare:CC (match_dup 0)
3790 [(set_attr "type" "logical")
3791 (set_attr "dot" "yes")
3792 (set_attr "length" "4,8")])
3794 (define_insn_and_split "*bool<mode>3_dot2"
3795 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3796 (compare:CC (match_operator:GPR 3 "boolean_operator"
3797 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3798 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3800 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3802 "<MODE>mode == Pmode"
3806 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3810 (compare:CC (match_dup 0)
3813 [(set_attr "type" "logical")
3814 (set_attr "dot" "yes")
3815 (set_attr "length" "4,8")])
3818 (define_insn "*boolc<mode>3"
3819 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3820 (match_operator:GPR 3 "boolean_operator"
3821 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3822 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3825 [(set_attr "type" "logical")])
3827 (define_insn_and_split "*boolc<mode>3_dot"
3828 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3829 (compare:CC (match_operator:GPR 3 "boolean_operator"
3830 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3831 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3833 (clobber (match_scratch:GPR 0 "=r,r"))]
3834 "<MODE>mode == Pmode"
3838 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3842 (compare:CC (match_dup 0)
3845 [(set_attr "type" "logical")
3846 (set_attr "dot" "yes")
3847 (set_attr "length" "4,8")])
3849 (define_insn_and_split "*boolc<mode>3_dot2"
3850 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3851 (compare:CC (match_operator:GPR 3 "boolean_operator"
3852 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3853 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3855 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3857 "<MODE>mode == Pmode"
3861 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3865 (compare:CC (match_dup 0)
3868 [(set_attr "type" "logical")
3869 (set_attr "dot" "yes")
3870 (set_attr "length" "4,8")])
3873 (define_insn "*boolcc<mode>3"
3874 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3875 (match_operator:GPR 3 "boolean_operator"
3876 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3877 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3880 [(set_attr "type" "logical")])
3882 (define_insn_and_split "*boolcc<mode>3_dot"
3883 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3884 (compare:CC (match_operator:GPR 3 "boolean_operator"
3885 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3886 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3888 (clobber (match_scratch:GPR 0 "=r,r"))]
3889 "<MODE>mode == Pmode"
3893 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3897 (compare:CC (match_dup 0)
3900 [(set_attr "type" "logical")
3901 (set_attr "dot" "yes")
3902 (set_attr "length" "4,8")])
3904 (define_insn_and_split "*boolcc<mode>3_dot2"
3905 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3906 (compare:CC (match_operator:GPR 3 "boolean_operator"
3907 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3908 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3910 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3912 "<MODE>mode == Pmode"
3916 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3920 (compare:CC (match_dup 0)
3923 [(set_attr "type" "logical")
3924 (set_attr "dot" "yes")
3925 (set_attr "length" "4,8")])
3928 ;; TODO: Should have dots of this as well.
3929 (define_insn "*eqv<mode>3"
3930 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3931 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3932 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3935 [(set_attr "type" "logical")])
3937 ;; Rotate-and-mask and insert.
3939 (define_insn "*rotl<mode>3_mask"
3940 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3941 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3942 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3943 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3944 (match_operand:GPR 3 "const_int_operand" "n")))]
3945 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3947 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3949 [(set_attr "type" "shift")
3950 (set_attr "maybe_var_shift" "yes")])
3952 (define_insn_and_split "*rotl<mode>3_mask_dot"
3953 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3955 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3956 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3957 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3958 (match_operand:GPR 3 "const_int_operand" "n,n"))
3960 (clobber (match_scratch:GPR 0 "=r,r"))]
3961 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3962 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3964 if (which_alternative == 0)
3965 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3969 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3971 (and:GPR (match_dup 4)
3974 (compare:CC (match_dup 0)
3977 [(set_attr "type" "shift")
3978 (set_attr "maybe_var_shift" "yes")
3979 (set_attr "dot" "yes")
3980 (set_attr "length" "4,8")])
3982 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3983 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3985 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3986 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3987 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3988 (match_operand:GPR 3 "const_int_operand" "n,n"))
3990 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3991 (and:GPR (match_dup 4)
3993 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3994 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3996 if (which_alternative == 0)
3997 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
4001 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
4003 (and:GPR (match_dup 4)
4006 (compare:CC (match_dup 0)
4009 [(set_attr "type" "shift")
4010 (set_attr "maybe_var_shift" "yes")
4011 (set_attr "dot" "yes")
4012 (set_attr "length" "4,8")])
4014 ; Special case for less-than-0. We can do it with just one machine
4015 ; instruction, but the generic optimizers do not realise it is cheap.
4016 (define_insn "*lt0_<mode>di"
4017 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4018 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
4022 [(set_attr "type" "shift")])
4024 (define_insn "*lt0_<mode>si"
4025 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4026 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
4029 "rlwinm %0,%1,1,31,31"
4030 [(set_attr "type" "shift")])
4034 ; Two forms for insert (the two arms of the IOR are not canonicalized,
4035 ; both are an AND so are the same precedence).
4036 (define_insn "*rotl<mode>3_insert"
4037 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4038 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4039 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4040 (match_operand:SI 2 "const_int_operand" "n")])
4041 (match_operand:GPR 3 "const_int_operand" "n"))
4042 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4043 (match_operand:GPR 6 "const_int_operand" "n"))))]
4044 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4045 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4047 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4049 [(set_attr "type" "insert")])
4050 ; FIXME: this needs an attr "size", so that the scheduler can see the
4051 ; difference between rlwimi and rldimi. We also might want dot forms,
4052 ; but not for rlwimi on POWER4 and similar processors.
4054 (define_insn "*rotl<mode>3_insert_2"
4055 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4056 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4057 (match_operand:GPR 6 "const_int_operand" "n"))
4058 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4059 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4060 (match_operand:SI 2 "const_int_operand" "n")])
4061 (match_operand:GPR 3 "const_int_operand" "n"))))]
4062 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4063 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4065 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4067 [(set_attr "type" "insert")])
4069 ; There are also some forms without one of the ANDs.
4070 (define_insn "*rotl<mode>3_insert_3"
4071 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4072 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4073 (match_operand:GPR 4 "const_int_operand" "n"))
4074 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4075 (match_operand:SI 2 "const_int_operand" "n"))))]
4076 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4078 if (<MODE>mode == SImode)
4079 return "rlwimi %0,%1,%h2,0,31-%h2";
4081 return "rldimi %0,%1,%H2,0";
4083 [(set_attr "type" "insert")])
4085 (define_insn "*rotl<mode>3_insert_4"
4086 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4087 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4088 (match_operand:GPR 4 "const_int_operand" "n"))
4089 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4090 (match_operand:SI 2 "const_int_operand" "n"))))]
4091 "<MODE>mode == SImode &&
4092 GET_MODE_PRECISION (<MODE>mode)
4093 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4095 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4096 - INTVAL (operands[2]));
4097 if (<MODE>mode == SImode)
4098 return "rlwimi %0,%1,%h2,32-%h2,31";
4100 return "rldimi %0,%1,%H2,64-%H2";
4102 [(set_attr "type" "insert")])
4104 (define_insn "*rotlsi3_insert_5"
4105 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4106 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4107 (match_operand:SI 2 "const_int_operand" "n,n"))
4108 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4109 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4110 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4111 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4112 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4116 [(set_attr "type" "insert")])
4118 (define_insn "*rotldi3_insert_6"
4119 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4120 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4121 (match_operand:DI 2 "const_int_operand" "n"))
4122 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4123 (match_operand:DI 4 "const_int_operand" "n"))))]
4124 "exact_log2 (-UINTVAL (operands[2])) > 0
4125 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4127 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4128 return "rldimi %0,%3,0,%5";
4130 [(set_attr "type" "insert")
4131 (set_attr "size" "64")])
4133 (define_insn "*rotldi3_insert_7"
4134 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4135 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4136 (match_operand:DI 4 "const_int_operand" "n"))
4137 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4138 (match_operand:DI 2 "const_int_operand" "n"))))]
4139 "exact_log2 (-UINTVAL (operands[2])) > 0
4140 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4142 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4143 return "rldimi %0,%3,0,%5";
4145 [(set_attr "type" "insert")
4146 (set_attr "size" "64")])
4149 ; This handles the important case of multiple-precision shifts. There is
4150 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4152 [(set (match_operand:GPR 0 "gpc_reg_operand")
4153 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4154 (match_operand:SI 3 "const_int_operand"))
4155 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4156 (match_operand:SI 4 "const_int_operand"))))]
4157 "can_create_pseudo_p ()
4158 && INTVAL (operands[3]) + INTVAL (operands[4])
4159 >= GET_MODE_PRECISION (<MODE>mode)"
4161 (lshiftrt:GPR (match_dup 2)
4164 (ior:GPR (and:GPR (match_dup 5)
4166 (ashift:GPR (match_dup 1)
4169 unsigned HOST_WIDE_INT mask = 1;
4170 mask = (mask << INTVAL (operands[3])) - 1;
4171 operands[5] = gen_reg_rtx (<MODE>mode);
4172 operands[6] = GEN_INT (mask);
4176 [(set (match_operand:GPR 0 "gpc_reg_operand")
4177 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4178 (match_operand:SI 4 "const_int_operand"))
4179 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4180 (match_operand:SI 3 "const_int_operand"))))]
4181 "can_create_pseudo_p ()
4182 && INTVAL (operands[3]) + INTVAL (operands[4])
4183 >= GET_MODE_PRECISION (<MODE>mode)"
4185 (lshiftrt:GPR (match_dup 2)
4188 (ior:GPR (and:GPR (match_dup 5)
4190 (ashift:GPR (match_dup 1)
4193 unsigned HOST_WIDE_INT mask = 1;
4194 mask = (mask << INTVAL (operands[3])) - 1;
4195 operands[5] = gen_reg_rtx (<MODE>mode);
4196 operands[6] = GEN_INT (mask);
4200 ; Another important case is setting some bits to 1; we can do that with
4201 ; an insert instruction, in many cases.
4202 (define_insn_and_split "*ior<mode>_mask"
4203 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4204 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4205 (match_operand:GPR 2 "const_int_operand" "n")))
4206 (clobber (match_scratch:GPR 3 "=r"))]
4207 "!logical_const_operand (operands[2], <MODE>mode)
4208 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4214 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4217 (and:GPR (match_dup 1)
4221 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4222 if (GET_CODE (operands[3]) == SCRATCH)
4223 operands[3] = gen_reg_rtx (<MODE>mode);
4224 operands[4] = GEN_INT (ne);
4225 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4227 [(set_attr "type" "two")
4228 (set_attr "length" "8")])
4231 ; Yet another case is an rldimi with the second value coming from memory.
4232 ; The zero_extend that should become part of the rldimi is merged into the
4233 ; load from memory instead. Split things properly again.
4235 [(set (match_operand:DI 0 "gpc_reg_operand")
4236 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4237 (match_operand:SI 2 "const_int_operand"))
4238 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4239 "INTVAL (operands[2]) == <bits>"
4241 (zero_extend:DI (match_dup 3)))
4243 (ior:DI (and:DI (match_dup 4)
4245 (ashift:DI (match_dup 1)
4248 operands[4] = gen_reg_rtx (DImode);
4249 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4252 ; rldimi with UNSPEC_SI_FROM_SF.
4253 (define_insn_and_split "*rotldi3_insert_sf"
4254 [(set (match_operand:DI 0 "gpc_reg_operand")
4256 (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4257 (match_operand:SI 2 "const_int_operand"))
4260 [(match_operand:SF 3 "memory_operand")]
4261 UNSPEC_SI_FROM_SF))))
4262 (clobber (match_scratch:V4SF 4))]
4263 "TARGET_POWERPC64 && INTVAL (operands[2]) == <bits>"
4266 [(parallel [(set (match_dup 5)
4267 (zero_extend:DI (unspec:QHSI [(match_dup 3)] UNSPEC_SI_FROM_SF)))
4268 (clobber (match_dup 4))])
4271 (and:DI (match_dup 5) (match_dup 6))
4272 (ashift:DI (match_dup 1) (match_dup 2))))]
4274 operands[5] = gen_reg_rtx (DImode);
4275 operands[6] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4280 [(set (match_operand:SI 0 "gpc_reg_operand")
4281 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4282 (match_operand:SI 2 "const_int_operand"))
4283 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4284 "INTVAL (operands[2]) == <bits>"
4286 (zero_extend:SI (match_dup 3)))
4288 (ior:SI (and:SI (match_dup 4)
4290 (ashift:SI (match_dup 1)
4293 operands[4] = gen_reg_rtx (SImode);
4294 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4298 ;; Now the simple shifts.
4300 (define_insn "rotl<mode>3"
4301 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4302 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4303 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4305 "rotl<wd>%I2 %0,%1,%<hH>2"
4306 [(set_attr "type" "shift")
4307 (set_attr "maybe_var_shift" "yes")])
4309 (define_insn "*rotlsi3_64"
4310 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4312 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4313 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4315 "rotlw%I2 %0,%1,%h2"
4316 [(set_attr "type" "shift")
4317 (set_attr "maybe_var_shift" "yes")])
4319 (define_insn_and_split "*rotl<mode>3_dot"
4320 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4321 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4322 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4324 (clobber (match_scratch:GPR 0 "=r,r"))]
4325 "<MODE>mode == Pmode"
4327 rotl<wd>%I2. %0,%1,%<hH>2
4329 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4331 (rotate:GPR (match_dup 1)
4334 (compare:CC (match_dup 0)
4337 [(set_attr "type" "shift")
4338 (set_attr "maybe_var_shift" "yes")
4339 (set_attr "dot" "yes")
4340 (set_attr "length" "4,8")])
4342 (define_insn_and_split "*rotl<mode>3_dot2"
4343 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4344 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4345 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4347 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4348 (rotate:GPR (match_dup 1)
4350 "<MODE>mode == Pmode"
4352 rotl<wd>%I2. %0,%1,%<hH>2
4354 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4356 (rotate:GPR (match_dup 1)
4359 (compare:CC (match_dup 0)
4362 [(set_attr "type" "shift")
4363 (set_attr "maybe_var_shift" "yes")
4364 (set_attr "dot" "yes")
4365 (set_attr "length" "4,8")])
4368 (define_insn "ashl<mode>3"
4369 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4370 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4371 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4373 "sl<wd>%I2 %0,%1,%<hH>2"
4374 [(set_attr "type" "shift")
4375 (set_attr "maybe_var_shift" "yes")])
4377 (define_insn "*ashlsi3_64"
4378 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4380 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4381 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4384 [(set_attr "type" "shift")
4385 (set_attr "maybe_var_shift" "yes")])
4387 (define_insn_and_split "*ashl<mode>3_dot"
4388 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4389 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4390 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4392 (clobber (match_scratch:GPR 0 "=r,r"))]
4393 "<MODE>mode == Pmode"
4395 sl<wd>%I2. %0,%1,%<hH>2
4397 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4399 (ashift:GPR (match_dup 1)
4402 (compare:CC (match_dup 0)
4405 [(set_attr "type" "shift")
4406 (set_attr "maybe_var_shift" "yes")
4407 (set_attr "dot" "yes")
4408 (set_attr "length" "4,8")])
4410 (define_insn_and_split "*ashl<mode>3_dot2"
4411 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4412 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4413 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4415 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4416 (ashift:GPR (match_dup 1)
4418 "<MODE>mode == Pmode"
4420 sl<wd>%I2. %0,%1,%<hH>2
4422 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4424 (ashift:GPR (match_dup 1)
4427 (compare:CC (match_dup 0)
4430 [(set_attr "type" "shift")
4431 (set_attr "maybe_var_shift" "yes")
4432 (set_attr "dot" "yes")
4433 (set_attr "length" "4,8")])
4435 ;; Pretend we have a memory form of extswsli until register allocation is done
4436 ;; so that we use LWZ to load the value from memory, instead of LWA.
4437 (define_insn_and_split "ashdi3_extswsli"
4438 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4440 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4441 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4446 "&& reload_completed && MEM_P (operands[1])"
4450 (ashift:DI (sign_extend:DI (match_dup 3))
4453 operands[3] = gen_lowpart (SImode, operands[0]);
4455 [(set_attr "type" "shift")
4456 (set_attr "maybe_var_shift" "no")])
4459 (define_insn_and_split "ashdi3_extswsli_dot"
4460 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4463 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4464 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4466 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4473 "&& reload_completed
4474 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4475 || memory_operand (operands[1], SImode))"
4478 rtx dest = operands[0];
4479 rtx src = operands[1];
4480 rtx shift = operands[2];
4481 rtx cr = operands[3];
4488 src2 = gen_lowpart (SImode, dest);
4489 emit_move_insn (src2, src);
4492 if (REGNO (cr) == CR0_REGNO)
4494 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4498 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4499 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4502 [(set_attr "type" "shift")
4503 (set_attr "maybe_var_shift" "no")
4504 (set_attr "dot" "yes")
4505 (set_attr "length" "4,8,8,12")])
4507 (define_insn_and_split "ashdi3_extswsli_dot2"
4508 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4511 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4512 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4514 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4515 (ashift:DI (sign_extend:DI (match_dup 1))
4523 "&& reload_completed
4524 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4525 || memory_operand (operands[1], SImode))"
4528 rtx dest = operands[0];
4529 rtx src = operands[1];
4530 rtx shift = operands[2];
4531 rtx cr = operands[3];
4538 src2 = gen_lowpart (SImode, dest);
4539 emit_move_insn (src2, src);
4542 if (REGNO (cr) == CR0_REGNO)
4544 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4548 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4549 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4552 [(set_attr "type" "shift")
4553 (set_attr "maybe_var_shift" "no")
4554 (set_attr "dot" "yes")
4555 (set_attr "length" "4,8,8,12")])
4557 (define_insn "lshr<mode>3"
4558 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4559 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4560 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4562 "sr<wd>%I2 %0,%1,%<hH>2"
4563 [(set_attr "type" "shift")
4564 (set_attr "maybe_var_shift" "yes")])
4566 (define_insn "*lshrsi3_64"
4567 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4569 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4570 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4573 [(set_attr "type" "shift")
4574 (set_attr "maybe_var_shift" "yes")])
4576 (define_insn_and_split "*lshr<mode>3_dot"
4577 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4578 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4579 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4581 (clobber (match_scratch:GPR 0 "=r,r"))]
4582 "<MODE>mode == Pmode"
4584 sr<wd>%I2. %0,%1,%<hH>2
4586 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4588 (lshiftrt:GPR (match_dup 1)
4591 (compare:CC (match_dup 0)
4594 [(set_attr "type" "shift")
4595 (set_attr "maybe_var_shift" "yes")
4596 (set_attr "dot" "yes")
4597 (set_attr "length" "4,8")])
4599 (define_insn_and_split "*lshr<mode>3_dot2"
4600 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4601 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4602 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4604 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4605 (lshiftrt:GPR (match_dup 1)
4607 "<MODE>mode == Pmode"
4609 sr<wd>%I2. %0,%1,%<hH>2
4611 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4613 (lshiftrt:GPR (match_dup 1)
4616 (compare:CC (match_dup 0)
4619 [(set_attr "type" "shift")
4620 (set_attr "maybe_var_shift" "yes")
4621 (set_attr "dot" "yes")
4622 (set_attr "length" "4,8")])
4625 (define_insn "ashr<mode>3"
4626 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4627 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4628 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4629 (clobber (reg:GPR CA_REGNO))]
4631 "sra<wd>%I2 %0,%1,%<hH>2"
4632 [(set_attr "type" "shift")
4633 (set_attr "maybe_var_shift" "yes")])
4635 (define_insn "*ashrsi3_64"
4636 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4638 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4639 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4640 (clobber (reg:SI CA_REGNO))]
4643 [(set_attr "type" "shift")
4644 (set_attr "maybe_var_shift" "yes")])
4646 (define_insn_and_split "*ashr<mode>3_dot"
4647 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4648 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4649 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4651 (clobber (match_scratch:GPR 0 "=r,r"))
4652 (clobber (reg:GPR CA_REGNO))]
4653 "<MODE>mode == Pmode"
4655 sra<wd>%I2. %0,%1,%<hH>2
4657 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4658 [(parallel [(set (match_dup 0)
4659 (ashiftrt:GPR (match_dup 1)
4661 (clobber (reg:GPR CA_REGNO))])
4663 (compare:CC (match_dup 0)
4666 [(set_attr "type" "shift")
4667 (set_attr "maybe_var_shift" "yes")
4668 (set_attr "dot" "yes")
4669 (set_attr "length" "4,8")])
4671 (define_insn_and_split "*ashr<mode>3_dot2"
4672 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4673 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4674 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4676 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4677 (ashiftrt:GPR (match_dup 1)
4679 (clobber (reg:GPR CA_REGNO))]
4680 "<MODE>mode == Pmode"
4682 sra<wd>%I2. %0,%1,%<hH>2
4684 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4685 [(parallel [(set (match_dup 0)
4686 (ashiftrt:GPR (match_dup 1)
4688 (clobber (reg:GPR CA_REGNO))])
4690 (compare:CC (match_dup 0)
4693 [(set_attr "type" "shift")
4694 (set_attr "maybe_var_shift" "yes")
4695 (set_attr "dot" "yes")
4696 (set_attr "length" "4,8")])
4698 ;; Builtins to replace a division to generate FRE reciprocal estimate
4699 ;; instructions and the necessary fixup instructions
4700 (define_expand "recip<mode>3"
4701 [(match_operand:RECIPF 0 "gpc_reg_operand")
4702 (match_operand:RECIPF 1 "gpc_reg_operand")
4703 (match_operand:RECIPF 2 "gpc_reg_operand")]
4704 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4706 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4710 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4711 ;; hardware division. This is only done before register allocation and with
4712 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4713 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4714 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4716 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4717 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4718 (match_operand 2 "gpc_reg_operand")))]
4719 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4720 && can_create_pseudo_p () && flag_finite_math_only
4721 && !flag_trapping_math && flag_reciprocal_math"
4724 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4728 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4729 ;; appropriate fixup.
4730 (define_expand "rsqrt<mode>2"
4731 [(match_operand:RECIPF 0 "gpc_reg_operand")
4732 (match_operand:RECIPF 1 "gpc_reg_operand")]
4733 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4735 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4739 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4740 ;; modes here, and also add in conditional vsx/power8-vector support to access
4741 ;; values in the traditional Altivec registers if the appropriate
4742 ;; -mupper-regs-{df,sf} option is enabled.
4744 (define_expand "abs<mode>2"
4745 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4746 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4750 (define_insn "*abs<mode>2_fpr"
4751 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4752 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4757 [(set_attr "type" "fpsimple")])
4759 (define_insn "*nabs<mode>2_fpr"
4760 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4763 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4768 [(set_attr "type" "fpsimple")])
4770 (define_expand "neg<mode>2"
4771 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4772 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4776 (define_insn "*neg<mode>2_fpr"
4777 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4778 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4783 [(set_attr "type" "fpsimple")])
4785 (define_expand "add<mode>3"
4786 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4787 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4788 (match_operand:SFDF 2 "gpc_reg_operand")))]
4792 (define_insn "*add<mode>3_fpr"
4793 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4794 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4795 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4799 xsadd<sd>p %x0,%x1,%x2"
4800 [(set_attr "type" "fp")
4801 (set_attr "isa" "*,<Fisa>")])
4803 (define_expand "sub<mode>3"
4804 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4805 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4806 (match_operand:SFDF 2 "gpc_reg_operand")))]
4810 (define_insn "*sub<mode>3_fpr"
4811 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4812 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4813 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4817 xssub<sd>p %x0,%x1,%x2"
4818 [(set_attr "type" "fp")
4819 (set_attr "isa" "*,<Fisa>")])
4821 (define_expand "mul<mode>3"
4822 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4823 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4824 (match_operand:SFDF 2 "gpc_reg_operand")))]
4828 (define_insn "*mul<mode>3_fpr"
4829 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4830 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4831 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4835 xsmul<sd>p %x0,%x1,%x2"
4836 [(set_attr "type" "dmul")
4837 (set_attr "isa" "*,<Fisa>")])
4839 (define_expand "div<mode>3"
4840 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4841 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4842 (match_operand:SFDF 2 "gpc_reg_operand")))]
4845 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4846 && can_create_pseudo_p () && flag_finite_math_only
4847 && !flag_trapping_math && flag_reciprocal_math)
4849 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4854 (define_insn "*div<mode>3_fpr"
4855 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4856 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4857 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4861 xsdiv<sd>p %x0,%x1,%x2"
4862 [(set_attr "type" "<sd>div")
4863 (set_attr "isa" "*,<Fisa>")])
4865 (define_insn "*sqrt<mode>2_internal"
4866 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4867 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4868 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4871 xssqrt<sd>p %x0,%x1"
4872 [(set_attr "type" "<sd>sqrt")
4873 (set_attr "isa" "*,<Fisa>")])
4875 (define_expand "sqrt<mode>2"
4876 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4877 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4878 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4880 if (<MODE>mode == SFmode
4881 && TARGET_RECIP_PRECISION
4882 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4883 && !optimize_function_for_size_p (cfun)
4884 && flag_finite_math_only && !flag_trapping_math
4885 && flag_unsafe_math_optimizations)
4887 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4892 ;; Floating point reciprocal approximation
4893 (define_insn "fre<sd>"
4894 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4895 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4901 [(set_attr "type" "fp")
4902 (set_attr "isa" "*,<Fisa>")])
4904 (define_insn "*rsqrt<mode>2"
4905 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4906 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4908 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4911 xsrsqrte<sd>p %x0,%x1"
4912 [(set_attr "type" "fp")
4913 (set_attr "isa" "*,<Fisa>")])
4915 ;; Floating point comparisons
4916 (define_insn "*cmp<mode>_fpr"
4917 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4918 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4919 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4923 xscmpudp %0,%x1,%x2"
4924 [(set_attr "type" "fpcompare")
4925 (set_attr "isa" "*,<Fisa>")])
4927 ;; Floating point conversions
4928 (define_expand "extendsfdf2"
4929 [(set (match_operand:DF 0 "gpc_reg_operand")
4930 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4933 if (HONOR_SNANS (SFmode))
4934 operands[1] = force_reg (SFmode, operands[1]);
4937 (define_insn_and_split "*extendsfdf2_fpr"
4938 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4939 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4940 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4946 xscpsgndp %x0,%x1,%x1
4949 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4952 emit_note (NOTE_INSN_DELETED);
4955 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4956 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4958 (define_insn "*extendsfdf2_snan"
4959 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4960 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4961 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4965 [(set_attr "type" "fp")
4966 (set_attr "isa" "*,p8v")])
4968 (define_expand "truncdfsf2"
4969 [(set (match_operand:SF 0 "gpc_reg_operand")
4970 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4974 (define_insn "*truncdfsf2_fpr"
4975 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4976 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4981 [(set_attr "type" "fp")
4982 (set_attr "isa" "*,p8v")])
4984 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4985 ;; builtins.c and optabs.c that are not correct for IBM long double
4986 ;; when little-endian.
4987 (define_expand "signbit<mode>2"
4989 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4991 (subreg:DI (match_dup 2) 0))
4994 (set (match_operand:SI 0 "gpc_reg_operand")
4997 && (!FLOAT128_IEEE_P (<MODE>mode)
4998 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
5000 if (FLOAT128_IEEE_P (<MODE>mode))
5002 rtx dest = operands[0];
5003 rtx src = operands[1];
5004 rtx tmp = gen_reg_rtx (DImode);
5005 rtx dest_di = gen_lowpart (DImode, dest);
5007 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
5008 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
5011 operands[2] = gen_reg_rtx (DFmode);
5012 operands[3] = gen_reg_rtx (DImode);
5013 if (TARGET_POWERPC64)
5015 operands[4] = gen_reg_rtx (DImode);
5016 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
5017 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
5018 WORDS_BIG_ENDIAN ? 4 : 0);
5022 operands[4] = gen_reg_rtx (SImode);
5023 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
5024 WORDS_BIG_ENDIAN ? 0 : 4);
5025 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
5029 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
5030 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
5031 ;; register allocator would typically move the entire _Float128 item to GPRs (2
5032 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
5034 ;; After register allocation, if the _Float128 had originally been in GPRs, the
5035 ;; split allows the post reload phases to eliminate the move, and do the shift
5036 ;; directly with the register that contains the signbit.
5037 (define_insn_and_split "@signbit<mode>2_dm"
5038 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5039 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
5041 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5045 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
5049 operands[2] = gen_highpart (DImode, operands[1]);
5051 [(set_attr "type" "mfvsr,*")])
5053 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
5054 ;; register and then doing a direct move if the value comes from memory. On
5055 ;; little endian, we have to load the 2nd double-word to get the sign bit.
5056 (define_insn_and_split "*signbit<mode>2_dm_mem"
5057 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
5058 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
5060 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5066 rtx dest = operands[0];
5067 rtx src = operands[1];
5068 rtx addr = XEXP (src, 0);
5070 if (WORDS_BIG_ENDIAN)
5071 operands[2] = adjust_address (src, DImode, 0);
5073 else if (REG_P (addr) || SUBREG_P (addr))
5074 operands[2] = adjust_address (src, DImode, 8);
5076 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
5077 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
5078 operands[2] = adjust_address (src, DImode, 8);
5082 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
5083 emit_insn (gen_rtx_SET (tmp, addr));
5084 operands[2] = change_address (src, DImode,
5085 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
5089 (define_expand "copysign<mode>3"
5091 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
5093 (neg:SFDF (abs:SFDF (match_dup 1))))
5094 (set (match_operand:SFDF 0 "gpc_reg_operand")
5095 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5100 && ((TARGET_PPC_GFXOPT
5101 && !HONOR_NANS (<MODE>mode)
5102 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5104 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5106 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5108 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5113 operands[3] = gen_reg_rtx (<MODE>mode);
5114 operands[4] = gen_reg_rtx (<MODE>mode);
5115 operands[5] = CONST0_RTX (<MODE>mode);
5118 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5119 ;; compiler from optimizing -0.0
5120 (define_insn "copysign<mode>3_fcpsgn"
5121 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5122 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5123 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5125 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5128 xscpsgndp %x0,%x2,%x1"
5129 [(set_attr "type" "fpsimple")])
5131 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5132 ;; fsel instruction and some auxiliary computations. Then we just have a
5133 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5135 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5136 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5137 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5138 ;; define_splits to make them if made by combine. On VSX machines we have the
5139 ;; min/max instructions.
5141 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5142 ;; to allow either DF/SF to use only traditional registers.
5144 (define_expand "s<minmax><mode>3"
5145 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5146 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5147 (match_operand:SFDF 2 "gpc_reg_operand")))]
5150 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5154 (define_insn "*s<minmax><mode>3_vsx"
5155 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5156 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5157 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5158 "TARGET_VSX && TARGET_HARD_FLOAT"
5160 return (TARGET_P9_MINMAX
5161 ? "xs<minmax>cdp %x0,%x1,%x2"
5162 : "xs<minmax>dp %x0,%x1,%x2");
5164 [(set_attr "type" "fp")])
5166 ;; The conditional move instructions allow us to perform max and min operations
5167 ;; even when we don't have the appropriate max/min instruction using the FSEL
5170 (define_insn_and_split "*s<minmax><mode>3_fpr"
5171 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5172 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5173 (match_operand:SFDF 2 "gpc_reg_operand")))]
5174 "!TARGET_VSX && TARGET_MINMAX"
5179 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5183 (define_expand "mov<mode>cc"
5184 [(set (match_operand:GPR 0 "gpc_reg_operand")
5185 (if_then_else:GPR (match_operand 1 "comparison_operator")
5186 (match_operand:GPR 2 "gpc_reg_operand")
5187 (match_operand:GPR 3 "gpc_reg_operand")))]
5190 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5196 ;; We use the BASE_REGS for the isel input operands because, if rA is
5197 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5198 ;; because we may switch the operands and rB may end up being rA.
5200 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5201 ;; leave out the mode in operand 4 and use one pattern, but reload can
5202 ;; change the mode underneath our feet and then gets confused trying
5203 ;; to reload the value.
5204 (define_mode_iterator CCEITHER [CC CCUNS])
5205 (define_mode_attr un [(CC "") (CCUNS "un")])
5206 (define_insn "isel_<un>signed_<GPR:mode>"
5207 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5209 (match_operator 1 "scc_comparison_operator"
5210 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5212 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5213 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5216 [(set_attr "type" "isel")])
5218 ;; These patterns can be useful for combine; they let combine know that
5219 ;; isel can handle reversed comparisons so long as the operands are
5222 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5223 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5225 (match_operator 1 "scc_rev_comparison_operator"
5226 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5228 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5229 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5232 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5233 return "isel %0,%3,%2,%j1";
5235 [(set_attr "type" "isel")])
5237 ; Set Boolean Condition (Reverse)
5238 (define_insn "setbc_<un>signed_<GPR:mode>"
5239 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5240 (match_operator:GPR 1 "scc_comparison_operator"
5241 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5245 [(set_attr "type" "isel")])
5247 (define_insn "*setbcr_<un>signed_<GPR:mode>"
5248 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5249 (match_operator:GPR 1 "scc_rev_comparison_operator"
5250 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5254 [(set_attr "type" "isel")])
5256 ; Set Negative Boolean Condition (Reverse)
5257 (define_insn "*setnbc_<un>signed_<GPR:mode>"
5258 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5259 (neg:GPR (match_operator:GPR 1 "scc_comparison_operator"
5260 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5264 [(set_attr "type" "isel")])
5266 (define_insn "*setnbcr_<un>signed_<GPR:mode>"
5267 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5268 (neg:GPR (match_operator:GPR 1 "scc_rev_comparison_operator"
5269 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5273 [(set_attr "type" "isel")])
5275 ;; Floating point conditional move
5276 (define_expand "mov<mode>cc"
5277 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5278 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5279 (match_operand:SFDF 2 "gpc_reg_operand")
5280 (match_operand:SFDF 3 "gpc_reg_operand")))]
5281 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5283 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5289 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5290 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5292 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5293 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5294 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5295 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5296 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5298 [(set_attr "type" "fp")])
5300 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5301 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5303 (match_operator:CCFP 1 "fpmask_comparison_operator"
5304 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5305 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5306 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5307 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5308 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5313 (if_then_else:V2DI (match_dup 1)
5317 (if_then_else:SFDF (ne (match_dup 6)
5322 if (GET_CODE (operands[6]) == SCRATCH)
5323 operands[6] = gen_reg_rtx (V2DImode);
5325 operands[7] = CONSTM1_RTX (V2DImode);
5326 operands[8] = CONST0_RTX (V2DImode);
5328 [(set_attr "length" "8")
5329 (set_attr "type" "vecperm")])
5331 ;; Handle inverting the fpmask comparisons.
5332 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5333 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5335 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5336 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5337 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5338 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5339 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5340 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5345 (if_then_else:V2DI (match_dup 9)
5349 (if_then_else:SFDF (ne (match_dup 6)
5354 rtx op1 = operands[1];
5355 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5357 if (GET_CODE (operands[6]) == SCRATCH)
5358 operands[6] = gen_reg_rtx (V2DImode);
5360 operands[7] = CONSTM1_RTX (V2DImode);
5361 operands[8] = CONST0_RTX (V2DImode);
5363 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5365 [(set_attr "length" "8")
5366 (set_attr "type" "vecperm")])
5368 (define_insn "*fpmask<mode>"
5369 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5371 (match_operator:CCFP 1 "fpmask_comparison_operator"
5372 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5373 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5374 (match_operand:V2DI 4 "all_ones_constant" "")
5375 (match_operand:V2DI 5 "zero_constant" "")))]
5377 "xscmp%V1dp %x0,%x2,%x3"
5378 [(set_attr "type" "fpcompare")])
5380 (define_insn "*xxsel<mode>"
5381 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5382 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5383 (match_operand:V2DI 2 "zero_constant" ""))
5384 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5385 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5387 "xxsel %x0,%x4,%x3,%x1"
5388 [(set_attr "type" "vecmove")])
5391 ;; Conversions to and from floating-point.
5393 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5394 ; don't want to support putting SImode in FPR registers.
5395 (define_insn "lfiwax"
5396 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5397 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5399 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5405 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5406 (set_attr "isa" "*,p8v,p8v,p9v")])
5408 ; This split must be run before register allocation because it allocates the
5409 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5410 ; it earlier to allow for the combiner to merge insns together where it might
5411 ; not be needed and also in case the insns are deleted as dead code.
5413 (define_insn_and_split "floatsi<mode>2_lfiwax"
5414 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5415 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5416 (clobber (match_scratch:DI 2 "=d,wa"))]
5417 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5418 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5423 rtx dest = operands[0];
5424 rtx src = operands[1];
5427 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5428 tmp = convert_to_mode (DImode, src, false);
5432 if (GET_CODE (tmp) == SCRATCH)
5433 tmp = gen_reg_rtx (DImode);
5436 src = rs6000_force_indexed_or_indirect_mem (src);
5437 emit_insn (gen_lfiwax (tmp, src));
5441 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5442 emit_move_insn (stack, src);
5443 emit_insn (gen_lfiwax (tmp, stack));
5446 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5449 [(set_attr "length" "12")
5450 (set_attr "type" "fpload")])
5452 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5453 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5456 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5457 (clobber (match_scratch:DI 2 "=d,wa"))]
5458 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5463 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5464 if (GET_CODE (operands[2]) == SCRATCH)
5465 operands[2] = gen_reg_rtx (DImode);
5466 if (TARGET_P8_VECTOR)
5467 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5469 emit_insn (gen_lfiwax (operands[2], operands[1]));
5470 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5473 [(set_attr "length" "8")
5474 (set_attr "type" "fpload")])
5476 (define_insn "lfiwzx"
5477 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5478 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5480 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5485 xxextractuw %x0,%x1,4"
5486 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5487 (set_attr "isa" "*,p8v,p8v,p9v")])
5489 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5490 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5491 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5492 (clobber (match_scratch:DI 2 "=d,wa"))]
5493 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5498 rtx dest = operands[0];
5499 rtx src = operands[1];
5502 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5503 tmp = convert_to_mode (DImode, src, true);
5507 if (GET_CODE (tmp) == SCRATCH)
5508 tmp = gen_reg_rtx (DImode);
5511 src = rs6000_force_indexed_or_indirect_mem (src);
5512 emit_insn (gen_lfiwzx (tmp, src));
5516 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5517 emit_move_insn (stack, src);
5518 emit_insn (gen_lfiwzx (tmp, stack));
5521 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5524 [(set_attr "length" "12")
5525 (set_attr "type" "fpload")])
5527 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5528 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5529 (unsigned_float:SFDF
5531 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5532 (clobber (match_scratch:DI 2 "=d,wa"))]
5533 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5538 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5539 if (GET_CODE (operands[2]) == SCRATCH)
5540 operands[2] = gen_reg_rtx (DImode);
5541 if (TARGET_P8_VECTOR)
5542 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5544 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5545 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5548 [(set_attr "length" "8")
5549 (set_attr "type" "fpload")])
5551 ; For each of these conversions, there is a define_expand, a define_insn
5552 ; with a '#' template, and a define_split (with C code). The idea is
5553 ; to allow constant folding with the template of the define_insn,
5554 ; then to have the insns split later (between sched1 and final).
5556 (define_expand "floatsidf2"
5557 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5558 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5561 (clobber (match_dup 4))
5562 (clobber (match_dup 5))
5563 (clobber (match_dup 6))])]
5566 if (TARGET_LFIWAX && TARGET_FCFID)
5568 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5571 else if (TARGET_FCFID)
5573 rtx dreg = operands[1];
5575 dreg = force_reg (SImode, dreg);
5576 dreg = convert_to_mode (DImode, dreg, false);
5577 emit_insn (gen_floatdidf2 (operands[0], dreg));
5581 if (!REG_P (operands[1]))
5582 operands[1] = force_reg (SImode, operands[1]);
5583 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5584 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5585 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5586 operands[5] = gen_reg_rtx (DFmode);
5587 operands[6] = gen_reg_rtx (SImode);
5590 (define_insn_and_split "*floatsidf2_internal"
5591 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5592 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5593 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5594 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5595 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5596 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5597 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5598 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5603 rtx lowword, highword;
5604 gcc_assert (MEM_P (operands[4]));
5605 highword = adjust_address (operands[4], SImode, 0);
5606 lowword = adjust_address (operands[4], SImode, 4);
5607 if (! WORDS_BIG_ENDIAN)
5608 std::swap (lowword, highword);
5610 emit_insn (gen_xorsi3 (operands[6], operands[1],
5611 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5612 emit_move_insn (lowword, operands[6]);
5613 emit_move_insn (highword, operands[2]);
5614 emit_move_insn (operands[5], operands[4]);
5615 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5618 [(set_attr "length" "24")
5619 (set_attr "type" "fp")])
5621 ;; If we don't have a direct conversion to single precision, don't enable this
5622 ;; conversion for 32-bit without fast math, because we don't have the insn to
5623 ;; generate the fixup swizzle to avoid double rounding problems.
5624 (define_expand "floatunssisf2"
5625 [(set (match_operand:SF 0 "gpc_reg_operand")
5626 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5628 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5630 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5632 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5634 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5639 rtx dreg = operands[1];
5641 dreg = force_reg (SImode, dreg);
5642 dreg = convert_to_mode (DImode, dreg, true);
5643 emit_insn (gen_floatdisf2 (operands[0], dreg));
5648 (define_expand "floatunssidf2"
5649 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5650 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5653 (clobber (match_dup 4))
5654 (clobber (match_dup 5))])]
5657 if (TARGET_LFIWZX && TARGET_FCFID)
5659 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5662 else if (TARGET_FCFID)
5664 rtx dreg = operands[1];
5666 dreg = force_reg (SImode, dreg);
5667 dreg = convert_to_mode (DImode, dreg, true);
5668 emit_insn (gen_floatdidf2 (operands[0], dreg));
5672 if (!REG_P (operands[1]))
5673 operands[1] = force_reg (SImode, operands[1]);
5674 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5675 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5676 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5677 operands[5] = gen_reg_rtx (DFmode);
5680 (define_insn_and_split "*floatunssidf2_internal"
5681 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5682 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5683 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5684 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5685 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5686 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5687 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5688 && !(TARGET_FCFID && TARGET_POWERPC64)"
5693 rtx lowword, highword;
5694 gcc_assert (MEM_P (operands[4]));
5695 highword = adjust_address (operands[4], SImode, 0);
5696 lowword = adjust_address (operands[4], SImode, 4);
5697 if (! WORDS_BIG_ENDIAN)
5698 std::swap (lowword, highword);
5700 emit_move_insn (lowword, operands[1]);
5701 emit_move_insn (highword, operands[2]);
5702 emit_move_insn (operands[5], operands[4]);
5703 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5706 [(set_attr "length" "20")
5707 (set_attr "type" "fp")])
5709 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5710 ;; vector registers. These insns favor doing the sign/zero extension in
5711 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5712 ;; extension and then a direct move.
5714 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5715 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5717 (match_operand:QHI 1 "input_operand")))
5718 (clobber (match_scratch:DI 2))
5719 (clobber (match_scratch:DI 3))
5720 (clobber (match_scratch:<QHI:MODE> 4))])]
5721 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5723 if (MEM_P (operands[1]))
5724 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5727 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5728 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5730 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5731 (clobber (match_scratch:DI 2 "=v,wa,v"))
5732 (clobber (match_scratch:DI 3 "=X,r,X"))
5733 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5734 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5736 "&& reload_completed"
5739 rtx result = operands[0];
5740 rtx input = operands[1];
5741 rtx di = operands[2];
5745 rtx tmp = operands[3];
5746 if (altivec_register_operand (input, <QHI:MODE>mode))
5747 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5748 else if (GET_CODE (tmp) == SCRATCH)
5749 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5752 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5753 emit_move_insn (di, tmp);
5758 rtx tmp = operands[4];
5759 emit_move_insn (tmp, input);
5760 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5763 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5766 [(set_attr "isa" "p9v,*,p9v")])
5768 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5769 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5770 (unsigned_float:FP_ISA3
5771 (match_operand:QHI 1 "input_operand")))
5772 (clobber (match_scratch:DI 2))
5773 (clobber (match_scratch:DI 3))])]
5774 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5776 if (MEM_P (operands[1]))
5777 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5780 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5781 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5782 (unsigned_float:FP_ISA3
5783 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5784 (clobber (match_scratch:DI 2 "=v,wa,wa"))
5785 (clobber (match_scratch:DI 3 "=X,r,X"))]
5786 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5788 "&& reload_completed"
5791 rtx result = operands[0];
5792 rtx input = operands[1];
5793 rtx di = operands[2];
5795 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5796 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5799 rtx tmp = operands[3];
5800 if (GET_CODE (tmp) == SCRATCH)
5801 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5804 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5805 emit_move_insn (di, tmp);
5809 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5812 [(set_attr "isa" "p9v,*,p9v")])
5814 (define_expand "fix_trunc<mode>si2"
5815 [(set (match_operand:SI 0 "gpc_reg_operand")
5816 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5819 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5821 rtx src = force_reg (<MODE>mode, operands[1]);
5824 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5827 rtx tmp = gen_reg_rtx (DImode);
5828 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5829 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5836 ; Like the convert to float patterns, this insn must be split before
5837 ; register allocation so that it can allocate the memory slot if it
5839 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5840 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5841 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5842 (clobber (match_scratch:DI 2 "=d"))]
5843 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5844 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5849 rtx dest = operands[0];
5850 rtx src = operands[1];
5851 rtx tmp = operands[2];
5853 if (GET_CODE (tmp) == SCRATCH)
5854 tmp = gen_reg_rtx (DImode);
5856 emit_insn (gen_fctiwz_<mode> (tmp, src));
5857 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5859 dest = rs6000_force_indexed_or_indirect_mem (dest);
5860 emit_insn (gen_stfiwx (dest, tmp));
5863 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5865 dest = gen_lowpart (DImode, dest);
5866 emit_move_insn (dest, tmp);
5871 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5872 emit_insn (gen_stfiwx (stack, tmp));
5873 emit_move_insn (dest, stack);
5877 [(set_attr "length" "12")
5878 (set_attr "type" "fp")])
5880 (define_insn_and_split "fix_trunc<mode>si2_internal"
5881 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5882 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5883 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5884 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5886 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5892 gcc_assert (MEM_P (operands[3]));
5893 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5895 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5896 emit_move_insn (operands[3], operands[2]);
5897 emit_move_insn (operands[0], lowword);
5900 [(set_attr "length" "16")
5901 (set_attr "type" "fp")])
5903 (define_expand "fix_trunc<mode>di2"
5904 [(set (match_operand:DI 0 "gpc_reg_operand")
5905 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5906 "TARGET_HARD_FLOAT && TARGET_FCFID"
5909 (define_insn "*fix_trunc<mode>di2_fctidz"
5910 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5911 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5912 "TARGET_HARD_FLOAT && TARGET_FCFID"
5916 [(set_attr "type" "fp")])
5918 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5919 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5920 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5921 ;; values can go in VSX registers. Keeping the direct move part through
5922 ;; register allocation prevents the register allocator from doing a direct move
5923 ;; of the SImode value to a GPR, and then a store/load.
5924 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5925 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5926 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5927 (clobber (match_scratch:SI 2 "=X,X,wa"))]
5928 "TARGET_DIRECT_MOVE"
5931 xscvdp<su>xws %x0,%x1
5933 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5935 (any_fix:SI (match_dup 1)))
5939 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5941 [(set_attr "type" "fp")
5942 (set_attr "length" "4,4,8")
5943 (set_attr "isa" "p9v,p9v,*")])
5945 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5946 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5947 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5948 "TARGET_DIRECT_MOVE"
5951 xscvdp<su>xws %x0,%x1"
5952 [(set_attr "type" "fp")])
5954 ;; Keep the convert and store together through register allocation to prevent
5955 ;; the register allocator from getting clever and doing a direct move to a GPR
5956 ;; and then store for reg+offset stores.
5957 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5958 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5959 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5960 (clobber (match_scratch:SI 2 "=wa"))]
5961 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5963 "&& reload_completed"
5965 (any_fix:SI (match_dup 1)))
5969 operands[3] = (<QHSI:MODE>mode == SImode
5971 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5974 (define_expand "fixuns_trunc<mode>si2"
5975 [(set (match_operand:SI 0 "gpc_reg_operand")
5976 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5977 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5979 if (!TARGET_P8_VECTOR)
5981 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5986 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5987 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5988 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5989 (clobber (match_scratch:DI 2 "=d"))]
5990 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5991 && TARGET_STFIWX && can_create_pseudo_p ()
5992 && !TARGET_P8_VECTOR"
5997 rtx dest = operands[0];
5998 rtx src = operands[1];
5999 rtx tmp = operands[2];
6001 if (GET_CODE (tmp) == SCRATCH)
6002 tmp = gen_reg_rtx (DImode);
6004 emit_insn (gen_fctiwuz_<mode> (tmp, src));
6007 dest = rs6000_force_indexed_or_indirect_mem (dest);
6008 emit_insn (gen_stfiwx (dest, tmp));
6011 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
6013 dest = gen_lowpart (DImode, dest);
6014 emit_move_insn (dest, tmp);
6019 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6020 emit_insn (gen_stfiwx (stack, tmp));
6021 emit_move_insn (dest, stack);
6025 [(set_attr "length" "12")
6026 (set_attr "type" "fp")])
6028 (define_insn "fixuns_trunc<mode>di2"
6029 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6030 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
6031 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
6035 [(set_attr "type" "fp")])
6037 (define_insn "rs6000_mtfsb0"
6038 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6042 [(set_attr "type" "fp")])
6044 (define_insn "rs6000_mtfsb1"
6045 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6049 [(set_attr "type" "fp")])
6051 (define_insn "rs6000_mffscrn"
6052 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6053 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
6057 [(set_attr "type" "fp")])
6059 (define_insn "rs6000_mffscdrn"
6060 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6061 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
6062 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
6065 [(set_attr "type" "fp")])
6067 (define_expand "rs6000_set_fpscr_rn"
6068 [(match_operand:DI 0 "reg_or_cint_operand")]
6071 rtx tmp_df = gen_reg_rtx (DFmode);
6073 /* The floating point rounding control bits are FPSCR[62:63]. Put the
6074 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
6077 rtx src_df = force_reg (DImode, operands[0]);
6078 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
6079 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
6083 if (CONST_INT_P (operands[0]))
6085 if ((INTVAL (operands[0]) & 0x1) == 0x1)
6086 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
6088 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
6090 if ((INTVAL (operands[0]) & 0x2) == 0x2)
6091 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
6093 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
6097 rtx tmp_rn = gen_reg_rtx (DImode);
6098 rtx tmp_di = gen_reg_rtx (DImode);
6100 /* Extract new RN mode from operand. */
6101 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
6103 /* Insert new RN mode into FSCPR. */
6104 emit_insn (gen_rs6000_mffs (tmp_df));
6105 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6106 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
6107 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6109 /* Need to write to field k=15. The fields are [0:15]. Hence with
6110 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
6111 8-bit field[0:7]. Need to set the bit that corresponds to the
6112 value of i that you want [0:7]. */
6113 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6114 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
6119 (define_expand "rs6000_set_fpscr_drn"
6120 [(match_operand:DI 0 "gpc_reg_operand")]
6123 rtx tmp_df = gen_reg_rtx (DFmode);
6125 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
6126 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
6129 rtx src_df = gen_reg_rtx (DFmode);
6131 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
6132 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
6133 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6137 rtx tmp_rn = gen_reg_rtx (DImode);
6138 rtx tmp_di = gen_reg_rtx (DImode);
6140 /* Extract new DRN mode from operand. */
6141 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6142 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6144 /* Insert new RN mode into FSCPR. */
6145 emit_insn (gen_rs6000_mffs (tmp_df));
6146 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6147 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6148 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6150 /* Need to write to field 7. The fields are [0:15]. The equation to
6151 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6152 i to 0x1 to get field 7 where i selects the field. */
6153 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6154 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6159 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6160 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6161 ;; because the first makes it clear that operand 0 is not live
6162 ;; before the instruction.
6163 (define_insn "fctiwz_<mode>"
6164 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6166 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6172 [(set_attr "type" "fp")])
6174 (define_insn "fctiwuz_<mode>"
6175 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6176 (unspec:DI [(unsigned_fix:SI
6177 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6179 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6183 [(set_attr "type" "fp")])
6185 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6186 ;; since the friz instruction does not truncate the value if the floating
6187 ;; point value is < LONG_MIN or > LONG_MAX.
6188 (define_insn "*friz"
6189 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6190 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6191 "TARGET_HARD_FLOAT && TARGET_FPRND
6192 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6196 [(set_attr "type" "fp")])
6198 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6199 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6200 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6201 ;; extend it, store it back on the stack from the GPR, load it back into the
6202 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6203 ;; disable using store and load to sign/zero extend the value.
6204 (define_insn_and_split "*round32<mode>2_fprs"
6205 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6207 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6208 (clobber (match_scratch:DI 2 "=d"))
6209 (clobber (match_scratch:DI 3 "=d"))]
6211 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6212 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6217 rtx dest = operands[0];
6218 rtx src = operands[1];
6219 rtx tmp1 = operands[2];
6220 rtx tmp2 = operands[3];
6221 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6223 if (GET_CODE (tmp1) == SCRATCH)
6224 tmp1 = gen_reg_rtx (DImode);
6225 if (GET_CODE (tmp2) == SCRATCH)
6226 tmp2 = gen_reg_rtx (DImode);
6228 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6229 emit_insn (gen_stfiwx (stack, tmp1));
6230 emit_insn (gen_lfiwax (tmp2, stack));
6231 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6234 [(set_attr "type" "fpload")
6235 (set_attr "length" "16")])
6237 (define_insn_and_split "*roundu32<mode>2_fprs"
6238 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6239 (unsigned_float:SFDF
6240 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6241 (clobber (match_scratch:DI 2 "=d"))
6242 (clobber (match_scratch:DI 3 "=d"))]
6244 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6245 && can_create_pseudo_p ()"
6250 rtx dest = operands[0];
6251 rtx src = operands[1];
6252 rtx tmp1 = operands[2];
6253 rtx tmp2 = operands[3];
6254 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6256 if (GET_CODE (tmp1) == SCRATCH)
6257 tmp1 = gen_reg_rtx (DImode);
6258 if (GET_CODE (tmp2) == SCRATCH)
6259 tmp2 = gen_reg_rtx (DImode);
6261 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6262 emit_insn (gen_stfiwx (stack, tmp1));
6263 emit_insn (gen_lfiwzx (tmp2, stack));
6264 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6267 [(set_attr "type" "fpload")
6268 (set_attr "length" "16")])
6270 ;; No VSX equivalent to fctid
6271 (define_insn "lrint<mode>di2"
6272 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6273 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6275 "TARGET_HARD_FLOAT && TARGET_FPRND"
6277 [(set_attr "type" "fp")])
6279 (define_insn "btrunc<mode>2"
6280 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6281 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6283 "TARGET_HARD_FLOAT && TARGET_FPRND"
6287 [(set_attr "type" "fp")])
6289 (define_insn "ceil<mode>2"
6290 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6291 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6293 "TARGET_HARD_FLOAT && TARGET_FPRND"
6297 [(set_attr "type" "fp")])
6299 (define_insn "floor<mode>2"
6300 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6301 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6303 "TARGET_HARD_FLOAT && TARGET_FPRND"
6307 [(set_attr "type" "fp")])
6309 ;; No VSX equivalent to frin
6310 (define_insn "round<mode>2"
6311 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6312 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6314 "TARGET_HARD_FLOAT && TARGET_FPRND"
6316 [(set_attr "type" "fp")])
6318 (define_insn "*xsrdpi<mode>2"
6319 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6320 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6322 "TARGET_HARD_FLOAT && TARGET_VSX"
6324 [(set_attr "type" "fp")])
6326 (define_expand "lround<mode>di2"
6328 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6330 (set (match_operand:DI 0 "gpc_reg_operand")
6331 (unspec:DI [(match_dup 2)]
6333 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6335 operands[2] = gen_reg_rtx (<MODE>mode);
6338 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6339 (define_insn "stfiwx"
6340 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6341 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6347 [(set_attr "type" "fpstore")
6348 (set_attr "isa" "*,p8v")])
6350 ;; If we don't have a direct conversion to single precision, don't enable this
6351 ;; conversion for 32-bit without fast math, because we don't have the insn to
6352 ;; generate the fixup swizzle to avoid double rounding problems.
6353 (define_expand "floatsisf2"
6354 [(set (match_operand:SF 0 "gpc_reg_operand")
6355 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6357 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6359 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6361 if (TARGET_FCFIDS && TARGET_LFIWAX)
6363 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6366 else if (TARGET_FCFID && TARGET_LFIWAX)
6368 rtx dfreg = gen_reg_rtx (DFmode);
6369 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6370 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6375 rtx dreg = operands[1];
6377 dreg = force_reg (SImode, dreg);
6378 dreg = convert_to_mode (DImode, dreg, false);
6379 emit_insn (gen_floatdisf2 (operands[0], dreg));
6384 (define_insn "floatdidf2"
6385 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6386 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6387 "TARGET_FCFID && TARGET_HARD_FLOAT"
6391 [(set_attr "type" "fp")])
6393 ; Allow the combiner to merge source memory operands to the conversion so that
6394 ; the optimizer/register allocator doesn't try to load the value too early in a
6395 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6396 ; hit. We will split after reload to avoid the trip through the GPRs
6398 (define_insn_and_split "*floatdidf2_mem"
6399 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6400 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6401 (clobber (match_scratch:DI 2 "=d,wa"))]
6402 "TARGET_HARD_FLOAT && TARGET_FCFID"
6404 "&& reload_completed"
6405 [(set (match_dup 2) (match_dup 1))
6406 (set (match_dup 0) (float:DF (match_dup 2)))]
6408 [(set_attr "length" "8")
6409 (set_attr "type" "fpload")])
6411 (define_expand "floatunsdidf2"
6412 [(set (match_operand:DF 0 "gpc_reg_operand")
6414 (match_operand:DI 1 "gpc_reg_operand")))]
6415 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6418 (define_insn "*floatunsdidf2_fcfidu"
6419 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6420 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6421 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6425 [(set_attr "type" "fp")])
6427 (define_insn_and_split "*floatunsdidf2_mem"
6428 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6429 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6430 (clobber (match_scratch:DI 2 "=d,wa"))]
6431 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6433 "&& reload_completed"
6434 [(set (match_dup 2) (match_dup 1))
6435 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6437 [(set_attr "length" "8")
6438 (set_attr "type" "fpload")])
6440 (define_expand "floatdisf2"
6441 [(set (match_operand:SF 0 "gpc_reg_operand")
6442 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6443 "TARGET_FCFID && TARGET_HARD_FLOAT
6444 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6448 rtx val = operands[1];
6449 if (!flag_unsafe_math_optimizations)
6451 rtx label = gen_label_rtx ();
6452 val = gen_reg_rtx (DImode);
6453 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6456 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6461 (define_insn "floatdisf2_fcfids"
6462 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6463 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6464 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6468 [(set_attr "type" "fp")
6469 (set_attr "isa" "*,p8v")])
6471 (define_insn_and_split "*floatdisf2_mem"
6472 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6473 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6474 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6475 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6477 "&& reload_completed"
6480 emit_move_insn (operands[2], operands[1]);
6481 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6484 [(set_attr "length" "8")
6485 (set_attr "isa" "*,p8v,p8v")])
6487 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6488 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6489 ;; from double rounding.
6490 ;; Instead of creating a new cpu type for two FP operations, just use fp
6491 (define_insn_and_split "floatdisf2_internal1"
6492 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6493 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6494 (clobber (match_scratch:DF 2 "=d"))]
6495 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6497 "&& reload_completed"
6499 (float:DF (match_dup 1)))
6501 (float_truncate:SF (match_dup 2)))]
6503 [(set_attr "length" "8")
6504 (set_attr "type" "fp")])
6506 ;; Twiddles bits to avoid double rounding.
6507 ;; Bits that might be truncated when converting to DFmode are replaced
6508 ;; by a bit that won't be lost at that stage, but is below the SFmode
6509 ;; rounding position.
6510 (define_expand "floatdisf2_internal2"
6511 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6513 (clobber (reg:DI CA_REGNO))])
6514 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6516 (set (match_dup 3) (plus:DI (match_dup 3)
6518 (set (match_dup 0) (plus:DI (match_dup 0)
6520 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6522 (set (match_dup 0) (ior:DI (match_dup 0)
6524 (set (match_dup 0) (and:DI (match_dup 0)
6526 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6527 (label_ref (match_operand:DI 2 ""))
6529 (set (match_dup 0) (match_dup 1))]
6530 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6532 operands[3] = gen_reg_rtx (DImode);
6533 operands[4] = gen_reg_rtx (CCUNSmode);
6536 (define_expand "floatunsdisf2"
6537 [(set (match_operand:SF 0 "gpc_reg_operand")
6538 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6539 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6542 (define_insn "floatunsdisf2_fcfidus"
6543 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6544 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6545 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6549 [(set_attr "type" "fp")
6550 (set_attr "isa" "*,p8v")])
6552 (define_insn_and_split "*floatunsdisf2_mem"
6553 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6554 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6555 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6556 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6558 "&& reload_completed"
6561 emit_move_insn (operands[2], operands[1]);
6562 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6565 [(set_attr "type" "fpload")
6566 (set_attr "length" "8")
6567 (set_attr "isa" "*,p8v,p8v")])
6569 ;; Define the TImode operations that can be done in a small number
6570 ;; of instructions. The & constraints are to prevent the register
6571 ;; allocator from allocating registers that overlap with the inputs
6572 ;; (for example, having an input in 7,8 and an output in 6,7). We
6573 ;; also allow for the output being the same as one of the inputs.
6575 (define_expand "addti3"
6576 [(set (match_operand:TI 0 "gpc_reg_operand")
6577 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6578 (match_operand:TI 2 "reg_or_short_operand")))]
6581 rtx lo0 = gen_lowpart (DImode, operands[0]);
6582 rtx lo1 = gen_lowpart (DImode, operands[1]);
6583 rtx lo2 = gen_lowpart (DImode, operands[2]);
6584 rtx hi0 = gen_highpart (DImode, operands[0]);
6585 rtx hi1 = gen_highpart (DImode, operands[1]);
6586 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6588 if (!reg_or_short_operand (lo2, DImode))
6589 lo2 = force_reg (DImode, lo2);
6590 if (!adde_operand (hi2, DImode))
6591 hi2 = force_reg (DImode, hi2);
6593 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6594 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6598 (define_expand "subti3"
6599 [(set (match_operand:TI 0 "gpc_reg_operand")
6600 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6601 (match_operand:TI 2 "gpc_reg_operand")))]
6604 rtx lo0 = gen_lowpart (DImode, operands[0]);
6605 rtx lo1 = gen_lowpart (DImode, operands[1]);
6606 rtx lo2 = gen_lowpart (DImode, operands[2]);
6607 rtx hi0 = gen_highpart (DImode, operands[0]);
6608 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6609 rtx hi2 = gen_highpart (DImode, operands[2]);
6611 if (!reg_or_short_operand (lo1, DImode))
6612 lo1 = force_reg (DImode, lo1);
6613 if (!adde_operand (hi1, DImode))
6614 hi1 = force_reg (DImode, hi1);
6616 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6617 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6621 ;; 128-bit logical operations expanders
6623 (define_expand "and<mode>3"
6624 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6625 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6626 (match_operand:BOOL_128 2 "vlogical_operand")))]
6630 (define_expand "ior<mode>3"
6631 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6632 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6633 (match_operand:BOOL_128 2 "vlogical_operand")))]
6637 (define_expand "xor<mode>3"
6638 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6639 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6640 (match_operand:BOOL_128 2 "vlogical_operand")))]
6644 (define_expand "nor<mode>3"
6645 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6647 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6648 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6652 (define_expand "andc<mode>3"
6653 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6655 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6656 (match_operand:BOOL_128 1 "vlogical_operand")))]
6660 ;; Power8 vector logical instructions.
6661 (define_expand "eqv<mode>3"
6662 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6664 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6665 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6666 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6669 ;; Rewrite nand into canonical form
6670 (define_expand "nand<mode>3"
6671 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6673 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6674 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6675 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6678 ;; The canonical form is to have the negated element first, so we need to
6679 ;; reverse arguments.
6680 (define_expand "orc<mode>3"
6681 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6683 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6684 (match_operand:BOOL_128 1 "vlogical_operand")))]
6685 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6688 ;; 128-bit logical operations insns and split operations
6689 (define_insn_and_split "*and<mode>3_internal"
6690 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6692 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6693 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6696 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6697 return "xxland %x0,%x1,%x2";
6699 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6700 return "vand %0,%1,%2";
6704 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6707 rs6000_split_logical (operands, AND, false, false, false);
6712 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6713 (const_string "veclogical")
6714 (const_string "integer")))
6715 (set (attr "length")
6717 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6720 (match_test "TARGET_POWERPC64")
6722 (const_string "16"))))])
6725 (define_insn_and_split "*bool<mode>3_internal"
6726 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6727 (match_operator:BOOL_128 3 "boolean_or_operator"
6728 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6729 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6732 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6733 return "xxl%q3 %x0,%x1,%x2";
6735 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6736 return "v%q3 %0,%1,%2";
6740 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6743 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6748 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6749 (const_string "veclogical")
6750 (const_string "integer")))
6751 (set (attr "length")
6753 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6756 (match_test "TARGET_POWERPC64")
6758 (const_string "16"))))])
6761 (define_insn_and_split "*boolc<mode>3_internal1"
6762 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6763 (match_operator:BOOL_128 3 "boolean_operator"
6765 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6766 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6767 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6769 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6770 return "xxl%q3 %x0,%x1,%x2";
6772 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6773 return "v%q3 %0,%1,%2";
6777 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6778 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6781 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6786 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6787 (const_string "veclogical")
6788 (const_string "integer")))
6789 (set (attr "length")
6791 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6794 (match_test "TARGET_POWERPC64")
6796 (const_string "16"))))])
6798 (define_insn_and_split "*boolc<mode>3_internal2"
6799 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6800 (match_operator:TI2 3 "boolean_operator"
6802 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6803 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6804 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6806 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6809 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6812 [(set_attr "type" "integer")
6813 (set (attr "length")
6815 (match_test "TARGET_POWERPC64")
6817 (const_string "16")))])
6820 (define_insn_and_split "*boolcc<mode>3_internal1"
6821 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6822 (match_operator:BOOL_128 3 "boolean_operator"
6824 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6826 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6827 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6829 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6830 return "xxl%q3 %x0,%x1,%x2";
6832 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6833 return "v%q3 %0,%1,%2";
6837 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6838 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6841 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6846 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6847 (const_string "veclogical")
6848 (const_string "integer")))
6849 (set (attr "length")
6851 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6854 (match_test "TARGET_POWERPC64")
6856 (const_string "16"))))])
6858 (define_insn_and_split "*boolcc<mode>3_internal2"
6859 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6860 (match_operator:TI2 3 "boolean_operator"
6862 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6864 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6865 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6867 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6870 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6873 [(set_attr "type" "integer")
6874 (set (attr "length")
6876 (match_test "TARGET_POWERPC64")
6878 (const_string "16")))])
6882 (define_insn_and_split "*eqv<mode>3_internal1"
6883 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6886 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6887 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6890 if (vsx_register_operand (operands[0], <MODE>mode))
6891 return "xxleqv %x0,%x1,%x2";
6895 "TARGET_P8_VECTOR && reload_completed
6896 && int_reg_operand (operands[0], <MODE>mode)"
6899 rs6000_split_logical (operands, XOR, true, false, false);
6904 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6905 (const_string "veclogical")
6906 (const_string "integer")))
6907 (set (attr "length")
6909 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6912 (match_test "TARGET_POWERPC64")
6914 (const_string "16"))))])
6916 (define_insn_and_split "*eqv<mode>3_internal2"
6917 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6920 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6921 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6924 "reload_completed && !TARGET_P8_VECTOR"
6927 rs6000_split_logical (operands, XOR, true, false, false);
6930 [(set_attr "type" "integer")
6931 (set (attr "length")
6933 (match_test "TARGET_POWERPC64")
6935 (const_string "16")))])
6937 ;; 128-bit one's complement
6938 (define_insn_and_split "one_cmpl<mode>2"
6939 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6941 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6944 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6945 return "xxlnor %x0,%x1,%x1";
6947 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6948 return "vnor %0,%1,%1";
6952 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6955 rs6000_split_logical (operands, NOT, false, false, false);
6960 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6961 (const_string "veclogical")
6962 (const_string "integer")))
6963 (set (attr "length")
6965 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6968 (match_test "TARGET_POWERPC64")
6970 (const_string "16"))))])
6973 ;; Now define ways of moving data around.
6975 ;; Set up a register with a value from the GOT table
6977 (define_expand "movsi_got"
6978 [(set (match_operand:SI 0 "gpc_reg_operand")
6979 (unspec:SI [(match_operand:SI 1 "got_operand")
6980 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6981 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6983 if (GET_CODE (operands[1]) == CONST)
6985 rtx offset = const0_rtx;
6986 HOST_WIDE_INT value;
6988 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6989 value = INTVAL (offset);
6992 rtx tmp = (!can_create_pseudo_p ()
6994 : gen_reg_rtx (Pmode));
6995 emit_insn (gen_movsi_got (tmp, operands[1]));
6996 emit_insn (gen_addsi3 (operands[0], tmp, offset));
7001 operands[2] = rs6000_got_register (operands[1]);
7004 (define_insn "*movsi_got_internal"
7005 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7006 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7007 (match_operand:SI 2 "gpc_reg_operand" "b")]
7009 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7010 "lwz %0,%a1@got(%2)"
7011 [(set_attr "type" "load")])
7013 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
7014 ;; didn't get allocated to a hard register.
7016 [(set (match_operand:SI 0 "gpc_reg_operand")
7017 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
7018 (match_operand:SI 2 "memory_operand")]
7020 "DEFAULT_ABI == ABI_V4
7022 && reload_completed"
7023 [(set (match_dup 0) (match_dup 2))
7024 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
7029 ;; LWZ LFIWZX LXSIWZX
7030 ;; STW STFIWX STXSIWX
7032 ;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
7033 ;; XXLXOR 0 XXLORC -1 P9 const
7037 (define_insn "*movsi_internal1"
7038 [(set (match_operand:SI 0 "nonimmediate_operand"
7047 (match_operand:SI 1 "input_operand"
7056 "gpc_reg_operand (operands[0], SImode)
7057 || gpc_reg_operand (operands[1], SImode)"
7085 load, fpload, fpload,
7086 store, fpstore, fpstore,
7088 veclogical, vecsimple, vecsimple, vecsimple,
7089 veclogical, veclogical, vecsimple,
7111 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
7112 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
7114 ;; Because SF values are actually stored as DF values within the vector
7115 ;; registers, we need to convert the value to the vector SF format when
7116 ;; we need to use the bits in a union or similar cases. We only need
7117 ;; to do this transformation when the value is a vector register. Loads,
7118 ;; stores, and transfers within GPRs are assumed to be safe.
7120 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
7121 ;; no alternatives, because the call is created as part of secondary_reload,
7122 ;; and operand #2's register class is used to allocate the temporary register.
7123 ;; This function is called before reload, and it creates the temporary as
7126 ;; MR LWZ LFIWZX LXSIWZX STW
7127 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
7130 (define_insn_and_split "movsi_from_sf"
7131 [(set (match_operand:SI 0 "nonimmediate_operand"
7132 "=r, r, ?*d, ?*v, m,
7135 (unspec:SI [(match_operand:SF 1 "input_operand"
7140 (clobber (match_scratch:V4SF 2
7144 "TARGET_NO_SF_SUBREG
7145 && (register_operand (operands[0], SImode)
7146 || register_operand (operands[1], SFmode))"
7159 "&& reload_completed
7160 && int_reg_operand (operands[0], SImode)
7161 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7164 rtx op0 = operands[0];
7165 rtx op1 = operands[1];
7166 rtx op2 = operands[2];
7167 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7168 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7170 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7171 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7175 "*, load, fpload, fpload, store,
7176 fpstore, fpstore, fpstore, mfvsr, fp,
7184 *, p9v, p8v, p8v, p8v,
7187 ;; movsi_from_sf with zero extension
7189 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7192 (define_insn_and_split "*movdi_from_sf_zero_ext"
7193 [(set (match_operand:DI 0 "gpc_reg_operand"
7194 "=r, r, ?*d, ?*v, r,
7197 (unspec:SI [(match_operand:SF 1 "input_operand"
7200 UNSPEC_SI_FROM_SF)))
7201 (clobber (match_scratch:V4SF 2
7204 "TARGET_DIRECT_MOVE_64BIT
7205 && (register_operand (operands[0], DImode)
7206 || register_operand (operands[1], SImode))"
7215 "&& reload_completed
7216 && register_operand (operands[0], DImode)
7217 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7220 rtx op0 = operands[0];
7221 rtx op1 = operands[1];
7222 rtx op2 = operands[2];
7223 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7225 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7226 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7230 "*, load, fpload, fpload, two,
7236 "*, *, p8v, p8v, p8v,
7239 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7240 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7241 ;; conversion explicitly since that doesn't work in most cases if the input
7242 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7243 ;; former handles cases where the input will not fit in a SFmode, and the
7244 ;; latter assumes the value has already been rounded.
7245 (define_insn "*movsi_from_df"
7246 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7247 (unspec:SI [(float_truncate:SF
7248 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7249 UNSPEC_SI_FROM_SF))]
7250 "TARGET_NO_SF_SUBREG"
7252 [(set_attr "type" "fp")])
7254 ;; Split a load of a large constant into the appropriate two-insn
7258 [(set (match_operand:SI 0 "gpc_reg_operand")
7259 (match_operand:SI 1 "const_int_operand"))]
7260 "num_insns_constant (operands[1], SImode) > 1"
7264 (ior:SI (match_dup 0)
7267 if (rs6000_emit_set_const (operands[0], operands[1]))
7273 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7275 [(set (match_operand:DI 0 "altivec_register_operand")
7276 (match_operand:DI 1 "xxspltib_constant_split"))]
7277 "TARGET_P9_VECTOR && reload_completed"
7280 rtx op0 = operands[0];
7281 rtx op1 = operands[1];
7282 int r = REGNO (op0);
7283 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7285 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7286 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7290 (define_insn "*mov<mode>_internal2"
7291 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7292 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7294 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7300 [(set_attr "type" "cmp,logical,cmp")
7301 (set_attr "dot" "yes")
7302 (set_attr "length" "4,4,8")])
7305 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7306 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7308 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7310 [(set (match_dup 0) (match_dup 1))
7312 (compare:CC (match_dup 0)
7316 (define_expand "mov<mode>"
7317 [(set (match_operand:INT 0 "general_operand")
7318 (match_operand:INT 1 "any_operand"))]
7321 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7325 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7326 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7327 ;; MTVSRWZ MF%1 MT%1 NOP
7328 (define_insn "*mov<mode>_internal"
7329 [(set (match_operand:QHI 0 "nonimmediate_operand"
7330 "=r, r, wa, m, Z, r,
7331 wa, wa, wa, v, ?v, r,
7333 (match_operand:QHI 1 "input_operand"
7335 wa, O, wM, wB, wS, wa,
7337 "gpc_reg_operand (operands[0], <MODE>mode)
7338 || gpc_reg_operand (operands[1], <MODE>mode)"
7357 "*, load, fpload, store, fpstore, *,
7358 vecsimple, vecperm, vecperm, vecperm, vecperm, mfvsr,
7359 mtvsr, mfjmpr, mtjmpr, *")
7365 "*, *, p9v, *, p9v, *,
7366 p9v, p9v, p9v, p9v, p9v, p9v,
7370 ;; Here is how to move condition codes around. When we store CC data in
7371 ;; an integer register or memory, we store just the high-order 4 bits.
7372 ;; This lets us not shift in the most common case of CR0.
7373 (define_expand "movcc"
7374 [(set (match_operand:CC 0 "nonimmediate_operand")
7375 (match_operand:CC 1 "nonimmediate_operand"))]
7379 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7381 (define_insn "*movcc_<mode>"
7382 [(set (match_operand:CC_any 0 "nonimmediate_operand"
7383 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7384 (match_operand:CC_any 1 "general_operand"
7385 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7386 "register_operand (operands[0], <MODE>mode)
7387 || register_operand (operands[1], <MODE>mode)"
7391 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7394 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7401 [(set_attr_alternative "type"
7402 [(const_string "cr_logical")
7403 (const_string "mtcr")
7404 (const_string "mtcr")
7405 (const_string "cr_logical")
7406 (if_then_else (match_test "TARGET_MFCRF")
7407 (const_string "mfcrf") (const_string "mfcr"))
7408 (if_then_else (match_test "TARGET_MFCRF")
7409 (const_string "mfcrf") (const_string "mfcr"))
7410 (const_string "integer")
7411 (const_string "integer")
7412 (const_string "mfjmpr")
7413 (const_string "mtjmpr")
7414 (const_string "load")
7415 (const_string "store")])
7416 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7418 ;; For floating-point, we normally deal with the floating-point registers
7419 ;; unless -msoft-float is used. The sole exception is that parameter passing
7420 ;; can produce floating-point values in fixed-point registers. Unless the
7421 ;; value is a simple constant or already in memory, we deal with this by
7422 ;; allocating memory and copying the value explicitly via that memory location.
7424 ;; Move 32-bit binary/decimal floating point
7425 (define_expand "mov<mode>"
7426 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7427 (match_operand:FMOVE32 1 "any_operand"))]
7430 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7435 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7436 (match_operand:FMOVE32 1 "const_double_operand"))]
7438 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7439 || (SUBREG_P (operands[0])
7440 && REG_P (SUBREG_REG (operands[0]))
7441 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7442 [(set (match_dup 2) (match_dup 3))]
7446 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7448 if (! TARGET_POWERPC64)
7449 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7451 operands[2] = gen_lowpart (SImode, operands[0]);
7453 operands[3] = gen_int_mode (l, SImode);
7456 ;; Originally, we tried to keep movsf and movsd common, but the differences
7457 ;; addressing was making it rather difficult to hide with mode attributes. In
7458 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7459 ;; before the VSX stores meant that the register allocator would tend to do a
7460 ;; direct move to the GPR (which involves conversion from scalar to
7461 ;; vector/memory formats) to save values in the traditional Altivec registers,
7462 ;; while SDmode had problems on power6 if the GPR store was not first due to
7463 ;; the power6 not having an integer store operation.
7465 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7466 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7467 ;; MR MT<x> MF<x> NOP
7469 (define_insn "movsf_hardfloat"
7470 [(set (match_operand:SF 0 "nonimmediate_operand"
7471 "=!r, f, v, wa, m, wY,
7472 Z, m, wa, !r, f, wa,
7474 (match_operand:SF 1 "input_operand"
7478 "(register_operand (operands[0], SFmode)
7479 || register_operand (operands[1], SFmode))
7480 && TARGET_HARD_FLOAT
7481 && (TARGET_ALLOW_SF_SUBREG
7482 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7495 xscpsgndp %x0,%x1,%x1
7501 "load, fpload, fpload, fpload, fpstore, fpstore,
7502 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7503 *, mtjmpr, mfjmpr, *")
7505 "*, *, p9v, p8v, *, p9v,
7509 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7510 ;; FMR MR MT%0 MF%1 NOP
7511 (define_insn "movsd_hardfloat"
7512 [(set (match_operand:SD 0 "nonimmediate_operand"
7513 "=!r, d, m, Z, ?d, ?r,
7514 f, !r, *c*l, !r, *h")
7515 (match_operand:SD 1 "input_operand"
7518 "(register_operand (operands[0], SDmode)
7519 || register_operand (operands[1], SDmode))
7520 && TARGET_HARD_FLOAT"
7534 "load, fpload, store, fpstore, mtvsr, mfvsr,
7535 fpsimple, *, mtjmpr, mfjmpr, *")
7537 "*, p7, *, *, p8v, p8v,
7540 ;; MR MT%0 MF%0 LWZ STW LI
7541 ;; LIS G-const. F/n-const NOP
7542 (define_insn "*mov<mode>_softfloat"
7543 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7544 "=r, *c*l, r, r, m, r,
7547 (match_operand:FMOVE32 1 "input_operand"
7551 "(gpc_reg_operand (operands[0], <MODE>mode)
7552 || gpc_reg_operand (operands[1], <MODE>mode))
7553 && TARGET_SOFT_FLOAT"
7566 "*, mtjmpr, mfjmpr, load, store, *,
7573 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7574 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7576 ;; Because SF values are actually stored as DF values within the vector
7577 ;; registers, we need to convert the value to the vector SF format when
7578 ;; we need to use the bits in a union or similar cases. We only need
7579 ;; to do this transformation when the value is a vector register. Loads,
7580 ;; stores, and transfers within GPRs are assumed to be safe.
7582 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7583 ;; no alternatives, because the call is created as part of secondary_reload,
7584 ;; and operand #2's register class is used to allocate the temporary register.
7585 ;; This function is called before reload, and it creates the temporary as
7588 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7589 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7590 (define_insn_and_split "movsf_from_si"
7591 [(set (match_operand:SF 0 "nonimmediate_operand"
7592 "=!r, f, v, wa, m, Z,
7594 (unspec:SF [(match_operand:SI 1 "input_operand"
7598 (clobber (match_scratch:DI 2
7601 "TARGET_NO_SF_SUBREG
7602 && (register_operand (operands[0], SFmode)
7603 || register_operand (operands[1], SImode))"
7616 "&& reload_completed
7617 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7618 && int_reg_operand_not_pseudo (operands[1], SImode)"
7621 rtx op0 = operands[0];
7622 rtx op1 = operands[1];
7623 rtx op2 = operands[2];
7624 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7626 /* Move SF value to upper 32-bits for xscvspdpn. */
7627 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7628 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7629 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7636 "load, fpload, fpload, fpload, store, fpstore,
7637 fpstore, vecfloat, mfvsr, *")
7639 "*, *, p9v, p8v, *, *,
7640 p8v, p8v, p8v, *")])
7642 ;; For extracting high part element from DImode register like:
7643 ;; {%1:SF=unspec[r122:DI>>0x20#0] 86;clobber scratch;}
7644 ;; split it before reload with "and mask" to avoid generating shift right
7645 ;; 32 bit then shift left 32 bit.
7646 (define_insn_and_split "movsf_from_si2"
7647 [(set (match_operand:SF 0 "gpc_reg_operand" "=wa")
7651 (match_operand:DI 1 "input_operand" "r")
7655 (clobber (match_scratch:DI 2 "=r"))]
7656 "TARGET_NO_SF_SUBREG"
7661 if (GET_CODE (operands[2]) == SCRATCH)
7662 operands[2] = gen_reg_rtx (DImode);
7664 rtx mask = GEN_INT (HOST_WIDE_INT_M1U << 32);
7665 emit_insn (gen_anddi3 (operands[2], operands[1], mask));
7666 emit_insn (gen_p8_mtvsrd_sf (operands[0], operands[2]));
7667 emit_insn (gen_vsx_xscvspdpn_directmove (operands[0], operands[0]));
7670 [(set_attr "length" "12")
7671 (set_attr "type" "vecfloat")
7672 (set_attr "isa" "p8v")])
7674 ;; Move 64-bit binary/decimal floating point
7675 (define_expand "mov<mode>"
7676 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7677 (match_operand:FMOVE64 1 "any_operand"))]
7680 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7685 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7686 (match_operand:FMOVE64 1 "const_int_operand"))]
7687 "! TARGET_POWERPC64 && reload_completed
7688 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7689 || (SUBREG_P (operands[0])
7690 && REG_P (SUBREG_REG (operands[0]))
7691 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7692 [(set (match_dup 2) (match_dup 4))
7693 (set (match_dup 3) (match_dup 1))]
7695 int endian = (WORDS_BIG_ENDIAN == 0);
7696 HOST_WIDE_INT value = INTVAL (operands[1]);
7698 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7699 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7700 operands[4] = GEN_INT (value >> 32);
7701 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7705 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7706 (match_operand:FMOVE64 1 "const_double_operand"))]
7707 "! TARGET_POWERPC64 && reload_completed
7708 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7709 || (SUBREG_P (operands[0])
7710 && REG_P (SUBREG_REG (operands[0]))
7711 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7712 [(set (match_dup 2) (match_dup 4))
7713 (set (match_dup 3) (match_dup 5))]
7715 int endian = (WORDS_BIG_ENDIAN == 0);
7718 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7720 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7721 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7722 operands[4] = gen_int_mode (l[endian], SImode);
7723 operands[5] = gen_int_mode (l[1 - endian], SImode);
7727 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7728 (match_operand:FMOVE64 1 "const_double_operand"))]
7729 "TARGET_POWERPC64 && reload_completed
7730 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7731 || (SUBREG_P (operands[0])
7732 && REG_P (SUBREG_REG (operands[0]))
7733 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7734 [(set (match_dup 2) (match_dup 3))]
7736 int endian = (WORDS_BIG_ENDIAN == 0);
7740 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7742 operands[2] = gen_lowpart (DImode, operands[0]);
7743 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7744 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7745 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7747 operands[3] = gen_int_mode (val, DImode);
7750 ;; Don't have reload use general registers to load a constant. It is
7751 ;; less efficient than loading the constant into an FP register, since
7752 ;; it will probably be used there.
7754 ;; The move constraints are ordered to prefer floating point registers before
7755 ;; general purpose registers to avoid doing a store and a load to get the value
7756 ;; into a floating point register when it is needed for a floating point
7757 ;; operation. Prefer traditional floating point registers over VSX registers,
7758 ;; since the D-form version of the memory instructions does not need a GPR for
7759 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7762 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7763 ;; except for 0.0 which can be created on VSX with an xor instruction.
7765 ;; STFD LFD FMR LXSD STXSD
7766 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7770 (define_insn "*mov<mode>_hardfloat32"
7771 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7772 "=m, d, d, <f64_p9>, wY,
7773 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7775 (match_operand:FMOVE64 1 "input_operand"
7776 "d, m, d, wY, <f64_p9>,
7777 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7779 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7780 && (gpc_reg_operand (operands[0], <MODE>mode)
7781 || gpc_reg_operand (operands[1], <MODE>mode))"
7797 "fpstore, fpload, fpsimple, fpload, fpstore,
7798 fpload, fpstore, veclogical, veclogical, two,
7800 (set_attr "size" "64")
7810 ;; STW LWZ MR G-const H-const F-const
7812 (define_insn "*mov<mode>_softfloat32"
7813 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7814 "=Y, r, r, r, r, r")
7816 (match_operand:FMOVE64 1 "input_operand"
7817 "r, Y, r, G, H, F"))]
7820 && (gpc_reg_operand (operands[0], <MODE>mode)
7821 || gpc_reg_operand (operands[1], <MODE>mode))"
7824 "store, load, two, *, *, *")
7827 "8, 8, 8, 8, 12, 16")])
7829 ; ld/std require word-aligned displacements -> 'Y' constraint.
7830 ; List Y->r and r->Y before r->r for reload.
7832 ;; STFD LFD FMR LXSD STXSD
7833 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7834 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7835 ;; NOP MFVSRD MTVSRD
7837 (define_insn "*mov<mode>_hardfloat64"
7838 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7839 "=m, d, d, <f64_p9>, wY,
7840 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7841 YZ, r, !r, *c*l, !r,
7843 (match_operand:FMOVE64 1 "input_operand"
7844 "d, m, d, wY, <f64_p9>,
7845 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7848 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7849 && (gpc_reg_operand (operands[0], <MODE>mode)
7850 || gpc_reg_operand (operands[1], <MODE>mode))"
7871 "fpstore, fpload, fpsimple, fpload, fpstore,
7872 fpload, fpstore, veclogical, veclogical, integer,
7873 store, load, *, mtjmpr, mfjmpr,
7875 (set_attr "size" "64")
7882 ;; STD LD MR MT<SPR> MF<SPR> G-const
7883 ;; H-const F-const Special
7885 (define_insn "*mov<mode>_softfloat64"
7886 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7887 "=Y, r, r, *c*l, r, r,
7890 (match_operand:FMOVE64 1 "input_operand"
7894 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7895 && (gpc_reg_operand (operands[0], <MODE>mode)
7896 || gpc_reg_operand (operands[1], <MODE>mode))"
7908 "store, load, *, mtjmpr, mfjmpr, *,
7915 (define_expand "mov<mode>"
7916 [(set (match_operand:FMOVE128 0 "general_operand")
7917 (match_operand:FMOVE128 1 "any_operand"))]
7920 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7924 ;; It's important to list Y->r and r->Y before r->r because otherwise
7925 ;; reload, given m->r, will try to pick r->r and reload it, which
7926 ;; doesn't make progress.
7928 ;; We can't split little endian direct moves of TDmode, because the words are
7929 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7930 ;; problematical. Don't allow direct move for this case.
7932 ;; FPR load FPR store FPR move FPR zero GPR load
7933 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
7935 (define_insn_and_split "*mov<mode>_64bit_dm"
7936 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7940 (match_operand:FMOVE128_FPR 1 "input_operand"
7941 "d, m, d, <zero_fp>, r,
7942 <zero_fp>, Y, r, d, r"))]
7944 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7945 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7946 && (gpc_reg_operand (operands[0], <MODE>mode)
7947 || gpc_reg_operand (operands[1], <MODE>mode))"
7949 "&& reload_completed"
7952 rs6000_split_multireg_move (operands[0], operands[1]);
7955 [(set_attr "length" "8")
7956 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7957 (set_attr "max_prefixed_insns" "2")
7958 (set_attr "num_insns" "2")])
7960 (define_insn_and_split "*movtd_64bit_nodm"
7961 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7962 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7963 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7964 && (gpc_reg_operand (operands[0], TDmode)
7965 || gpc_reg_operand (operands[1], TDmode))"
7967 "&& reload_completed"
7970 rs6000_split_multireg_move (operands[0], operands[1]);
7973 [(set_attr "length" "8,8,8,12,12,8")
7974 (set_attr "max_prefixed_insns" "2")
7975 (set_attr "num_insns" "2,2,2,3,3,2")])
7977 (define_insn_and_split "*mov<mode>_32bit"
7978 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7979 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7980 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7981 && (FLOAT128_2REG_P (<MODE>mode)
7982 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7983 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7984 && (gpc_reg_operand (operands[0], <MODE>mode)
7985 || gpc_reg_operand (operands[1], <MODE>mode))"
7987 "&& reload_completed"
7990 rs6000_split_multireg_move (operands[0], operands[1]);
7993 [(set_attr "length" "8,8,8,8,20,20,16")])
7995 (define_insn_and_split "*mov<mode>_softfloat"
7996 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7997 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7999 && (gpc_reg_operand (operands[0], <MODE>mode)
8000 || gpc_reg_operand (operands[1], <MODE>mode))"
8002 "&& reload_completed"
8005 rs6000_split_multireg_move (operands[0], operands[1]);
8008 [(set_attr_alternative "length"
8009 [(if_then_else (match_test "TARGET_POWERPC64")
8011 (const_string "16"))
8012 (if_then_else (match_test "TARGET_POWERPC64")
8014 (const_string "16"))
8015 (if_then_else (match_test "TARGET_POWERPC64")
8017 (const_string "32"))
8018 (if_then_else (match_test "TARGET_POWERPC64")
8020 (const_string "16"))])])
8022 (define_expand "@extenddf<mode>2"
8023 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8024 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
8025 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8027 if (FLOAT128_IEEE_P (<MODE>mode))
8028 rs6000_expand_float128_convert (operands[0], operands[1], false);
8029 else if (TARGET_VSX)
8030 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
8033 rtx zero = gen_reg_rtx (DFmode);
8034 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
8036 emit_insn (gen_extenddf2_fprs (<MODE>mode,
8037 operands[0], operands[1], zero));
8042 ;; Allow memory operands for the source to be created by the combiner.
8043 (define_insn_and_split "@extenddf<mode>2_fprs"
8044 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
8045 (float_extend:IBM128
8046 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
8047 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
8048 "!TARGET_VSX && TARGET_HARD_FLOAT
8049 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
8051 "&& reload_completed"
8052 [(set (match_dup 3) (match_dup 1))
8053 (set (match_dup 4) (match_dup 2))]
8055 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8056 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8058 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8059 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8062 (define_insn_and_split "@extenddf<mode>2_vsx"
8063 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
8064 (float_extend:IBM128
8065 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
8066 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
8068 "&& reload_completed"
8069 [(set (match_dup 2) (match_dup 1))
8070 (set (match_dup 3) (match_dup 4))]
8072 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8073 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8075 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8076 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8077 operands[4] = CONST0_RTX (DFmode);
8080 (define_expand "extendsf<mode>2"
8081 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8082 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
8083 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8085 if (FLOAT128_IEEE_P (<MODE>mode))
8086 rs6000_expand_float128_convert (operands[0], operands[1], false);
8089 rtx tmp = gen_reg_rtx (DFmode);
8090 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8091 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
8096 (define_expand "trunc<mode>df2"
8097 [(set (match_operand:DF 0 "gpc_reg_operand")
8098 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8099 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8101 if (FLOAT128_IEEE_P (<MODE>mode))
8103 rs6000_expand_float128_convert (operands[0], operands[1], false);
8108 (define_insn_and_split "trunc<mode>df2_internal1"
8109 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8111 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
8112 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
8113 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8117 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8120 emit_note (NOTE_INSN_DELETED);
8123 [(set_attr "type" "fpsimple")])
8125 (define_insn "trunc<mode>df2_internal2"
8126 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8127 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8128 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8129 && TARGET_LONG_DOUBLE_128"
8131 [(set_attr "type" "fp")])
8133 (define_expand "trunc<mode>sf2"
8134 [(set (match_operand:SF 0 "gpc_reg_operand")
8135 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8136 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8138 if (FLOAT128_IEEE_P (<MODE>mode))
8139 rs6000_expand_float128_convert (operands[0], operands[1], false);
8142 rtx tmp = gen_reg_rtx (DFmode);
8143 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
8144 emit_insn (gen_truncdfsf2 (operands[0], tmp));
8149 (define_expand "floatsi<mode>2"
8150 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8151 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
8152 (clobber (match_scratch:DI 2))])]
8153 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8155 rtx op0 = operands[0];
8156 rtx op1 = operands[1];
8158 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8160 else if (FLOAT128_IEEE_P (<MODE>mode))
8162 rs6000_expand_float128_convert (op0, op1, false);
8167 rtx tmp = gen_reg_rtx (DFmode);
8168 expand_float (tmp, op1, false);
8169 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8174 ; fadd, but rounding towards zero.
8175 ; This is probably not the optimal code sequence.
8176 (define_insn "fix_trunc_helper<mode>"
8177 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8178 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8179 UNSPEC_FIX_TRUNC_TF))
8180 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8181 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8182 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8183 [(set_attr "type" "fp")
8184 (set_attr "length" "20")])
8186 (define_expand "fix_trunc<mode>si2"
8187 [(set (match_operand:SI 0 "gpc_reg_operand")
8188 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8189 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8191 rtx op0 = operands[0];
8192 rtx op1 = operands[1];
8194 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8198 if (FLOAT128_IEEE_P (<MODE>mode))
8199 rs6000_expand_float128_convert (op0, op1, false);
8201 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8206 (define_expand "@fix_trunc<mode>si2_fprs"
8207 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8208 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8209 (clobber (match_dup 2))
8210 (clobber (match_dup 3))
8211 (clobber (match_dup 4))
8212 (clobber (match_dup 5))])]
8213 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8215 operands[2] = gen_reg_rtx (DFmode);
8216 operands[3] = gen_reg_rtx (DFmode);
8217 operands[4] = gen_reg_rtx (DImode);
8218 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8221 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8222 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8223 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8224 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8225 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8226 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8227 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8228 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8234 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8237 gcc_assert (MEM_P (operands[5]));
8238 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8240 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8241 emit_move_insn (operands[5], operands[4]);
8242 emit_move_insn (operands[0], lowword);
8246 (define_expand "fix_trunc<mode>di2"
8247 [(set (match_operand:DI 0 "gpc_reg_operand")
8248 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8249 "TARGET_FLOAT128_TYPE"
8251 if (!TARGET_FLOAT128_HW)
8253 rs6000_expand_float128_convert (operands[0], operands[1], false);
8258 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8259 [(set (match_operand:SDI 0 "gpc_reg_operand")
8260 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8261 "TARGET_FLOAT128_TYPE"
8263 rs6000_expand_float128_convert (operands[0], operands[1], true);
8267 (define_expand "floatdi<mode>2"
8268 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8269 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8270 "TARGET_FLOAT128_TYPE"
8272 if (!TARGET_FLOAT128_HW)
8274 rs6000_expand_float128_convert (operands[0], operands[1], false);
8279 (define_expand "floatunsdi<IEEE128:mode>2"
8280 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8281 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8282 "TARGET_FLOAT128_TYPE"
8284 if (!TARGET_FLOAT128_HW)
8286 rs6000_expand_float128_convert (operands[0], operands[1], true);
8291 (define_expand "floatuns<IEEE128:mode>2"
8292 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8293 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8294 "TARGET_FLOAT128_TYPE"
8296 rtx op0 = operands[0];
8297 rtx op1 = operands[1];
8299 if (TARGET_FLOAT128_HW)
8300 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8302 rs6000_expand_float128_convert (op0, op1, true);
8306 (define_expand "neg<mode>2"
8307 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8308 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8309 "FLOAT128_IEEE_P (<MODE>mode)
8310 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8312 if (FLOAT128_IEEE_P (<MODE>mode))
8314 if (TARGET_FLOAT128_HW)
8315 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8316 else if (TARGET_FLOAT128_TYPE)
8317 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8318 operands[0], operands[1]));
8321 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8322 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8324 operands[1], <MODE>mode);
8326 if (target && !rtx_equal_p (target, operands[0]))
8327 emit_move_insn (operands[0], target);
8333 (define_insn "neg<mode>2_internal"
8334 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8335 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8336 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8338 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8339 return "fneg %L0,%L1\;fneg %0,%1";
8341 return "fneg %0,%1\;fneg %L0,%L1";
8343 [(set_attr "type" "fpsimple")
8344 (set_attr "length" "8")])
8346 (define_expand "abs<mode>2"
8347 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8348 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8349 "FLOAT128_IEEE_P (<MODE>mode)
8350 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8354 if (FLOAT128_IEEE_P (<MODE>mode))
8356 if (TARGET_FLOAT128_HW)
8358 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8361 else if (TARGET_FLOAT128_TYPE)
8363 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8364 operands[0], operands[1]));
8371 label = gen_label_rtx ();
8372 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8377 (define_expand "@abs<mode>2_internal"
8378 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8379 (match_operand:IBM128 1 "gpc_reg_operand"))
8380 (set (match_dup 3) (match_dup 5))
8381 (set (match_dup 5) (abs:DF (match_dup 5)))
8382 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8383 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8384 (label_ref (match_operand 2 ""))
8386 (set (match_dup 6) (neg:DF (match_dup 6)))]
8387 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8389 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8390 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8391 operands[3] = gen_reg_rtx (DFmode);
8392 operands[4] = gen_reg_rtx (CCFPmode);
8393 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8394 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8398 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8401 (define_expand "ieee_128bit_negative_zero"
8402 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8403 "TARGET_FLOAT128_TYPE"
8405 rtvec v = rtvec_alloc (16);
8408 for (i = 0; i < 16; i++)
8409 RTVEC_ELT (v, i) = const0_rtx;
8411 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8412 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8414 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8418 ;; IEEE 128-bit negate
8420 ;; We have 2 insns here for negate and absolute value. The first uses
8421 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8422 ;; insns, and second insn after the first split pass loads up the bit to
8423 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8424 ;; neg/abs to create the constant just once.
8426 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8427 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8428 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8429 (clobber (match_scratch:V16QI 2 "=v"))]
8430 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8433 [(parallel [(set (match_dup 0)
8434 (neg:IEEE128 (match_dup 1)))
8435 (use (match_dup 2))])]
8437 if (GET_CODE (operands[2]) == SCRATCH)
8438 operands[2] = gen_reg_rtx (V16QImode);
8440 operands[3] = gen_reg_rtx (V16QImode);
8441 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8443 [(set_attr "length" "8")
8444 (set_attr "type" "vecsimple")])
8446 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8447 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8448 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8449 (use (match_operand:V16QI 2 "register_operand" "v"))]
8450 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8451 "xxlxor %x0,%x1,%x2"
8452 [(set_attr "type" "veclogical")])
8454 ;; IEEE 128-bit absolute value
8455 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8456 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8457 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8458 (clobber (match_scratch:V16QI 2 "=v"))]
8459 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8462 [(parallel [(set (match_dup 0)
8463 (abs:IEEE128 (match_dup 1)))
8464 (use (match_dup 2))])]
8466 if (GET_CODE (operands[2]) == SCRATCH)
8467 operands[2] = gen_reg_rtx (V16QImode);
8469 operands[3] = gen_reg_rtx (V16QImode);
8470 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8472 [(set_attr "length" "8")
8473 (set_attr "type" "vecsimple")])
8475 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8476 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8477 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8478 (use (match_operand:V16QI 2 "register_operand" "v"))]
8479 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8480 "xxlandc %x0,%x1,%x2"
8481 [(set_attr "type" "veclogical")])
8483 ;; IEEE 128-bit negative absolute value
8484 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8485 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8488 (match_operand:IEEE128 1 "register_operand" "wa"))))
8489 (clobber (match_scratch:V16QI 2 "=v"))]
8490 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8491 && FLOAT128_IEEE_P (<MODE>mode)"
8494 [(parallel [(set (match_dup 0)
8495 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8496 (use (match_dup 2))])]
8498 if (GET_CODE (operands[2]) == SCRATCH)
8499 operands[2] = gen_reg_rtx (V16QImode);
8501 operands[3] = gen_reg_rtx (V16QImode);
8502 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8504 [(set_attr "length" "8")
8505 (set_attr "type" "vecsimple")])
8507 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8508 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8511 (match_operand:IEEE128 1 "register_operand" "wa"))))
8512 (use (match_operand:V16QI 2 "register_operand" "v"))]
8513 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8515 [(set_attr "type" "veclogical")])
8517 ;; Float128 conversion functions. These expand to library function calls.
8518 ;; We use expand to convert from IBM double double to IEEE 128-bit
8519 ;; and trunc for the opposite.
8520 (define_expand "extendiftf2"
8521 [(set (match_operand:TF 0 "gpc_reg_operand")
8522 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8523 "TARGET_FLOAT128_TYPE"
8525 rs6000_expand_float128_convert (operands[0], operands[1], false);
8529 (define_expand "extendifkf2"
8530 [(set (match_operand:KF 0 "gpc_reg_operand")
8531 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8532 "TARGET_FLOAT128_TYPE"
8534 rs6000_expand_float128_convert (operands[0], operands[1], false);
8538 (define_expand "extendtfkf2"
8539 [(set (match_operand:KF 0 "gpc_reg_operand")
8540 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8541 "TARGET_FLOAT128_TYPE"
8543 rs6000_expand_float128_convert (operands[0], operands[1], false);
8547 (define_expand "extendtfif2"
8548 [(set (match_operand:IF 0 "gpc_reg_operand")
8549 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8550 "TARGET_FLOAT128_TYPE"
8552 rs6000_expand_float128_convert (operands[0], operands[1], false);
8556 (define_expand "trunciftf2"
8557 [(set (match_operand:TF 0 "gpc_reg_operand")
8558 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8559 "TARGET_FLOAT128_TYPE"
8561 rs6000_expand_float128_convert (operands[0], operands[1], false);
8565 (define_expand "truncifkf2"
8566 [(set (match_operand:KF 0 "gpc_reg_operand")
8567 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8568 "TARGET_FLOAT128_TYPE"
8570 rs6000_expand_float128_convert (operands[0], operands[1], false);
8574 (define_expand "trunckftf2"
8575 [(set (match_operand:TF 0 "gpc_reg_operand")
8576 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8577 "TARGET_FLOAT128_TYPE"
8579 rs6000_expand_float128_convert (operands[0], operands[1], false);
8583 (define_expand "trunctfif2"
8584 [(set (match_operand:IF 0 "gpc_reg_operand")
8585 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8586 "TARGET_FLOAT128_TYPE"
8588 rs6000_expand_float128_convert (operands[0], operands[1], false);
8592 (define_insn_and_split "*extend<mode>tf2_internal"
8593 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8595 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8596 "TARGET_FLOAT128_TYPE
8597 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8599 "&& reload_completed"
8600 [(set (match_dup 0) (match_dup 2))]
8602 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8605 (define_insn_and_split "*extendtf<mode>2_internal"
8606 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8608 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8609 "TARGET_FLOAT128_TYPE
8610 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8612 "&& reload_completed"
8613 [(set (match_dup 0) (match_dup 2))]
8615 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8619 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8620 ;; must have 3 arguments, and scratch register constraint must be a single
8623 ;; Reload patterns to support gpr load/store with misaligned mem.
8624 ;; and multiple gpr load/store at offset >= 0xfffc
8625 (define_expand "reload_<mode>_store"
8626 [(parallel [(match_operand 0 "memory_operand" "=m")
8627 (match_operand 1 "gpc_reg_operand" "r")
8628 (match_operand:GPR 2 "register_operand" "=&b")])]
8631 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8635 (define_expand "reload_<mode>_load"
8636 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8637 (match_operand 1 "memory_operand" "m")
8638 (match_operand:GPR 2 "register_operand" "=b")])]
8641 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8646 ;; Reload patterns for various types using the vector registers. We may need
8647 ;; an additional base register to convert the reg+offset addressing to reg+reg
8648 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8649 ;; index register for gpr registers.
8650 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8651 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8652 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8653 (match_operand:P 2 "register_operand" "=b")])]
8656 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8660 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8661 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8662 (match_operand:RELOAD 1 "memory_operand" "m")
8663 (match_operand:P 2 "register_operand" "=b")])]
8666 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8671 ;; Reload sometimes tries to move the address to a GPR, and can generate
8672 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8673 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8675 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8676 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8677 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8678 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8680 "TARGET_ALTIVEC && reload_completed"
8682 "&& reload_completed"
8684 (plus:P (match_dup 1)
8687 (and:P (match_dup 0)
8690 ;; Power8 merge instructions to allow direct move to/from floating point
8691 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8692 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8693 ;; value, since it is allocated in reload and not all of the flow information
8694 ;; is setup for it. We have two patterns to do the two moves between gprs and
8695 ;; fprs. There isn't a dependancy between the two, but we could potentially
8696 ;; schedule other instructions between the two instructions.
8698 (define_insn "p8_fmrgow_<mode>"
8699 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8701 (match_operand:DF 1 "register_operand" "d")
8702 (match_operand:DF 2 "register_operand" "d")]
8703 UNSPEC_P8V_FMRGOW))]
8704 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8706 [(set_attr "type" "fpsimple")])
8708 (define_insn "p8_mtvsrwz"
8709 [(set (match_operand:DF 0 "register_operand" "=d")
8710 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8711 UNSPEC_P8V_MTVSRWZ))]
8712 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8714 [(set_attr "type" "mtvsr")])
8716 (define_insn "p8_mtvsrwz_v16qisi2"
8717 [(set (match_operand:V16QI 0 "register_operand" "=wa")
8718 (unspec:V16QI [(match_operand:SI 1 "register_operand" "r")]
8719 UNSPEC_P8V_MTVSRWZ))]
8720 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8722 [(set_attr "type" "mtvsr")])
8724 (define_insn "p8_mtvsrd_v16qidi2"
8725 [(set (match_operand:V16QI 0 "register_operand" "=wa")
8726 (unspec:V16QI [(match_operand:DI 1 "register_operand" "r")]
8727 UNSPEC_P8V_MTVSRD))]
8728 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8730 [(set_attr "type" "mtvsr")])
8732 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8733 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8734 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8735 UNSPEC_P8V_RELOAD_FROM_GPR))
8736 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8737 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8739 "&& reload_completed"
8742 rtx dest = operands[0];
8743 rtx src = operands[1];
8744 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8745 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8746 rtx gpr_hi_reg = gen_highpart (SImode, src);
8747 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8749 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8750 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8751 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8754 [(set_attr "length" "12")
8755 (set_attr "type" "three")])
8757 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8758 (define_insn "p8_mtvsrd_df"
8759 [(set (match_operand:DF 0 "register_operand" "=wa")
8760 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8761 UNSPEC_P8V_MTVSRD))]
8762 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8764 [(set_attr "type" "mtvsr")])
8766 (define_insn "p8_xxpermdi_<mode>"
8767 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8768 (unspec:FMOVE128_GPR [
8769 (match_operand:DF 1 "register_operand" "wa")
8770 (match_operand:DF 2 "register_operand" "wa")]
8771 UNSPEC_P8V_XXPERMDI))]
8772 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8773 "xxpermdi %x0,%x1,%x2,0"
8774 [(set_attr "type" "vecperm")])
8776 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8777 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8778 (unspec:FMOVE128_GPR
8779 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8780 UNSPEC_P8V_RELOAD_FROM_GPR))
8781 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8782 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8784 "&& reload_completed"
8787 rtx dest = operands[0];
8788 rtx src = operands[1];
8789 /* You might think that we could use op0 as one temp and a DF clobber
8790 as op2, but you'd be wrong. Secondary reload move patterns don't
8791 check for overlap of the clobber and the destination. */
8792 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8793 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8794 rtx gpr_hi_reg = gen_highpart (DImode, src);
8795 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8797 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8798 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8799 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8802 [(set_attr "length" "12")
8803 (set_attr "type" "three")])
8806 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8807 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8809 && (int_reg_operand (operands[0], <MODE>mode)
8810 || int_reg_operand (operands[1], <MODE>mode))
8811 && (!TARGET_DIRECT_MOVE_128
8812 || (!vsx_register_operand (operands[0], <MODE>mode)
8813 && !vsx_register_operand (operands[1], <MODE>mode)))"
8816 rs6000_split_multireg_move (operands[0], operands[1]);
8820 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8821 ;; type is stored internally as double precision in the VSX registers, we have
8822 ;; to convert it from the vector format.
8823 (define_insn "p8_mtvsrd_sf"
8824 [(set (match_operand:SF 0 "register_operand" "=wa")
8825 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8826 UNSPEC_P8V_MTVSRD))]
8827 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8829 [(set_attr "type" "mtvsr")])
8831 (define_insn_and_split "reload_vsx_from_gprsf"
8832 [(set (match_operand:SF 0 "register_operand" "=wa")
8833 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8834 UNSPEC_P8V_RELOAD_FROM_GPR))
8835 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8836 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8838 "&& reload_completed"
8841 rtx op0 = operands[0];
8842 rtx op1 = operands[1];
8843 rtx op2 = operands[2];
8844 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8846 /* Move SF value to upper 32-bits for xscvspdpn. */
8847 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8848 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8849 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8852 [(set_attr "length" "8")
8853 (set_attr "type" "two")])
8855 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8856 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8857 ;; and then doing a move of that.
8858 (define_insn "p8_mfvsrd_3_<mode>"
8859 [(set (match_operand:DF 0 "register_operand" "=r")
8860 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8861 UNSPEC_P8V_RELOAD_FROM_VSX))]
8862 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8864 [(set_attr "type" "mfvsr")])
8866 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8867 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8868 (unspec:FMOVE128_GPR
8869 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8870 UNSPEC_P8V_RELOAD_FROM_VSX))
8871 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8872 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8874 "&& reload_completed"
8877 rtx dest = operands[0];
8878 rtx src = operands[1];
8879 rtx tmp = operands[2];
8880 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8881 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8883 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8884 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8885 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8888 [(set_attr "length" "12")
8889 (set_attr "type" "three")])
8891 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8892 ;; type is stored internally as double precision, we have to convert it to the
8895 (define_insn_and_split "reload_gpr_from_vsxsf"
8896 [(set (match_operand:SF 0 "register_operand" "=r")
8897 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8898 UNSPEC_P8V_RELOAD_FROM_VSX))
8899 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8900 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8902 "&& reload_completed"
8905 rtx op0 = operands[0];
8906 rtx op1 = operands[1];
8907 rtx op2 = operands[2];
8908 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8909 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8911 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8912 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8915 [(set_attr "length" "8")
8916 (set_attr "type" "two")
8917 (set_attr "isa" "p8v")])
8919 ;; Next come the multi-word integer load and store and the load and store
8922 ;; List r->r after r->Y, otherwise reload will try to reload a
8923 ;; non-offsettable address by using r->r which won't make progress.
8924 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8925 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8927 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8928 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8929 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8932 (define_insn "*movdi_internal32"
8933 [(set (match_operand:DI 0 "nonimmediate_operand"
8934 "=Y, r, r, m, ^d, ^d,
8935 r, wY, Z, ^v, $v, ^wa,
8936 wa, wa, v, wa, *i, v,
8938 (match_operand:DI 1 "input_operand"
8939 "r, Y, r, ^d, m, ^d,
8940 IJKnF, ^v, $v, wY, Z, ^wa,
8941 Oj, wM, OjwM, Oj, wM, wS,
8944 && (gpc_reg_operand (operands[0], DImode)
8945 || gpc_reg_operand (operands[1], DImode))"
8967 "store, load, *, fpstore, fpload, fpsimple,
8968 *, fpstore, fpstore, fpload, fpload, veclogical,
8969 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8971 (set_attr "size" "64")
8979 *, p9v, p7v, p9v, p7v, *,
8980 p9v, p9v, p7v, *, *, p7v,
8984 [(set (match_operand:DI 0 "gpc_reg_operand")
8985 (match_operand:DI 1 "const_int_operand"))]
8986 "! TARGET_POWERPC64 && reload_completed
8987 && gpr_or_gpr_p (operands[0], operands[1])
8988 && !direct_move_p (operands[0], operands[1])"
8989 [(set (match_dup 2) (match_dup 4))
8990 (set (match_dup 3) (match_dup 1))]
8992 HOST_WIDE_INT value = INTVAL (operands[1]);
8993 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8995 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8997 operands[4] = GEN_INT (value >> 32);
8998 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
9002 [(set (match_operand:DIFD 0 "nonimmediate_operand")
9003 (match_operand:DIFD 1 "input_operand"))]
9004 "reload_completed && !TARGET_POWERPC64
9005 && gpr_or_gpr_p (operands[0], operands[1])
9006 && !direct_move_p (operands[0], operands[1])"
9009 rs6000_split_multireg_move (operands[0], operands[1]);
9013 ;; GPR store GPR load GPR move
9014 ;; GPR li GPR lis GPR pli GPR #
9015 ;; FPR store FPR load FPR move
9016 ;; AVX store AVX store AVX load AVX load VSX move
9017 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1
9018 ;; P9 const AVX const
9019 ;; From SPR To SPR SPR<->SPR
9020 ;; VSX->GPR GPR->VSX
9021 (define_insn "*movdi_internal64"
9022 [(set (match_operand:DI 0 "nonimmediate_operand"
9031 (match_operand:DI 1 "input_operand"
9036 Oj, wM, OjwM, Oj, wM,
9041 && (gpc_reg_operand (operands[0], DImode)
9042 || gpc_reg_operand (operands[1], DImode))"
9074 fpstore, fpload, fpsimple,
9075 fpstore, fpstore, fpload, fpload, veclogical,
9076 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
9077 vecsimple, vecsimple,
9080 (set_attr "size" "64")
9094 p9v, p7v, p9v, p7v, *,
9095 p9v, p9v, p7v, *, *,
9100 ; Some DImode loads are best done as a load of -1 followed by a mask
9103 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9104 (match_operand:DI 1 "const_int_operand"))]
9106 && num_insns_constant (operands[1], DImode) > 1
9107 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
9108 && rs6000_is_valid_and_mask (operands[1], DImode)"
9112 (and:DI (match_dup 0)
9116 ;; Split a load of a large constant into the appropriate five-instruction
9117 ;; sequence. Handle anything in a constant number of insns.
9118 ;; When non-easy constants can go in the TOC, this should use
9119 ;; easy_fp_constant predicate.
9121 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9122 (match_operand:DI 1 "const_int_operand"))]
9123 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9124 [(set (match_dup 0) (match_dup 2))
9125 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
9127 if (rs6000_emit_set_const (operands[0], operands[1]))
9134 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9135 (match_operand:DI 1 "const_scalar_int_operand"))]
9136 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9137 [(set (match_dup 0) (match_dup 2))
9138 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
9140 if (rs6000_emit_set_const (operands[0], operands[1]))
9147 [(set (match_operand:DI 0 "altivec_register_operand")
9148 (match_operand:DI 1 "s5bit_cint_operand"))]
9149 "TARGET_VSX && reload_completed"
9152 rtx op0 = operands[0];
9153 rtx op1 = operands[1];
9154 int r = REGNO (op0);
9155 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9157 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9158 if (op1 != const0_rtx && op1 != constm1_rtx)
9160 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9161 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9166 ;; Split integer constants that can be loaded with XXSPLTIB and a
9167 ;; sign extend operation.
9169 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
9170 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
9171 "TARGET_P9_VECTOR && reload_completed"
9174 rtx op0 = operands[0];
9175 rtx op1 = operands[1];
9176 int r = REGNO (op0);
9177 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9179 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9180 if (<MODE>mode == DImode)
9181 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9182 else if (<MODE>mode == SImode)
9183 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9184 else if (<MODE>mode == HImode)
9186 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9187 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9193 ;; TImode/PTImode is similar, except that we usually want to compute the
9194 ;; address into a register and use lsi/stsi (the exception is during reload).
9196 (define_insn "*mov<mode>_string"
9197 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9198 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9200 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9201 && (gpc_reg_operand (operands[0], <MODE>mode)
9202 || gpc_reg_operand (operands[1], <MODE>mode))"
9204 [(set_attr "type" "store,store,load,load,*,*")
9205 (set_attr "update" "yes")
9206 (set_attr "indexed" "yes")
9207 (set_attr "cell_micro" "conditional")])
9209 (define_insn "*mov<mode>_ppc64"
9210 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9211 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9212 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9213 && (gpc_reg_operand (operands[0], <MODE>mode)
9214 || gpc_reg_operand (operands[1], <MODE>mode)))"
9216 return rs6000_output_move_128bit (operands);
9218 [(set_attr "type" "store,store,load,load,*,*")
9219 (set_attr "length" "8")
9220 (set_attr "max_prefixed_insns" "2")])
9223 [(set (match_operand:TI2 0 "int_reg_operand")
9224 (match_operand:TI2 1 "const_scalar_int_operand"))]
9226 && (VECTOR_MEM_NONE_P (<MODE>mode)
9227 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9228 [(set (match_dup 2) (match_dup 4))
9229 (set (match_dup 3) (match_dup 5))]
9231 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9233 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9235 if (CONST_WIDE_INT_P (operands[1]))
9237 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9238 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9240 else if (CONST_INT_P (operands[1]))
9242 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9243 operands[5] = operands[1];
9250 [(set (match_operand:TI2 0 "nonimmediate_operand")
9251 (match_operand:TI2 1 "input_operand"))]
9253 && gpr_or_gpr_p (operands[0], operands[1])
9254 && !direct_move_p (operands[0], operands[1])
9255 && !quad_load_store_p (operands[0], operands[1])"
9258 rs6000_split_multireg_move (operands[0], operands[1]);
9262 (define_expand "setmemsi"
9263 [(parallel [(set (match_operand:BLK 0 "")
9264 (match_operand 2 "const_int_operand"))
9265 (use (match_operand:SI 1 ""))
9266 (use (match_operand:SI 3 ""))])]
9269 /* If value to set is not zero, use the library routine. */
9270 if (operands[2] != const0_rtx)
9273 if (expand_block_clear (operands))
9279 ;; String compare N insn.
9280 ;; Argument 0 is the target (result)
9281 ;; Argument 1 is the destination
9282 ;; Argument 2 is the source
9283 ;; Argument 3 is the length
9284 ;; Argument 4 is the alignment
9286 (define_expand "cmpstrnsi"
9287 [(parallel [(set (match_operand:SI 0)
9288 (compare:SI (match_operand:BLK 1)
9289 (match_operand:BLK 2)))
9290 (use (match_operand:SI 3))
9291 (use (match_operand:SI 4))])]
9292 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9294 if (optimize_insn_for_size_p ())
9297 if (expand_strn_compare (operands, 0))
9303 ;; String compare insn.
9304 ;; Argument 0 is the target (result)
9305 ;; Argument 1 is the destination
9306 ;; Argument 2 is the source
9307 ;; Argument 3 is the alignment
9309 (define_expand "cmpstrsi"
9310 [(parallel [(set (match_operand:SI 0)
9311 (compare:SI (match_operand:BLK 1)
9312 (match_operand:BLK 2)))
9313 (use (match_operand:SI 3))])]
9314 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9316 if (optimize_insn_for_size_p ())
9319 if (expand_strn_compare (operands, 1))
9325 ;; Block compare insn.
9326 ;; Argument 0 is the target (result)
9327 ;; Argument 1 is the destination
9328 ;; Argument 2 is the source
9329 ;; Argument 3 is the length
9330 ;; Argument 4 is the alignment
9332 (define_expand "cmpmemsi"
9333 [(parallel [(set (match_operand:SI 0)
9334 (compare:SI (match_operand:BLK 1)
9335 (match_operand:BLK 2)))
9336 (use (match_operand:SI 3))
9337 (use (match_operand:SI 4))])]
9340 if (expand_block_compare (operands))
9346 ;; String/block copy insn (source and destination must not overlap).
9347 ;; Argument 0 is the destination
9348 ;; Argument 1 is the source
9349 ;; Argument 2 is the length
9350 ;; Argument 3 is the alignment
9352 (define_expand "cpymemsi"
9353 [(parallel [(set (match_operand:BLK 0 "")
9354 (match_operand:BLK 1 ""))
9355 (use (match_operand:SI 2 ""))
9356 (use (match_operand:SI 3 ""))])]
9359 if (expand_block_move (operands, false))
9365 ;; String/block move insn (source and destination may overlap).
9366 ;; Argument 0 is the destination
9367 ;; Argument 1 is the source
9368 ;; Argument 2 is the length
9369 ;; Argument 3 is the alignment
9371 (define_expand "movmemsi"
9372 [(parallel [(set (match_operand:BLK 0 "")
9373 (match_operand:BLK 1 ""))
9374 (use (match_operand:SI 2 ""))
9375 (use (match_operand:SI 3 ""))])]
9378 if (expand_block_move (operands, true))
9385 ;; Define insns that do load or store with update. Some of these we can
9386 ;; get by using pre-decrement or pre-increment, but the hardware can also
9387 ;; do cases where the increment is not the size of the object.
9389 ;; In all these cases, we use operands 0 and 1 for the register being
9390 ;; incremented because those are the operands that local-alloc will
9391 ;; tie and these are the pair most likely to be tieable (and the ones
9392 ;; that will benefit the most).
9394 (define_insn "*movdi_update1"
9395 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9396 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9397 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9398 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9399 (plus:P (match_dup 1) (match_dup 2)))]
9400 "TARGET_POWERPC64 && TARGET_UPDATE
9401 && (!avoiding_indexed_address_p (DImode)
9402 || !gpc_reg_operand (operands[2], Pmode))"
9406 [(set_attr "type" "load")
9407 (set_attr "update" "yes")
9408 (set_attr "indexed" "yes,no")])
9410 (define_insn "movdi_<mode>_update"
9411 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9412 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9413 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9414 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9415 (plus:P (match_dup 1) (match_dup 2)))]
9416 "TARGET_POWERPC64 && TARGET_UPDATE
9417 && (!avoiding_indexed_address_p (DImode)
9418 || !gpc_reg_operand (operands[2], Pmode)
9419 || (REG_P (operands[0])
9420 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9424 [(set_attr "type" "store")
9425 (set_attr "update" "yes")
9426 (set_attr "indexed" "yes,no")])
9428 ;; This pattern is only conditional on TARGET_64BIT, as it is
9429 ;; needed for stack allocation, even if the user passes -mno-update.
9430 (define_insn "movdi_update_stack"
9431 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9432 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9433 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9434 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9435 (plus:DI (match_dup 1) (match_dup 2)))]
9440 [(set_attr "type" "store")
9441 (set_attr "update" "yes")
9442 (set_attr "indexed" "yes,no")])
9444 (define_insn "*movsi_update1"
9445 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9446 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9447 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9448 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9449 (plus:P (match_dup 1) (match_dup 2)))]
9451 && (!avoiding_indexed_address_p (SImode)
9452 || !gpc_reg_operand (operands[2], Pmode))"
9456 [(set_attr "type" "load")
9457 (set_attr "update" "yes")
9458 (set_attr "indexed" "yes,no")])
9460 (define_insn "*movsi_update2"
9461 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9463 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9464 (match_operand:P 2 "gpc_reg_operand" "r")))))
9465 (set (match_operand:P 0 "gpc_reg_operand" "=b")
9466 (plus:P (match_dup 1) (match_dup 2)))]
9467 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9469 [(set_attr "type" "load")
9470 (set_attr "sign_extend" "yes")
9471 (set_attr "update" "yes")
9472 (set_attr "indexed" "yes")])
9474 (define_insn "movsi_<mode>_update"
9475 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9476 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9477 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9478 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9479 (plus:P (match_dup 1) (match_dup 2)))]
9481 && (!avoiding_indexed_address_p (SImode)
9482 || !gpc_reg_operand (operands[2], Pmode)
9483 || (REG_P (operands[0])
9484 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9488 [(set_attr "type" "store")
9489 (set_attr "update" "yes")
9490 (set_attr "indexed" "yes,no")])
9492 ;; This is an unconditional pattern; needed for stack allocation, even
9493 ;; if the user passes -mno-update.
9494 (define_insn "movsi_update_stack"
9495 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9496 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9497 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9498 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9499 (plus:SI (match_dup 1) (match_dup 2)))]
9504 [(set_attr "type" "store")
9505 (set_attr "update" "yes")
9506 (set_attr "indexed" "yes,no")])
9508 (define_insn "*movhi_update1"
9509 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9510 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9511 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9512 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9513 (plus:P (match_dup 1) (match_dup 2)))]
9515 && (!avoiding_indexed_address_p (HImode)
9516 || !gpc_reg_operand (operands[2], SImode))"
9520 [(set_attr "type" "load")
9521 (set_attr "update" "yes")
9522 (set_attr "indexed" "yes,no")])
9524 (define_insn "*movhi_update2"
9525 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9527 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9528 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9529 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9530 (plus:P (match_dup 1) (match_dup 2)))]
9532 && (!avoiding_indexed_address_p (HImode)
9533 || !gpc_reg_operand (operands[2], Pmode))"
9537 [(set_attr "type" "load")
9538 (set_attr "update" "yes")
9539 (set_attr "indexed" "yes,no")])
9541 (define_insn "*movhi_update3"
9542 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9544 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9545 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9546 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9547 (plus:P (match_dup 1) (match_dup 2)))]
9549 && !(avoiding_indexed_address_p (HImode)
9550 && gpc_reg_operand (operands[2], Pmode))"
9554 [(set_attr "type" "load")
9555 (set_attr "sign_extend" "yes")
9556 (set_attr "update" "yes")
9557 (set_attr "indexed" "yes,no")])
9559 (define_insn "*movhi_update4"
9560 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9561 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9562 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9563 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9564 (plus:P (match_dup 1) (match_dup 2)))]
9566 && (!avoiding_indexed_address_p (HImode)
9567 || !gpc_reg_operand (operands[2], Pmode))"
9571 [(set_attr "type" "store")
9572 (set_attr "update" "yes")
9573 (set_attr "indexed" "yes,no")])
9575 (define_insn "*movqi_update1"
9576 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9577 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9578 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9579 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9580 (plus:P (match_dup 1) (match_dup 2)))]
9582 && (!avoiding_indexed_address_p (QImode)
9583 || !gpc_reg_operand (operands[2], Pmode))"
9587 [(set_attr "type" "load")
9588 (set_attr "update" "yes")
9589 (set_attr "indexed" "yes,no")])
9591 (define_insn "*movqi_update2"
9592 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9594 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9595 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9596 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9597 (plus:P (match_dup 1) (match_dup 2)))]
9599 && (!avoiding_indexed_address_p (QImode)
9600 || !gpc_reg_operand (operands[2], Pmode))"
9604 [(set_attr "type" "load")
9605 (set_attr "update" "yes")
9606 (set_attr "indexed" "yes,no")])
9608 (define_insn "*movqi_update3"
9609 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9610 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9611 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9612 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9613 (plus:P (match_dup 1) (match_dup 2)))]
9615 && (!avoiding_indexed_address_p (QImode)
9616 || !gpc_reg_operand (operands[2], Pmode))"
9620 [(set_attr "type" "store")
9621 (set_attr "update" "yes")
9622 (set_attr "indexed" "yes,no")])
9624 (define_insn "*mov<SFDF:mode>_update1"
9625 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9626 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9627 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9628 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9629 (plus:P (match_dup 1) (match_dup 2)))]
9630 "TARGET_HARD_FLOAT && TARGET_UPDATE
9631 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9632 || !gpc_reg_operand (operands[2], Pmode))"
9636 [(set_attr "type" "fpload")
9637 (set_attr "update" "yes")
9638 (set_attr "indexed" "yes,no")
9639 (set_attr "size" "<SFDF:bits>")])
9641 (define_insn "*mov<SFDF:mode>_update2"
9642 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9643 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9644 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9645 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9646 (plus:P (match_dup 1) (match_dup 2)))]
9647 "TARGET_HARD_FLOAT && TARGET_UPDATE
9648 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9649 || !gpc_reg_operand (operands[2], Pmode))"
9653 [(set_attr "type" "fpstore")
9654 (set_attr "update" "yes")
9655 (set_attr "indexed" "yes,no")
9656 (set_attr "size" "<SFDF:bits>")])
9658 (define_insn "*movsf_update3"
9659 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9660 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9661 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9662 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9663 (plus:P (match_dup 1) (match_dup 2)))]
9664 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9665 && (!avoiding_indexed_address_p (SFmode)
9666 || !gpc_reg_operand (operands[2], Pmode))"
9670 [(set_attr "type" "load")
9671 (set_attr "update" "yes")
9672 (set_attr "indexed" "yes,no")])
9674 (define_insn "*movsf_update4"
9675 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9676 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9677 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9678 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9679 (plus:P (match_dup 1) (match_dup 2)))]
9680 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9681 && (!avoiding_indexed_address_p (SFmode)
9682 || !gpc_reg_operand (operands[2], Pmode))"
9686 [(set_attr "type" "store")
9687 (set_attr "update" "yes")
9688 (set_attr "indexed" "yes,no")])
9691 ;; After inserting conditional returns we can sometimes have
9692 ;; unnecessary register moves. Unfortunately we cannot have a
9693 ;; modeless peephole here, because some single SImode sets have early
9694 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9695 ;; sequences, using get_attr_length here will smash the operands
9696 ;; array. Neither is there an early_cobbler_p predicate.
9697 ;; Also this optimization interferes with scalars going into
9698 ;; altivec registers (the code does reloading through the FPRs).
9700 [(set (match_operand:DF 0 "gpc_reg_operand")
9701 (match_operand:DF 1 "any_operand"))
9702 (set (match_operand:DF 2 "gpc_reg_operand")
9705 && peep2_reg_dead_p (2, operands[0])"
9706 [(set (match_dup 2) (match_dup 1))])
9709 [(set (match_operand:SF 0 "gpc_reg_operand")
9710 (match_operand:SF 1 "any_operand"))
9711 (set (match_operand:SF 2 "gpc_reg_operand")
9714 && peep2_reg_dead_p (2, operands[0])"
9715 [(set (match_dup 2) (match_dup 1))])
9720 (define_insn "*tls_gd_pcrel<bits>"
9721 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9722 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9725 "HAVE_AS_TLS && TARGET_ELF"
9726 "la %0,%1@got@tlsgd@pcrel"
9727 [(set_attr "prefixed" "yes")])
9729 (define_insn_and_split "*tls_gd<bits>"
9730 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9731 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9732 (match_operand:P 2 "gpc_reg_operand" "b")]
9734 "HAVE_AS_TLS && TARGET_ELF"
9735 "addi %0,%2,%1@got@tlsgd"
9736 "&& TARGET_CMODEL != CMODEL_SMALL"
9739 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9741 (lo_sum:P (match_dup 3)
9742 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9744 operands[3] = gen_reg_rtx (<MODE>mode);
9746 [(set (attr "length")
9747 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9751 (define_insn "*tls_gd_high<bits>"
9752 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9754 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9755 (match_operand:P 2 "gpc_reg_operand" "b")]
9757 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9758 "addis %0,%2,%1@got@tlsgd@ha")
9760 (define_insn "*tls_gd_low<bits>"
9761 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9762 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9763 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9764 (match_operand:P 3 "gpc_reg_operand" "b")]
9766 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9767 "addi %0,%1,%2@got@tlsgd@l")
9769 (define_insn "*tls_ld_pcrel<bits>"
9770 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9771 (unspec:P [(const_int 0)]
9773 "HAVE_AS_TLS && TARGET_ELF"
9774 "la %0,%&@got@tlsld@pcrel"
9775 [(set_attr "prefixed" "yes")])
9777 (define_insn_and_split "*tls_ld<bits>"
9778 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9779 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9781 "HAVE_AS_TLS && TARGET_ELF"
9782 "addi %0,%1,%&@got@tlsld"
9783 "&& TARGET_CMODEL != CMODEL_SMALL"
9786 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9788 (lo_sum:P (match_dup 2)
9789 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9791 operands[2] = gen_reg_rtx (<MODE>mode);
9793 [(set (attr "length")
9794 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9798 (define_insn "*tls_ld_high<bits>"
9799 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9801 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9803 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9804 "addis %0,%1,%&@got@tlsld@ha")
9806 (define_insn "*tls_ld_low<bits>"
9807 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9808 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9809 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9811 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9812 "addi %0,%1,%&@got@tlsld@l")
9814 (define_insn "tls_dtprel_<bits>"
9815 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9816 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9817 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9820 "addi %0,%1,%2@dtprel"
9821 [(set (attr "prefixed")
9822 (if_then_else (match_test "rs6000_tls_size == 16")
9824 (const_string "yes")))])
9826 (define_insn "tls_dtprel_ha_<bits>"
9827 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9828 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9829 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9830 UNSPEC_TLSDTPRELHA))]
9832 "addis %0,%1,%2@dtprel@ha")
9834 (define_insn "tls_dtprel_lo_<bits>"
9835 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9836 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9837 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9838 UNSPEC_TLSDTPRELLO))]
9840 "addi %0,%1,%2@dtprel@l")
9842 (define_insn_and_split "tls_got_dtprel_<bits>"
9843 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9844 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9845 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9846 UNSPEC_TLSGOTDTPREL))]
9848 "<ptrload> %0,%2@got@dtprel(%1)"
9849 "&& TARGET_CMODEL != CMODEL_SMALL"
9852 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9854 (lo_sum:P (match_dup 3)
9855 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9857 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9859 [(set (attr "length")
9860 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9864 (define_insn "*tls_got_dtprel_high<bits>"
9865 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9867 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9868 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9869 UNSPEC_TLSGOTDTPREL)))]
9870 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9871 "addis %0,%1,%2@got@dtprel@ha")
9873 (define_insn "*tls_got_dtprel_low<bits>"
9874 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9875 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9876 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9877 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9878 UNSPEC_TLSGOTDTPREL)))]
9879 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9880 "<ptrload> %0,%2@got@dtprel@l(%1)")
9882 (define_insn "tls_tprel_<bits>"
9883 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9884 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9885 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9888 "addi %0,%1,%2@tprel"
9889 [(set (attr "prefixed")
9890 (if_then_else (match_test "rs6000_tls_size == 16")
9892 (const_string "yes")))])
9894 (define_insn "tls_tprel_ha_<bits>"
9895 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9896 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9897 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9898 UNSPEC_TLSTPRELHA))]
9900 "addis %0,%1,%2@tprel@ha")
9902 (define_insn "tls_tprel_lo_<bits>"
9903 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9904 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9905 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9906 UNSPEC_TLSTPRELLO))]
9908 "addi %0,%1,%2@tprel@l")
9910 (define_insn "*tls_got_tprel_pcrel_<bits>"
9911 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9912 (unspec:P [(const_int 0)
9913 (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9914 UNSPEC_TLSGOTTPREL))]
9916 "<ptrload> %0,%1@got@tprel@pcrel"
9917 [(set_attr "prefixed" "yes")])
9919 ;; "b" output constraint here and on tls_tls input to support linker tls
9920 ;; optimization. The linker may edit the instructions emitted by a
9921 ;; tls_got_tprel/tls_tls pair to addis,addi.
9922 (define_insn_and_split "tls_got_tprel_<bits>"
9923 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9924 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9925 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9926 UNSPEC_TLSGOTTPREL))]
9928 "<ptrload> %0,%2@got@tprel(%1)"
9929 "&& TARGET_CMODEL != CMODEL_SMALL"
9932 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9934 (lo_sum:P (match_dup 3)
9935 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9937 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9939 [(set (attr "length")
9940 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9944 (define_insn "*tls_got_tprel_high<bits>"
9945 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9947 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9948 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9949 UNSPEC_TLSGOTTPREL)))]
9950 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9951 "addis %0,%1,%2@got@tprel@ha")
9953 (define_insn "*tls_got_tprel_low<bits>"
9954 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9955 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9956 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9957 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9958 UNSPEC_TLSGOTTPREL)))]
9959 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9960 "<ptrload> %0,%2@got@tprel@l(%1)")
9962 (define_insn "tls_tls_pcrel_<bits>"
9963 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9964 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9965 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9966 UNSPEC_TLSTLS_PCREL))]
9967 "TARGET_ELF && HAVE_AS_TLS"
9968 "add %0,%1,%2@tls@pcrel")
9970 (define_insn "tls_tls_<bits>"
9971 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9972 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9973 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9975 "TARGET_ELF && HAVE_AS_TLS"
9978 (define_expand "tls_get_tpointer"
9979 [(set (match_operand:SI 0 "gpc_reg_operand")
9980 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9981 "TARGET_XCOFF && HAVE_AS_TLS"
9983 emit_insn (gen_tls_get_tpointer_internal ());
9984 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9988 (define_insn "tls_get_tpointer_internal"
9990 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9991 (clobber (reg:SI LR_REGNO))]
9992 "TARGET_XCOFF && HAVE_AS_TLS"
9993 "bla __get_tpointer")
9995 (define_expand "tls_get_addr<mode>"
9996 [(set (match_operand:P 0 "gpc_reg_operand")
9997 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9998 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9999 "TARGET_XCOFF && HAVE_AS_TLS"
10001 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10002 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10003 emit_insn (gen_tls_get_addr_internal<mode> ());
10004 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10008 (define_insn "tls_get_addr_internal<mode>"
10010 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10011 (clobber (reg:P 0))
10012 (clobber (reg:P 4))
10013 (clobber (reg:P 5))
10014 (clobber (reg:P 11))
10015 (clobber (reg:CC CR0_REGNO))
10016 (clobber (reg:P LR_REGNO))]
10017 "TARGET_XCOFF && HAVE_AS_TLS"
10018 "bla __tls_get_addr")
10020 ;; Next come insns related to the calling sequence.
10022 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10023 ;; We move the back-chain and decrement the stack pointer.
10025 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
10026 ;; constant alloca, using that predicate will force the generic code to put
10027 ;; the constant size into a register before calling the expander.
10029 ;; As a result the expander would not have the constant size information
10030 ;; in those cases and would have to generate less efficient code.
10032 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10033 ;; the constant size. The value is forced into a register if necessary.
10035 (define_expand "allocate_stack"
10036 [(set (match_operand 0 "gpc_reg_operand")
10037 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
10039 (minus (reg 1) (match_dup 1)))]
10042 rtx chain = gen_reg_rtx (Pmode);
10043 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10045 rtx insn, par, set, mem;
10047 /* By allowing reg_or_cint_operand as the predicate we can get
10048 better code for stack-clash-protection because we do not lose
10049 size information. But the rest of the code expects the operand
10050 to be reg_or_short_operand. If it isn't, then force it into
10052 rtx orig_op1 = operands[1];
10053 if (!reg_or_short_operand (operands[1], Pmode))
10054 operands[1] = force_reg (Pmode, operands[1]);
10056 emit_move_insn (chain, stack_bot);
10058 /* Check stack bounds if necessary. */
10059 if (crtl->limit_stack)
10062 available = expand_binop (Pmode, sub_optab,
10063 stack_pointer_rtx, stack_limit_rtx,
10064 NULL_RTX, 1, OPTAB_WIDEN);
10065 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10068 /* Allocate and probe if requested.
10069 This may look similar to the loop we use for prologue allocations,
10070 but it is critically different. For the former we know the loop
10071 will iterate, but do not know that generally here. The former
10072 uses that knowledge to rotate the loop. Combining them would be
10073 possible with some performance cost. */
10074 if (flag_stack_clash_protection)
10076 rtx rounded_size, last_addr, residual;
10077 HOST_WIDE_INT probe_interval;
10078 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10079 &residual, &probe_interval,
10082 /* We do occasionally get in here with constant sizes, we might
10083 as well do a reasonable job when we obviously can. */
10084 if (rounded_size != const0_rtx)
10086 rtx loop_lab, end_loop;
10087 bool rotated = CONST_INT_P (rounded_size);
10088 rtx update = GEN_INT (-probe_interval);
10089 if (probe_interval > 32768)
10090 update = force_reg (Pmode, update);
10092 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10093 last_addr, rotated);
10096 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10100 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
10103 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10104 last_addr, rotated);
10107 /* Now handle residuals. We just have to set operands[1] correctly
10108 and let the rest of the expander run. */
10109 operands[1] = residual;
10112 if (!(CONST_INT_P (operands[1])
10113 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
10115 operands[1] = force_reg (Pmode, operands[1]);
10116 neg_op0 = gen_reg_rtx (Pmode);
10117 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
10120 neg_op0 = GEN_INT (-INTVAL (operands[1]));
10122 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10123 : gen_movdi_update_stack))
10124 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10126 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10127 it now and set the alias set/attributes. The above gen_*_update
10128 calls will generate a PARALLEL with the MEM set being the first
10130 par = PATTERN (insn);
10131 gcc_assert (GET_CODE (par) == PARALLEL);
10132 set = XVECEXP (par, 0, 0);
10133 gcc_assert (GET_CODE (set) == SET);
10134 mem = SET_DEST (set);
10135 gcc_assert (MEM_P (mem));
10136 MEM_NOTRAP_P (mem) = 1;
10137 set_mem_alias_set (mem, get_frame_alias_set ());
10139 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10143 ;; These patterns say how to save and restore the stack pointer. We need not
10144 ;; save the stack pointer at function level since we are careful to
10145 ;; preserve the backchain. At block level, we have to restore the backchain
10146 ;; when we restore the stack pointer.
10148 ;; For nonlocal gotos, we must save both the stack pointer and its
10149 ;; backchain and restore both. Note that in the nonlocal case, the
10150 ;; save area is a memory location.
10152 (define_expand "save_stack_function"
10153 [(match_operand 0 "any_operand")
10154 (match_operand 1 "any_operand")]
10158 (define_expand "restore_stack_function"
10159 [(match_operand 0 "any_operand")
10160 (match_operand 1 "any_operand")]
10164 ;; Adjust stack pointer (op0) to a new value (op1).
10165 ;; First copy old stack backchain to new location, and ensure that the
10166 ;; scheduler won't reorder the sp assignment before the backchain write.
10167 (define_expand "restore_stack_block"
10168 [(set (match_dup 2) (match_dup 3))
10169 (set (match_dup 4) (match_dup 2))
10171 (set (match_operand 0 "register_operand")
10172 (match_operand 1 "register_operand"))]
10177 operands[1] = force_reg (Pmode, operands[1]);
10178 operands[2] = gen_reg_rtx (Pmode);
10179 operands[3] = gen_frame_mem (Pmode, operands[0]);
10180 operands[4] = gen_frame_mem (Pmode, operands[1]);
10181 p = rtvec_alloc (1);
10182 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10184 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10187 (define_expand "save_stack_nonlocal"
10188 [(set (match_dup 3) (match_dup 4))
10189 (set (match_operand 0 "memory_operand") (match_dup 3))
10190 (set (match_dup 2) (match_operand 1 "register_operand"))]
10193 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10195 /* Copy the backchain to the first word, sp to the second. */
10196 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10197 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10198 operands[3] = gen_reg_rtx (Pmode);
10199 operands[4] = gen_frame_mem (Pmode, operands[1]);
10202 (define_expand "restore_stack_nonlocal"
10203 [(set (match_dup 2) (match_operand 1 "memory_operand"))
10204 (set (match_dup 3) (match_dup 4))
10205 (set (match_dup 5) (match_dup 2))
10207 (set (match_operand 0 "register_operand") (match_dup 3))]
10210 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10213 /* Restore the backchain from the first word, sp from the second. */
10214 operands[2] = gen_reg_rtx (Pmode);
10215 operands[3] = gen_reg_rtx (Pmode);
10216 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10217 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10218 operands[5] = gen_frame_mem (Pmode, operands[3]);
10219 p = rtvec_alloc (1);
10220 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10222 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10225 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10226 ;; to the symbol or label.
10227 (define_insn "*pcrel_local_addr"
10228 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10229 (match_operand:DI 1 "pcrel_local_address"))]
10232 [(set_attr "prefixed" "yes")])
10234 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10235 ;; program are both defined in the main program, the linker will optimize this
10236 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10237 ;; the dynamic linker and loaded up. Print_operand_address will append a
10238 ;; @got@pcrel to the symbol.
10239 (define_insn "*pcrel_extern_addr"
10240 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10241 (match_operand:DI 1 "pcrel_external_address"))]
10244 [(set_attr "prefixed" "yes")
10245 (set_attr "type" "load")])
10247 ;; TOC register handling.
10249 ;; Code to initialize the TOC register...
10251 (define_insn "load_toc_aix_si"
10252 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10253 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10254 (use (reg:SI 2))])]
10255 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10258 extern int need_toc_init;
10260 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10261 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10262 operands[2] = gen_rtx_REG (Pmode, 2);
10263 return "lwz %0,%1(%2)";
10265 [(set_attr "type" "load")
10266 (set_attr "update" "no")
10267 (set_attr "indexed" "no")])
10269 (define_insn "load_toc_aix_di"
10270 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10271 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10272 (use (reg:DI 2))])]
10273 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10276 extern int need_toc_init;
10278 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10279 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10281 strcat (buf, "@toc");
10282 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10283 operands[2] = gen_rtx_REG (Pmode, 2);
10284 return "ld %0,%1(%2)";
10286 [(set_attr "type" "load")
10287 (set_attr "update" "no")
10288 (set_attr "indexed" "no")])
10290 (define_insn "load_toc_v4_pic_si"
10291 [(set (reg:SI LR_REGNO)
10292 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10293 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10294 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10295 [(set_attr "type" "branch")])
10297 (define_expand "load_toc_v4_PIC_1"
10298 [(parallel [(set (reg:SI LR_REGNO)
10299 (match_operand:SI 0 "immediate_operand" "s"))
10300 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10301 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10302 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10305 (define_insn "load_toc_v4_PIC_1_normal"
10306 [(set (reg:SI LR_REGNO)
10307 (match_operand:SI 0 "immediate_operand" "s"))
10308 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10309 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10310 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10311 "bcl 20,31,%0\n%0:"
10312 [(set_attr "type" "branch")
10313 (set_attr "cannot_copy" "yes")])
10315 (define_insn "load_toc_v4_PIC_1_476"
10316 [(set (reg:SI LR_REGNO)
10317 (match_operand:SI 0 "immediate_operand" "s"))
10318 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10319 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10320 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10323 static char templ[32];
10325 get_ppc476_thunk_name (name);
10326 sprintf (templ, "bl %s\n%%0:", name);
10329 [(set_attr "type" "branch")
10330 (set_attr "cannot_copy" "yes")])
10332 (define_expand "load_toc_v4_PIC_1b"
10333 [(parallel [(set (reg:SI LR_REGNO)
10334 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10335 (label_ref (match_operand 1 ""))]
10338 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10341 (define_insn "load_toc_v4_PIC_1b_normal"
10342 [(set (reg:SI LR_REGNO)
10343 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10344 (label_ref (match_operand 1 "" ""))]
10347 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10348 "bcl 20,31,$+8\;.long %0-$"
10349 [(set_attr "type" "branch")
10350 (set_attr "length" "8")])
10352 (define_insn "load_toc_v4_PIC_1b_476"
10353 [(set (reg:SI LR_REGNO)
10354 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10355 (label_ref (match_operand 1 "" ""))]
10358 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10361 static char templ[32];
10363 get_ppc476_thunk_name (name);
10364 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10367 [(set_attr "type" "branch")
10368 (set_attr "length" "16")])
10370 (define_insn "load_toc_v4_PIC_2"
10371 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10373 (match_operand:SI 1 "gpc_reg_operand" "b")
10375 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10376 (match_operand:SI 3 "immediate_operand" "s"))))))]
10377 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10379 [(set_attr "type" "load")])
10381 (define_insn "load_toc_v4_PIC_3b"
10382 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10384 (match_operand:SI 1 "gpc_reg_operand" "b")
10387 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10388 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10389 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10390 "addis %0,%1,%2-%3@ha")
10392 (define_insn "load_toc_v4_PIC_3c"
10393 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10395 (match_operand:SI 1 "gpc_reg_operand" "b")
10397 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10398 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10399 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10400 "addi %0,%1,%2-%3@l")
10402 ;; If the TOC is shared over a translation unit, as happens with all
10403 ;; the kinds of PIC that we support, we need to restore the TOC
10404 ;; pointer only when jumping over units of translation.
10405 ;; On Darwin, we need to reload the picbase.
10407 (define_expand "builtin_setjmp_receiver"
10408 [(use (label_ref (match_operand 0 "")))]
10409 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10410 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10411 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10414 if (DEFAULT_ABI == ABI_DARWIN)
10416 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10417 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10421 crtl->uses_pic_offset_table = 1;
10422 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10423 CODE_LABEL_NUMBER (operands[0]));
10424 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10426 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10427 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10428 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10429 picrtx, tmplabrtx));
10433 rs6000_emit_load_toc_table (FALSE);
10437 ;; Largetoc support
10438 (define_insn "*largetoc_high"
10439 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10441 (unspec [(match_operand:DI 1 "" "")
10442 (match_operand:DI 2 "gpc_reg_operand" "b")]
10444 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10445 "addis %0,%2,%1@toc@ha")
10447 (define_insn "*largetoc_high_aix<mode>"
10448 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10450 (unspec [(match_operand:P 1 "" "")
10451 (match_operand:P 2 "gpc_reg_operand" "b")]
10453 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10454 "addis %0,%1@u(%2)")
10456 (define_insn "*largetoc_high_plus"
10457 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10460 (unspec [(match_operand:DI 1 "" "")
10461 (match_operand:DI 2 "gpc_reg_operand" "b")]
10463 (match_operand:DI 3 "add_cint_operand" "n"))))]
10464 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10465 "addis %0,%2,%1+%3@toc@ha")
10467 (define_insn "*largetoc_high_plus_aix<mode>"
10468 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10471 (unspec [(match_operand:P 1 "" "")
10472 (match_operand:P 2 "gpc_reg_operand" "b")]
10474 (match_operand:P 3 "add_cint_operand" "n"))))]
10475 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10476 "addis %0,%1+%3@u(%2)")
10478 (define_insn "*largetoc_low"
10479 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10480 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10481 (match_operand:DI 2 "" "")))]
10482 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10485 (define_insn "*largetoc_low_aix<mode>"
10486 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10487 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10488 (match_operand:P 2 "" "")))]
10489 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10492 (define_insn_and_split "*tocref<mode>"
10493 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10494 (match_operand:P 1 "small_toc_ref" "R"))]
10496 && legitimate_constant_pool_address_p (operands[1], QImode, false)"
10498 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10499 [(set (match_dup 0) (high:P (match_dup 1)))
10500 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10502 ;; Elf specific ways of loading addresses for non-PIC code.
10503 ;; The output of this could be r0, but we make a very strong
10504 ;; preference for a base register because it will usually
10505 ;; be needed there.
10506 (define_insn "elf_high"
10507 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10508 (high:SI (match_operand 1 "" "")))]
10509 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10512 (define_insn "elf_low"
10513 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10514 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10515 (match_operand 2 "" "")))]
10516 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10519 (define_insn "*pltseq_tocsave_<mode>"
10520 [(set (match_operand:P 0 "memory_operand" "=m")
10521 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10522 (match_operand:P 2 "symbol_ref_operand" "s")
10523 (match_operand:P 3 "" "")]
10526 && DEFAULT_ABI == ABI_ELFv2"
10528 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10531 (define_insn "*pltseq_plt16_ha_<mode>"
10532 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10533 (unspec:P [(match_operand:P 1 "" "")
10534 (match_operand:P 2 "symbol_ref_operand" "s")
10535 (match_operand:P 3 "" "")]
10539 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10542 (define_insn "*pltseq_plt16_lo_<mode>"
10543 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10544 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
10545 (match_operand:P 2 "symbol_ref_operand" "s")
10546 (match_operand:P 3 "" "")]
10547 UNSPECV_PLT16_LO))]
10550 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10552 [(set_attr "type" "load")])
10554 (define_insn "*pltseq_mtctr_<mode>"
10555 [(set (match_operand:P 0 "register_operand" "=c")
10556 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10557 (match_operand:P 2 "symbol_ref_operand" "s")
10558 (match_operand:P 3 "" "")]
10562 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10565 (define_insn "*pltseq_plt_pcrel<mode>"
10566 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10567 (unspec_volatile:P [(match_operand:P 1 "" "")
10568 (match_operand:P 2 "symbol_ref_operand" "s")
10569 (match_operand:P 3 "" "")]
10570 UNSPECV_PLT_PCREL))]
10571 "HAVE_AS_PLTSEQ && TARGET_ELF
10572 && rs6000_pcrel_p ()"
10574 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10576 [(set_attr "type" "load")
10577 (set_attr "length" "12")])
10579 ;; Call and call_value insns
10580 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10581 (define_expand "call"
10582 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10583 (match_operand 1 ""))
10584 (use (match_operand 2 ""))
10585 (clobber (reg:SI LR_REGNO))])]
10589 if (MACHOPIC_INDIRECT)
10590 operands[0] = machopic_indirect_call_target (operands[0]);
10593 gcc_assert (MEM_P (operands[0]));
10595 operands[0] = XEXP (operands[0], 0);
10597 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10598 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10599 else if (DEFAULT_ABI == ABI_V4)
10600 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10601 else if (DEFAULT_ABI == ABI_DARWIN)
10602 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10604 gcc_unreachable ();
10609 (define_expand "call_value"
10610 [(parallel [(set (match_operand 0 "")
10611 (call (mem:SI (match_operand 1 "address_operand"))
10612 (match_operand 2 "")))
10613 (use (match_operand 3 ""))
10614 (clobber (reg:SI LR_REGNO))])]
10618 if (MACHOPIC_INDIRECT)
10619 operands[1] = machopic_indirect_call_target (operands[1]);
10622 gcc_assert (MEM_P (operands[1]));
10624 operands[1] = XEXP (operands[1], 0);
10626 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10627 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10628 else if (DEFAULT_ABI == ABI_V4)
10629 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10630 else if (DEFAULT_ABI == ABI_DARWIN)
10631 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10633 gcc_unreachable ();
10638 ;; Call to function in current module. No TOC pointer reload needed.
10639 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10640 ;; either the function was not prototyped, or it was prototyped as a
10641 ;; variable argument function. It is > 0 if FP registers were passed
10642 ;; and < 0 if they were not.
10644 (define_insn "*call_local<mode>"
10645 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
10647 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10648 (clobber (reg:P LR_REGNO))]
10649 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10651 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10652 output_asm_insn ("crxor 6,6,6", operands);
10654 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10655 output_asm_insn ("creqv 6,6,6", operands);
10657 if (rs6000_pcrel_p ())
10658 return "bl %z0@notoc";
10659 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10661 [(set_attr "type" "branch")
10662 (set_attr "length" "4,8")])
10664 (define_insn "*call_value_local<mode>"
10665 [(set (match_operand 0 "" "")
10666 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
10667 (match_operand 2)))
10668 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10669 (clobber (reg:P LR_REGNO))]
10670 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10672 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10673 output_asm_insn ("crxor 6,6,6", operands);
10675 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10676 output_asm_insn ("creqv 6,6,6", operands);
10678 if (rs6000_pcrel_p ())
10679 return "bl %z1@notoc";
10680 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10682 [(set_attr "type" "branch")
10683 (set_attr "length" "4,8")])
10686 ;; A function pointer under System V is just a normal pointer
10687 ;; operands[0] is the function pointer
10688 ;; operands[1] is the tls call arg
10689 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10690 ;; which indicates how to set cr1
10692 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10693 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10695 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10696 (clobber (reg:P LR_REGNO))]
10697 "DEFAULT_ABI == ABI_V4
10698 || DEFAULT_ABI == ABI_DARWIN"
10700 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10701 output_asm_insn ("crxor 6,6,6", operands);
10703 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10704 output_asm_insn ("creqv 6,6,6", operands);
10706 return rs6000_indirect_call_template (operands, 0);
10708 [(set_attr "type" "jmpreg")
10709 (set (attr "length")
10710 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10711 (match_test "which_alternative != 1"))
10712 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10713 (const_string "12")
10714 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10715 (match_test "which_alternative != 1"))
10716 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10717 (const_string "8")]
10718 (const_string "4")))])
10720 (define_insn "*call_nonlocal_sysv<mode>"
10721 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10723 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10724 (clobber (reg:P LR_REGNO))]
10725 "(DEFAULT_ABI == ABI_DARWIN
10726 || (DEFAULT_ABI == ABI_V4
10727 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10729 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10730 output_asm_insn ("crxor 6,6,6", operands);
10732 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10733 output_asm_insn ("creqv 6,6,6", operands);
10735 return rs6000_call_template (operands, 0);
10737 [(set_attr "type" "branch,branch")
10738 (set_attr "length" "4,8")])
10740 (define_insn "*call_nonlocal_sysv_secure<mode>"
10741 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10743 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10744 (use (match_operand:SI 3 "register_operand" "r,r"))
10745 (clobber (reg:P LR_REGNO))]
10746 "(DEFAULT_ABI == ABI_V4
10747 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10748 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10750 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10751 output_asm_insn ("crxor 6,6,6", operands);
10753 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10754 output_asm_insn ("creqv 6,6,6", operands);
10756 return rs6000_call_template (operands, 0);
10758 [(set_attr "type" "branch,branch")
10759 (set_attr "length" "4,8")])
10761 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10762 [(set (match_operand 0 "" "")
10763 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10764 (match_operand:P 2 "unspec_tls" "")))
10765 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10766 (clobber (reg:P LR_REGNO))]
10767 "DEFAULT_ABI == ABI_V4
10768 || DEFAULT_ABI == ABI_DARWIN"
10770 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10771 output_asm_insn ("crxor 6,6,6", operands);
10773 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10774 output_asm_insn ("creqv 6,6,6", operands);
10776 return rs6000_indirect_call_template (operands, 1);
10778 [(set_attr "type" "jmpreg")
10779 (set (attr "length")
10781 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10784 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10785 (match_test "which_alternative != 1"))
10789 (define_insn "*call_value_nonlocal_sysv<mode>"
10790 [(set (match_operand 0 "" "")
10791 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10792 (match_operand:P 2 "unspec_tls" "")))
10793 (use (match_operand:SI 3 "immediate_operand" "n"))
10794 (clobber (reg:P LR_REGNO))]
10795 "(DEFAULT_ABI == ABI_DARWIN
10796 || (DEFAULT_ABI == ABI_V4
10797 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10799 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10800 output_asm_insn ("crxor 6,6,6", operands);
10802 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10803 output_asm_insn ("creqv 6,6,6", operands);
10805 return rs6000_call_template (operands, 1);
10807 [(set_attr "type" "branch")
10808 (set (attr "length")
10809 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10813 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10814 [(set (match_operand 0 "" "")
10815 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10816 (match_operand:P 2 "unspec_tls" "")))
10817 (use (match_operand:SI 3 "immediate_operand" "n"))
10818 (use (match_operand:SI 4 "register_operand" "r"))
10819 (clobber (reg:P LR_REGNO))]
10820 "(DEFAULT_ABI == ABI_V4
10821 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10822 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10824 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10825 output_asm_insn ("crxor 6,6,6", operands);
10827 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10828 output_asm_insn ("creqv 6,6,6", operands);
10830 return rs6000_call_template (operands, 1);
10832 [(set_attr "type" "branch")
10833 (set (attr "length")
10834 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10838 ;; Call to AIX abi function which may be in another module.
10839 ;; Restore the TOC pointer (r2) after the call.
10841 (define_insn "*call_nonlocal_aix<mode>"
10842 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10844 (use (match_operand:SI 2 "immediate_operand" "n"))
10845 (clobber (reg:P LR_REGNO))]
10846 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10847 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10849 return rs6000_call_template (operands, 0);
10851 [(set_attr "type" "branch")
10852 (set (attr "length")
10853 (if_then_else (match_test "rs6000_pcrel_p ()")
10857 (define_insn "*call_value_nonlocal_aix<mode>"
10858 [(set (match_operand 0 "" "")
10859 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10860 (match_operand:P 2 "unspec_tls" "")))
10861 (use (match_operand:SI 3 "immediate_operand" "n"))
10862 (clobber (reg:P LR_REGNO))]
10863 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10864 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10866 return rs6000_call_template (operands, 1);
10868 [(set_attr "type" "branch")
10869 (set (attr "length")
10870 (if_then_else (match_test "rs6000_pcrel_p ()")
10874 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10875 ;; Operand0 is the addresss of the function to call
10876 ;; Operand3 is the location in the function descriptor to load r2 from
10877 ;; Operand4 is the offset of the stack location holding the current TOC pointer
10879 (define_insn "*call_indirect_aix<mode>"
10880 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10882 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10883 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10884 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10885 (clobber (reg:P LR_REGNO))]
10886 "DEFAULT_ABI == ABI_AIX"
10888 return rs6000_indirect_call_template (operands, 0);
10890 [(set_attr "type" "jmpreg")
10891 (set (attr "length")
10892 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10893 (match_test "which_alternative != 1"))
10894 (const_string "16")
10895 (const_string "12")))])
10897 (define_insn "*call_value_indirect_aix<mode>"
10898 [(set (match_operand 0 "" "")
10899 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10900 (match_operand:P 2 "unspec_tls" "")))
10901 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10902 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10903 (set (reg:P TOC_REGNUM)
10904 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
10906 (clobber (reg:P LR_REGNO))]
10907 "DEFAULT_ABI == ABI_AIX"
10909 return rs6000_indirect_call_template (operands, 1);
10911 [(set_attr "type" "jmpreg")
10912 (set (attr "length")
10913 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10914 (match_test "which_alternative != 1"))
10915 (const_string "16")
10916 (const_string "12")))])
10918 ;; Call to indirect functions with the ELFv2 ABI.
10919 ;; Operand0 is the addresss of the function to call
10920 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10922 (define_insn "*call_indirect_elfv2<mode>"
10923 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10925 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10926 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10927 (clobber (reg:P LR_REGNO))]
10928 "DEFAULT_ABI == ABI_ELFv2"
10930 return rs6000_indirect_call_template (operands, 0);
10932 [(set_attr "type" "jmpreg")
10933 (set (attr "length")
10934 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10935 (match_test "which_alternative != 1"))
10936 (const_string "12")
10937 (const_string "8")))])
10939 (define_insn "*call_indirect_pcrel<mode>"
10940 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10942 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10943 (clobber (reg:P LR_REGNO))]
10944 "rs6000_pcrel_p ()"
10946 return rs6000_indirect_call_template (operands, 0);
10948 [(set_attr "type" "jmpreg")
10949 (set (attr "length")
10950 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10951 (match_test "which_alternative != 1"))
10953 (const_string "4")))])
10955 (define_insn "*call_value_indirect_elfv2<mode>"
10956 [(set (match_operand 0 "" "")
10957 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10958 (match_operand:P 2 "unspec_tls" "")))
10959 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10960 (set (reg:P TOC_REGNUM)
10961 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10963 (clobber (reg:P LR_REGNO))]
10964 "DEFAULT_ABI == ABI_ELFv2"
10966 return rs6000_indirect_call_template (operands, 1);
10968 [(set_attr "type" "jmpreg")
10969 (set (attr "length")
10970 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10971 (match_test "which_alternative != 1"))
10972 (const_string "12")
10973 (const_string "8")))])
10975 (define_insn "*call_value_indirect_pcrel<mode>"
10976 [(set (match_operand 0 "" "")
10977 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10978 (match_operand:P 2 "unspec_tls" "")))
10979 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10980 (clobber (reg:P LR_REGNO))]
10981 "rs6000_pcrel_p ()"
10983 return rs6000_indirect_call_template (operands, 1);
10985 [(set_attr "type" "jmpreg")
10986 (set (attr "length")
10987 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10988 (match_test "which_alternative != 1"))
10990 (const_string "4")))])
10992 ;; Call subroutine returning any type.
10993 (define_expand "untyped_call"
10994 [(parallel [(call (match_operand 0 "")
10996 (match_operand 1 "")
10997 (match_operand 2 "")])]
11002 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11004 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
11005 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
11006 emit_insn (gen_blockage ());
11008 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11010 rtx set = XVECEXP (operands[2], 0, i);
11011 emit_move_insn (SET_DEST (set), SET_SRC (set));
11014 /* The optimizer does not know that the call sets the function value
11015 registers we stored in the result block. We avoid problems by
11016 claiming that all hard registers are used and clobbered at this
11018 emit_insn (gen_blockage ());
11023 ;; sibling call patterns
11024 (define_expand "sibcall"
11025 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
11026 (match_operand 1 ""))
11027 (use (match_operand 2 ""))
11032 if (MACHOPIC_INDIRECT)
11033 operands[0] = machopic_indirect_call_target (operands[0]);
11036 gcc_assert (MEM_P (operands[0]));
11037 gcc_assert (CONST_INT_P (operands[1]));
11039 operands[0] = XEXP (operands[0], 0);
11041 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11042 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11043 else if (DEFAULT_ABI == ABI_V4)
11044 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
11045 else if (DEFAULT_ABI == ABI_DARWIN)
11046 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
11048 gcc_unreachable ();
11053 (define_expand "sibcall_value"
11054 [(parallel [(set (match_operand 0 "register_operand")
11055 (call (mem:SI (match_operand 1 "address_operand"))
11056 (match_operand 2 "")))
11057 (use (match_operand 3 ""))
11062 if (MACHOPIC_INDIRECT)
11063 operands[1] = machopic_indirect_call_target (operands[1]);
11066 gcc_assert (MEM_P (operands[1]));
11067 gcc_assert (CONST_INT_P (operands[2]));
11069 operands[1] = XEXP (operands[1], 0);
11071 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11072 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11073 else if (DEFAULT_ABI == ABI_V4)
11074 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
11075 else if (DEFAULT_ABI == ABI_DARWIN)
11076 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
11078 gcc_unreachable ();
11083 (define_insn "*sibcall_local<mode>"
11084 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
11086 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11088 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11090 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11091 output_asm_insn ("crxor 6,6,6", operands);
11093 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11094 output_asm_insn ("creqv 6,6,6", operands);
11096 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11098 [(set_attr "type" "branch")
11099 (set_attr "length" "4,8")])
11101 (define_insn "*sibcall_value_local<mode>"
11102 [(set (match_operand 0 "" "")
11103 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
11104 (match_operand 2)))
11105 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11107 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11109 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11110 output_asm_insn ("crxor 6,6,6", operands);
11112 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11113 output_asm_insn ("creqv 6,6,6", operands);
11115 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11117 [(set_attr "type" "branch")
11118 (set_attr "length" "4,8")])
11120 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11121 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11123 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11125 "DEFAULT_ABI == ABI_V4
11126 || DEFAULT_ABI == ABI_DARWIN"
11128 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11129 output_asm_insn ("crxor 6,6,6", operands);
11131 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11132 output_asm_insn ("creqv 6,6,6", operands);
11134 return rs6000_indirect_sibcall_template (operands, 0);
11136 [(set_attr "type" "jmpreg")
11137 (set (attr "length")
11138 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11139 (match_test "which_alternative != 1"))
11140 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11141 (const_string "12")
11142 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11143 (match_test "which_alternative != 1"))
11144 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11145 (const_string "8")]
11146 (const_string "4")))])
11148 (define_insn "*sibcall_nonlocal_sysv<mode>"
11149 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11151 (use (match_operand 2 "immediate_operand" "O,n"))
11153 "(DEFAULT_ABI == ABI_DARWIN
11154 || DEFAULT_ABI == ABI_V4)
11155 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11157 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11158 output_asm_insn ("crxor 6,6,6", operands);
11160 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11161 output_asm_insn ("creqv 6,6,6", operands);
11163 return rs6000_sibcall_template (operands, 0);
11165 [(set_attr "type" "branch")
11166 (set_attr "length" "4,8")])
11168 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11169 [(set (match_operand 0 "" "")
11170 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11171 (match_operand 2)))
11172 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11174 "DEFAULT_ABI == ABI_V4
11175 || DEFAULT_ABI == ABI_DARWIN"
11177 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11178 output_asm_insn ("crxor 6,6,6", operands);
11180 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11181 output_asm_insn ("creqv 6,6,6", operands);
11183 return rs6000_indirect_sibcall_template (operands, 1);
11185 [(set_attr "type" "jmpreg")
11186 (set (attr "length")
11187 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11188 (match_test "which_alternative != 1"))
11189 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11190 (const_string "12")
11191 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11192 (match_test "which_alternative != 1"))
11193 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11194 (const_string "8")]
11195 (const_string "4")))])
11197 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11198 [(set (match_operand 0 "" "")
11199 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11200 (match_operand 2)))
11201 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11203 "(DEFAULT_ABI == ABI_DARWIN
11204 || DEFAULT_ABI == ABI_V4)
11205 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11207 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11208 output_asm_insn ("crxor 6,6,6", operands);
11210 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11211 output_asm_insn ("creqv 6,6,6", operands);
11213 return rs6000_sibcall_template (operands, 1);
11215 [(set_attr "type" "branch")
11216 (set_attr "length" "4,8")])
11218 ;; AIX ABI sibling call patterns.
11220 (define_insn "*sibcall_aix<mode>"
11221 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11224 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11226 if (which_alternative == 0)
11227 return rs6000_sibcall_template (operands, 0);
11231 [(set_attr "type" "branch")])
11233 (define_insn "*sibcall_value_aix<mode>"
11234 [(set (match_operand 0 "" "")
11235 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11236 (match_operand 2)))
11238 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11240 if (which_alternative == 0)
11241 return rs6000_sibcall_template (operands, 1);
11245 [(set_attr "type" "branch")])
11247 (define_expand "sibcall_epilogue"
11248 [(use (const_int 0))]
11251 if (!TARGET_SCHED_PROLOG)
11252 emit_insn (gen_blockage ());
11253 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11257 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11258 ;; all of memory. This blocks insns from being moved across this point.
11260 (define_insn "blockage"
11261 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11264 [(set_attr "length" "0")])
11266 (define_expand "probe_stack_address"
11267 [(use (match_operand 0 "address_operand"))]
11270 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11271 MEM_VOLATILE_P (operands[0]) = 1;
11274 emit_insn (gen_probe_stack_di (operands[0]));
11276 emit_insn (gen_probe_stack_si (operands[0]));
11280 (define_insn "probe_stack_<mode>"
11281 [(set (match_operand:P 0 "memory_operand" "=m")
11282 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11285 operands[1] = gen_rtx_REG (Pmode, 0);
11286 return "st<wd>%U0%X0 %1,%0";
11288 [(set_attr "type" "store")
11289 (set (attr "update")
11290 (if_then_else (match_operand 0 "update_address_mem")
11291 (const_string "yes")
11292 (const_string "no")))
11293 (set (attr "indexed")
11294 (if_then_else (match_operand 0 "indexed_address_mem")
11295 (const_string "yes")
11296 (const_string "no")))])
11298 (define_insn "probe_stack_range<P:mode>"
11299 [(set (match_operand:P 0 "register_operand" "=&r")
11300 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11301 (match_operand:P 2 "register_operand" "r")
11302 (match_operand:P 3 "register_operand" "r")]
11303 UNSPECV_PROBE_STACK_RANGE))]
11305 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11306 [(set_attr "type" "three")])
11308 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11309 ;; signed & unsigned, and one type of branch.
11311 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11312 ;; insns, and branches.
11314 (define_expand "cbranch<mode>4"
11315 [(use (match_operator 0 "comparison_operator"
11316 [(match_operand:GPR 1 "gpc_reg_operand")
11317 (match_operand:GPR 2 "reg_or_short_operand")]))
11318 (use (match_operand 3))]
11321 /* Take care of the possibility that operands[2] might be negative but
11322 this might be a logical operation. That insn doesn't exist. */
11323 if (CONST_INT_P (operands[2])
11324 && INTVAL (operands[2]) < 0)
11326 operands[2] = force_reg (<MODE>mode, operands[2]);
11327 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11328 GET_MODE (operands[0]),
11329 operands[1], operands[2]);
11332 rs6000_emit_cbranch (<MODE>mode, operands);
11336 (define_expand "cbranch<mode>4"
11337 [(use (match_operator 0 "comparison_operator"
11338 [(match_operand:FP 1 "gpc_reg_operand")
11339 (match_operand:FP 2 "gpc_reg_operand")]))
11340 (use (match_operand 3))]
11343 rs6000_emit_cbranch (<MODE>mode, operands);
11347 (define_expand "cstore<mode>4_signed"
11348 [(use (match_operator 1 "signed_comparison_operator"
11349 [(match_operand:P 2 "gpc_reg_operand")
11350 (match_operand:P 3 "gpc_reg_operand")]))
11351 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11354 enum rtx_code cond_code = GET_CODE (operands[1]);
11356 rtx op0 = operands[0];
11357 rtx op1 = operands[2];
11358 rtx op2 = operands[3];
11360 if (cond_code == GE || cond_code == LT)
11362 cond_code = swap_condition (cond_code);
11363 std::swap (op1, op2);
11366 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11367 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11368 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11370 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11371 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11372 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11374 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11376 if (cond_code == LE)
11377 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11380 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11381 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11382 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11388 (define_expand "cstore<mode>4_unsigned"
11389 [(use (match_operator 1 "unsigned_comparison_operator"
11390 [(match_operand:P 2 "gpc_reg_operand")
11391 (match_operand:P 3 "reg_or_short_operand")]))
11392 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11395 enum rtx_code cond_code = GET_CODE (operands[1]);
11397 rtx op0 = operands[0];
11398 rtx op1 = operands[2];
11399 rtx op2 = operands[3];
11401 if (cond_code == GEU || cond_code == LTU)
11403 cond_code = swap_condition (cond_code);
11404 std::swap (op1, op2);
11407 if (!gpc_reg_operand (op1, <MODE>mode))
11408 op1 = force_reg (<MODE>mode, op1);
11409 if (!reg_or_short_operand (op2, <MODE>mode))
11410 op2 = force_reg (<MODE>mode, op2);
11412 rtx tmp = gen_reg_rtx (<MODE>mode);
11413 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11415 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11416 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11418 if (cond_code == LEU)
11419 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11421 emit_insn (gen_neg<mode>2 (op0, tmp2));
11426 (define_expand "cstore_si_as_di"
11427 [(use (match_operator 1 "unsigned_comparison_operator"
11428 [(match_operand:SI 2 "gpc_reg_operand")
11429 (match_operand:SI 3 "reg_or_short_operand")]))
11430 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11433 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11434 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11436 operands[2] = force_reg (SImode, operands[2]);
11437 operands[3] = force_reg (SImode, operands[3]);
11438 rtx op1 = gen_reg_rtx (DImode);
11439 rtx op2 = gen_reg_rtx (DImode);
11440 convert_move (op1, operands[2], uns_flag);
11441 convert_move (op2, operands[3], uns_flag);
11443 if (cond_code == GT || cond_code == LE)
11445 cond_code = swap_condition (cond_code);
11446 std::swap (op1, op2);
11449 rtx tmp = gen_reg_rtx (DImode);
11450 rtx tmp2 = gen_reg_rtx (DImode);
11451 emit_insn (gen_subdi3 (tmp, op1, op2));
11452 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11458 gcc_unreachable ();
11463 tmp3 = gen_reg_rtx (DImode);
11464 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11468 convert_move (operands[0], tmp3, 1);
11473 (define_expand "cstore<mode>4_signed_imm"
11474 [(use (match_operator 1 "signed_comparison_operator"
11475 [(match_operand:GPR 2 "gpc_reg_operand")
11476 (match_operand:GPR 3 "immediate_operand")]))
11477 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11480 bool invert = false;
11482 enum rtx_code cond_code = GET_CODE (operands[1]);
11484 rtx op0 = operands[0];
11485 rtx op1 = operands[2];
11486 HOST_WIDE_INT val = INTVAL (operands[3]);
11488 if (cond_code == GE || cond_code == GT)
11490 cond_code = reverse_condition (cond_code);
11494 if (cond_code == LE)
11497 rtx tmp = gen_reg_rtx (<MODE>mode);
11498 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11499 rtx x = gen_reg_rtx (<MODE>mode);
11501 emit_insn (gen_and<mode>3 (x, op1, tmp));
11503 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11507 rtx tmp = gen_reg_rtx (<MODE>mode);
11508 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11512 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11513 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11518 (define_expand "cstore<mode>4_unsigned_imm"
11519 [(use (match_operator 1 "unsigned_comparison_operator"
11520 [(match_operand:GPR 2 "gpc_reg_operand")
11521 (match_operand:GPR 3 "immediate_operand")]))
11522 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11525 bool invert = false;
11527 enum rtx_code cond_code = GET_CODE (operands[1]);
11529 rtx op0 = operands[0];
11530 rtx op1 = operands[2];
11531 HOST_WIDE_INT val = INTVAL (operands[3]);
11533 if (cond_code == GEU || cond_code == GTU)
11535 cond_code = reverse_condition (cond_code);
11539 if (cond_code == LEU)
11542 rtx tmp = gen_reg_rtx (<MODE>mode);
11543 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11544 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11545 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11546 rtx x = gen_reg_rtx (<MODE>mode);
11548 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11550 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11554 rtx tmp = gen_reg_rtx (<MODE>mode);
11555 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11559 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11560 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11565 (define_expand "cstore<mode>4"
11566 [(use (match_operator 1 "comparison_operator"
11567 [(match_operand:GPR 2 "gpc_reg_operand")
11568 (match_operand:GPR 3 "reg_or_short_operand")]))
11569 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11572 /* Everything is best done with setbc[r] if available. */
11573 if (TARGET_POWER10 && TARGET_ISEL)
11574 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11576 /* Expanding EQ and NE directly to some machine instructions does not help
11577 but does hurt combine. So don't. */
11578 if (GET_CODE (operands[1]) == EQ)
11579 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11580 else if (<MODE>mode == Pmode
11581 && GET_CODE (operands[1]) == NE)
11582 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11583 else if (GET_CODE (operands[1]) == NE)
11585 rtx tmp = gen_reg_rtx (<MODE>mode);
11586 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11587 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11590 /* If ISEL is fast, expand to it. */
11591 else if (TARGET_ISEL)
11592 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11594 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11595 etc. combinations magically work out just right. */
11596 else if (<MODE>mode == Pmode
11597 && unsigned_comparison_operator (operands[1], VOIDmode))
11598 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11599 operands[2], operands[3]));
11601 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11602 else if (<MODE>mode == SImode && Pmode == DImode)
11603 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11604 operands[2], operands[3]));
11606 /* For signed comparisons against a constant, we can do some simple
11608 else if (signed_comparison_operator (operands[1], VOIDmode)
11609 && CONST_INT_P (operands[3]))
11610 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11611 operands[2], operands[3]));
11613 /* And similarly for unsigned comparisons. */
11614 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11615 && CONST_INT_P (operands[3]))
11616 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11617 operands[2], operands[3]));
11619 /* We also do not want to use mfcr for signed comparisons. */
11620 else if (<MODE>mode == Pmode
11621 && signed_comparison_operator (operands[1], VOIDmode))
11622 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11623 operands[2], operands[3]));
11625 /* Everything else, use the mfcr brute force. */
11627 rs6000_emit_sCOND (<MODE>mode, operands);
11632 (define_expand "cstore<mode>4"
11633 [(use (match_operator 1 "comparison_operator"
11634 [(match_operand:FP 2 "gpc_reg_operand")
11635 (match_operand:FP 3 "gpc_reg_operand")]))
11636 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11639 rs6000_emit_sCOND (<MODE>mode, operands);
11644 (define_expand "stack_protect_set"
11645 [(match_operand 0 "memory_operand")
11646 (match_operand 1 "memory_operand")]
11649 if (rs6000_stack_protector_guard == SSP_TLS)
11651 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11652 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11653 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11654 operands[1] = gen_rtx_MEM (Pmode, addr);
11658 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11660 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11665 (define_insn "stack_protect_setsi"
11666 [(set (match_operand:SI 0 "memory_operand" "=m")
11667 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11668 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11670 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11671 [(set_attr "type" "three")
11672 (set_attr "length" "12")])
11674 ;; We can't use the prefixed attribute here because there are two memory
11675 ;; instructions. We can't split the insn due to the fact that this operation
11676 ;; needs to be done in one piece.
11677 (define_insn "stack_protect_setdi"
11678 [(set (match_operand:DI 0 "memory_operand" "=Y")
11679 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11680 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11683 if (prefixed_memory (operands[1], DImode))
11684 output_asm_insn ("pld %2,%1", operands);
11686 output_asm_insn ("ld%U1%X1 %2,%1", operands);
11688 if (prefixed_memory (operands[0], DImode))
11689 output_asm_insn ("pstd %2,%0", operands);
11691 output_asm_insn ("std%U0%X0 %2,%0", operands);
11695 [(set_attr "type" "three")
11697 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11698 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
11699 ;; the LI 0 at the end.
11700 (set_attr "prefixed" "no")
11701 (set_attr "num_insns" "3")
11702 (set (attr "length")
11703 (cond [(and (match_operand 0 "prefixed_memory")
11704 (match_operand 1 "prefixed_memory"))
11707 (ior (match_operand 0 "prefixed_memory")
11708 (match_operand 1 "prefixed_memory"))
11713 (define_expand "stack_protect_test"
11714 [(match_operand 0 "memory_operand")
11715 (match_operand 1 "memory_operand")
11716 (match_operand 2 "")]
11719 rtx guard = operands[1];
11721 if (rs6000_stack_protector_guard == SSP_TLS)
11723 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11724 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11725 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11726 guard = gen_rtx_MEM (Pmode, addr);
11729 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11730 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11731 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11732 emit_jump_insn (jump);
11737 (define_insn "stack_protect_testsi"
11738 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11739 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11740 (match_operand:SI 2 "memory_operand" "m,m")]
11742 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11743 (clobber (match_scratch:SI 3 "=&r,&r"))]
11746 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11747 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11748 [(set_attr "length" "16,20")])
11750 ;; We can't use the prefixed attribute here because there are two memory
11751 ;; instructions. We can't split the insn due to the fact that this operation
11752 ;; needs to be done in one piece.
11753 (define_insn "stack_protect_testdi"
11754 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11755 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11756 (match_operand:DI 2 "memory_operand" "Y,Y")]
11758 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11759 (clobber (match_scratch:DI 3 "=&r,&r"))]
11762 if (prefixed_memory (operands[1], DImode))
11763 output_asm_insn ("pld %3,%1", operands);
11765 output_asm_insn ("ld%U1%X1 %3,%1", operands);
11767 if (prefixed_memory (operands[2], DImode))
11768 output_asm_insn ("pld %4,%2", operands);
11770 output_asm_insn ("ld%U2%X2 %4,%2", operands);
11772 if (which_alternative == 0)
11773 output_asm_insn ("xor. %3,%3,%4", operands);
11775 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11779 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11780 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
11781 ;; 8 bytes to do the test.
11782 [(set_attr "prefixed" "no")
11783 (set_attr "num_insns" "4,5")
11784 (set (attr "length")
11785 (cond [(and (match_operand 1 "prefixed_memory")
11786 (match_operand 2 "prefixed_memory"))
11787 (if_then_else (eq_attr "alternative" "0")
11791 (ior (match_operand 1 "prefixed_memory")
11792 (match_operand 2 "prefixed_memory"))
11793 (if_then_else (eq_attr "alternative" "0")
11797 (if_then_else (eq_attr "alternative" "0")
11799 (const_int 20))))])
11802 ;; Here are the actual compare insns.
11803 (define_insn "*cmp<mode>_signed"
11804 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11805 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11806 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11808 "cmp<wd>%I2 %0,%1,%2"
11809 [(set_attr "type" "cmp")])
11811 (define_insn "*cmp<mode>_unsigned"
11812 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11813 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11814 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11816 "cmpl<wd>%I2 %0,%1,%2"
11817 [(set_attr "type" "cmp")])
11819 ;; If we are comparing a register for equality with a large constant,
11820 ;; we can do this with an XOR followed by a compare. But this is profitable
11821 ;; only if the large constant is only used for the comparison (and in this
11822 ;; case we already have a register to reuse as scratch).
11824 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11825 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11828 [(set (match_operand:SI 0 "register_operand")
11829 (match_operand:SI 1 "logical_const_operand"))
11830 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11832 (match_operand:SI 2 "logical_const_operand")]))
11833 (set (match_operand:CC 4 "cc_reg_operand")
11834 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11837 (if_then_else (match_operator 6 "equality_operator"
11838 [(match_dup 4) (const_int 0)])
11839 (match_operand 7 "")
11840 (match_operand 8 "")))]
11841 "peep2_reg_dead_p (3, operands[0])
11842 && peep2_reg_dead_p (4, operands[4])
11843 && REGNO (operands[0]) != REGNO (operands[5])"
11844 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11845 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11846 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11849 /* Get the constant we are comparing against, and see what it looks like
11850 when sign-extended from 16 to 32 bits. Then see what constant we could
11851 XOR with SEXTC to get the sign-extended value. */
11852 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11854 operands[1], operands[2]);
11855 HOST_WIDE_INT c = INTVAL (cnst);
11856 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11857 HOST_WIDE_INT xorv = c ^ sextc;
11859 operands[9] = GEN_INT (xorv);
11860 operands[10] = GEN_INT (sextc);
11863 ;; Only need to compare second words if first words equal
11864 (define_insn "*cmp<mode>_internal1"
11865 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11866 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11867 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11868 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11869 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11870 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11871 [(set_attr "type" "fpcompare")
11872 (set_attr "length" "12")])
11874 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11875 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11876 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11877 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11878 (clobber (match_scratch:DF 3 "=d"))
11879 (clobber (match_scratch:DF 4 "=d"))
11880 (clobber (match_scratch:DF 5 "=d"))
11881 (clobber (match_scratch:DF 6 "=d"))
11882 (clobber (match_scratch:DF 7 "=d"))
11883 (clobber (match_scratch:DF 8 "=d"))
11884 (clobber (match_scratch:DF 9 "=d"))
11885 (clobber (match_scratch:DF 10 "=d"))
11886 (clobber (match_scratch:GPR 11 "=b"))]
11887 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11888 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11890 "&& reload_completed"
11891 [(set (match_dup 3) (match_dup 14))
11892 (set (match_dup 4) (match_dup 15))
11893 (set (match_dup 9) (abs:DF (match_dup 5)))
11894 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11895 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11896 (label_ref (match_dup 12))
11898 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11899 (set (pc) (label_ref (match_dup 13)))
11901 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11902 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11903 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11904 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11907 REAL_VALUE_TYPE rv;
11908 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11909 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11911 operands[5] = simplify_gen_subreg (DFmode, operands[1],
11912 <IBM128:MODE>mode, hi_word);
11913 operands[6] = simplify_gen_subreg (DFmode, operands[1],
11914 <IBM128:MODE>mode, lo_word);
11915 operands[7] = simplify_gen_subreg (DFmode, operands[2],
11916 <IBM128:MODE>mode, hi_word);
11917 operands[8] = simplify_gen_subreg (DFmode, operands[2],
11918 <IBM128:MODE>mode, lo_word);
11919 operands[12] = gen_label_rtx ();
11920 operands[13] = gen_label_rtx ();
11922 operands[14] = force_const_mem (DFmode,
11923 const_double_from_real_value (rv, DFmode));
11924 operands[15] = force_const_mem (DFmode,
11925 const_double_from_real_value (dconst0,
11930 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11931 operands[14] = gen_const_mem (DFmode, tocref);
11932 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11933 operands[15] = gen_const_mem (DFmode, tocref);
11934 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11935 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11939 ;; Now we have the scc insns. We can do some combinations because of the
11940 ;; way the machine works.
11942 ;; Note that this is probably faster if we can put an insn between the
11943 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11944 ;; cases the insns below which don't use an intermediate CR field will
11945 ;; be used instead.
11946 (define_insn "set<mode>_cc"
11947 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11948 (match_operator:GPR 1 "scc_comparison_operator"
11949 [(match_operand 2 "cc_reg_operand" "y")
11952 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11953 [(set (attr "type")
11954 (cond [(match_test "TARGET_MFCRF")
11955 (const_string "mfcrf")
11957 (const_string "mfcr")))
11958 (set_attr "length" "8")])
11961 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11962 (define_code_attr UNS [(eq "CC")
11964 (lt "CC") (ltu "CCUNS")
11965 (gt "CC") (gtu "CCUNS")
11966 (le "CC") (leu "CCUNS")
11967 (ge "CC") (geu "CCUNS")])
11968 (define_code_attr UNSu_ [(eq "")
11973 (ge "") (geu "u_")])
11974 (define_code_attr UNSIK [(eq "I")
11979 (ge "I") (geu "K")])
11981 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11982 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11983 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11984 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11985 (clobber (match_scratch:GPR 3 "=r"))
11986 (clobber (match_scratch:GPR 4 "=r"))
11987 (clobber (match_scratch:<UNS> 5 "=y"))]
11988 "!TARGET_POWER10 && TARGET_ISEL
11989 && !(<CODE> == EQ && operands[2] == const0_rtx)
11990 && !(<CODE> == NE && operands[2] == const0_rtx
11991 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11996 rtx_code code = <CODE>;
11997 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11999 HOST_WIDE_INT val = INTVAL (operands[2]);
12000 if (code == LT && val != -0x8000)
12005 if (code == GT && val != 0x7fff)
12010 if (code == LTU && val != 0)
12015 if (code == GTU && val != 0xffff)
12020 operands[2] = GEN_INT (val);
12023 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
12024 operands[3] = const0_rtx;
12027 if (GET_CODE (operands[3]) == SCRATCH)
12028 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
12029 emit_move_insn (operands[3], const0_rtx);
12032 if (GET_CODE (operands[4]) == SCRATCH)
12033 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12034 emit_move_insn (operands[4], const1_rtx);
12036 if (GET_CODE (operands[5]) == SCRATCH)
12037 operands[5] = gen_reg_rtx (<UNS>mode);
12039 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12040 emit_insn (gen_rtx_SET (operands[5], c1));
12042 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12043 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12044 emit_move_insn (operands[0], x);
12048 [(set (attr "cost")
12049 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12051 || <CODE> == LE || <CODE> == GE
12052 || <CODE> == LEU || <CODE> == GEU")
12054 (const_string "10")))])
12056 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12059 (define_expand "eq<mode>3"
12061 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12062 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12063 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12064 (clobber (match_scratch:GPR 3 "=r"))
12065 (clobber (match_scratch:GPR 4 "=r"))])]
12068 if (TARGET_POWER10)
12070 rtx cc = gen_reg_rtx (CCmode);
12071 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12072 emit_insn (gen_rtx_SET (cc, compare));
12073 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
12074 emit_insn (gen_setbc_signed_<mode> (operands[0], eq, cc));
12078 if (TARGET_ISEL && operands[2] != const0_rtx)
12080 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12086 (define_insn_and_split "*eq<mode>3"
12087 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12088 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12089 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12090 (clobber (match_scratch:GPR 3 "=r"))
12091 (clobber (match_scratch:GPR 4 "=r"))]
12092 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12095 [(set (match_dup 4)
12096 (clz:GPR (match_dup 3)))
12098 (lshiftrt:GPR (match_dup 4)
12101 operands[3] = rs6000_emit_eqne (<MODE>mode,
12102 operands[1], operands[2], operands[3]);
12104 if (GET_CODE (operands[4]) == SCRATCH)
12105 operands[4] = gen_reg_rtx (<MODE>mode);
12107 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12109 [(set (attr "length")
12110 (if_then_else (match_test "operands[2] == const0_rtx")
12112 (const_string "12")))])
12114 (define_expand "ne<mode>3"
12116 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12117 (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12118 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12119 (clobber (match_scratch:GPR 3 "=r"))
12120 (clobber (match_scratch:GPR 4 "=r"))
12121 (clobber (reg:GPR CA_REGNO))])]
12124 if (TARGET_POWER10)
12126 rtx cc = gen_reg_rtx (CCmode);
12127 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12128 emit_insn (gen_rtx_SET (cc, compare));
12129 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
12130 emit_insn (gen_setbc_signed_<mode> (operands[0], ne, cc));
12134 if (<MODE>mode != Pmode)
12136 rtx x = gen_reg_rtx (<MODE>mode);
12137 emit_insn (gen_eq<mode>3 (x, operands[1], operands[2]));
12138 emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx));
12142 if (TARGET_ISEL && operands[2] != const0_rtx)
12144 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12150 (define_insn_and_split "*ne<mode>3"
12151 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12152 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12153 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12154 (clobber (match_scratch:P 3 "=r"))
12155 (clobber (match_scratch:P 4 "=r"))
12156 (clobber (reg:P CA_REGNO))]
12157 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12160 [(parallel [(set (match_dup 4)
12161 (plus:P (match_dup 3)
12163 (set (reg:P CA_REGNO)
12164 (ne:P (match_dup 3)
12166 (parallel [(set (match_dup 0)
12167 (plus:P (plus:P (not:P (match_dup 4))
12170 (clobber (reg:P CA_REGNO))])]
12172 operands[3] = rs6000_emit_eqne (<MODE>mode,
12173 operands[1], operands[2], operands[3]);
12175 if (GET_CODE (operands[4]) == SCRATCH)
12176 operands[4] = gen_reg_rtx (<MODE>mode);
12178 [(set (attr "length")
12179 (if_then_else (match_test "operands[2] == const0_rtx")
12181 (const_string "12")))])
12183 (define_insn_and_split "*neg_eq_<mode>"
12184 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12185 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12186 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12187 (clobber (match_scratch:P 3 "=r"))
12188 (clobber (match_scratch:P 4 "=r"))
12189 (clobber (reg:P CA_REGNO))]
12193 [(parallel [(set (match_dup 4)
12194 (plus:P (match_dup 3)
12196 (set (reg:P CA_REGNO)
12197 (ne:P (match_dup 3)
12199 (parallel [(set (match_dup 0)
12200 (plus:P (reg:P CA_REGNO)
12202 (clobber (reg:P CA_REGNO))])]
12204 operands[3] = rs6000_emit_eqne (<MODE>mode,
12205 operands[1], operands[2], operands[3]);
12207 if (GET_CODE (operands[4]) == SCRATCH)
12208 operands[4] = gen_reg_rtx (<MODE>mode);
12210 [(set (attr "length")
12211 (if_then_else (match_test "operands[2] == const0_rtx")
12213 (const_string "12")))])
12215 (define_insn_and_split "*neg_ne_<mode>"
12216 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12217 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12218 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12219 (clobber (match_scratch:P 3 "=r"))
12220 (clobber (match_scratch:P 4 "=r"))
12221 (clobber (reg:P CA_REGNO))]
12225 [(parallel [(set (match_dup 4)
12226 (neg:P (match_dup 3)))
12227 (set (reg:P CA_REGNO)
12228 (eq:P (match_dup 3)
12230 (parallel [(set (match_dup 0)
12231 (plus:P (reg:P CA_REGNO)
12233 (clobber (reg:P CA_REGNO))])]
12235 operands[3] = rs6000_emit_eqne (<MODE>mode,
12236 operands[1], operands[2], operands[3]);
12238 if (GET_CODE (operands[4]) == SCRATCH)
12239 operands[4] = gen_reg_rtx (<MODE>mode);
12241 [(set (attr "length")
12242 (if_then_else (match_test "operands[2] == const0_rtx")
12244 (const_string "12")))])
12246 (define_insn_and_split "*plus_eq_<mode>"
12247 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12248 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12249 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12250 (match_operand:P 3 "gpc_reg_operand" "r")))
12251 (clobber (match_scratch:P 4 "=r"))
12252 (clobber (match_scratch:P 5 "=r"))
12253 (clobber (reg:P CA_REGNO))]
12257 [(parallel [(set (match_dup 5)
12258 (neg:P (match_dup 4)))
12259 (set (reg:P CA_REGNO)
12260 (eq:P (match_dup 4)
12262 (parallel [(set (match_dup 0)
12263 (plus:P (match_dup 3)
12265 (clobber (reg:P CA_REGNO))])]
12267 operands[4] = rs6000_emit_eqne (<MODE>mode,
12268 operands[1], operands[2], operands[4]);
12270 if (GET_CODE (operands[5]) == SCRATCH)
12271 operands[5] = gen_reg_rtx (<MODE>mode);
12273 [(set (attr "length")
12274 (if_then_else (match_test "operands[2] == const0_rtx")
12276 (const_string "12")))])
12278 (define_insn_and_split "*plus_ne_<mode>"
12279 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12280 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12281 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12282 (match_operand:P 3 "gpc_reg_operand" "r")))
12283 (clobber (match_scratch:P 4 "=r"))
12284 (clobber (match_scratch:P 5 "=r"))
12285 (clobber (reg:P CA_REGNO))]
12289 [(parallel [(set (match_dup 5)
12290 (plus:P (match_dup 4)
12292 (set (reg:P CA_REGNO)
12293 (ne:P (match_dup 4)
12295 (parallel [(set (match_dup 0)
12296 (plus:P (match_dup 3)
12298 (clobber (reg:P CA_REGNO))])]
12300 operands[4] = rs6000_emit_eqne (<MODE>mode,
12301 operands[1], operands[2], operands[4]);
12303 if (GET_CODE (operands[5]) == SCRATCH)
12304 operands[5] = gen_reg_rtx (<MODE>mode);
12306 [(set (attr "length")
12307 (if_then_else (match_test "operands[2] == const0_rtx")
12309 (const_string "12")))])
12311 (define_insn_and_split "*minus_eq_<mode>"
12312 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12313 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12314 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12315 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12316 (clobber (match_scratch:P 4 "=r"))
12317 (clobber (match_scratch:P 5 "=r"))
12318 (clobber (reg:P CA_REGNO))]
12322 [(parallel [(set (match_dup 5)
12323 (plus:P (match_dup 4)
12325 (set (reg:P CA_REGNO)
12326 (ne:P (match_dup 4)
12328 (parallel [(set (match_dup 0)
12329 (plus:P (plus:P (match_dup 3)
12332 (clobber (reg:P CA_REGNO))])]
12334 operands[4] = rs6000_emit_eqne (<MODE>mode,
12335 operands[1], operands[2], operands[4]);
12337 if (GET_CODE (operands[5]) == SCRATCH)
12338 operands[5] = gen_reg_rtx (<MODE>mode);
12340 [(set (attr "length")
12341 (if_then_else (match_test "operands[2] == const0_rtx")
12343 (const_string "12")))])
12345 (define_insn_and_split "*minus_ne_<mode>"
12346 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12347 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12348 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12349 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12350 (clobber (match_scratch:P 4 "=r"))
12351 (clobber (match_scratch:P 5 "=r"))
12352 (clobber (reg:P CA_REGNO))]
12356 [(parallel [(set (match_dup 5)
12357 (neg:P (match_dup 4)))
12358 (set (reg:P CA_REGNO)
12359 (eq:P (match_dup 4)
12361 (parallel [(set (match_dup 0)
12362 (plus:P (plus:P (match_dup 3)
12365 (clobber (reg:P CA_REGNO))])]
12367 operands[4] = rs6000_emit_eqne (<MODE>mode,
12368 operands[1], operands[2], operands[4]);
12370 if (GET_CODE (operands[5]) == SCRATCH)
12371 operands[5] = gen_reg_rtx (<MODE>mode);
12373 [(set (attr "length")
12374 (if_then_else (match_test "operands[2] == const0_rtx")
12376 (const_string "12")))])
12378 (define_insn_and_split "*eqsi3_ext<mode>"
12379 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12380 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12381 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12382 (clobber (match_scratch:SI 3 "=r"))
12383 (clobber (match_scratch:SI 4 "=r"))]
12387 [(set (match_dup 4)
12388 (clz:SI (match_dup 3)))
12391 (lshiftrt:SI (match_dup 4)
12394 operands[3] = rs6000_emit_eqne (SImode,
12395 operands[1], operands[2], operands[3]);
12397 if (GET_CODE (operands[4]) == SCRATCH)
12398 operands[4] = gen_reg_rtx (SImode);
12400 [(set (attr "length")
12401 (if_then_else (match_test "operands[2] == const0_rtx")
12403 (const_string "12")))])
12405 (define_insn_and_split "*nesi3_ext<mode>"
12406 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12407 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12408 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12409 (clobber (match_scratch:SI 3 "=r"))
12410 (clobber (match_scratch:SI 4 "=r"))
12411 (clobber (match_scratch:EXTSI 5 "=r"))]
12415 [(set (match_dup 4)
12416 (clz:SI (match_dup 3)))
12419 (lshiftrt:SI (match_dup 4)
12422 (xor:EXTSI (match_dup 5)
12425 operands[3] = rs6000_emit_eqne (SImode,
12426 operands[1], operands[2], operands[3]);
12428 if (GET_CODE (operands[4]) == SCRATCH)
12429 operands[4] = gen_reg_rtx (SImode);
12430 if (GET_CODE (operands[5]) == SCRATCH)
12431 operands[5] = gen_reg_rtx (<MODE>mode);
12433 [(set (attr "length")
12434 (if_then_else (match_test "operands[2] == const0_rtx")
12435 (const_string "12")
12436 (const_string "16")))])
12439 (define_code_iterator fp_rev [ordered ne unle unge])
12440 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12442 (define_insn_and_split "*<code><mode>_cc"
12443 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12444 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12446 "!flag_finite_math_only"
12451 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12452 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
12453 rtx tmp = gen_reg_rtx (<MODE>mode);
12454 emit_move_insn (tmp, eq);
12455 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12458 [(set_attr "length" "12")])
12460 (define_insn_and_split "*<code><mode>_cc"
12461 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12462 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12464 "!flag_finite_math_only"
12469 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
12471 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12474 [(set_attr "length" "12")])
12476 ;; Conditional branches.
12477 ;; These either are a single bc insn, or a bc around a b.
12479 (define_insn "*cbranch"
12481 (if_then_else (match_operator 1 "branch_comparison_operator"
12482 [(match_operand 2 "cc_reg_operand" "y")
12484 (label_ref (match_operand 0))
12488 return output_cbranch (operands[1], "%l0", 0, insn);
12490 [(set_attr "type" "branch")
12491 (set (attr "length")
12492 (if_then_else (and (ge (minus (match_dup 0) (pc))
12493 (const_int -32768))
12494 (lt (minus (match_dup 0) (pc))
12495 (const_int 32764)))
12499 (define_insn_and_split "*cbranch_2insn"
12501 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
12502 [(match_operand 2 "cc_reg_operand" "y")
12504 (label_ref (match_operand 0))
12506 "!flag_finite_math_only"
12511 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
12513 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
12515 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
12516 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12517 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12518 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12522 profile_probability prob
12523 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
12525 add_reg_br_prob_note (get_last_insn (), prob);
12530 [(set_attr "type" "branch")
12531 (set (attr "length")
12532 (if_then_else (and (ge (minus (match_dup 0) (pc))
12533 (const_int -32764))
12534 (lt (minus (match_dup 0) (pc))
12535 (const_int 32760)))
12539 ;; Conditional return.
12540 (define_insn "*creturn"
12542 (if_then_else (match_operator 0 "branch_comparison_operator"
12543 [(match_operand 1 "cc_reg_operand" "y")
12549 return output_cbranch (operands[0], NULL, 0, insn);
12551 [(set_attr "type" "jmpreg")])
12553 ;; Logic on condition register values.
12555 ; This pattern matches things like
12556 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12557 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12559 ; which are generated by the branch logic.
12560 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12562 (define_insn "@cceq_ior_compare_<mode>"
12563 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12564 (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
12565 [(match_operator:GPR 2
12566 "branch_positive_comparison_operator"
12568 "cc_reg_operand" "y,y")
12570 (match_operator:GPR 4
12571 "branch_positive_comparison_operator"
12573 "cc_reg_operand" "0,y")
12577 "cr%q1 %E0,%j2,%j4"
12578 [(set_attr "type" "cr_logical")
12579 (set_attr "cr_logical_3op" "no,yes")])
12581 ; Why is the constant -1 here, but 1 in the previous pattern?
12582 ; Because ~1 has all but the low bit set.
12583 (define_insn "cceq_ior_compare_complement"
12584 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12585 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12586 [(not:SI (match_operator:SI 2
12587 "branch_positive_comparison_operator"
12589 "cc_reg_operand" "y,y")
12591 (match_operator:SI 4
12592 "branch_positive_comparison_operator"
12594 "cc_reg_operand" "0,y")
12598 "cr%q1 %E0,%j2,%j4"
12599 [(set_attr "type" "cr_logical")
12600 (set_attr "cr_logical_3op" "no,yes")])
12602 (define_insn "@cceq_rev_compare_<mode>"
12603 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12604 (compare:CCEQ (match_operator:GPR 1
12605 "branch_positive_comparison_operator"
12607 "cc_reg_operand" "0,y")
12612 [(set_attr "type" "cr_logical")
12613 (set_attr "cr_logical_3op" "no,yes")])
12615 ;; If we are comparing the result of two comparisons, this can be done
12616 ;; using creqv or crxor.
12618 (define_insn_and_split ""
12619 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12620 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12621 [(match_operand 2 "cc_reg_operand" "y")
12623 (match_operator 3 "branch_comparison_operator"
12624 [(match_operand 4 "cc_reg_operand" "y")
12629 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12632 int positive_1, positive_2;
12634 positive_1 = branch_positive_comparison_operator (operands[1],
12635 GET_MODE (operands[1]));
12636 positive_2 = branch_positive_comparison_operator (operands[3],
12637 GET_MODE (operands[3]));
12640 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12641 GET_CODE (operands[1])),
12643 operands[2], const0_rtx);
12644 else if (GET_MODE (operands[1]) != SImode)
12645 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12646 operands[2], const0_rtx);
12649 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12650 GET_CODE (operands[3])),
12652 operands[4], const0_rtx);
12653 else if (GET_MODE (operands[3]) != SImode)
12654 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12655 operands[4], const0_rtx);
12657 if (positive_1 == positive_2)
12659 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12660 operands[5] = constm1_rtx;
12664 operands[5] = const1_rtx;
12668 ;; Unconditional branch and return.
12670 (define_insn "jump"
12672 (label_ref (match_operand 0)))]
12675 [(set_attr "type" "branch")])
12677 (define_insn "<return_str>return"
12681 [(set_attr "type" "jmpreg")])
12683 (define_expand "indirect_jump"
12684 [(set (pc) (match_operand 0 "register_operand"))]
12687 if (!rs6000_speculate_indirect_jumps) {
12688 rtx ccreg = gen_reg_rtx (CCmode);
12689 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12694 (define_insn "*indirect_jump<mode>"
12696 (match_operand:P 0 "register_operand" "c,*l"))]
12697 "rs6000_speculate_indirect_jumps"
12699 [(set_attr "type" "jmpreg")])
12701 (define_insn "@indirect_jump<mode>_nospec"
12702 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12703 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12704 "!rs6000_speculate_indirect_jumps"
12705 "crset %E1\;beq%T0- %1\;b $"
12706 [(set_attr "type" "jmpreg")
12707 (set_attr "length" "12")])
12709 ;; Table jump for switch statements:
12710 (define_expand "tablejump"
12711 [(use (match_operand 0))
12712 (use (label_ref (match_operand 1)))]
12715 if (rs6000_speculate_indirect_jumps)
12716 emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
12719 rtx ccreg = gen_reg_rtx (CCmode);
12722 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12724 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12725 emit_jump_insn (jump);
12730 (define_expand "@tablejump<mode>_normal"
12731 [(use (match_operand:SI 0))
12732 (use (match_operand:P 1))]
12733 "rs6000_speculate_indirect_jumps"
12735 rtx off = force_reg (SImode, operands[0]);
12736 if (<MODE>mode != SImode)
12738 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
12739 off = gen_reg_rtx (Pmode);
12740 emit_move_insn (off, src);
12743 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
12744 rtx addr = gen_reg_rtx (Pmode);
12746 emit_insn (gen_add<mode>3 (addr, off, lab));
12747 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
12751 (define_expand "@tablejump<mode>_nospec"
12752 [(use (match_operand:SI 0))
12753 (use (match_operand:P 1))
12754 (use (match_operand:CC 2))]
12755 "!rs6000_speculate_indirect_jumps"
12757 rtx off = force_reg (SImode, operands[0]);
12758 if (<MODE>mode != SImode)
12760 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
12761 off = gen_reg_rtx (Pmode);
12762 emit_move_insn (off, src);
12765 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
12766 rtx addr = gen_reg_rtx (Pmode);
12768 emit_insn (gen_add<mode>3 (addr, off, lab));
12769 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
12774 (define_insn "@tablejump<mode>_insn_normal"
12776 (match_operand:P 0 "register_operand" "c,*l"))
12777 (use (label_ref (match_operand 1)))]
12778 "rs6000_speculate_indirect_jumps"
12780 [(set_attr "type" "jmpreg")])
12782 (define_insn "@tablejump<mode>_insn_nospec"
12784 (match_operand:P 0 "register_operand" "c,*l"))
12785 (use (label_ref (match_operand 1)))
12786 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12787 "!rs6000_speculate_indirect_jumps"
12788 "crset %E2\;beq%T0- %2\;b $"
12789 [(set_attr "type" "jmpreg")
12790 (set_attr "length" "12")])
12793 [(unspec [(const_int 0)] UNSPEC_NOP)]
12797 (define_insn "group_ending_nop"
12798 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12801 operands[0] = gen_rtx_REG (Pmode,
12802 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12803 return "ori %0,%0,0";
12806 (define_insn "speculation_barrier"
12807 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12810 operands[0] = gen_rtx_REG (Pmode, 31);
12811 return "ori %0,%0,0";
12814 ;; Define the subtract-one-and-jump insns, starting with the template
12815 ;; so loop.c knows what to generate.
12817 (define_expand "doloop_end"
12818 [(use (match_operand 0)) ; loop pseudo
12819 (use (match_operand 1))] ; label
12822 if (GET_MODE (operands[0]) != Pmode)
12825 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12829 (define_expand "@ctr<mode>"
12830 [(parallel [(set (pc)
12831 (if_then_else (ne (match_operand:P 0 "register_operand")
12833 (label_ref (match_operand 1))
12836 (plus:P (match_dup 0)
12838 (clobber (match_scratch:CC 2))
12839 (clobber (match_scratch:P 3))])]
12843 ;; We need to be able to do this for any operand, including MEM, or we
12844 ;; will cause reload to blow up since we don't allow output reloads on
12846 ;; For the length attribute to be calculated correctly, the
12847 ;; label MUST be operand 0.
12848 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12849 ;; the ctr<mode> insns.
12851 (define_code_iterator eqne [eq ne])
12852 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12853 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12855 (define_insn "<bd>_<mode>"
12857 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12859 (label_ref (match_operand 0))
12861 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12862 (plus:P (match_dup 1)
12864 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12865 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12868 if (which_alternative != 0)
12870 else if (get_attr_length (insn) == 4)
12873 return "<bd_neg> $+8\;b %l0";
12875 [(set_attr "type" "branch")
12876 (set_attr_alternative "length"
12877 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12878 (const_int -32768))
12879 (lt (minus (match_dup 0) (pc))
12880 (const_int 32764)))
12883 (const_string "16")
12884 (const_string "20")
12885 (const_string "20")])])
12887 ;; Now the splitter if we could not allocate the CTR register
12890 (if_then_else (match_operator 2 "comparison_operator"
12891 [(match_operand:P 1 "gpc_reg_operand")
12894 (match_operand 6)))
12895 (set (match_operand:P 0 "nonimmediate_operand")
12896 (plus:P (match_dup 1)
12898 (clobber (match_scratch:CC 3))
12899 (clobber (match_scratch:P 4))]
12902 (if_then_else (match_dup 7)
12906 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12908 emit_insn (gen_rtx_SET (operands[3],
12909 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12910 if (int_reg_operand (operands[0], <MODE>mode))
12911 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12914 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12915 emit_move_insn (operands[0], operands[4]);
12917 /* No DONE so branch comes from the pattern. */
12920 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12921 ;; Note that in the case of long branches we have to decompose this into
12922 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12923 ;; and the CR bit, which means there is no way to conveniently invert the
12924 ;; comparison as is done with plain bdnz/bdz.
12926 (define_insn "<bd>tf_<mode>"
12930 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12932 (match_operator 3 "branch_comparison_operator"
12933 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12935 (label_ref (match_operand 0))
12937 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12938 (plus:P (match_dup 1)
12940 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12941 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12942 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12945 if (which_alternative != 0)
12947 else if (get_attr_length (insn) == 4)
12949 if (branch_positive_comparison_operator (operands[3],
12950 GET_MODE (operands[3])))
12951 return "<bd>t %j3,%l0";
12953 return "<bd>f %j3,%l0";
12957 static char seq[96];
12958 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12959 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12963 [(set_attr "type" "branch")
12964 (set_attr_alternative "length"
12965 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12966 (const_int -32768))
12967 (lt (minus (match_dup 0) (pc))
12968 (const_int 32764)))
12971 (const_string "16")
12972 (const_string "20")
12973 (const_string "20")])])
12975 ;; Now the splitter if we could not allocate the CTR register
12980 (match_operator 1 "comparison_operator"
12981 [(match_operand:P 0 "gpc_reg_operand")
12983 (match_operator 3 "branch_comparison_operator"
12984 [(match_operand 2 "cc_reg_operand")
12987 (match_operand 5)))
12988 (set (match_operand:P 6 "nonimmediate_operand")
12989 (plus:P (match_dup 0)
12991 (clobber (match_scratch:P 7))
12992 (clobber (match_scratch:CC 8))
12993 (clobber (match_scratch:CCEQ 9))]
12997 rtx ctr = operands[0];
12998 rtx ctrcmp = operands[1];
12999 rtx ccin = operands[2];
13000 rtx cccmp = operands[3];
13001 rtx dst1 = operands[4];
13002 rtx dst2 = operands[5];
13003 rtx ctrout = operands[6];
13004 rtx ctrtmp = operands[7];
13005 enum rtx_code cmpcode = GET_CODE (ctrcmp);
13006 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
13008 cmpcode = reverse_condition (cmpcode);
13009 /* Generate crand/crandc here. */
13010 emit_insn (gen_rtx_SET (operands[8],
13011 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
13012 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
13014 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
13016 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
13017 operands[8], cccmp, ccin));
13019 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
13020 operands[8], cccmp, ccin));
13021 if (int_reg_operand (ctrout, <MODE>mode))
13022 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
13025 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
13026 emit_move_insn (ctrout, ctrtmp);
13028 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
13029 emit_jump_insn (gen_rtx_SET (pc_rtx,
13030 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
13036 (define_insn "trap"
13037 [(trap_if (const_int 1) (const_int 0))]
13040 [(set_attr "type" "trap")])
13042 (define_expand "ctrap<mode>4"
13043 [(trap_if (match_operator 0 "ordered_comparison_operator"
13044 [(match_operand:GPR 1 "register_operand")
13045 (match_operand:GPR 2 "reg_or_short_operand")])
13046 (match_operand 3 "zero_constant" ""))]
13051 [(trap_if (match_operator 0 "ordered_comparison_operator"
13052 [(match_operand:GPR 1 "register_operand" "r")
13053 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13056 "t<wd>%V0%I2 %1,%2"
13057 [(set_attr "type" "trap")])
13059 ;; Insns related to generating the function prologue and epilogue.
13061 (define_expand "prologue"
13062 [(use (const_int 0))]
13065 rs6000_emit_prologue ();
13066 if (!TARGET_SCHED_PROLOG)
13067 emit_insn (gen_blockage ());
13071 (define_insn "*movesi_from_cr_one"
13072 [(match_parallel 0 "mfcr_operation"
13073 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13074 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13075 (match_operand 3 "immediate_operand" "n")]
13076 UNSPEC_MOVESI_FROM_CR))])]
13081 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13083 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13084 operands[4] = GEN_INT (mask);
13085 output_asm_insn ("mfcr %1,%4", operands);
13089 [(set_attr "type" "mfcrf")])
13091 ;; Don't include the volatile CRs since their values are not used wrt CR save
13092 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13093 ;; prologue past an insn (early exit test) that defines a register used in the
13095 (define_insn "prologue_movesi_from_cr"
13096 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13097 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13098 (reg:CC CR4_REGNO)]
13099 UNSPEC_MOVESI_FROM_CR))]
13102 [(set_attr "type" "mfcr")])
13104 (define_insn "*crsave"
13105 [(match_parallel 0 "crsave_operation"
13106 [(set (match_operand:SI 1 "memory_operand" "=m")
13107 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13110 [(set_attr "type" "store")])
13112 (define_insn "*stmw"
13113 [(match_parallel 0 "stmw_operation"
13114 [(set (match_operand:SI 1 "memory_operand" "=m")
13115 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13118 [(set_attr "type" "store")
13119 (set_attr "update" "yes")
13120 (set_attr "indexed" "yes")])
13122 ; The following comment applies to:
13126 ; return_and_restore_gpregs*
13127 ; return_and_restore_fpregs*
13128 ; return_and_restore_fpregs_aix*
13130 ; The out-of-line save / restore functions expects one input argument.
13131 ; Since those are not standard call_insn's, we must avoid using
13132 ; MATCH_OPERAND for that argument. That way the register rename
13133 ; optimization will not try to rename this register.
13134 ; Each pattern is repeated for each possible register number used in
13135 ; various ABIs (r11, r1, and for some functions r12)
13137 (define_insn "*save_gpregs_<mode>_r11"
13138 [(match_parallel 0 "any_parallel_operand"
13139 [(clobber (reg:P LR_REGNO))
13140 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13142 (set (match_operand:P 2 "memory_operand" "=m")
13143 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13146 [(set_attr "type" "branch")])
13148 (define_insn "*save_gpregs_<mode>_r12"
13149 [(match_parallel 0 "any_parallel_operand"
13150 [(clobber (reg:P LR_REGNO))
13151 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13153 (set (match_operand:P 2 "memory_operand" "=m")
13154 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13157 [(set_attr "type" "branch")])
13159 (define_insn "*save_gpregs_<mode>_r1"
13160 [(match_parallel 0 "any_parallel_operand"
13161 [(clobber (reg:P LR_REGNO))
13162 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13164 (set (match_operand:P 2 "memory_operand" "=m")
13165 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13168 [(set_attr "type" "branch")])
13170 (define_insn "*save_fpregs_<mode>_r11"
13171 [(match_parallel 0 "any_parallel_operand"
13172 [(clobber (reg:P LR_REGNO))
13173 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13175 (set (match_operand:DF 2 "memory_operand" "=m")
13176 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13179 [(set_attr "type" "branch")])
13181 (define_insn "*save_fpregs_<mode>_r12"
13182 [(match_parallel 0 "any_parallel_operand"
13183 [(clobber (reg:P LR_REGNO))
13184 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13186 (set (match_operand:DF 2 "memory_operand" "=m")
13187 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13190 [(set_attr "type" "branch")])
13192 (define_insn "*save_fpregs_<mode>_r1"
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:DF 2 "memory_operand" "=m")
13198 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13201 [(set_attr "type" "branch")])
13203 ; This is to explain that changes to the stack pointer should
13204 ; not be moved over loads from or stores to stack memory.
13205 (define_insn "stack_tie"
13206 [(match_parallel 0 "tie_operand"
13207 [(set (mem:BLK (reg 1)) (const_int 0))])]
13210 [(set_attr "length" "0")])
13212 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13213 ; stay behind all restores from the stack, it cannot be reordered to before
13214 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13215 (define_insn "stack_restore_tie"
13216 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13217 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13218 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13219 (set (mem:BLK (scratch)) (const_int 0))]
13224 [(set_attr "type" "*,add")])
13226 (define_expand "epilogue"
13227 [(use (const_int 0))]
13230 if (!TARGET_SCHED_PROLOG)
13231 emit_insn (gen_blockage ());
13232 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13236 ; On some processors, doing the mtcrf one CC register at a time is
13237 ; faster (like on the 604e). On others, doing them all at once is
13238 ; faster; for instance, on the 601 and 750.
13240 (define_expand "movsi_to_cr_one"
13241 [(set (match_operand:CC 0 "cc_reg_operand")
13242 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13243 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13245 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13247 (define_insn "*movsi_to_cr"
13248 [(match_parallel 0 "mtcrf_operation"
13249 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13250 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13251 (match_operand 3 "immediate_operand" "n")]
13252 UNSPEC_MOVESI_TO_CR))])]
13257 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13258 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13259 operands[4] = GEN_INT (mask);
13260 return "mtcrf %4,%2";
13262 [(set_attr "type" "mtcr")])
13264 (define_insn "*mtcrfsi"
13265 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13266 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13267 (match_operand 2 "immediate_operand" "n")]
13268 UNSPEC_MOVESI_TO_CR))]
13269 "REG_P (operands[0])
13270 && CR_REGNO_P (REGNO (operands[0]))
13271 && CONST_INT_P (operands[2])
13272 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13274 [(set_attr "type" "mtcr")])
13276 ; The load-multiple instructions have similar properties.
13277 ; Note that "load_multiple" is a name known to the machine-independent
13278 ; code that actually corresponds to the PowerPC load-string.
13280 (define_insn "*lmw"
13281 [(match_parallel 0 "lmw_operation"
13282 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13283 (match_operand:SI 2 "memory_operand" "m"))])]
13286 [(set_attr "type" "load")
13287 (set_attr "update" "yes")
13288 (set_attr "indexed" "yes")
13289 (set_attr "cell_micro" "always")])
13291 ; FIXME: "any_parallel_operand" is a bit flexible...
13293 ; The following comment applies to:
13297 ; return_and_restore_gpregs*
13298 ; return_and_restore_fpregs*
13299 ; return_and_restore_fpregs_aix*
13301 ; The out-of-line save / restore functions expects one input argument.
13302 ; Since those are not standard call_insn's, we must avoid using
13303 ; MATCH_OPERAND for that argument. That way the register rename
13304 ; optimization will not try to rename this register.
13305 ; Each pattern is repeated for each possible register number used in
13306 ; various ABIs (r11, r1, and for some functions r12)
13308 (define_insn "*restore_gpregs_<mode>_r11"
13309 [(match_parallel 0 "any_parallel_operand"
13310 [(clobber (reg:P LR_REGNO))
13311 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13313 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13314 (match_operand:P 3 "memory_operand" "m"))])]
13317 [(set_attr "type" "branch")])
13319 (define_insn "*restore_gpregs_<mode>_r12"
13320 [(match_parallel 0 "any_parallel_operand"
13321 [(clobber (reg:P LR_REGNO))
13322 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13324 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13325 (match_operand:P 3 "memory_operand" "m"))])]
13328 [(set_attr "type" "branch")])
13330 (define_insn "*restore_gpregs_<mode>_r1"
13331 [(match_parallel 0 "any_parallel_operand"
13332 [(clobber (reg:P LR_REGNO))
13333 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13335 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13336 (match_operand:P 3 "memory_operand" "m"))])]
13339 [(set_attr "type" "branch")])
13341 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13342 [(match_parallel 0 "any_parallel_operand"
13344 (clobber (reg:P LR_REGNO))
13345 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13347 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13348 (match_operand:P 3 "memory_operand" "m"))])]
13351 [(set_attr "type" "branch")])
13353 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13354 [(match_parallel 0 "any_parallel_operand"
13356 (clobber (reg:P LR_REGNO))
13357 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13359 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13360 (match_operand:P 3 "memory_operand" "m"))])]
13363 [(set_attr "type" "branch")])
13365 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13366 [(match_parallel 0 "any_parallel_operand"
13368 (clobber (reg:P LR_REGNO))
13369 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13371 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13372 (match_operand:P 3 "memory_operand" "m"))])]
13375 [(set_attr "type" "branch")])
13377 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13378 [(match_parallel 0 "any_parallel_operand"
13380 (clobber (reg:P LR_REGNO))
13381 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13383 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13384 (match_operand:DF 3 "memory_operand" "m"))])]
13387 [(set_attr "type" "branch")])
13389 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13390 [(match_parallel 0 "any_parallel_operand"
13392 (clobber (reg:P LR_REGNO))
13393 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13395 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13396 (match_operand:DF 3 "memory_operand" "m"))])]
13399 [(set_attr "type" "branch")])
13401 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13402 [(match_parallel 0 "any_parallel_operand"
13404 (clobber (reg:P LR_REGNO))
13405 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13407 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13408 (match_operand:DF 3 "memory_operand" "m"))])]
13411 [(set_attr "type" "branch")])
13413 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13414 [(match_parallel 0 "any_parallel_operand"
13416 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13418 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13419 (match_operand:DF 3 "memory_operand" "m"))])]
13422 [(set_attr "type" "branch")])
13424 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13425 [(match_parallel 0 "any_parallel_operand"
13427 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13429 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13430 (match_operand:DF 3 "memory_operand" "m"))])]
13433 [(set_attr "type" "branch")])
13435 ; This is used in compiling the unwind routines.
13436 (define_expand "eh_return"
13437 [(use (match_operand 0 "general_operand"))]
13440 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13444 ; We can't expand this before we know where the link register is stored.
13445 (define_insn_and_split "@eh_set_lr_<mode>"
13446 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13447 (clobber (match_scratch:P 1 "=&b"))]
13453 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13457 (define_insn "prefetch"
13458 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13459 (match_operand:SI 1 "const_int_operand" "n")
13460 (match_operand:SI 2 "const_int_operand" "n"))]
13465 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13466 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13467 The AIX assembler does not support the three operand form of dcbt
13468 and dcbtst on Power 7 (-mpwr7). */
13469 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13471 if (REG_P (operands[0]))
13473 if (INTVAL (operands[1]) == 0)
13474 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13476 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13480 if (INTVAL (operands[1]) == 0)
13481 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13483 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13486 [(set_attr "type" "load")])
13488 ;; Handle -fsplit-stack.
13490 (define_expand "split_stack_prologue"
13494 rs6000_expand_split_stack_prologue ();
13498 (define_expand "load_split_stack_limit"
13499 [(set (match_operand 0)
13500 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13503 emit_insn (gen_rtx_SET (operands[0],
13504 gen_rtx_UNSPEC (Pmode,
13505 gen_rtvec (1, const0_rtx),
13506 UNSPEC_STACK_CHECK)));
13510 (define_insn "load_split_stack_limit_di"
13511 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13512 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13514 "ld %0,-0x7040(13)"
13515 [(set_attr "type" "load")
13516 (set_attr "update" "no")
13517 (set_attr "indexed" "no")])
13519 (define_insn "load_split_stack_limit_si"
13520 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13521 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13523 "lwz %0,-0x7020(2)"
13524 [(set_attr "type" "load")
13525 (set_attr "update" "no")
13526 (set_attr "indexed" "no")])
13528 ;; A return instruction which the middle-end doesn't see.
13529 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13530 ;; after the call to __morestack.
13531 (define_insn "split_stack_return"
13532 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13535 [(set_attr "type" "jmpreg")])
13537 ;; If there are operand 0 bytes available on the stack, jump to
13539 (define_expand "split_stack_space_check"
13540 [(set (match_dup 2)
13541 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13543 (minus (reg STACK_POINTER_REGNUM)
13544 (match_operand 0)))
13545 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13546 (set (pc) (if_then_else
13547 (geu (match_dup 4) (const_int 0))
13548 (label_ref (match_operand 1))
13552 rs6000_split_stack_space_check (operands[0], operands[1]);
13556 (define_insn "bpermd_<mode>"
13557 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13558 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13559 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13562 [(set_attr "type" "popcnt")])
13565 ;; Builtin fma support. Handle
13566 ;; Note that the conditions for expansion are in the FMA_F iterator.
13568 (define_expand "fma<mode>4"
13569 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13571 (match_operand:FMA_F 1 "gpc_reg_operand")
13572 (match_operand:FMA_F 2 "gpc_reg_operand")
13573 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13577 (define_insn "*fma<mode>4_fpr"
13578 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13580 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13581 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13582 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13583 "TARGET_HARD_FLOAT"
13585 fmadd<s> %0,%1,%2,%3
13586 xsmadda<sd>p %x0,%x1,%x2
13587 xsmaddm<sd>p %x0,%x1,%x3"
13588 [(set_attr "type" "fp")
13589 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13591 ; Altivec only has fma and nfms.
13592 (define_expand "fms<mode>4"
13593 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13595 (match_operand:FMA_F 1 "gpc_reg_operand")
13596 (match_operand:FMA_F 2 "gpc_reg_operand")
13597 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13598 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13601 (define_insn "*fms<mode>4_fpr"
13602 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13604 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13605 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13606 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13607 "TARGET_HARD_FLOAT"
13609 fmsub<s> %0,%1,%2,%3
13610 xsmsuba<sd>p %x0,%x1,%x2
13611 xsmsubm<sd>p %x0,%x1,%x3"
13612 [(set_attr "type" "fp")
13613 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13615 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13616 (define_expand "fnma<mode>4"
13617 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13620 (match_operand:FMA_F 1 "gpc_reg_operand")
13621 (match_operand:FMA_F 2 "gpc_reg_operand")
13622 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13623 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13626 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13627 (define_expand "fnms<mode>4"
13628 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13631 (match_operand:FMA_F 1 "gpc_reg_operand")
13632 (match_operand:FMA_F 2 "gpc_reg_operand")
13633 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13634 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13637 ; Not an official optab name, but used from builtins.
13638 (define_expand "nfma<mode>4"
13639 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13642 (match_operand:FMA_F 1 "gpc_reg_operand")
13643 (match_operand:FMA_F 2 "gpc_reg_operand")
13644 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13645 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13648 (define_insn "*nfma<mode>4_fpr"
13649 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13652 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13653 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13654 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13655 "TARGET_HARD_FLOAT"
13657 fnmadd<s> %0,%1,%2,%3
13658 xsnmadda<sd>p %x0,%x1,%x2
13659 xsnmaddm<sd>p %x0,%x1,%x3"
13660 [(set_attr "type" "fp")
13661 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13663 ; Not an official optab name, but used from builtins.
13664 (define_expand "nfms<mode>4"
13665 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13668 (match_operand:FMA_F 1 "gpc_reg_operand")
13669 (match_operand:FMA_F 2 "gpc_reg_operand")
13670 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13674 (define_insn "*nfmssf4_fpr"
13675 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13678 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13679 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13681 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13682 "TARGET_HARD_FLOAT"
13684 fnmsub<s> %0,%1,%2,%3
13685 xsnmsuba<sd>p %x0,%x1,%x2
13686 xsnmsubm<sd>p %x0,%x1,%x3"
13687 [(set_attr "type" "fp")
13688 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13690 (define_expand "rs6000_get_timebase"
13691 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13694 if (TARGET_POWERPC64)
13695 emit_insn (gen_rs6000_mftb_di (operands[0]));
13697 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13701 (define_insn "rs6000_get_timebase_ppc32"
13702 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13703 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13704 (clobber (match_scratch:SI 1 "=r"))
13705 (clobber (match_scratch:CC 2 "=y"))]
13706 "!TARGET_POWERPC64"
13708 if (WORDS_BIG_ENDIAN)
13711 return "mfspr %0,269\;"
13719 return "mftbu %0\;"
13728 return "mfspr %L0,269\;"
13736 return "mftbu %L0\;"
13743 [(set_attr "length" "20")])
13745 (define_insn "rs6000_mftb_<mode>"
13746 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13747 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13751 return "mfspr %0,268";
13757 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13758 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13759 (define_insn "rs6000_mffsl_hw"
13760 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13761 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13762 "TARGET_HARD_FLOAT"
13765 (define_expand "rs6000_mffsl"
13766 [(set (match_operand:DF 0 "gpc_reg_operand")
13767 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13768 "TARGET_HARD_FLOAT"
13770 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13771 otherwise fall back to the older mffs instruction to emulate the mffsl
13774 if (!TARGET_P9_MISC)
13776 rtx tmp1 = gen_reg_rtx (DFmode);
13778 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13779 instruction using the mffs instruction and masking the result. */
13780 emit_insn (gen_rs6000_mffs (tmp1));
13782 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
13783 rtx tmp2 = gen_reg_rtx (DImode);
13784 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
13786 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
13787 emit_move_insn (operands[0], tmp2df);
13791 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13795 (define_insn "rs6000_mffs"
13796 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13797 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13798 "TARGET_HARD_FLOAT"
13801 (define_insn "rs6000_mtfsf"
13802 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13803 (match_operand:DF 1 "gpc_reg_operand" "d")]
13805 "TARGET_HARD_FLOAT"
13808 (define_insn "rs6000_mtfsf_hi"
13809 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13810 (match_operand:DF 1 "gpc_reg_operand" "d")]
13812 "TARGET_HARD_FLOAT"
13816 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13817 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13818 ;; register that is being loaded. The fused ops must be physically adjacent.
13820 ;; On Power8 GPR loads, we try to use the register that is being load. The
13821 ;; peephole2 then gathers any other fused possibilities that it can find after
13822 ;; register allocation. If power9 fusion is selected, we also fuse floating
13823 ;; point loads/stores.
13825 ;; Find cases where the addis that feeds into a load instruction is either used
13826 ;; once or is the same as the target register, and replace it with the fusion
13830 [(set (match_operand:P 0 "base_reg_operand")
13831 (match_operand:P 1 "fusion_gpr_addis"))
13832 (set (match_operand:INT1 2 "base_reg_operand")
13833 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13835 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13839 expand_fusion_gpr_load (operands);
13843 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13846 (define_insn "*fusion_gpr_load_<mode>"
13847 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13848 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13849 UNSPEC_FUSION_GPR))]
13852 return emit_fusion_gpr_load (operands[0], operands[1]);
13854 [(set_attr "type" "load")
13855 (set_attr "length" "8")])
13858 ;; Optimize cases where we want to do a D-form load (register+offset) on
13859 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13864 ;; and we change this to:
13869 [(match_scratch:P 0 "b")
13870 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13871 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13872 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13874 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13875 [(set (match_dup 0)
13880 rtx tmp_reg = operands[0];
13881 rtx mem = operands[2];
13882 rtx addr = XEXP (mem, 0);
13883 rtx add_op0, add_op1, new_addr;
13885 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13886 add_op0 = XEXP (addr, 0);
13887 add_op1 = XEXP (addr, 1);
13888 gcc_assert (REG_P (add_op0));
13889 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13891 operands[4] = add_op1;
13892 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13895 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13896 ;; Altivec register, and the register allocator has generated:
13900 ;; and we change this to:
13905 [(match_scratch:P 0 "b")
13906 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13907 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13908 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13910 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13911 [(set (match_dup 0)
13916 rtx tmp_reg = operands[0];
13917 rtx mem = operands[3];
13918 rtx addr = XEXP (mem, 0);
13919 rtx add_op0, add_op1, new_addr;
13921 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13922 add_op0 = XEXP (addr, 0);
13923 add_op1 = XEXP (addr, 1);
13924 gcc_assert (REG_P (add_op0));
13925 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13927 operands[4] = add_op1;
13928 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13932 ;; Miscellaneous ISA 2.06 (power7) instructions
13933 (define_insn "addg6s"
13934 [(set (match_operand:SI 0 "register_operand" "=r")
13935 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13936 (match_operand:SI 2 "register_operand" "r")]
13940 [(set_attr "type" "integer")])
13942 (define_insn "cdtbcd"
13943 [(set (match_operand:SI 0 "register_operand" "=r")
13944 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13948 [(set_attr "type" "integer")])
13950 (define_insn "cbcdtd"
13951 [(set (match_operand:SI 0 "register_operand" "=r")
13952 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13956 [(set_attr "type" "integer")])
13958 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13961 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13962 (UNSPEC_DIVEU "eu")])
13964 (define_insn "div<div_extend>_<mode>"
13965 [(set (match_operand:GPR 0 "register_operand" "=r")
13966 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13967 (match_operand:GPR 2 "register_operand" "r")]
13968 UNSPEC_DIV_EXTEND))]
13970 "div<wd><div_extend> %0,%1,%2"
13971 [(set_attr "type" "div")
13972 (set_attr "size" "<bits>")])
13975 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13977 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13978 (define_mode_attr FP128_64 [(TF "DF")
13983 (define_expand "unpack<mode>"
13984 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13986 [(match_operand:FMOVE128 1 "register_operand")
13987 (match_operand:QI 2 "const_0_to_1_operand")]
13988 UNSPEC_UNPACK_128BIT))]
13989 "FLOAT128_2REG_P (<MODE>mode)"
13992 (define_insn_and_split "unpack<mode>_dm"
13993 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13995 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13996 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13997 UNSPEC_UNPACK_128BIT))]
13998 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14000 "&& reload_completed"
14001 [(set (match_dup 0) (match_dup 3))]
14003 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14005 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14007 emit_note (NOTE_INSN_DELETED);
14011 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14013 [(set_attr "type" "fp,fpstore,mtvsr,mfvsr,store")])
14015 (define_insn_and_split "unpack<mode>_nodm"
14016 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14018 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14019 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14020 UNSPEC_UNPACK_128BIT))]
14021 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14023 "&& reload_completed"
14024 [(set (match_dup 0) (match_dup 3))]
14026 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14028 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14030 emit_note (NOTE_INSN_DELETED);
14034 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14036 [(set_attr "type" "fp,fpstore")])
14038 (define_insn_and_split "pack<mode>"
14039 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
14041 [(match_operand:<FP128_64> 1 "register_operand" "d")
14042 (match_operand:<FP128_64> 2 "register_operand" "d")]
14043 UNSPEC_PACK_128BIT))]
14044 "FLOAT128_2REG_P (<MODE>mode)"
14046 "&& reload_completed"
14047 [(set (match_dup 3) (match_dup 1))
14048 (set (match_dup 4) (match_dup 2))]
14050 unsigned dest_hi = REGNO (operands[0]);
14051 unsigned dest_lo = dest_hi + 1;
14053 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14054 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14056 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14057 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14059 [(set_attr "type" "fp")
14060 (set_attr "length" "8")])
14062 (define_insn "unpack<mode>"
14063 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14064 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14065 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14066 UNSPEC_UNPACK_128BIT))]
14067 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14069 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14070 return ASM_COMMENT_START " xxpermdi to same register";
14072 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14073 return "xxpermdi %x0,%x1,%x1,%3";
14075 [(set_attr "type" "vecperm")])
14077 (define_insn "pack<mode>"
14078 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14079 (unspec:FMOVE128_VSX
14080 [(match_operand:DI 1 "register_operand" "wa")
14081 (match_operand:DI 2 "register_operand" "wa")]
14082 UNSPEC_PACK_128BIT))]
14084 "xxpermdi %x0,%x1,%x2,0"
14085 [(set_attr "type" "vecperm")])
14089 ;; ISA 2.08 IEEE 128-bit floating point support.
14091 (define_insn "add<mode>3"
14092 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14094 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14095 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14096 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14098 [(set_attr "type" "vecfloat")
14099 (set_attr "size" "128")])
14101 (define_insn "sub<mode>3"
14102 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14104 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14105 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14106 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14108 [(set_attr "type" "vecfloat")
14109 (set_attr "size" "128")])
14111 (define_insn "mul<mode>3"
14112 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14114 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14115 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14116 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14118 [(set_attr "type" "qmul")
14119 (set_attr "size" "128")])
14121 (define_insn "div<mode>3"
14122 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14124 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14125 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14126 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14128 [(set_attr "type" "vecdiv")
14129 (set_attr "size" "128")])
14131 (define_insn "sqrt<mode>2"
14132 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14134 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14135 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14137 [(set_attr "type" "vecdiv")
14138 (set_attr "size" "128")])
14140 (define_expand "copysign<mode>3"
14141 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14142 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14143 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14144 "FLOAT128_IEEE_P (<MODE>mode)"
14146 if (TARGET_FLOAT128_HW)
14147 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14150 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14155 (define_insn "copysign<mode>3_hard"
14156 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14158 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14159 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14161 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14162 "xscpsgnqp %0,%2,%1"
14163 [(set_attr "type" "vecmove")
14164 (set_attr "size" "128")])
14166 (define_insn "copysign<mode>3_soft"
14167 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14169 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14170 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14172 (clobber (match_scratch:IEEE128 3 "=&v"))]
14173 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14174 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14175 [(set_attr "type" "veccomplex")
14176 (set_attr "length" "8")])
14178 (define_insn "@neg<mode>2_hw"
14179 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14181 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14182 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14184 [(set_attr "type" "vecmove")
14185 (set_attr "size" "128")])
14188 (define_insn "@abs<mode>2_hw"
14189 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14191 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14192 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14194 [(set_attr "type" "vecmove")
14195 (set_attr "size" "128")])
14198 (define_insn "*nabs<mode>2_hw"
14199 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14202 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14203 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14205 [(set_attr "type" "vecmove")
14206 (set_attr "size" "128")])
14208 ;; Initially don't worry about doing fusion
14209 (define_insn "fma<mode>4_hw"
14210 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14212 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14213 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14214 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14215 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14216 "xsmaddqp %0,%1,%2"
14217 [(set_attr "type" "qmul")
14218 (set_attr "size" "128")])
14220 (define_insn "*fms<mode>4_hw"
14221 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14223 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14224 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14226 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14227 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14228 "xsmsubqp %0,%1,%2"
14229 [(set_attr "type" "qmul")
14230 (set_attr "size" "128")])
14232 (define_insn "*nfma<mode>4_hw"
14233 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14236 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14237 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14238 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14239 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14240 "xsnmaddqp %0,%1,%2"
14241 [(set_attr "type" "qmul")
14242 (set_attr "size" "128")])
14244 (define_insn "*nfms<mode>4_hw"
14245 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14248 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14249 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14251 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14252 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14253 "xsnmsubqp %0,%1,%2"
14254 [(set_attr "type" "qmul")
14255 (set_attr "size" "128")])
14257 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14258 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14259 (float_extend:IEEE128
14260 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14261 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14263 [(set_attr "type" "vecfloat")
14264 (set_attr "size" "128")])
14266 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14267 ;; point is a simple copy.
14268 (define_insn_and_split "extendkftf2"
14269 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14270 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14271 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14275 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14278 emit_note (NOTE_INSN_DELETED);
14281 [(set_attr "type" "*,veclogical")
14282 (set_attr "length" "0,4")])
14284 (define_insn_and_split "trunctfkf2"
14285 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14286 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14287 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14291 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14294 emit_note (NOTE_INSN_DELETED);
14297 [(set_attr "type" "*,veclogical")
14298 (set_attr "length" "0,4")])
14300 (define_insn "trunc<mode>df2_hw"
14301 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14303 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14304 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14306 [(set_attr "type" "vecfloat")
14307 (set_attr "size" "128")])
14309 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14310 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14312 (define_insn_and_split "trunc<mode>sf2_hw"
14313 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14315 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14316 (clobber (match_scratch:DF 2 "=v"))]
14317 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14320 [(set (match_dup 2)
14321 (unspec:DF [(match_dup 1)]
14322 UNSPEC_TRUNC_ROUND_TO_ODD))
14324 (float_truncate:SF (match_dup 2)))]
14326 if (GET_CODE (operands[2]) == SCRATCH)
14327 operands[2] = gen_reg_rtx (DFmode);
14329 [(set_attr "type" "vecfloat")
14330 (set_attr "length" "8")
14331 (set_attr "isa" "p8v")])
14333 ;; Conversion between IEEE 128-bit and integer types
14335 ;; The fix function for DImode and SImode was declared earlier as a
14336 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14337 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14338 ;; unless we have the IEEE 128-bit hardware.
14340 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14341 ;; to provide a GPR target that used direct move and a conversion in the GPR
14342 ;; which works around QImode/HImode not being allowed in vector registers in
14343 ;; ISA 2.07 (power8).
14344 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14345 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14346 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14347 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14348 "xscvqp<su><wd>z %0,%1"
14349 [(set_attr "type" "vecfloat")
14350 (set_attr "size" "128")])
14352 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14353 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14355 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14356 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14357 "xscvqp<su>wz %0,%1"
14358 [(set_attr "type" "vecfloat")
14359 (set_attr "size" "128")])
14361 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14362 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14363 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14364 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14366 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14367 (clobber (match_scratch:QHSI 2 "=v"))]
14368 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14370 "&& reload_completed"
14371 [(set (match_dup 2)
14372 (any_fix:QHSI (match_dup 1)))
14376 (define_insn "float_<mode>di2_hw"
14377 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14378 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14379 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14381 [(set_attr "type" "vecfloat")
14382 (set_attr "size" "128")])
14384 (define_insn_and_split "float_<mode>si2_hw"
14385 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14386 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14387 (clobber (match_scratch:DI 2 "=v"))]
14388 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14391 [(set (match_dup 2)
14392 (sign_extend:DI (match_dup 1)))
14394 (float:IEEE128 (match_dup 2)))]
14396 if (GET_CODE (operands[2]) == SCRATCH)
14397 operands[2] = gen_reg_rtx (DImode);
14399 if (MEM_P (operands[1]))
14400 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14403 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14404 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14405 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14406 (clobber (match_scratch:DI 2 "=X,r,X"))]
14407 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14409 "&& reload_completed"
14412 rtx dest = operands[0];
14413 rtx src = operands[1];
14414 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14416 if (altivec_register_operand (src, <QHI:MODE>mode))
14417 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14418 else if (int_reg_operand (src, <QHI:MODE>mode))
14420 rtx ext_di = operands[2];
14421 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14422 emit_move_insn (dest_di, ext_di);
14424 else if (MEM_P (src))
14426 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14427 emit_move_insn (dest_qhi, src);
14428 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14431 gcc_unreachable ();
14433 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14436 [(set_attr "length" "8,12,12")
14437 (set_attr "type" "vecfloat")
14438 (set_attr "size" "128")])
14440 (define_insn "floatuns_<mode>di2_hw"
14441 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14442 (unsigned_float:IEEE128
14443 (match_operand:DI 1 "altivec_register_operand" "v")))]
14444 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14446 [(set_attr "type" "vecfloat")
14447 (set_attr "size" "128")])
14449 (define_insn_and_split "floatuns_<mode>si2_hw"
14450 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14451 (unsigned_float:IEEE128
14452 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14453 (clobber (match_scratch:DI 2 "=v"))]
14454 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14457 [(set (match_dup 2)
14458 (zero_extend:DI (match_dup 1)))
14460 (float:IEEE128 (match_dup 2)))]
14462 if (GET_CODE (operands[2]) == SCRATCH)
14463 operands[2] = gen_reg_rtx (DImode);
14465 if (MEM_P (operands[1]))
14466 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14469 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14470 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14471 (unsigned_float:IEEE128
14472 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14473 (clobber (match_scratch:DI 2 "=X,r,X"))]
14474 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14476 "&& reload_completed"
14479 rtx dest = operands[0];
14480 rtx src = operands[1];
14481 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14483 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14484 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14485 else if (int_reg_operand (src, <QHI:MODE>mode))
14487 rtx ext_di = operands[2];
14488 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14489 emit_move_insn (dest_di, ext_di);
14492 gcc_unreachable ();
14494 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14497 [(set_attr "length" "8,12,8")
14498 (set_attr "type" "vecfloat")
14499 (set_attr "size" "128")])
14501 ;; IEEE 128-bit round to integer built-in functions
14502 (define_insn "floor<mode>2"
14503 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14505 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14507 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14509 [(set_attr "type" "vecfloat")
14510 (set_attr "size" "128")])
14512 (define_insn "ceil<mode>2"
14513 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14515 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14517 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14519 [(set_attr "type" "vecfloat")
14520 (set_attr "size" "128")])
14522 (define_insn "btrunc<mode>2"
14523 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14525 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14527 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14529 [(set_attr "type" "vecfloat")
14530 (set_attr "size" "128")])
14532 (define_insn "round<mode>2"
14533 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14535 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14537 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14539 [(set_attr "type" "vecfloat")
14540 (set_attr "size" "128")])
14542 ;; IEEE 128-bit instructions with round to odd semantics
14543 (define_insn "add<mode>3_odd"
14544 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14546 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14547 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14548 UNSPEC_ADD_ROUND_TO_ODD))]
14549 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14550 "xsaddqpo %0,%1,%2"
14551 [(set_attr "type" "vecfloat")
14552 (set_attr "size" "128")])
14554 (define_insn "sub<mode>3_odd"
14555 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14557 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14558 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14559 UNSPEC_SUB_ROUND_TO_ODD))]
14560 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14561 "xssubqpo %0,%1,%2"
14562 [(set_attr "type" "vecfloat")
14563 (set_attr "size" "128")])
14565 (define_insn "mul<mode>3_odd"
14566 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14568 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14569 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14570 UNSPEC_MUL_ROUND_TO_ODD))]
14571 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14572 "xsmulqpo %0,%1,%2"
14573 [(set_attr "type" "qmul")
14574 (set_attr "size" "128")])
14576 (define_insn "div<mode>3_odd"
14577 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14579 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14580 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14581 UNSPEC_DIV_ROUND_TO_ODD))]
14582 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14583 "xsdivqpo %0,%1,%2"
14584 [(set_attr "type" "vecdiv")
14585 (set_attr "size" "128")])
14587 (define_insn "sqrt<mode>2_odd"
14588 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14590 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14591 UNSPEC_SQRT_ROUND_TO_ODD))]
14592 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14594 [(set_attr "type" "vecdiv")
14595 (set_attr "size" "128")])
14597 (define_insn "fma<mode>4_odd"
14598 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14600 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14601 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14602 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14603 UNSPEC_FMA_ROUND_TO_ODD))]
14604 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14605 "xsmaddqpo %0,%1,%2"
14606 [(set_attr "type" "qmul")
14607 (set_attr "size" "128")])
14609 (define_insn "*fms<mode>4_odd"
14610 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14612 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14613 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14615 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14616 UNSPEC_FMA_ROUND_TO_ODD))]
14617 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14618 "xsmsubqpo %0,%1,%2"
14619 [(set_attr "type" "qmul")
14620 (set_attr "size" "128")])
14622 (define_insn "*nfma<mode>4_odd"
14623 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14626 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14627 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14628 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14629 UNSPEC_FMA_ROUND_TO_ODD)))]
14630 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14631 "xsnmaddqpo %0,%1,%2"
14632 [(set_attr "type" "qmul")
14633 (set_attr "size" "128")])
14635 (define_insn "*nfms<mode>4_odd"
14636 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14639 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14640 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14642 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14643 UNSPEC_FMA_ROUND_TO_ODD)))]
14644 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14645 "xsnmsubqpo %0,%1,%2"
14646 [(set_attr "type" "qmul")
14647 (set_attr "size" "128")])
14649 (define_insn "trunc<mode>df2_odd"
14650 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14651 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14652 UNSPEC_TRUNC_ROUND_TO_ODD))]
14653 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14655 [(set_attr "type" "vecfloat")
14656 (set_attr "size" "128")])
14658 ;; IEEE 128-bit comparisons
14659 (define_insn "*cmp<mode>_hw"
14660 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14661 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14662 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14663 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14664 "xscmpuqp %0,%1,%2"
14665 [(set_attr "type" "veccmp")
14666 (set_attr "size" "128")])
14668 ;; Miscellaneous ISA 3.0 (power9) instructions
14670 (define_insn "darn_32"
14671 [(set (match_operand:SI 0 "register_operand" "=r")
14672 (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14675 [(set_attr "type" "integer")])
14677 (define_insn "darn_raw"
14678 [(set (match_operand:DI 0 "register_operand" "=r")
14679 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14680 "TARGET_P9_MISC && TARGET_64BIT"
14682 [(set_attr "type" "integer")])
14684 (define_insn "darn"
14685 [(set (match_operand:DI 0 "register_operand" "=r")
14686 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14687 "TARGET_P9_MISC && TARGET_64BIT"
14689 [(set_attr "type" "integer")])
14691 ;; Test byte within range.
14693 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14694 ;; represents a byte whose value is ignored in this context and
14695 ;; vv, the least significant byte, holds the byte value that is to
14696 ;; be tested for membership within the range specified by operand 2.
14697 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14699 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14700 ;; vv <= hi. Otherwise, set register operand 0 to 0.
14702 ;; Though the instructions to which this expansion maps operate on
14703 ;; 64-bit registers, the current implementation only operates on
14704 ;; SI-mode operands as the high-order bits provide no information
14705 ;; that is not already available in the low-order bits. To avoid the
14706 ;; costs of data widening operations, future enhancements might allow
14707 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14708 (define_expand "cmprb"
14709 [(set (match_dup 3)
14710 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14711 (match_operand:SI 2 "gpc_reg_operand" "r")]
14713 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14714 (if_then_else:SI (lt (match_dup 3)
14717 (if_then_else (gt (match_dup 3)
14723 operands[3] = gen_reg_rtx (CCmode);
14726 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14727 ;; represents a byte whose value is ignored in this context and
14728 ;; vv, the least significant byte, holds the byte value that is to
14729 ;; be tested for membership within the range specified by operand 2.
14730 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14732 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14733 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
14734 ;; 3 bits of the target CR register are all set to 0.
14735 (define_insn "*cmprb_internal"
14736 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14737 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14738 (match_operand:SI 2 "gpc_reg_operand" "r")]
14742 [(set_attr "type" "logical")])
14744 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14745 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
14746 ;; if the GT bit (0x4) of condition register operand 1 is on.
14747 ;; Otherwise, set operand 0 to 0. Note that the result stored into
14748 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14749 ;; within condition register operand 1.
14750 (define_insn "setb_signed"
14751 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14752 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14755 (if_then_else (gt (match_dup 1)
14761 [(set_attr "type" "logical")])
14763 (define_insn "setb_unsigned"
14764 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14765 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14768 (if_then_else (gtu (match_dup 1)
14774 [(set_attr "type" "logical")])
14776 ;; Test byte within two ranges.
14778 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14779 ;; represents a byte whose value is ignored in this context and
14780 ;; vv, the least significant byte, holds the byte value that is to
14781 ;; be tested for membership within the range specified by operand 2.
14782 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14784 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14785 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
14788 ;; Though the instructions to which this expansion maps operate on
14789 ;; 64-bit registers, the current implementation only operates on
14790 ;; SI-mode operands as the high-order bits provide no information
14791 ;; that is not already available in the low-order bits. To avoid the
14792 ;; costs of data widening operations, future enhancements might allow
14793 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14794 (define_expand "cmprb2"
14795 [(set (match_dup 3)
14796 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14797 (match_operand:SI 2 "gpc_reg_operand" "r")]
14799 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14800 (if_then_else:SI (lt (match_dup 3)
14803 (if_then_else (gt (match_dup 3)
14809 operands[3] = gen_reg_rtx (CCmode);
14812 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14813 ;; represents a byte whose value is ignored in this context and
14814 ;; vv, the least significant byte, holds the byte value that is to
14815 ;; be tested for membership within the ranges specified by operand 2.
14816 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14818 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14819 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14820 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
14821 ;; CR register are all set to 0.
14822 (define_insn "*cmprb2_internal"
14823 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14824 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14825 (match_operand:SI 2 "gpc_reg_operand" "r")]
14829 [(set_attr "type" "logical")])
14831 ;; Test byte membership within set of 8 bytes.
14833 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14834 ;; represents a byte whose value is ignored in this context and
14835 ;; vv, the least significant byte, holds the byte value that is to
14836 ;; be tested for membership within the set specified by operand 2.
14837 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14839 ;; Return in target register operand 0 a value of 1 if vv equals one
14840 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
14841 ;; register operand 0 to 0. Note that the 8 byte values held within
14842 ;; operand 2 need not be unique.
14844 ;; Though the instructions to which this expansion maps operate on
14845 ;; 64-bit registers, the current implementation requires that operands
14846 ;; 0 and 1 have mode SI as the high-order bits provide no information
14847 ;; that is not already available in the low-order bits. To avoid the
14848 ;; costs of data widening operations, future enhancements might allow
14849 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14850 (define_expand "cmpeqb"
14851 [(set (match_dup 3)
14852 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14853 (match_operand:DI 2 "gpc_reg_operand" "r")]
14855 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14856 (if_then_else:SI (lt (match_dup 3)
14859 (if_then_else (gt (match_dup 3)
14863 "TARGET_P9_MISC && TARGET_64BIT"
14865 operands[3] = gen_reg_rtx (CCmode);
14868 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14869 ;; represents a byte whose value is ignored in this context and
14870 ;; vv, the least significant byte, holds the byte value that is to
14871 ;; be tested for membership within the set specified by operand 2.
14872 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14874 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14875 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
14876 ;; set the GT bit to zero. The other 3 bits of the target CR register
14877 ;; are all set to 0.
14878 (define_insn "*cmpeqb_internal"
14879 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14880 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14881 (match_operand:DI 2 "gpc_reg_operand" "r")]
14883 "TARGET_P9_MISC && TARGET_64BIT"
14885 [(set_attr "type" "logical")])
14888 (include "sync.md")
14889 (include "vector.md")
14891 (include "altivec.md")
14894 (include "crypto.md")