1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2022 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
159 UNSPEC_XXSPLTIDP_CONST
160 UNSPEC_XXSPLTIW_CONST
164 ;; UNSPEC_VOLATILE usage
167 (define_c_enum "unspecv"
169 UNSPECV_LL ; load-locked
170 UNSPECV_SC ; store-conditional
171 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
172 UNSPECV_EH_RR ; eh_reg_restore
173 UNSPECV_ISYNC ; isync instruction
174 UNSPECV_MFTB ; move from time base
175 UNSPECV_DARN ; darn (deliver a random number)
176 UNSPECV_NLGR ; non-local goto receiver
177 UNSPECV_MFFS ; Move from FPSCR
178 UNSPECV_MFFSL ; Move from FPSCR light instruction version
179 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
180 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
181 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
182 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
183 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
184 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
185 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
186 UNSPECV_SPEC_BARRIER ; Speculation barrier
191 ; The three different kinds of epilogue.
192 (define_enum "epilogue_type" [normal sibcall eh_return])
194 ;; Define an insn type attribute. This is used in function unit delay
198 add,logical,shift,insert,
200 exts,cntlz,popcnt,isel,
201 load,store,fpload,fpstore,vecload,vecstore,
203 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
204 cr_logical,mfcr,mfcrf,mtcr,
205 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
206 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
207 vecfloat,vecfdiv,vecdouble,mtvsr,mfvsr,crypto,
208 veclogical,veccmpfx,vecexts,vecmove,
209 htm,htmsimple,dfp,mma,
214 fused_load_load,fused_store_store,
218 (const_string "integer"))
219 ;; Attr type definitions for fused pairs:
220 ;; fused_arith_logical is used for scalar logical+add/subf and
221 ;; add/subf+logical pairs of instructions.
222 ;; fused_load_cmpi is used for a D-form load fused with
223 ;; a compare immediate.
224 ;; fused_load_load is for a fused pair of loads to adjacent addresses.
225 ;; fused_store_store is for a fused pair of stores to adjacent addresses.
226 ;; fused_addis_load is for addis fused to D-form load for a larger immediate.
227 ;; fused_mtbc is for fused mtlr and bclr[l] pairs.
228 ;; fused_vector is for a fused pair of vector logical instructions.
230 ;; What data size does this instruction work on?
231 ;; This is used for insert, mul and others as necessary.
232 (define_attr "size" "8,16,32,64,128,256" (const_string "32"))
234 ;; What is the insn_cost for this insn? The target hook can still override
235 ;; this. For optimizing for size the "length" attribute is used instead.
236 (define_attr "cost" "" (const_int 0))
238 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
239 ;; This is used for add, logical, shift, exts, mul.
240 (define_attr "dot" "no,yes" (const_string "no"))
242 ;; Does this instruction sign-extend its result?
243 ;; This is used for load insns.
244 (define_attr "sign_extend" "no,yes" (const_string "no"))
246 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
247 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
249 ;; Does this instruction use indexed (that is, reg+reg) addressing?
250 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
251 ;; it is automatically set based on that. If a load or store instruction
252 ;; has fewer than two operands it needs to set this attribute manually
253 ;; or the compiler will crash.
254 (define_attr "indexed" "no,yes"
255 (if_then_else (ior (match_operand 0 "indexed_address_mem")
256 (match_operand 1 "indexed_address_mem"))
258 (const_string "no")))
260 ;; Does this instruction use update addressing?
261 ;; This is used for load and store insns. See the comments for "indexed".
262 (define_attr "update" "no,yes"
263 (if_then_else (ior (match_operand 0 "update_address_mem")
264 (match_operand 1 "update_address_mem"))
266 (const_string "no")))
268 ;; Is this instruction using operands[2] as shift amount, and can that be a
270 ;; This is used for shift insns.
271 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
273 ;; Is this instruction using a shift amount from a register?
274 ;; This is used for shift insns.
275 (define_attr "var_shift" "no,yes"
276 (if_then_else (and (eq_attr "type" "shift")
277 (eq_attr "maybe_var_shift" "yes"))
278 (if_then_else (match_operand 2 "gpc_reg_operand")
281 (const_string "no")))
283 ;; Is copying of this instruction disallowed?
284 (define_attr "cannot_copy" "no,yes" (const_string "no"))
287 ;; Whether this insn has a prefixed form and a non-prefixed form.
288 (define_attr "maybe_prefixed" "no,yes"
289 (if_then_else (eq_attr "type" "load,fpload,vecload,store,fpstore,vecstore,
292 (const_string "no")))
294 ;; Whether an insn is a prefixed insn. A prefixed instruction has a prefix
295 ;; instruction word that conveys additional information such as a larger
296 ;; immediate, additional operands, etc., in addition to the normal instruction
297 ;; word. The default "length" attribute will also be adjusted by default to
299 (define_attr "prefixed" "no,yes"
300 (cond [(ior (match_test "!TARGET_PREFIXED")
301 (match_test "!NONJUMP_INSN_P (insn)")
302 (eq_attr "maybe_prefixed" "no"))
305 (eq_attr "type" "load,fpload,vecload")
306 (if_then_else (match_test "prefixed_load_p (insn)")
310 (eq_attr "type" "store,fpstore,vecstore")
311 (if_then_else (match_test "prefixed_store_p (insn)")
315 (eq_attr "type" "integer,add")
316 (if_then_else (match_test "prefixed_paddi_p (insn)")
318 (const_string "no"))]
320 (const_string "no")))
322 ;; Whether an insn loads an external address for the PCREL_OPT optimizaton.
323 (define_attr "loads_external_address" "no,yes"
326 ;; Return the number of real hardware instructions in a combined insn. If it
327 ;; is 0, just use the length / 4.
328 (define_attr "num_insns" "" (const_int 0))
330 ;; If an insn is prefixed, return the maximum number of prefixed instructions
331 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
333 (define_attr "max_prefixed_insns" "" (const_int 1))
335 ;; Length of the instruction (in bytes). This length does not consider the
336 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
337 ;; the length if there are prefixed instructions.
339 ;; While it might be tempting to use num_insns to calculate the length, it can
340 ;; be problematical unless all insn lengths are adjusted to use num_insns
341 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
342 ;; num_insns and recurse).
343 (define_attr "length" "" (const_int 4))
345 ;; Processor type -- this attribute must exactly match the processor_type
346 ;; enumeration in rs6000-opts.h.
348 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
349 ppc750,ppc7400,ppc7450,
350 ppc403,ppc405,ppc440,ppc476,
351 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
352 power4,power5,power6,power7,power8,power9,power10,
353 rs64a,mpccore,cell,ppca2,titan"
354 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
356 ;; The ISA we implement.
357 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10"
358 (const_string "any"))
360 ;; Is this alternative enabled for the current CPU/ISA/etc.?
361 (define_attr "enabled" ""
363 [(eq_attr "isa" "any")
366 (and (eq_attr "isa" "p5")
367 (match_test "TARGET_POPCNTB"))
370 (and (eq_attr "isa" "p6")
371 (match_test "TARGET_CMPB"))
374 (and (eq_attr "isa" "p7")
375 (match_test "TARGET_POPCNTD"))
378 (and (eq_attr "isa" "p7v")
379 (match_test "TARGET_VSX"))
382 (and (eq_attr "isa" "p8v")
383 (match_test "TARGET_P8_VECTOR"))
386 (and (eq_attr "isa" "p9")
387 (match_test "TARGET_MODULO"))
390 (and (eq_attr "isa" "p9v")
391 (match_test "TARGET_P9_VECTOR"))
394 (and (eq_attr "isa" "p9kf")
395 (match_test "TARGET_FLOAT128_TYPE"))
398 (and (eq_attr "isa" "p9tf")
399 (match_test "FLOAT128_VECTOR_P (TFmode)"))
402 (and (eq_attr "isa" "p10")
403 (match_test "TARGET_POWER10"))
407 ;; If this instruction is microcoded on the CELL processor
408 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
409 (define_attr "cell_micro" "not,conditional,always"
410 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
411 (eq_attr "dot" "yes"))
412 (and (eq_attr "type" "load")
413 (eq_attr "sign_extend" "yes"))
414 (and (eq_attr "type" "shift")
415 (eq_attr "var_shift" "yes")))
416 (const_string "always")
417 (const_string "not")))
419 (automata_option "ndfa")
432 (include "e300c2c3.md")
433 (include "e500mc.md")
434 (include "e500mc64.md")
437 (include "power4.md")
438 (include "power5.md")
439 (include "power6.md")
440 (include "power7.md")
441 (include "power8.md")
442 (include "power9.md")
443 (include "power10.md")
448 (include "predicates.md")
449 (include "constraints.md")
454 ; This mode iterator allows :GPR to be used to indicate the allowable size
455 ; of whole values in GPRs.
456 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
458 ; And again, for patterns that need two (potentially) different integer modes.
459 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
461 ; Any supported integer mode.
462 (define_mode_iterator INT [QI HI SI DI TI PTI])
464 ; Any supported integer mode that fits in one register.
465 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
467 ; Integer modes supported in VSX registers with ISA 3.0 instructions
468 (define_mode_iterator INT_ISA3 [QI HI SI DI])
470 ; Everything we can extend QImode to.
471 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
473 ; Everything we can extend HImode to.
474 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
476 ; Everything we can extend SImode to.
477 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
479 ; QImode or HImode for small integer moves and small atomic ops
480 (define_mode_iterator QHI [QI HI])
482 ; QImode, HImode, SImode for fused ops only for GPR loads
483 (define_mode_iterator QHSI [QI HI SI])
485 ; HImode or SImode for sign extended fusion ops
486 (define_mode_iterator HSI [HI SI])
488 ; SImode or DImode, even if DImode doesn't fit in GPRs.
489 (define_mode_iterator SDI [SI DI])
491 ; The size of a pointer. Also, the size of the value that a record-condition
492 ; (one with a '.') will compare; and the size used for arithmetic carries.
493 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
495 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
496 ; PTImode is GPR only)
497 (define_mode_iterator TI2 [TI PTI])
499 ; Any hardware-supported floating-point mode
500 (define_mode_iterator FP [
501 (SF "TARGET_HARD_FLOAT")
502 (DF "TARGET_HARD_FLOAT")
503 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
504 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
505 (KF "TARGET_FLOAT128_TYPE")
509 ; Any fma capable floating-point mode.
510 (define_mode_iterator FMA_F [
511 (SF "TARGET_HARD_FLOAT")
512 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
513 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
514 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
515 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
516 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
519 ; Floating point move iterators to combine binary and decimal moves
520 (define_mode_iterator FMOVE32 [SF SD])
521 (define_mode_iterator FMOVE64 [DF DD])
522 (define_mode_iterator FMOVE64X [DI DF DD])
523 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
524 (IF "FLOAT128_IBM_P (IFmode)")
525 (TD "TARGET_HARD_FLOAT")])
527 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
528 (IF "FLOAT128_2REG_P (IFmode)")
529 (TD "TARGET_HARD_FLOAT")])
531 ; Iterators for 128 bit types for direct move
532 (define_mode_iterator FMOVE128_GPR [TI
540 (KF "FLOAT128_VECTOR_P (KFmode)")
541 (TF "FLOAT128_VECTOR_P (TFmode)")])
543 ; Iterator for 128-bit VSX types for pack/unpack
544 (define_mode_iterator FMOVE128_VSX [V1TI KF])
546 ; Iterators for converting to/from TFmode
547 (define_mode_iterator IFKF [IF KF])
549 ; Constraints for moving IF/KFmode.
550 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
552 ; Whether a floating point move is ok, don't allow SD without hardware FP
553 (define_mode_attr fmove_ok [(SF "")
555 (SD "TARGET_HARD_FLOAT")
558 ; Convert REAL_VALUE to the appropriate bits
559 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
560 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
561 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
562 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
564 ; Whether 0.0 has an all-zero bit pattern
565 (define_mode_attr zero_fp [(SF "j")
574 ; Definitions for 64-bit VSX
575 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
577 ; Definitions for 64-bit direct move
578 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
580 ; Definitions for 64-bit use of altivec registers
581 (define_mode_attr f64_av [(DF "v") (DD "wn")])
583 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
584 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
586 ; These modes do not fit in integer registers in 32-bit mode.
587 (define_mode_iterator DIFD [DI DF DD])
589 ; Iterator for reciprocal estimate instructions
590 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
593 (define_mode_iterator SFDF [SF DF])
595 ; And again, for when we need two FP modes in a pattern.
596 (define_mode_iterator SFDF2 [SF DF])
598 ; A generic s/d attribute, for sp/dp for example.
599 (define_mode_attr sd [(SF "s") (DF "d")
600 (V4SF "s") (V2DF "d")])
602 ; "s" or nothing, for fmuls/fmul for example.
603 (define_mode_attr s [(SF "s") (DF "")])
605 ; Iterator for 128-bit floating point that uses the IBM double-double format
606 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
607 (TF "FLOAT128_IBM_P (TFmode)")])
609 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
610 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
611 (TF "FLOAT128_IEEE_P (TFmode)")])
613 ; Iterator for 128-bit floating point
614 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
615 (IF "TARGET_FLOAT128_TYPE")
616 (TF "TARGET_LONG_DOUBLE_128")])
618 ; Iterator for signbit on 64-bit machines with direct move
619 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
620 (TF "FLOAT128_VECTOR_P (TFmode)")])
622 ; Which isa is needed for those float instructions?
623 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
626 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
628 ; Conditional returns.
629 (define_code_iterator any_return [return simple_return])
630 (define_code_attr return_pred [(return "direct_return ()")
631 (simple_return "1")])
632 (define_code_attr return_str [(return "") (simple_return "simple_")])
635 (define_code_iterator iorxor [ior xor])
636 (define_code_iterator and_ior_xor [and ior xor])
638 ; Signed/unsigned variants of ops.
639 (define_code_iterator any_extend [sign_extend zero_extend])
640 (define_code_iterator any_fix [fix unsigned_fix])
641 (define_code_iterator any_float [float unsigned_float])
643 (define_code_attr u [(sign_extend "")
648 (define_code_attr su [(sign_extend "s")
653 (unsigned_float "u")])
655 (define_code_attr az [(sign_extend "a")
660 (unsigned_float "z")])
662 (define_code_attr uns [(fix "")
665 (unsigned_float "uns")])
667 ; Various instructions that come in SI and DI forms.
668 ; A generic w/d attribute, for things like cmpw/cmpd.
669 (define_mode_attr wd [(QI "b")
680 ; For double extract from different origin types
681 (define_mode_attr du_or_d [(QI "du")
690 ;; How many bits (per element) in this mode?
691 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
694 (V4SI "32") (V2DI "64")])
697 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
699 ;; Bitmask for shift instructions
700 (define_mode_attr hH [(SI "h") (DI "H")])
702 ;; A mode twice the size of the given mode
703 (define_mode_attr dmode [(SI "di") (DI "ti")])
704 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
706 ;; Suffix for reload patterns
707 (define_mode_attr ptrsize [(SI "32bit")
710 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
711 (DI "TARGET_64BIT")])
713 (define_mode_attr mptrsize [(SI "si")
716 (define_mode_attr ptrload [(SI "lwz")
719 (define_mode_attr ptrm [(SI "m")
722 (define_mode_attr rreg [(SF "f")
729 (define_mode_attr rreg2 [(SF "f")
732 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
733 (DF "TARGET_FCFID")])
735 ;; Mode iterator for logical operations on 128-bit types
736 (define_mode_iterator BOOL_128 [TI
738 (V16QI "TARGET_ALTIVEC")
739 (V8HI "TARGET_ALTIVEC")
740 (V4SI "TARGET_ALTIVEC")
741 (V4SF "TARGET_ALTIVEC")
742 (V2DI "TARGET_ALTIVEC")
743 (V2DF "TARGET_ALTIVEC")
744 (V1TI "TARGET_ALTIVEC")])
746 ;; For the GPRs we use 3 constraints for register outputs, two that are the
747 ;; same as the output register, and a third where the output register is an
748 ;; early clobber, so we don't have to deal with register overlaps. For the
749 ;; vector types, we prefer to use the vector registers. For TI mode, allow
752 ;; Mode attribute for boolean operation register constraints for output
753 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
755 (V16QI "wa,v,&?r,?r,?r")
756 (V8HI "wa,v,&?r,?r,?r")
757 (V4SI "wa,v,&?r,?r,?r")
758 (V4SF "wa,v,&?r,?r,?r")
759 (V2DI "wa,v,&?r,?r,?r")
760 (V2DF "wa,v,&?r,?r,?r")
761 (V1TI "wa,v,&?r,?r,?r")])
763 ;; Mode attribute for boolean operation register constraints for operand1
764 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
772 (V1TI "wa,v,r,0,r")])
774 ;; Mode attribute for boolean operation register constraints for operand2
775 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
783 (V1TI "wa,v,r,r,0")])
785 ;; Mode attribute for boolean operation register constraints for operand1
786 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
787 ;; is used for operand1 or operand2
788 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
796 (V1TI "wa,v,r,0,0")])
798 ;; Reload iterator for creating the function to allocate a base register to
799 ;; supplement addressing modes.
800 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
801 SF SD SI DF DD DI TI PTI KF IF TF
804 ;; Iterate over smin, smax
805 (define_code_iterator fp_minmax [smin smax])
807 (define_code_attr minmax [(smin "min")
810 (define_code_attr SMINMAX [(smin "SMIN")
813 ;; Iterator to optimize the following cases:
814 ;; D-form load to FPR register & move to Altivec register
815 ;; Move Altivec register to FPR register and store
816 (define_mode_iterator ALTIVEC_DFORM [DF
817 (SF "TARGET_P8_VECTOR")
818 (DI "TARGET_POWERPC64")])
820 (include "darwin.md")
822 ;; Start with fixed-point load and store insns. Here we put only the more
823 ;; complex forms. Basic data transfer is done later.
825 (define_insn "zero_extendqi<mode>2"
826 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,wa,^v")
827 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,?Z,v")))]
834 [(set_attr "type" "load,shift,fpload,vecperm")
835 (set_attr "isa" "*,*,p9v,p9v")])
837 (define_insn_and_split "*zero_extendqi<mode>2_dot"
838 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
839 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
841 (clobber (match_scratch:EXTQI 0 "=r,r"))]
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")])
857 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
858 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
859 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
861 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
862 (zero_extend:EXTQI (match_dup 1)))]
867 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
869 (zero_extend:EXTQI (match_dup 1)))
871 (compare:CC (match_dup 0)
874 [(set_attr "type" "logical")
875 (set_attr "dot" "yes")
876 (set_attr "length" "4,8")])
879 (define_insn "zero_extendhi<mode>2"
880 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,wa,^v")
881 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,?Z,v")))]
885 rlwinm %0,%1,0,0xffff
888 [(set_attr "type" "load,shift,fpload,vecperm")
889 (set_attr "isa" "*,*,p9v,p9v")])
891 (define_insn_and_split "*zero_extendhi<mode>2_dot"
892 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
893 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
895 (clobber (match_scratch:EXTHI 0 "=r,r"))]
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")])
911 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
912 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
913 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
915 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
916 (zero_extend:EXTHI (match_dup 1)))]
921 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
923 (zero_extend:EXTHI (match_dup 1)))
925 (compare:CC (match_dup 0)
928 [(set_attr "type" "logical")
929 (set_attr "dot" "yes")
930 (set_attr "length" "4,8")])
933 (define_insn "zero_extendsi<mode>2"
934 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
935 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,?Z,?Z,r,wa,wa")))]
944 xxextractuw %x0,%x1,4"
945 [(set_attr "type" "load,shift,fpload,fpload,mtvsr,mfvsr,vecexts")
946 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
948 (define_insn_and_split "*zero_extendsi<mode>2_dot"
949 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
950 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
952 (clobber (match_scratch:EXTSI 0 "=r,r"))]
957 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
959 (zero_extend:DI (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")])
968 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
969 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
970 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
972 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
973 (zero_extend:EXTSI (match_dup 1)))]
978 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
980 (zero_extend:EXTSI (match_dup 1)))
982 (compare:CC (match_dup 0)
985 [(set_attr "type" "shift")
986 (set_attr "dot" "yes")
987 (set_attr "length" "4,8")])
990 (define_insn "extendqi<mode>2"
991 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
992 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
997 [(set_attr "type" "exts,vecperm")
998 (set_attr "isa" "*,p9v")])
1000 (define_insn_and_split "*extendqi<mode>2_dot"
1001 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1002 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
1004 (clobber (match_scratch:EXTQI 0 "=r,r"))]
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")])
1020 (define_insn_and_split "*extendqi<mode>2_dot2"
1021 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1022 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
1024 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
1025 (sign_extend:EXTQI (match_dup 1)))]
1030 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1032 (sign_extend:EXTQI (match_dup 1)))
1034 (compare:CC (match_dup 0)
1037 [(set_attr "type" "exts")
1038 (set_attr "dot" "yes")
1039 (set_attr "length" "4,8")])
1042 (define_expand "extendhi<mode>2"
1043 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1044 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1048 (define_insn "*extendhi<mode>2"
1049 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1050 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1057 [(set_attr "type" "load,exts,fpload,vecperm")
1058 (set_attr "sign_extend" "yes")
1059 (set_attr "length" "*,*,8,*")
1060 (set_attr "isa" "*,*,p9v,p9v")])
1063 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1065 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1066 "TARGET_P9_VECTOR && reload_completed"
1070 (sign_extend:EXTHI (match_dup 2)))]
1072 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1075 (define_insn_and_split "*extendhi<mode>2_dot"
1076 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1077 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1079 (clobber (match_scratch:EXTHI 0 "=r,r"))]
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")])
1095 (define_insn_and_split "*extendhi<mode>2_dot2"
1096 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1097 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1099 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1100 (sign_extend:EXTHI (match_dup 1)))]
1105 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1107 (sign_extend:EXTHI (match_dup 1)))
1109 (compare:CC (match_dup 0)
1112 [(set_attr "type" "exts")
1113 (set_attr "dot" "yes")
1114 (set_attr "length" "4,8")])
1117 (define_insn "extendsi<mode>2"
1118 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1119 "=r, r, d, wa, wa, v, v, wr")
1120 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1121 "YZ, r, Z, Z, r, v, v, ?wa")))]
1132 [(set_attr "type" "load,exts,fpload,fpload,mtvsr,vecexts,vecperm,mfvsr")
1133 (set_attr "sign_extend" "yes")
1134 (set_attr "length" "*,*,*,*,*,*,8,8")
1135 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1138 [(set (match_operand:EXTSI 0 "int_reg_operand")
1139 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1140 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1144 (sign_extend:DI (match_dup 2)))]
1146 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1150 [(set (match_operand:DI 0 "altivec_register_operand")
1151 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1152 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1155 rtx dest = operands[0];
1156 rtx src = operands[1];
1157 int dest_regno = REGNO (dest);
1158 int src_regno = REGNO (src);
1159 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1160 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1162 if (BYTES_BIG_ENDIAN)
1164 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1165 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1169 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1170 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1175 (define_insn_and_split "*extendsi<mode>2_dot"
1176 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1177 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1179 (clobber (match_scratch:EXTSI 0 "=r,r"))]
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 (define_insn_and_split "*extendsi<mode>2_dot2"
1196 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1197 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1199 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1200 (sign_extend:EXTSI (match_dup 1)))]
1205 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1207 (sign_extend:EXTSI (match_dup 1)))
1209 (compare:CC (match_dup 0)
1212 [(set_attr "type" "exts")
1213 (set_attr "dot" "yes")
1214 (set_attr "length" "4,8")])
1216 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1218 (define_insn "*macchwc"
1219 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1220 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1221 (match_operand:SI 2 "gpc_reg_operand" "r")
1224 (match_operand:HI 1 "gpc_reg_operand" "r")))
1225 (match_operand:SI 4 "gpc_reg_operand" "0"))
1227 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1228 (plus:SI (mult:SI (ashiftrt:SI
1236 [(set_attr "type" "halfmul")])
1238 (define_insn "*macchw"
1239 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1240 (plus:SI (mult:SI (ashiftrt:SI
1241 (match_operand:SI 2 "gpc_reg_operand" "r")
1244 (match_operand:HI 1 "gpc_reg_operand" "r")))
1245 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1248 [(set_attr "type" "halfmul")])
1250 (define_insn "*macchwuc"
1251 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1252 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1253 (match_operand:SI 2 "gpc_reg_operand" "r")
1256 (match_operand:HI 1 "gpc_reg_operand" "r")))
1257 (match_operand:SI 4 "gpc_reg_operand" "0"))
1259 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1260 (plus:SI (mult:SI (lshiftrt:SI
1268 [(set_attr "type" "halfmul")])
1270 (define_insn "*macchwu"
1271 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1272 (plus:SI (mult:SI (lshiftrt:SI
1273 (match_operand:SI 2 "gpc_reg_operand" "r")
1276 (match_operand:HI 1 "gpc_reg_operand" "r")))
1277 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1280 [(set_attr "type" "halfmul")])
1282 (define_insn "*machhwc"
1283 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1284 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1285 (match_operand:SI 1 "gpc_reg_operand" "%r")
1288 (match_operand:SI 2 "gpc_reg_operand" "r")
1290 (match_operand:SI 4 "gpc_reg_operand" "0"))
1292 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1293 (plus:SI (mult:SI (ashiftrt:SI
1302 [(set_attr "type" "halfmul")])
1304 (define_insn "*machhw"
1305 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1306 (plus:SI (mult:SI (ashiftrt:SI
1307 (match_operand:SI 1 "gpc_reg_operand" "%r")
1310 (match_operand:SI 2 "gpc_reg_operand" "r")
1312 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1315 [(set_attr "type" "halfmul")])
1317 (define_insn "*machhwuc"
1318 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1319 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1320 (match_operand:SI 1 "gpc_reg_operand" "%r")
1323 (match_operand:SI 2 "gpc_reg_operand" "r")
1325 (match_operand:SI 4 "gpc_reg_operand" "0"))
1327 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1328 (plus:SI (mult:SI (lshiftrt:SI
1337 [(set_attr "type" "halfmul")])
1339 (define_insn "*machhwu"
1340 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341 (plus:SI (mult:SI (lshiftrt:SI
1342 (match_operand:SI 1 "gpc_reg_operand" "%r")
1345 (match_operand:SI 2 "gpc_reg_operand" "r")
1347 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1350 [(set_attr "type" "halfmul")])
1352 (define_insn "*maclhwc"
1353 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1354 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1355 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1357 (match_operand:HI 2 "gpc_reg_operand" "r")))
1358 (match_operand:SI 4 "gpc_reg_operand" "0"))
1360 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1361 (plus:SI (mult:SI (sign_extend:SI
1368 [(set_attr "type" "halfmul")])
1370 (define_insn "*maclhw"
1371 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1372 (plus:SI (mult:SI (sign_extend:SI
1373 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1375 (match_operand:HI 2 "gpc_reg_operand" "r")))
1376 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1379 [(set_attr "type" "halfmul")])
1381 (define_insn "*maclhwuc"
1382 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1383 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1384 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1386 (match_operand:HI 2 "gpc_reg_operand" "r")))
1387 (match_operand:SI 4 "gpc_reg_operand" "0"))
1389 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390 (plus:SI (mult:SI (zero_extend:SI
1397 [(set_attr "type" "halfmul")])
1399 (define_insn "*maclhwu"
1400 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1401 (plus:SI (mult:SI (zero_extend:SI
1402 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1404 (match_operand:HI 2 "gpc_reg_operand" "r")))
1405 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1408 [(set_attr "type" "halfmul")])
1410 (define_insn "*nmacchwc"
1411 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1412 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1413 (mult:SI (ashiftrt:SI
1414 (match_operand:SI 2 "gpc_reg_operand" "r")
1417 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1419 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1420 (minus:SI (match_dup 4)
1421 (mult:SI (ashiftrt:SI
1428 [(set_attr "type" "halfmul")])
1430 (define_insn "*nmacchw"
1431 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1432 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1433 (mult:SI (ashiftrt:SI
1434 (match_operand:SI 2 "gpc_reg_operand" "r")
1437 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1440 [(set_attr "type" "halfmul")])
1442 (define_insn "*nmachhwc"
1443 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1444 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1445 (mult:SI (ashiftrt:SI
1446 (match_operand:SI 1 "gpc_reg_operand" "%r")
1449 (match_operand:SI 2 "gpc_reg_operand" "r")
1452 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1453 (minus:SI (match_dup 4)
1454 (mult:SI (ashiftrt:SI
1462 [(set_attr "type" "halfmul")])
1464 (define_insn "*nmachhw"
1465 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1466 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1467 (mult:SI (ashiftrt:SI
1468 (match_operand:SI 1 "gpc_reg_operand" "%r")
1471 (match_operand:SI 2 "gpc_reg_operand" "r")
1475 [(set_attr "type" "halfmul")])
1477 (define_insn "*nmaclhwc"
1478 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1479 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1480 (mult:SI (sign_extend:SI
1481 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1483 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1485 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1486 (minus:SI (match_dup 4)
1487 (mult:SI (sign_extend:SI
1493 [(set_attr "type" "halfmul")])
1495 (define_insn "*nmaclhw"
1496 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1497 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1498 (mult:SI (sign_extend:SI
1499 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1501 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1504 [(set_attr "type" "halfmul")])
1506 (define_insn "*mulchwc"
1507 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1508 (compare:CC (mult:SI (ashiftrt:SI
1509 (match_operand:SI 2 "gpc_reg_operand" "r")
1512 (match_operand:HI 1 "gpc_reg_operand" "r")))
1514 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1515 (mult:SI (ashiftrt:SI
1522 [(set_attr "type" "halfmul")])
1524 (define_insn "*mulchw"
1525 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1526 (mult:SI (ashiftrt:SI
1527 (match_operand:SI 2 "gpc_reg_operand" "r")
1530 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1533 [(set_attr "type" "halfmul")])
1535 (define_insn "*mulchwuc"
1536 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1537 (compare:CC (mult:SI (lshiftrt:SI
1538 (match_operand:SI 2 "gpc_reg_operand" "r")
1541 (match_operand:HI 1 "gpc_reg_operand" "r")))
1543 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1544 (mult:SI (lshiftrt:SI
1551 [(set_attr "type" "halfmul")])
1553 (define_insn "*mulchwu"
1554 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1555 (mult:SI (lshiftrt:SI
1556 (match_operand:SI 2 "gpc_reg_operand" "r")
1559 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1562 [(set_attr "type" "halfmul")])
1564 (define_insn "*mulhhwc"
1565 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1566 (compare:CC (mult:SI (ashiftrt:SI
1567 (match_operand:SI 1 "gpc_reg_operand" "%r")
1570 (match_operand:SI 2 "gpc_reg_operand" "r")
1573 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1574 (mult:SI (ashiftrt:SI
1582 [(set_attr "type" "halfmul")])
1584 (define_insn "*mulhhw"
1585 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1586 (mult:SI (ashiftrt:SI
1587 (match_operand:SI 1 "gpc_reg_operand" "%r")
1590 (match_operand:SI 2 "gpc_reg_operand" "r")
1594 [(set_attr "type" "halfmul")])
1596 (define_insn "*mulhhwuc"
1597 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1598 (compare:CC (mult:SI (lshiftrt:SI
1599 (match_operand:SI 1 "gpc_reg_operand" "%r")
1602 (match_operand:SI 2 "gpc_reg_operand" "r")
1605 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1606 (mult:SI (lshiftrt:SI
1614 [(set_attr "type" "halfmul")])
1616 (define_insn "*mulhhwu"
1617 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1618 (mult:SI (lshiftrt:SI
1619 (match_operand:SI 1 "gpc_reg_operand" "%r")
1622 (match_operand:SI 2 "gpc_reg_operand" "r")
1626 [(set_attr "type" "halfmul")])
1628 (define_insn "*mullhwc"
1629 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1630 (compare:CC (mult:SI (sign_extend:SI
1631 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1633 (match_operand:HI 2 "gpc_reg_operand" "r")))
1635 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1636 (mult:SI (sign_extend:SI
1642 [(set_attr "type" "halfmul")])
1644 (define_insn "*mullhw"
1645 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1646 (mult:SI (sign_extend:SI
1647 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1649 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1652 [(set_attr "type" "halfmul")])
1654 (define_insn "*mullhwuc"
1655 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1656 (compare:CC (mult:SI (zero_extend:SI
1657 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1659 (match_operand:HI 2 "gpc_reg_operand" "r")))
1661 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1662 (mult:SI (zero_extend:SI
1668 [(set_attr "type" "halfmul")])
1670 (define_insn "*mullhwu"
1671 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1672 (mult:SI (zero_extend:SI
1673 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1675 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1678 [(set_attr "type" "halfmul")])
1680 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1681 (define_insn "dlmzb"
1682 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1683 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1684 (match_operand:SI 2 "gpc_reg_operand" "r")]
1686 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1687 (unspec:SI [(match_dup 1)
1693 (define_expand "strlensi"
1694 [(set (match_operand:SI 0 "gpc_reg_operand")
1695 (unspec:SI [(match_operand:BLK 1 "general_operand")
1696 (match_operand:QI 2 "const_int_operand")
1697 (match_operand 3 "const_int_operand")]
1698 UNSPEC_DLMZB_STRLEN))
1699 (clobber (match_scratch:CC 4))]
1700 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1702 rtx result = operands[0];
1703 rtx src = operands[1];
1704 rtx search_char = operands[2];
1705 rtx align = operands[3];
1706 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1707 rtx loop_label, end_label, mem, cr0, cond;
1708 if (search_char != const0_rtx
1709 || !CONST_INT_P (align)
1710 || INTVAL (align) < 8)
1712 word1 = gen_reg_rtx (SImode);
1713 word2 = gen_reg_rtx (SImode);
1714 scratch_dlmzb = gen_reg_rtx (SImode);
1715 scratch_string = gen_reg_rtx (Pmode);
1716 loop_label = gen_label_rtx ();
1717 end_label = gen_label_rtx ();
1718 addr = force_reg (Pmode, XEXP (src, 0));
1719 emit_move_insn (scratch_string, addr);
1720 emit_label (loop_label);
1721 mem = change_address (src, SImode, scratch_string);
1722 emit_move_insn (word1, mem);
1723 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1724 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1725 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1726 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1727 emit_jump_insn (gen_rtx_SET (pc_rtx,
1728 gen_rtx_IF_THEN_ELSE (VOIDmode,
1734 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1735 emit_jump_insn (gen_rtx_SET (pc_rtx,
1736 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1738 emit_label (end_label);
1739 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1740 emit_insn (gen_subsi3 (result, scratch_string, addr));
1741 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1745 ;; Fixed-point arithmetic insns.
1747 (define_expand "add<mode>3"
1748 [(set (match_operand:SDI 0 "gpc_reg_operand")
1749 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1750 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1753 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1755 rtx lo0 = gen_lowpart (SImode, operands[0]);
1756 rtx lo1 = gen_lowpart (SImode, operands[1]);
1757 rtx lo2 = gen_lowpart (SImode, operands[2]);
1758 rtx hi0 = gen_highpart (SImode, operands[0]);
1759 rtx hi1 = gen_highpart (SImode, operands[1]);
1760 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1762 if (!reg_or_short_operand (lo2, SImode))
1763 lo2 = force_reg (SImode, lo2);
1764 if (!adde_operand (hi2, SImode))
1765 hi2 = force_reg (SImode, hi2);
1767 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1768 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1772 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1774 rtx tmp = ((!can_create_pseudo_p ()
1775 || rtx_equal_p (operands[0], operands[1]))
1776 ? operands[0] : gen_reg_rtx (<MODE>mode));
1778 /* Adding a constant to r0 is not a valid insn, so use a different
1779 strategy in that case. */
1780 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1782 if (operands[0] == operands[1])
1784 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1785 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1789 HOST_WIDE_INT val = INTVAL (operands[2]);
1790 HOST_WIDE_INT low = sext_hwi (val, 16);
1791 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1793 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1796 /* The ordering here is important for the prolog expander.
1797 When space is allocated from the stack, adding 'low' first may
1798 produce a temporary deallocation (which would be bad). */
1799 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1800 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1805 (define_insn "*add<mode>3"
1806 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1807 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1808 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1815 [(set_attr "type" "add")
1816 (set_attr "isa" "*,*,*,p10")])
1818 (define_insn "*addsi3_high"
1819 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1820 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1821 (high:SI (match_operand 2 "" ""))))]
1822 "TARGET_MACHO && !TARGET_64BIT"
1823 "addis %0,%1,ha16(%2)"
1824 [(set_attr "type" "add")])
1826 (define_insn_and_split "*add<mode>3_dot"
1827 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1828 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1829 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1831 (clobber (match_scratch:GPR 0 "=r,r"))]
1832 "<MODE>mode == Pmode"
1836 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1838 (plus:GPR (match_dup 1)
1841 (compare:CC (match_dup 0)
1844 [(set_attr "type" "add")
1845 (set_attr "dot" "yes")
1846 (set_attr "length" "4,8")])
1848 (define_insn_and_split "*add<mode>3_dot2"
1849 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1850 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1851 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1853 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1854 (plus:GPR (match_dup 1)
1856 "<MODE>mode == Pmode"
1860 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1862 (plus:GPR (match_dup 1)
1865 (compare:CC (match_dup 0)
1868 [(set_attr "type" "add")
1869 (set_attr "dot" "yes")
1870 (set_attr "length" "4,8")])
1872 (define_insn_and_split "*add<mode>3_imm_dot"
1873 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1874 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1875 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1877 (clobber (match_scratch:GPR 0 "=r,r"))
1878 (clobber (reg:GPR CA_REGNO))]
1879 "<MODE>mode == Pmode"
1883 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1885 (plus:GPR (match_dup 1)
1888 (compare:CC (match_dup 0)
1891 [(set_attr "type" "add")
1892 (set_attr "dot" "yes")
1893 (set_attr "length" "4,8")])
1895 (define_insn_and_split "*add<mode>3_imm_dot2"
1896 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1897 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1898 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1900 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1901 (plus:GPR (match_dup 1)
1903 (clobber (reg:GPR CA_REGNO))]
1904 "<MODE>mode == Pmode"
1908 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1910 (plus:GPR (match_dup 1)
1913 (compare:CC (match_dup 0)
1916 [(set_attr "type" "add")
1917 (set_attr "dot" "yes")
1918 (set_attr "length" "4,8")])
1920 ;; Split an add that we can't do in one insn into two insns, each of which
1921 ;; does one 16-bit part. This is used by combine. Note that the low-order
1922 ;; add should be last in case the result gets used in an address.
1925 [(set (match_operand:GPR 0 "gpc_reg_operand")
1926 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1927 (match_operand:GPR 2 "non_add_cint_operand")))]
1929 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1930 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1932 HOST_WIDE_INT val = INTVAL (operands[2]);
1933 HOST_WIDE_INT low = sext_hwi (val, 16);
1934 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1936 operands[4] = GEN_INT (low);
1937 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1938 operands[3] = GEN_INT (rest);
1939 else if (can_create_pseudo_p ())
1941 operands[3] = gen_reg_rtx (DImode);
1942 emit_move_insn (operands[3], operands[2]);
1943 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1951 (define_insn "add<mode>3_carry"
1952 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1953 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1954 (match_operand:P 2 "reg_or_short_operand" "rI")))
1955 (set (reg:P CA_REGNO)
1956 (ltu:P (plus:P (match_dup 1)
1961 [(set_attr "type" "add")])
1963 (define_insn "*add<mode>3_imm_carry_pos"
1964 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1965 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1966 (match_operand:P 2 "short_cint_operand" "n")))
1967 (set (reg:P CA_REGNO)
1968 (geu:P (match_dup 1)
1969 (match_operand:P 3 "const_int_operand" "n")))]
1970 "INTVAL (operands[2]) > 0
1971 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1973 [(set_attr "type" "add")])
1975 (define_insn "*add<mode>3_imm_carry_0"
1976 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1977 (match_operand:P 1 "gpc_reg_operand" "r"))
1978 (set (reg:P CA_REGNO)
1982 [(set_attr "type" "add")])
1984 (define_insn "*add<mode>3_imm_carry_m1"
1985 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1986 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1988 (set (reg:P CA_REGNO)
1993 [(set_attr "type" "add")])
1995 (define_insn "*add<mode>3_imm_carry_neg"
1996 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1997 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1998 (match_operand:P 2 "short_cint_operand" "n")))
1999 (set (reg:P CA_REGNO)
2000 (gtu:P (match_dup 1)
2001 (match_operand:P 3 "const_int_operand" "n")))]
2002 "INTVAL (operands[2]) < 0
2003 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
2005 [(set_attr "type" "add")])
2008 (define_expand "add<mode>3_carry_in"
2010 (set (match_operand:GPR 0 "gpc_reg_operand")
2011 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
2012 (match_operand:GPR 2 "adde_operand"))
2013 (reg:GPR CA_REGNO)))
2014 (clobber (reg:GPR CA_REGNO))])]
2017 if (operands[2] == const0_rtx)
2019 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
2022 if (operands[2] == constm1_rtx)
2024 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
2029 (define_insn "*add<mode>3_carry_in_internal"
2030 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2031 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2032 (match_operand:GPR 2 "gpc_reg_operand" "r"))
2033 (reg:GPR CA_REGNO)))
2034 (clobber (reg:GPR CA_REGNO))]
2037 [(set_attr "type" "add")])
2039 (define_insn "*add<mode>3_carry_in_internal2"
2040 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2041 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2043 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2044 (clobber (reg:GPR CA_REGNO))]
2047 [(set_attr "type" "add")])
2049 (define_insn "add<mode>3_carry_in_0"
2050 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2051 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2052 (reg:GPR CA_REGNO)))
2053 (clobber (reg:GPR CA_REGNO))]
2056 [(set_attr "type" "add")])
2058 (define_insn "add<mode>3_carry_in_m1"
2059 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2060 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2063 (clobber (reg:GPR CA_REGNO))]
2066 [(set_attr "type" "add")])
2069 (define_expand "one_cmpl<mode>2"
2070 [(set (match_operand:SDI 0 "gpc_reg_operand")
2071 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2074 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2076 rs6000_split_logical (operands, NOT, false, false, false);
2081 (define_insn "*one_cmpl<mode>2"
2082 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2083 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2087 (define_insn_and_split "*one_cmpl<mode>2_dot"
2088 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2089 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2091 (clobber (match_scratch:GPR 0 "=r,r"))]
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")])
2107 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2108 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2109 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2111 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2112 (not:GPR (match_dup 1)))]
2113 "<MODE>mode == Pmode"
2117 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2119 (not:GPR (match_dup 1)))
2121 (compare:CC (match_dup 0)
2124 [(set_attr "type" "logical")
2125 (set_attr "dot" "yes")
2126 (set_attr "length" "4,8")])
2129 (define_expand "sub<mode>3"
2130 [(set (match_operand:SDI 0 "gpc_reg_operand")
2131 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2132 (match_operand:SDI 2 "gpc_reg_operand")))]
2135 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2137 rtx lo0 = gen_lowpart (SImode, operands[0]);
2138 rtx lo1 = gen_lowpart (SImode, operands[1]);
2139 rtx lo2 = gen_lowpart (SImode, operands[2]);
2140 rtx hi0 = gen_highpart (SImode, operands[0]);
2141 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2142 rtx hi2 = gen_highpart (SImode, operands[2]);
2144 if (!reg_or_short_operand (lo1, SImode))
2145 lo1 = force_reg (SImode, lo1);
2146 if (!adde_operand (hi1, SImode))
2147 hi1 = force_reg (SImode, hi1);
2149 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2150 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2154 if (short_cint_operand (operands[1], <MODE>mode))
2156 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2161 (define_insn "*subf<mode>3"
2162 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2163 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2164 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2167 [(set_attr "type" "add")])
2169 (define_insn_and_split "*subf<mode>3_dot"
2170 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2171 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2172 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2174 (clobber (match_scratch:GPR 0 "=r,r"))]
2175 "<MODE>mode == Pmode"
2179 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2181 (minus:GPR (match_dup 2)
2184 (compare:CC (match_dup 0)
2187 [(set_attr "type" "add")
2188 (set_attr "dot" "yes")
2189 (set_attr "length" "4,8")])
2191 (define_insn_and_split "*subf<mode>3_dot2"
2192 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2193 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2194 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2196 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2197 (minus:GPR (match_dup 2)
2199 "<MODE>mode == Pmode"
2203 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2205 (minus:GPR (match_dup 2)
2208 (compare:CC (match_dup 0)
2211 [(set_attr "type" "add")
2212 (set_attr "dot" "yes")
2213 (set_attr "length" "4,8")])
2215 (define_insn "subf<mode>3_imm"
2216 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2217 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2218 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2219 (clobber (reg:GPR CA_REGNO))]
2222 [(set_attr "type" "add")])
2224 (define_insn_and_split "subf<mode>3_carry_dot2"
2225 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2226 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2227 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2229 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2230 (minus:P (match_dup 2)
2232 (set (reg:P CA_REGNO)
2233 (leu:P (match_dup 1)
2235 "<MODE>mode == Pmode"
2239 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2240 [(parallel [(set (match_dup 0)
2241 (minus:P (match_dup 2)
2243 (set (reg:P CA_REGNO)
2244 (leu:P (match_dup 1)
2247 (compare:CC (match_dup 0)
2250 [(set_attr "type" "add")
2251 (set_attr "dot" "yes")
2252 (set_attr "length" "4,8")])
2254 (define_insn "subf<mode>3_carry"
2255 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2256 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2257 (match_operand:P 1 "gpc_reg_operand" "r")))
2258 (set (reg:P CA_REGNO)
2259 (leu:P (match_dup 1)
2263 [(set_attr "type" "add")])
2265 (define_insn "*subf<mode>3_imm_carry_0"
2266 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2267 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2268 (set (reg:P CA_REGNO)
2273 [(set_attr "type" "add")])
2275 (define_insn "*subf<mode>3_imm_carry_m1"
2276 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2277 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2278 (set (reg:P CA_REGNO)
2282 [(set_attr "type" "add")])
2285 (define_expand "subf<mode>3_carry_in"
2287 (set (match_operand:GPR 0 "gpc_reg_operand")
2288 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2290 (match_operand:GPR 2 "adde_operand")))
2291 (clobber (reg:GPR CA_REGNO))])]
2294 if (operands[2] == const0_rtx)
2296 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2299 if (operands[2] == constm1_rtx)
2301 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2306 (define_insn "*subf<mode>3_carry_in_internal"
2307 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2308 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2310 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2311 (clobber (reg:GPR CA_REGNO))]
2314 [(set_attr "type" "add")])
2316 (define_insn "subf<mode>3_carry_in_0"
2317 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2318 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2319 (reg:GPR CA_REGNO)))
2320 (clobber (reg:GPR CA_REGNO))]
2323 [(set_attr "type" "add")])
2325 (define_insn "subf<mode>3_carry_in_m1"
2326 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2327 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2328 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2330 (clobber (reg:GPR CA_REGNO))]
2333 [(set_attr "type" "add")])
2335 (define_insn "subf<mode>3_carry_in_xx"
2336 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2337 (plus:GPR (reg:GPR CA_REGNO)
2339 (clobber (reg:GPR CA_REGNO))]
2342 [(set_attr "type" "add")])
2344 (define_insn_and_split "*subfsi3_carry_in_xx_64"
2345 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2346 (sign_extend:DI (plus:SI (reg:SI CA_REGNO)
2351 [(parallel [(set (match_dup 0)
2352 (plus:DI (reg:DI CA_REGNO)
2354 (clobber (reg:DI CA_REGNO))])]
2358 (define_insn "@neg<mode>2"
2359 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2360 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2363 [(set_attr "type" "add")])
2365 (define_insn_and_split "*neg<mode>2_dot"
2366 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2367 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2369 (clobber (match_scratch:GPR 0 "=r,r"))]
2370 "<MODE>mode == Pmode"
2374 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2376 (neg:GPR (match_dup 1)))
2378 (compare:CC (match_dup 0)
2381 [(set_attr "type" "add")
2382 (set_attr "dot" "yes")
2383 (set_attr "length" "4,8")])
2385 (define_insn_and_split "*neg<mode>2_dot2"
2386 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2387 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2389 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2390 (neg:GPR (match_dup 1)))]
2391 "<MODE>mode == Pmode"
2395 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2397 (neg:GPR (match_dup 1)))
2399 (compare:CC (match_dup 0)
2402 [(set_attr "type" "add")
2403 (set_attr "dot" "yes")
2404 (set_attr "length" "4,8")])
2407 (define_insn "clz<mode>2"
2408 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2409 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2412 [(set_attr "type" "cntlz")])
2414 (define_expand "ctz<mode>2"
2415 [(set (match_operand:GPR 0 "gpc_reg_operand")
2416 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2421 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2425 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2426 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2427 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2431 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2432 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2433 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2434 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2438 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2439 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2440 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2441 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2447 (define_insn "ctz<mode>2_hw"
2448 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2449 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2452 [(set_attr "type" "cntlz")])
2454 (define_expand "ffs<mode>2"
2455 [(set (match_operand:GPR 0 "gpc_reg_operand")
2456 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2459 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2460 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2461 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2462 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2463 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2464 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2465 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2470 (define_expand "popcount<mode>2"
2471 [(set (match_operand:GPR 0 "gpc_reg_operand")
2472 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2473 "TARGET_POPCNTB || TARGET_POPCNTD"
2475 rs6000_emit_popcount (operands[0], operands[1]);
2479 (define_insn "popcntb<mode>2"
2480 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2481 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2485 [(set_attr "type" "popcnt")])
2487 (define_insn "popcntd<mode>2"
2488 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2489 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2492 [(set_attr "type" "popcnt")])
2495 (define_expand "parity<mode>2"
2496 [(set (match_operand:GPR 0 "gpc_reg_operand")
2497 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2500 rs6000_emit_parity (operands[0], operands[1]);
2504 (define_insn "parity<mode>2_cmpb"
2505 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2506 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2507 "TARGET_CMPB && TARGET_POPCNTB"
2509 [(set_attr "type" "popcnt")])
2511 (define_insn "cfuged"
2512 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2513 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2514 (match_operand:DI 2 "gpc_reg_operand" "r")]
2516 "TARGET_POWER10 && TARGET_64BIT"
2518 [(set_attr "type" "integer")])
2520 (define_insn "cntlzdm"
2521 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2522 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2523 (match_operand:DI 2 "gpc_reg_operand" "r")]
2525 "TARGET_POWER10 && TARGET_POWERPC64"
2527 [(set_attr "type" "integer")])
2529 (define_insn "cnttzdm"
2530 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2531 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2532 (match_operand:DI 2 "gpc_reg_operand" "r")]
2534 "TARGET_POWER10 && TARGET_POWERPC64"
2536 [(set_attr "type" "integer")])
2538 (define_insn "pdepd"
2539 [(set (match_operand:DI 0 "register_operand" "=r")
2540 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2541 (match_operand:DI 2 "gpc_reg_operand" "r")]
2543 "TARGET_POWER10 && TARGET_POWERPC64"
2545 [(set_attr "type" "integer")])
2547 (define_insn "pextd"
2548 [(set (match_operand:DI 0 "register_operand" "=r")
2549 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2550 (match_operand:DI 2 "gpc_reg_operand" "r")]
2552 "TARGET_POWER10 && TARGET_POWERPC64"
2554 [(set_attr "type" "integer")])
2556 (define_insn "cmpb<mode>3"
2557 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2558 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2559 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2562 [(set_attr "type" "cmp")])
2564 ;; Since the hardware zeros the upper part of the register, save generating the
2565 ;; AND immediate if we are converting to unsigned
2566 (define_insn "*bswap<mode>2_extenddi"
2567 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2569 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2572 [(set_attr "type" "load")])
2574 (define_insn "*bswaphi2_extendsi"
2575 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2577 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2580 [(set_attr "type" "load")])
2582 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2583 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2584 ;; load with byte swap, which can be slower than doing it in the registers. It
2585 ;; also prevents certain failures with the RELOAD register allocator.
2587 (define_expand "bswap<mode>2"
2588 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2589 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2592 rtx dest = operands[0];
2593 rtx src = operands[1];
2595 if (!REG_P (dest) && !REG_P (src))
2596 src = force_reg (<MODE>mode, src);
2600 src = rs6000_force_indexed_or_indirect_mem (src);
2601 emit_insn (gen_bswap<mode>2_load (dest, src));
2603 else if (MEM_P (dest))
2605 dest = rs6000_force_indexed_or_indirect_mem (dest);
2606 emit_insn (gen_bswap<mode>2_store (dest, src));
2609 emit_insn (gen_bswap<mode>2_reg (dest, src));
2613 (define_insn "bswap<mode>2_load"
2614 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2615 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2618 [(set_attr "type" "load")])
2620 (define_insn "bswap<mode>2_store"
2621 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2622 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2625 [(set_attr "type" "store")])
2627 (define_insn_and_split "bswaphi2_reg"
2628 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,&r,wa")
2630 (match_operand:HI 1 "gpc_reg_operand" "r,r,wa")))
2631 (clobber (match_scratch:SI 2 "=X,&r,X"))]
2637 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], HImode)"
2639 (and:SI (lshiftrt:SI (match_dup 4)
2643 (and:SI (ashift:SI (match_dup 4)
2645 (const_int 65280))) ;; 0xff00
2647 (ior:SI (match_dup 3)
2650 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2651 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2653 [(set_attr "length" "*,12,*")
2654 (set_attr "type" "shift,*,vecperm")
2655 (set_attr "isa" "p10,*,p9v")])
2657 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2658 ;; zero_extract insns do not change for -mlittle.
2659 (define_insn_and_split "bswapsi2_reg"
2660 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,wa")
2662 (match_operand:SI 1 "gpc_reg_operand" "r,r,wa")))]
2668 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], SImode)"
2669 [(set (match_dup 0) ; DABC
2670 (rotate:SI (match_dup 1)
2672 (set (match_dup 0) ; DCBC
2673 (ior:SI (and:SI (ashift:SI (match_dup 1)
2675 (const_int 16711680))
2676 (and:SI (match_dup 0)
2677 (const_int -16711681))))
2678 (set (match_dup 0) ; DCBA
2679 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2682 (and:SI (match_dup 0)
2683 (const_int -256))))]
2685 [(set_attr "length" "4,12,4")
2686 (set_attr "type" "shift,*,vecperm")
2687 (set_attr "isa" "p10,*,p9v")])
2689 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2690 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2693 (define_expand "bswapdi2"
2694 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2696 (match_operand:DI 1 "reg_or_mem_operand")))
2697 (clobber (match_scratch:DI 2))
2698 (clobber (match_scratch:DI 3))])]
2701 rtx dest = operands[0];
2702 rtx src = operands[1];
2704 if (!REG_P (dest) && !REG_P (src))
2705 operands[1] = src = force_reg (DImode, src);
2707 if (TARGET_POWERPC64 && TARGET_LDBRX)
2711 src = rs6000_force_indexed_or_indirect_mem (src);
2712 emit_insn (gen_bswapdi2_load (dest, src));
2714 else if (MEM_P (dest))
2716 dest = rs6000_force_indexed_or_indirect_mem (dest);
2717 emit_insn (gen_bswapdi2_store (dest, src));
2719 else if (TARGET_P9_VECTOR)
2720 emit_insn (gen_bswapdi2_brd (dest, src));
2722 emit_insn (gen_bswapdi2_reg (dest, src));
2726 if (!TARGET_POWERPC64)
2728 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2729 that uses 64-bit registers needs the same scratch registers as 64-bit
2731 emit_insn (gen_bswapdi2_32bit (dest, src));
2736 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2737 (define_insn "bswapdi2_load"
2738 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2739 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2740 "TARGET_POWERPC64 && TARGET_LDBRX"
2742 [(set_attr "type" "load")])
2744 (define_insn "bswapdi2_store"
2745 [(set (match_operand:DI 0 "memory_operand" "=Z")
2746 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2747 "TARGET_POWERPC64 && TARGET_LDBRX"
2749 [(set_attr "type" "store")])
2751 (define_insn "bswapdi2_brd"
2752 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,wa")
2753 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r,wa")))]
2758 [(set_attr "type" "shift,vecperm")
2759 (set_attr "isa" "p10,p9v")])
2761 (define_insn "bswapdi2_reg"
2762 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2763 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2764 (clobber (match_scratch:DI 2 "=&r"))
2765 (clobber (match_scratch:DI 3 "=&r"))]
2766 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2768 [(set_attr "length" "36")])
2770 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2771 (define_insn "*bswapdi2_64bit"
2772 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2773 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2774 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2775 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2776 "TARGET_POWERPC64 && !TARGET_LDBRX
2777 && (REG_P (operands[0]) || REG_P (operands[1]))
2778 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2779 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2781 [(set_attr "length" "16,12,36")])
2784 [(set (match_operand:DI 0 "gpc_reg_operand")
2785 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2786 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2787 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2788 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2791 rtx dest = operands[0];
2792 rtx src = operands[1];
2793 rtx op2 = operands[2];
2794 rtx op3 = operands[3];
2795 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2796 BYTES_BIG_ENDIAN ? 4 : 0);
2797 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2798 BYTES_BIG_ENDIAN ? 4 : 0);
2804 addr1 = XEXP (src, 0);
2805 if (GET_CODE (addr1) == PLUS)
2807 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2808 if (TARGET_AVOID_XFORM)
2810 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2814 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2816 else if (TARGET_AVOID_XFORM)
2818 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2823 emit_move_insn (op2, GEN_INT (4));
2824 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2827 word1 = change_address (src, SImode, addr1);
2828 word2 = change_address (src, SImode, addr2);
2830 if (BYTES_BIG_ENDIAN)
2832 emit_insn (gen_bswapsi2 (op3_32, word2));
2833 emit_insn (gen_bswapsi2 (dest_32, word1));
2837 emit_insn (gen_bswapsi2 (op3_32, word1));
2838 emit_insn (gen_bswapsi2 (dest_32, word2));
2841 emit_insn (gen_rotldi3_insert_3 (dest, op3, GEN_INT (32), dest,
2842 GEN_INT (0xffffffff)));
2847 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2848 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2849 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2850 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2851 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2854 rtx dest = operands[0];
2855 rtx src = operands[1];
2856 rtx op2 = operands[2];
2857 rtx op3 = operands[3];
2858 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2859 BYTES_BIG_ENDIAN ? 4 : 0);
2860 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2861 BYTES_BIG_ENDIAN ? 4 : 0);
2867 addr1 = XEXP (dest, 0);
2868 if (GET_CODE (addr1) == PLUS)
2870 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2871 if (TARGET_AVOID_XFORM)
2873 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2877 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2879 else if (TARGET_AVOID_XFORM)
2881 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2886 emit_move_insn (op2, GEN_INT (4));
2887 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2890 word1 = change_address (dest, SImode, addr1);
2891 word2 = change_address (dest, SImode, addr2);
2893 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2895 if (BYTES_BIG_ENDIAN)
2897 emit_insn (gen_bswapsi2 (word1, src_si));
2898 emit_insn (gen_bswapsi2 (word2, op3_si));
2902 emit_insn (gen_bswapsi2 (word2, src_si));
2903 emit_insn (gen_bswapsi2 (word1, op3_si));
2909 [(set (match_operand:DI 0 "gpc_reg_operand")
2910 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2911 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2912 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2913 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2916 rtx dest = operands[0];
2917 rtx src = operands[1];
2918 rtx op2 = operands[2];
2919 rtx op3 = operands[3];
2920 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2921 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2922 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2923 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2924 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2926 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2927 emit_insn (gen_bswapsi2 (op3_si, src_si));
2928 emit_insn (gen_bswapsi2 (dest_si, op2_si));
2929 emit_insn (gen_rotldi3_insert_3 (dest, op3, GEN_INT (32), dest,
2930 GEN_INT (0xffffffff)));
2934 (define_insn "bswapdi2_32bit"
2935 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2936 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2937 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2938 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2940 [(set_attr "length" "16,12,36")])
2943 [(set (match_operand:DI 0 "gpc_reg_operand")
2944 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2945 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2946 "!TARGET_POWERPC64 && reload_completed"
2949 rtx dest = operands[0];
2950 rtx src = operands[1];
2951 rtx op2 = operands[2];
2952 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2953 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2959 addr1 = XEXP (src, 0);
2960 if (GET_CODE (addr1) == PLUS)
2962 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2963 if (TARGET_AVOID_XFORM
2964 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2966 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2970 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2972 else if (TARGET_AVOID_XFORM
2973 || REGNO (addr1) == REGNO (dest2))
2975 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2980 emit_move_insn (op2, GEN_INT (4));
2981 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2984 word1 = change_address (src, SImode, addr1);
2985 word2 = change_address (src, SImode, addr2);
2987 emit_insn (gen_bswapsi2 (dest2, word1));
2988 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2989 thus allowing us to omit an early clobber on the output. */
2990 emit_insn (gen_bswapsi2 (dest1, word2));
2995 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2996 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2997 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2998 "!TARGET_POWERPC64 && reload_completed"
3001 rtx dest = operands[0];
3002 rtx src = operands[1];
3003 rtx op2 = operands[2];
3004 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3005 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3011 addr1 = XEXP (dest, 0);
3012 if (GET_CODE (addr1) == PLUS)
3014 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
3015 if (TARGET_AVOID_XFORM)
3017 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
3021 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
3023 else if (TARGET_AVOID_XFORM)
3025 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
3030 emit_move_insn (op2, GEN_INT (4));
3031 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
3034 word1 = change_address (dest, SImode, addr1);
3035 word2 = change_address (dest, SImode, addr2);
3037 emit_insn (gen_bswapsi2 (word2, src1));
3038 emit_insn (gen_bswapsi2 (word1, src2));
3043 [(set (match_operand:DI 0 "gpc_reg_operand")
3044 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
3045 (clobber (match_operand:SI 2 ""))]
3046 "!TARGET_POWERPC64 && reload_completed"
3049 rtx dest = operands[0];
3050 rtx src = operands[1];
3051 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3052 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3053 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
3054 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
3056 emit_insn (gen_bswapsi2 (dest1, src2));
3057 emit_insn (gen_bswapsi2 (dest2, src1));
3062 (define_insn "mul<mode>3"
3063 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3064 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3065 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
3070 [(set_attr "type" "mul")
3072 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
3074 (match_operand:GPR 2 "short_cint_operand")
3075 (const_string "16")]
3076 (const_string "<bits>")))])
3078 (define_insn_and_split "*mul<mode>3_dot"
3079 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3080 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3081 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3083 (clobber (match_scratch:GPR 0 "=r,r"))]
3084 "<MODE>mode == Pmode"
3088 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3090 (mult:GPR (match_dup 1)
3093 (compare:CC (match_dup 0)
3096 [(set_attr "type" "mul")
3097 (set_attr "size" "<bits>")
3098 (set_attr "dot" "yes")
3099 (set_attr "length" "4,8")])
3101 (define_insn_and_split "*mul<mode>3_dot2"
3102 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3103 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3104 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3106 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3107 (mult:GPR (match_dup 1)
3109 "<MODE>mode == Pmode"
3113 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3115 (mult:GPR (match_dup 1)
3118 (compare:CC (match_dup 0)
3121 [(set_attr "type" "mul")
3122 (set_attr "size" "<bits>")
3123 (set_attr "dot" "yes")
3124 (set_attr "length" "4,8")])
3127 (define_expand "<su>mul<mode>3_highpart"
3128 [(set (match_operand:GPR 0 "gpc_reg_operand")
3130 (mult:<DMODE> (any_extend:<DMODE>
3131 (match_operand:GPR 1 "gpc_reg_operand"))
3133 (match_operand:GPR 2 "gpc_reg_operand")))
3137 if (<MODE>mode == SImode && TARGET_POWERPC64)
3139 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3144 if (!WORDS_BIG_ENDIAN)
3146 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3152 (define_insn "*<su>mul<mode>3_highpart"
3153 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3155 (mult:<DMODE> (any_extend:<DMODE>
3156 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3158 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3160 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3161 "mulh<wd><u> %0,%1,%2"
3162 [(set_attr "type" "mul")
3163 (set_attr "size" "<bits>")])
3165 (define_insn "<su>mulsi3_highpart_le"
3166 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3168 (mult:DI (any_extend:DI
3169 (match_operand:SI 1 "gpc_reg_operand" "r"))
3171 (match_operand:SI 2 "gpc_reg_operand" "r")))
3173 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3175 [(set_attr "type" "mul")])
3177 (define_insn "<su>muldi3_highpart_le"
3178 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3180 (mult:TI (any_extend:TI
3181 (match_operand:DI 1 "gpc_reg_operand" "r"))
3183 (match_operand:DI 2 "gpc_reg_operand" "r")))
3185 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3187 [(set_attr "type" "mul")
3188 (set_attr "size" "64")])
3190 (define_insn "<su>mulsi3_highpart_64"
3191 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3194 (mult:DI (any_extend:DI
3195 (match_operand:SI 1 "gpc_reg_operand" "r"))
3197 (match_operand:SI 2 "gpc_reg_operand" "r")))
3201 [(set_attr "type" "mul")])
3203 (define_expand "<u>mul<mode><dmode>3"
3204 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3205 (mult:<DMODE> (any_extend:<DMODE>
3206 (match_operand:GPR 1 "gpc_reg_operand"))
3208 (match_operand:GPR 2 "gpc_reg_operand"))))]
3209 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3211 rtx l = gen_reg_rtx (<MODE>mode);
3212 rtx h = gen_reg_rtx (<MODE>mode);
3213 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3214 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3215 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3216 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3220 (define_insn "maddld<mode>4"
3221 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3222 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3223 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3224 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3226 "maddld %0,%1,%2,%3"
3227 [(set_attr "type" "mul")])
3229 (define_expand "<u>maddditi4"
3230 [(set (match_operand:TI 0 "gpc_reg_operand")
3232 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand"))
3233 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand")))
3234 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand"))))]
3235 "TARGET_MADDLD && TARGET_POWERPC64"
3237 rtx op0_lo = gen_rtx_SUBREG (DImode, operands[0], BYTES_BIG_ENDIAN ? 8 : 0);
3238 rtx op0_hi = gen_rtx_SUBREG (DImode, operands[0], BYTES_BIG_ENDIAN ? 0 : 8);
3240 emit_insn (gen_maddlddi4 (op0_lo, operands[1], operands[2], operands[3]));
3242 if (BYTES_BIG_ENDIAN)
3243 emit_insn (gen_<u>madddi4_highpart (op0_hi, operands[1], operands[2],
3246 emit_insn (gen_<u>madddi4_highpart_le (op0_hi, operands[1], operands[2],
3251 (define_insn "<u>madddi4_highpart"
3252 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3255 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand" "r"))
3256 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand" "r")))
3257 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand" "r")))
3259 "TARGET_MADDLD && BYTES_BIG_ENDIAN && TARGET_POWERPC64"
3260 "maddhd<u> %0,%1,%2,%3"
3261 [(set_attr "type" "mul")])
3263 (define_insn "<u>madddi4_highpart_le"
3264 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3267 (mult:TI (any_extend:TI (match_operand:DI 1 "gpc_reg_operand" "r"))
3268 (any_extend:TI (match_operand:DI 2 "gpc_reg_operand" "r")))
3269 (any_extend:TI (match_operand:DI 3 "gpc_reg_operand" "r")))
3271 "TARGET_MADDLD && !BYTES_BIG_ENDIAN && TARGET_POWERPC64"
3272 "maddhd<u> %0,%1,%2,%3"
3273 [(set_attr "type" "mul")])
3275 (define_insn "udiv<mode>3"
3276 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3277 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3278 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3281 [(set_attr "type" "div")
3282 (set_attr "size" "<bits>")])
3284 (define_insn "udivti3"
3285 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3286 (udiv:TI (match_operand:TI 1 "altivec_register_operand" "v")
3287 (match_operand:TI 2 "altivec_register_operand" "v")))]
3288 "TARGET_POWER10 && TARGET_POWERPC64"
3290 [(set_attr "type" "vecdiv")
3291 (set_attr "size" "128")])
3293 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3294 ;; modulus. If it isn't a power of two, force operands into register and do
3296 (define_expand "div<mode>3"
3297 [(set (match_operand:GPR 0 "gpc_reg_operand")
3298 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3299 (match_operand:GPR 2 "reg_or_cint_operand")))]
3302 if (CONST_INT_P (operands[2])
3303 && INTVAL (operands[2]) > 0
3304 && exact_log2 (INTVAL (operands[2])) >= 0)
3306 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3310 operands[2] = force_reg (<MODE>mode, operands[2]);
3313 (define_insn "*div<mode>3"
3314 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3315 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3316 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3319 [(set_attr "type" "div")
3320 (set_attr "size" "<bits>")])
3322 (define_insn "div<mode>3_sra"
3323 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3324 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3325 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3326 (clobber (reg:GPR CA_REGNO))]
3328 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3329 [(set_attr "type" "two")
3330 (set_attr "length" "8")])
3332 (define_insn_and_split "*div<mode>3_sra_dot"
3333 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3334 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3335 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3337 (clobber (match_scratch:GPR 0 "=r,r"))
3338 (clobber (reg:GPR CA_REGNO))]
3339 "<MODE>mode == Pmode"
3341 sra<wd>i %0,%1,%p2\;addze. %0,%0
3343 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3344 [(parallel [(set (match_dup 0)
3345 (div:GPR (match_dup 1)
3347 (clobber (reg:GPR CA_REGNO))])
3349 (compare:CC (match_dup 0)
3352 [(set_attr "type" "two")
3353 (set_attr "length" "8,12")
3354 (set_attr "cell_micro" "not")])
3356 (define_insn_and_split "*div<mode>3_sra_dot2"
3357 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3358 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3359 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3361 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3362 (div:GPR (match_dup 1)
3364 (clobber (reg:GPR CA_REGNO))]
3365 "<MODE>mode == Pmode"
3367 sra<wd>i %0,%1,%p2\;addze. %0,%0
3369 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3370 [(parallel [(set (match_dup 0)
3371 (div:GPR (match_dup 1)
3373 (clobber (reg:GPR CA_REGNO))])
3375 (compare:CC (match_dup 0)
3378 [(set_attr "type" "two")
3379 (set_attr "length" "8,12")
3380 (set_attr "cell_micro" "not")])
3382 (define_insn "divti3"
3383 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3384 (div:TI (match_operand:TI 1 "altivec_register_operand" "v")
3385 (match_operand:TI 2 "altivec_register_operand" "v")))]
3386 "TARGET_POWER10 && TARGET_POWERPC64"
3388 [(set_attr "type" "vecdiv")
3389 (set_attr "size" "128")])
3391 (define_expand "mod<mode>3"
3392 [(set (match_operand:GPR 0 "gpc_reg_operand")
3393 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3394 (match_operand:GPR 2 "reg_or_cint_operand")))]
3401 if (!CONST_INT_P (operands[2])
3402 || INTVAL (operands[2]) <= 0
3403 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3408 operands[2] = force_reg (<MODE>mode, operands[2]);
3412 temp1 = gen_reg_rtx (<MODE>mode);
3413 temp2 = gen_reg_rtx (<MODE>mode);
3415 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3416 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3417 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3422 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3423 ;; mod, prefer putting the result of mod into a different register
3424 (define_insn "*mod<mode>3"
3425 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3426 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3427 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3430 [(set_attr "type" "div")
3431 (set_attr "size" "<bits>")])
3434 (define_insn "umod<mode>3"
3435 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3436 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3437 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3440 [(set_attr "type" "div")
3441 (set_attr "size" "<bits>")])
3443 ;; On machines with modulo support, do a combined div/mod the old fashioned
3444 ;; method, since the multiply/subtract is faster than doing the mod instruction
3448 [(set (match_operand:GPR 0 "gpc_reg_operand")
3449 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3450 (match_operand:GPR 2 "gpc_reg_operand")))
3451 (set (match_operand:GPR 3 "gpc_reg_operand")
3452 (mod:GPR (match_dup 1)
3455 && ! reg_mentioned_p (operands[0], operands[1])
3456 && ! reg_mentioned_p (operands[0], operands[2])
3457 && ! reg_mentioned_p (operands[3], operands[1])
3458 && ! reg_mentioned_p (operands[3], operands[2])"
3460 (div:GPR (match_dup 1)
3463 (mult:GPR (match_dup 0)
3466 (minus:GPR (match_dup 1)
3470 [(set (match_operand:GPR 0 "gpc_reg_operand")
3471 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3472 (match_operand:GPR 2 "gpc_reg_operand")))
3473 (set (match_operand:GPR 3 "gpc_reg_operand")
3474 (umod:GPR (match_dup 1)
3477 && ! reg_mentioned_p (operands[0], operands[1])
3478 && ! reg_mentioned_p (operands[0], operands[2])
3479 && ! reg_mentioned_p (operands[3], operands[1])
3480 && ! reg_mentioned_p (operands[3], operands[2])"
3482 (udiv:GPR (match_dup 1)
3485 (mult:GPR (match_dup 0)
3488 (minus:GPR (match_dup 1)
3491 (define_insn "umodti3"
3492 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3493 (umod:TI (match_operand:TI 1 "altivec_register_operand" "v")
3494 (match_operand:TI 2 "altivec_register_operand" "v")))]
3495 "TARGET_POWER10 && TARGET_POWERPC64"
3497 [(set_attr "type" "vecdiv")
3498 (set_attr "size" "128")])
3500 (define_insn "modti3"
3501 [(set (match_operand:TI 0 "altivec_register_operand" "=v")
3502 (mod:TI (match_operand:TI 1 "altivec_register_operand" "v")
3503 (match_operand:TI 2 "altivec_register_operand" "v")))]
3504 "TARGET_POWER10 && TARGET_POWERPC64"
3506 [(set_attr "type" "vecdiv")
3507 (set_attr "size" "128")])
3509 ;; Logical instructions
3510 ;; The logical instructions are mostly combined by using match_operator,
3511 ;; but the plain AND insns are somewhat different because there is no
3512 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3513 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3515 (define_expand "and<mode>3"
3516 [(set (match_operand:SDI 0 "gpc_reg_operand")
3517 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3518 (match_operand:SDI 2 "reg_or_cint_operand")))]
3521 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3523 rs6000_split_logical (operands, AND, false, false, false);
3527 if (CONST_INT_P (operands[2]))
3529 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3531 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3535 if (logical_const_operand (operands[2], <MODE>mode))
3537 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3541 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3543 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3547 operands[2] = force_reg (<MODE>mode, operands[2]);
3552 (define_insn "and<mode>3_imm"
3553 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3554 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3555 (match_operand:GPR 2 "logical_const_operand" "n")))
3556 (clobber (match_scratch:CC 3 "=x"))]
3557 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3558 "andi%e2. %0,%1,%u2"
3559 [(set_attr "type" "logical")
3560 (set_attr "dot" "yes")])
3562 (define_insn_and_split "*and<mode>3_imm_dot"
3563 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3564 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3565 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3567 (clobber (match_scratch:GPR 0 "=r,r"))
3568 (clobber (match_scratch:CC 4 "=X,x"))]
3569 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3570 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3574 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3575 [(parallel [(set (match_dup 0)
3576 (and:GPR (match_dup 1)
3578 (clobber (match_dup 4))])
3580 (compare:CC (match_dup 0)
3583 [(set_attr "type" "logical")
3584 (set_attr "dot" "yes")
3585 (set_attr "length" "4,8")])
3587 (define_insn_and_split "*and<mode>3_imm_dot2"
3588 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3589 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3590 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3592 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3593 (and:GPR (match_dup 1)
3595 (clobber (match_scratch:CC 4 "=X,x"))]
3596 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3597 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3601 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3602 [(parallel [(set (match_dup 0)
3603 (and:GPR (match_dup 1)
3605 (clobber (match_dup 4))])
3607 (compare:CC (match_dup 0)
3610 [(set_attr "type" "logical")
3611 (set_attr "dot" "yes")
3612 (set_attr "length" "4,8")])
3614 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3615 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3616 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3617 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3619 (clobber (match_scratch:GPR 0 "=r,r"))]
3620 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3621 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3625 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3627 (and:GPR (match_dup 1)
3630 (compare:CC (match_dup 0)
3633 [(set_attr "type" "logical")
3634 (set_attr "dot" "yes")
3635 (set_attr "length" "4,8")])
3637 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3638 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3639 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3640 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3642 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3643 (and:GPR (match_dup 1)
3645 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3646 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3650 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3652 (and:GPR (match_dup 1)
3655 (compare:CC (match_dup 0)
3658 [(set_attr "type" "logical")
3659 (set_attr "dot" "yes")
3660 (set_attr "length" "4,8")])
3662 (define_insn "*and<mode>3_imm_dot_shifted"
3663 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3666 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3667 (match_operand:SI 4 "const_int_operand" "n"))
3668 (match_operand:GPR 2 "const_int_operand" "n"))
3670 (clobber (match_scratch:GPR 0 "=r"))]
3671 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3672 << INTVAL (operands[4])),
3674 && (<MODE>mode == Pmode
3675 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3677 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3678 return "andi%e2. %0,%1,%u2";
3680 [(set_attr "type" "logical")
3681 (set_attr "dot" "yes")])
3684 (define_insn "and<mode>3_mask"
3685 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3686 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3687 (match_operand:GPR 2 "const_int_operand" "n")))]
3688 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3690 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3692 [(set_attr "type" "shift")])
3694 (define_insn_and_split "*and<mode>3_mask_dot"
3695 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3696 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3697 (match_operand:GPR 2 "const_int_operand" "n,n"))
3699 (clobber (match_scratch:GPR 0 "=r,r"))]
3700 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3701 && !logical_const_operand (operands[2], <MODE>mode)
3702 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3704 if (which_alternative == 0)
3705 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3709 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3711 (and:GPR (match_dup 1)
3714 (compare:CC (match_dup 0)
3717 [(set_attr "type" "shift")
3718 (set_attr "dot" "yes")
3719 (set_attr "length" "4,8")])
3721 (define_insn_and_split "*and<mode>3_mask_dot2"
3722 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3723 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3724 (match_operand:GPR 2 "const_int_operand" "n,n"))
3726 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3727 (and:GPR (match_dup 1)
3729 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3730 && !logical_const_operand (operands[2], <MODE>mode)
3731 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3733 if (which_alternative == 0)
3734 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3738 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3740 (and:GPR (match_dup 1)
3743 (compare:CC (match_dup 0)
3746 [(set_attr "type" "shift")
3747 (set_attr "dot" "yes")
3748 (set_attr "length" "4,8")])
3751 (define_insn_and_split "*and<mode>3_2insn"
3752 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3753 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3754 (match_operand:GPR 2 "const_int_operand" "n")))]
3755 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3756 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3757 || logical_const_operand (operands[2], <MODE>mode))"
3762 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3765 [(set_attr "type" "shift")
3766 (set_attr "length" "8")])
3768 (define_insn_and_split "*and<mode>3_2insn_dot"
3769 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3770 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3771 (match_operand:GPR 2 "const_int_operand" "n,n"))
3773 (clobber (match_scratch:GPR 0 "=r,r"))]
3774 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3775 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3776 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3777 || logical_const_operand (operands[2], <MODE>mode))"
3779 "&& reload_completed"
3782 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3785 [(set_attr "type" "shift")
3786 (set_attr "dot" "yes")
3787 (set_attr "length" "8,12")])
3789 (define_insn_and_split "*and<mode>3_2insn_dot2"
3790 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3791 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3792 (match_operand:GPR 2 "const_int_operand" "n,n"))
3794 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3795 (and:GPR (match_dup 1)
3797 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3798 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3799 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3800 || logical_const_operand (operands[2], <MODE>mode))"
3802 "&& reload_completed"
3805 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3808 [(set_attr "type" "shift")
3809 (set_attr "dot" "yes")
3810 (set_attr "length" "8,12")])
3812 (define_insn_and_split "*branch_anddi3_dot"
3814 (if_then_else (eq (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
3815 (match_operand:DI 2 "const_int_operand" "n,n"))
3817 (label_ref (match_operand 3 ""))
3819 (clobber (match_scratch:DI 0 "=r,r"))
3820 (clobber (reg:CC CR0_REGNO))]
3821 "rs6000_is_valid_rotate_dot_mask (operands[2], DImode)
3822 && TARGET_POWERPC64"
3824 "&& reload_completed"
3828 if (rs6000_is_valid_mask (operands[2], &nb, &ne, DImode)
3832 unsigned HOST_WIDE_INT val = INTVAL (operands[2]);
3833 int shift = 63 - nb;
3834 rtx tmp = gen_rtx_ASHIFT (DImode, operands[1], GEN_INT (shift));
3835 tmp = gen_rtx_AND (DImode, tmp, GEN_INT (val << shift));
3836 rtx cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
3837 rs6000_emit_dot_insn (operands[0], tmp, 1, cr0);
3838 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
3839 rtx cond = gen_rtx_EQ (CCEQmode, cr0, const0_rtx);
3840 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
3841 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
3847 [(set_attr "type" "shift")
3848 (set_attr "dot" "yes")
3849 (set_attr "length" "8,12")])
3851 (define_expand "<code><mode>3"
3852 [(set (match_operand:SDI 0 "gpc_reg_operand")
3853 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3854 (match_operand:SDI 2 "reg_or_cint_operand")))]
3857 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3859 rs6000_split_logical (operands, <CODE>, false, false, false);
3863 if (non_logical_cint_operand (operands[2], <MODE>mode))
3865 rtx tmp = ((!can_create_pseudo_p ()
3866 || rtx_equal_p (operands[0], operands[1]))
3867 ? operands[0] : gen_reg_rtx (<MODE>mode));
3869 HOST_WIDE_INT value = INTVAL (operands[2]);
3870 HOST_WIDE_INT lo = value & 0xffff;
3871 HOST_WIDE_INT hi = value - lo;
3873 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3874 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3878 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3879 operands[2] = force_reg (<MODE>mode, operands[2]);
3883 [(set (match_operand:GPR 0 "gpc_reg_operand")
3884 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3885 (match_operand:GPR 2 "non_logical_cint_operand")))]
3888 (iorxor:GPR (match_dup 1)
3891 (iorxor:GPR (match_dup 3)
3894 operands[3] = ((!can_create_pseudo_p ()
3895 || rtx_equal_p (operands[0], operands[1]))
3896 ? operands[0] : gen_reg_rtx (<MODE>mode));
3898 HOST_WIDE_INT value = INTVAL (operands[2]);
3899 HOST_WIDE_INT lo = value & 0xffff;
3900 HOST_WIDE_INT hi = value - lo;
3902 operands[4] = GEN_INT (hi);
3903 operands[5] = GEN_INT (lo);
3906 (define_insn "*bool<mode>3_imm"
3907 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3908 (match_operator:GPR 3 "boolean_or_operator"
3909 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3910 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3913 [(set_attr "type" "logical")])
3915 (define_insn "*bool<mode>3"
3916 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3917 (match_operator:GPR 3 "boolean_operator"
3918 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3919 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3922 [(set_attr "type" "logical")])
3924 (define_insn_and_split "*bool<mode>3_dot"
3925 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3926 (compare:CC (match_operator:GPR 3 "boolean_operator"
3927 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3928 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3930 (clobber (match_scratch:GPR 0 "=r,r"))]
3931 "<MODE>mode == Pmode"
3935 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3939 (compare:CC (match_dup 0)
3942 [(set_attr "type" "logical")
3943 (set_attr "dot" "yes")
3944 (set_attr "length" "4,8")])
3946 (define_insn_and_split "*bool<mode>3_dot2"
3947 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3948 (compare:CC (match_operator:GPR 3 "boolean_operator"
3949 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3950 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3952 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3954 "<MODE>mode == Pmode"
3958 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3962 (compare:CC (match_dup 0)
3965 [(set_attr "type" "logical")
3966 (set_attr "dot" "yes")
3967 (set_attr "length" "4,8")])
3970 (define_insn "*boolc<mode>3"
3971 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3972 (match_operator:GPR 3 "boolean_operator"
3973 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3974 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3977 [(set_attr "type" "logical")])
3979 (define_insn_and_split "*boolc<mode>3_dot"
3980 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3981 (compare:CC (match_operator:GPR 3 "boolean_operator"
3982 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3983 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3985 (clobber (match_scratch:GPR 0 "=r,r"))]
3986 "<MODE>mode == Pmode"
3990 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3994 (compare:CC (match_dup 0)
3997 [(set_attr "type" "logical")
3998 (set_attr "dot" "yes")
3999 (set_attr "length" "4,8")])
4001 (define_insn_and_split "*boolc<mode>3_dot2"
4002 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4003 (compare:CC (match_operator:GPR 3 "boolean_operator"
4004 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
4005 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
4007 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4009 "<MODE>mode == Pmode"
4013 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4017 (compare:CC (match_dup 0)
4020 [(set_attr "type" "logical")
4021 (set_attr "dot" "yes")
4022 (set_attr "length" "4,8")])
4025 (define_insn "*boolcc<mode>3"
4026 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4027 (match_operator:GPR 3 "boolean_operator"
4028 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
4029 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
4032 [(set_attr "type" "logical")])
4034 (define_insn_and_split "*boolcc<mode>3_dot"
4035 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4036 (compare:CC (match_operator:GPR 3 "boolean_operator"
4037 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
4038 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
4040 (clobber (match_scratch:GPR 0 "=r,r"))]
4041 "<MODE>mode == Pmode"
4045 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4049 (compare:CC (match_dup 0)
4052 [(set_attr "type" "logical")
4053 (set_attr "dot" "yes")
4054 (set_attr "length" "4,8")])
4056 (define_insn_and_split "*boolcc<mode>3_dot2"
4057 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4058 (compare:CC (match_operator:GPR 3 "boolean_operator"
4059 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
4060 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
4062 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4064 "<MODE>mode == Pmode"
4068 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4072 (compare:CC (match_dup 0)
4075 [(set_attr "type" "logical")
4076 (set_attr "dot" "yes")
4077 (set_attr "length" "4,8")])
4080 ;; TODO: Should have dots of this as well.
4081 (define_insn "*eqv<mode>3"
4082 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4083 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4084 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
4087 [(set_attr "type" "logical")])
4089 ;; Rotate-and-mask and insert.
4091 (define_insn "*rotl<mode>3_mask"
4092 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4093 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4094 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4095 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
4096 (match_operand:GPR 3 "const_int_operand" "n")))]
4097 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4099 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
4101 [(set_attr "type" "shift")
4102 (set_attr "maybe_var_shift" "yes")])
4104 (define_insn_and_split "*rotl<mode>3_mask_dot"
4105 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
4107 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4108 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
4109 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
4110 (match_operand:GPR 3 "const_int_operand" "n,n"))
4112 (clobber (match_scratch:GPR 0 "=r,r"))]
4113 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
4114 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4116 if (which_alternative == 0)
4117 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
4121 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
4123 (and:GPR (match_dup 4)
4126 (compare:CC (match_dup 0)
4129 [(set_attr "type" "shift")
4130 (set_attr "maybe_var_shift" "yes")
4131 (set_attr "dot" "yes")
4132 (set_attr "length" "4,8")])
4134 (define_insn_and_split "*rotl<mode>3_mask_dot2"
4135 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
4137 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4138 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
4139 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
4140 (match_operand:GPR 3 "const_int_operand" "n,n"))
4142 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4143 (and:GPR (match_dup 4)
4145 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
4146 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
4148 if (which_alternative == 0)
4149 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
4153 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
4155 (and:GPR (match_dup 4)
4158 (compare:CC (match_dup 0)
4161 [(set_attr "type" "shift")
4162 (set_attr "maybe_var_shift" "yes")
4163 (set_attr "dot" "yes")
4164 (set_attr "length" "4,8")])
4166 ; Special case for less-than-0. We can do it with just one machine
4167 ; instruction, but the generic optimizers do not realise it is cheap.
4168 (define_insn "*lt0_<mode>di"
4169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4170 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
4174 [(set_attr "type" "shift")])
4176 (define_insn "*lt0_<mode>si"
4177 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4178 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
4181 "rlwinm %0,%1,1,31,31"
4182 [(set_attr "type" "shift")])
4186 ; Two forms for insert (the two arms of the IOR are not canonicalized,
4187 ; both are an AND so are the same precedence).
4188 (define_insn "*rotl<mode>3_insert"
4189 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4190 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4191 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4192 (match_operand:SI 2 "const_int_operand" "n")])
4193 (match_operand:GPR 3 "const_int_operand" "n"))
4194 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4195 (match_operand:GPR 6 "const_int_operand" "n"))))]
4196 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4197 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4199 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4201 [(set_attr "type" "insert")])
4202 ; FIXME: this needs an attr "size", so that the scheduler can see the
4203 ; difference between rlwimi and rldimi. We also might want dot forms,
4204 ; but not for rlwimi on POWER4 and similar processors.
4206 (define_insn "*rotl<mode>3_insert_2"
4207 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4208 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4209 (match_operand:GPR 6 "const_int_operand" "n"))
4210 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4211 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4212 (match_operand:SI 2 "const_int_operand" "n")])
4213 (match_operand:GPR 3 "const_int_operand" "n"))))]
4214 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4215 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4217 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4219 [(set_attr "type" "insert")])
4221 ; There are also some forms without one of the ANDs.
4222 (define_insn "rotl<mode>3_insert_3"
4223 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4224 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4225 (match_operand:GPR 4 "const_int_operand" "n"))
4226 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4227 (match_operand:SI 2 "const_int_operand" "n"))))]
4228 "INTVAL (operands[2]) > 0
4229 && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4231 if (<MODE>mode == SImode)
4232 return "rlwimi %0,%1,%h2,0,31-%h2";
4234 return "rldimi %0,%1,%H2,0";
4236 [(set_attr "type" "insert")])
4238 ; Canonicalize the PLUS and XOR forms to IOR for rotl<mode>3_insert_3
4239 (define_code_iterator plus_xor [plus xor])
4241 (define_insn_and_split "*rotl<mode>3_insert_3_<code>"
4242 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4244 (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4245 (match_operand:GPR 4 "const_int_operand" "n"))
4246 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4247 (match_operand:SI 2 "const_int_operand" "n"))))]
4248 "INTVAL (operands[2]) > 0
4249 && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4253 (ior:GPR (and:GPR (match_dup 3) (match_dup 4))
4254 (ashift:GPR (match_dup 1) (match_dup 2))))])
4256 (define_code_iterator plus_ior_xor [plus ior xor])
4259 [(set (match_operand:GPR 0 "gpc_reg_operand")
4260 (plus_ior_xor:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4261 (match_operand:SI 2 "const_int_operand"))
4262 (match_operand:GPR 3 "gpc_reg_operand")))]
4263 "nonzero_bits (operands[3], <MODE>mode)
4264 < HOST_WIDE_INT_1U << INTVAL (operands[2])"
4266 (ior:GPR (and:GPR (match_dup 3)
4268 (ashift:GPR (match_dup 1)
4271 operands[4] = GEN_INT ((HOST_WIDE_INT_1U << INTVAL (operands[2])) - 1);
4274 (define_insn "*rotlsi3_insert_4"
4275 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4276 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "0")
4277 (match_operand:SI 4 "const_int_operand" "n"))
4278 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4279 (match_operand:SI 2 "const_int_operand" "n"))))]
4280 "INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4])) == 32"
4281 "rlwimi %0,%1,32-%h2,%h2,31"
4282 [(set_attr "type" "insert")])
4284 (define_insn "*rotlsi3_insert_5"
4285 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4286 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4287 (match_operand:SI 2 "const_int_operand" "n,n"))
4288 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4289 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4290 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4291 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4292 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4296 [(set_attr "type" "insert")])
4298 (define_insn "*rotldi3_insert_6"
4299 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4300 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4301 (match_operand:DI 2 "const_int_operand" "n"))
4302 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4303 (match_operand:DI 4 "const_int_operand" "n"))))]
4304 "exact_log2 (-UINTVAL (operands[2])) > 0
4305 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4307 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4308 return "rldimi %0,%3,0,%5";
4310 [(set_attr "type" "insert")
4311 (set_attr "size" "64")])
4313 (define_insn "*rotldi3_insert_7"
4314 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4315 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4316 (match_operand:DI 4 "const_int_operand" "n"))
4317 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4318 (match_operand:DI 2 "const_int_operand" "n"))))]
4319 "exact_log2 (-UINTVAL (operands[2])) > 0
4320 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4322 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4323 return "rldimi %0,%3,0,%5";
4325 [(set_attr "type" "insert")
4326 (set_attr "size" "64")])
4329 ; This handles the important case of multiple-precision shifts. There is
4330 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4332 [(set (match_operand:GPR 0 "gpc_reg_operand")
4333 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4334 (match_operand:SI 3 "const_int_operand"))
4335 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4336 (match_operand:SI 4 "const_int_operand"))))]
4337 "can_create_pseudo_p ()
4338 && INTVAL (operands[3]) + INTVAL (operands[4])
4339 >= GET_MODE_PRECISION (<MODE>mode)"
4341 (lshiftrt:GPR (match_dup 2)
4344 (ior:GPR (and:GPR (match_dup 5)
4346 (ashift:GPR (match_dup 1)
4349 unsigned HOST_WIDE_INT mask = 1;
4350 mask = (mask << INTVAL (operands[3])) - 1;
4351 operands[5] = gen_reg_rtx (<MODE>mode);
4352 operands[6] = GEN_INT (mask);
4356 [(set (match_operand:GPR 0 "gpc_reg_operand")
4357 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4358 (match_operand:SI 4 "const_int_operand"))
4359 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4360 (match_operand:SI 3 "const_int_operand"))))]
4361 "can_create_pseudo_p ()
4362 && INTVAL (operands[3]) + INTVAL (operands[4])
4363 >= GET_MODE_PRECISION (<MODE>mode)"
4365 (lshiftrt:GPR (match_dup 2)
4368 (ior:GPR (and:GPR (match_dup 5)
4370 (ashift:GPR (match_dup 1)
4373 unsigned HOST_WIDE_INT mask = 1;
4374 mask = (mask << INTVAL (operands[3])) - 1;
4375 operands[5] = gen_reg_rtx (<MODE>mode);
4376 operands[6] = GEN_INT (mask);
4380 ; Another important case is setting some bits to 1; we can do that with
4381 ; an insert instruction, in many cases.
4382 (define_insn_and_split "*ior<mode>_mask"
4383 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4384 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4385 (match_operand:GPR 2 "const_int_operand" "n")))
4386 (clobber (match_scratch:GPR 3 "=r"))]
4387 "!logical_const_operand (operands[2], <MODE>mode)
4388 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4394 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4397 (and:GPR (match_dup 1)
4401 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4402 if (GET_CODE (operands[3]) == SCRATCH)
4403 operands[3] = gen_reg_rtx (<MODE>mode);
4404 operands[4] = GEN_INT (ne);
4405 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4407 [(set_attr "type" "two")
4408 (set_attr "length" "8")])
4411 ; Yet another case is an rldimi with the second value coming from memory.
4412 ; The zero_extend that should become part of the rldimi is merged into the
4413 ; load from memory instead. Split things properly again.
4415 [(set (match_operand:DI 0 "gpc_reg_operand")
4416 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4417 (match_operand:SI 2 "const_int_operand"))
4418 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4419 "INTVAL (operands[2]) == <bits>"
4421 (zero_extend:DI (match_dup 3)))
4423 (ior:DI (and:DI (match_dup 4)
4425 (ashift:DI (match_dup 1)
4428 operands[4] = gen_reg_rtx (DImode);
4429 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4432 ; rldimi with UNSPEC_SI_FROM_SF.
4433 (define_insn_and_split "*rotldi3_insert_sf"
4434 [(set (match_operand:DI 0 "gpc_reg_operand")
4436 (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4437 (match_operand:SI 2 "const_int_operand"))
4440 [(match_operand:SF 3 "memory_operand")]
4441 UNSPEC_SI_FROM_SF))))
4442 (clobber (match_scratch:V4SF 4))]
4443 "TARGET_POWERPC64 && INTVAL (operands[2]) == <bits>"
4446 [(parallel [(set (match_dup 5)
4447 (zero_extend:DI (unspec:QHSI [(match_dup 3)] UNSPEC_SI_FROM_SF)))
4448 (clobber (match_dup 4))])
4451 (and:DI (match_dup 5) (match_dup 6))
4452 (ashift:DI (match_dup 1) (match_dup 2))))]
4454 operands[5] = gen_reg_rtx (DImode);
4455 operands[6] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4460 [(set (match_operand:SI 0 "gpc_reg_operand")
4461 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4462 (match_operand:SI 2 "const_int_operand"))
4463 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4464 "INTVAL (operands[2]) == <bits>"
4466 (zero_extend:SI (match_dup 3)))
4468 (ior:SI (and:SI (match_dup 4)
4470 (ashift:SI (match_dup 1)
4473 operands[4] = gen_reg_rtx (SImode);
4474 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4478 ;; Now the simple shifts.
4480 (define_insn "rotl<mode>3"
4481 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4482 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4483 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4485 "rotl<wd>%I2 %0,%1,%<hH>2"
4486 [(set_attr "type" "shift")
4487 (set_attr "maybe_var_shift" "yes")])
4489 (define_insn "*rotlsi3_64"
4490 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4492 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4493 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4495 "rotlw%I2 %0,%1,%h2"
4496 [(set_attr "type" "shift")
4497 (set_attr "maybe_var_shift" "yes")])
4499 (define_insn_and_split "*rotl<mode>3_dot"
4500 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4501 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4502 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4504 (clobber (match_scratch:GPR 0 "=r,r"))]
4505 "<MODE>mode == Pmode"
4507 rotl<wd>%I2. %0,%1,%<hH>2
4509 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4511 (rotate:GPR (match_dup 1)
4514 (compare:CC (match_dup 0)
4517 [(set_attr "type" "shift")
4518 (set_attr "maybe_var_shift" "yes")
4519 (set_attr "dot" "yes")
4520 (set_attr "length" "4,8")])
4522 (define_insn_and_split "*rotl<mode>3_dot2"
4523 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4524 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4525 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4527 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4528 (rotate:GPR (match_dup 1)
4530 "<MODE>mode == Pmode"
4532 rotl<wd>%I2. %0,%1,%<hH>2
4534 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4536 (rotate:GPR (match_dup 1)
4539 (compare:CC (match_dup 0)
4542 [(set_attr "type" "shift")
4543 (set_attr "maybe_var_shift" "yes")
4544 (set_attr "dot" "yes")
4545 (set_attr "length" "4,8")])
4548 (define_insn "ashl<mode>3"
4549 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4550 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4551 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4553 "sl<wd>%I2 %0,%1,%<hH>2"
4554 [(set_attr "type" "shift")
4555 (set_attr "maybe_var_shift" "yes")])
4557 (define_insn "*ashlsi3_64"
4558 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4560 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4561 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4564 [(set_attr "type" "shift")
4565 (set_attr "maybe_var_shift" "yes")])
4567 (define_insn_and_split "*ashl<mode>3_dot"
4568 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4569 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4570 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4572 (clobber (match_scratch:GPR 0 "=r,r"))]
4573 "<MODE>mode == Pmode"
4575 sl<wd>%I2. %0,%1,%<hH>2
4577 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4579 (ashift:GPR (match_dup 1)
4582 (compare:CC (match_dup 0)
4585 [(set_attr "type" "shift")
4586 (set_attr "maybe_var_shift" "yes")
4587 (set_attr "dot" "yes")
4588 (set_attr "length" "4,8")])
4590 (define_insn_and_split "*ashl<mode>3_dot2"
4591 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4592 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4593 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4595 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4596 (ashift:GPR (match_dup 1)
4598 "<MODE>mode == Pmode"
4600 sl<wd>%I2. %0,%1,%<hH>2
4602 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4604 (ashift:GPR (match_dup 1)
4607 (compare:CC (match_dup 0)
4610 [(set_attr "type" "shift")
4611 (set_attr "maybe_var_shift" "yes")
4612 (set_attr "dot" "yes")
4613 (set_attr "length" "4,8")])
4615 ;; Pretend we have a memory form of extswsli until register allocation is done
4616 ;; so that we use LWZ to load the value from memory, instead of LWA.
4617 (define_insn_and_split "ashdi3_extswsli"
4618 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4620 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4621 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4626 "&& reload_completed && MEM_P (operands[1])"
4630 (ashift:DI (sign_extend:DI (match_dup 3))
4633 operands[3] = gen_lowpart (SImode, operands[0]);
4635 [(set_attr "type" "shift")
4636 (set_attr "maybe_var_shift" "no")])
4639 (define_insn_and_split "ashdi3_extswsli_dot"
4640 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4643 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4644 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4646 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4653 "&& reload_completed
4654 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4655 || memory_operand (operands[1], SImode))"
4658 rtx dest = operands[0];
4659 rtx src = operands[1];
4660 rtx shift = operands[2];
4661 rtx cr = operands[3];
4668 src2 = gen_lowpart (SImode, dest);
4669 emit_move_insn (src2, src);
4672 if (REGNO (cr) == CR0_REGNO)
4674 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4678 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4679 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4682 [(set_attr "type" "shift")
4683 (set_attr "maybe_var_shift" "no")
4684 (set_attr "dot" "yes")
4685 (set_attr "length" "4,8,8,12")])
4687 (define_insn_and_split "ashdi3_extswsli_dot2"
4688 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4691 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4692 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4694 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4695 (ashift:DI (sign_extend:DI (match_dup 1))
4703 "&& reload_completed
4704 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4705 || memory_operand (operands[1], SImode))"
4708 rtx dest = operands[0];
4709 rtx src = operands[1];
4710 rtx shift = operands[2];
4711 rtx cr = operands[3];
4718 src2 = gen_lowpart (SImode, dest);
4719 emit_move_insn (src2, src);
4722 if (REGNO (cr) == CR0_REGNO)
4724 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4728 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4729 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4732 [(set_attr "type" "shift")
4733 (set_attr "maybe_var_shift" "no")
4734 (set_attr "dot" "yes")
4735 (set_attr "length" "4,8,8,12")])
4737 (define_insn "lshr<mode>3"
4738 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4739 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4740 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4742 "sr<wd>%I2 %0,%1,%<hH>2"
4743 [(set_attr "type" "shift")
4744 (set_attr "maybe_var_shift" "yes")])
4746 (define_insn "*lshrsi3_64"
4747 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4749 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4750 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4753 [(set_attr "type" "shift")
4754 (set_attr "maybe_var_shift" "yes")])
4756 (define_insn_and_split "*lshr<mode>3_dot"
4757 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4758 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4759 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4761 (clobber (match_scratch:GPR 0 "=r,r"))]
4762 "<MODE>mode == Pmode"
4764 sr<wd>%I2. %0,%1,%<hH>2
4766 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4768 (lshiftrt:GPR (match_dup 1)
4771 (compare:CC (match_dup 0)
4774 [(set_attr "type" "shift")
4775 (set_attr "maybe_var_shift" "yes")
4776 (set_attr "dot" "yes")
4777 (set_attr "length" "4,8")])
4779 (define_insn_and_split "*lshr<mode>3_dot2"
4780 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4781 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4782 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4784 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4785 (lshiftrt:GPR (match_dup 1)
4787 "<MODE>mode == Pmode"
4789 sr<wd>%I2. %0,%1,%<hH>2
4791 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4793 (lshiftrt:GPR (match_dup 1)
4796 (compare:CC (match_dup 0)
4799 [(set_attr "type" "shift")
4800 (set_attr "maybe_var_shift" "yes")
4801 (set_attr "dot" "yes")
4802 (set_attr "length" "4,8")])
4805 (define_insn "ashr<mode>3"
4806 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4807 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4808 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4809 (clobber (reg:GPR CA_REGNO))]
4811 "sra<wd>%I2 %0,%1,%<hH>2"
4812 [(set_attr "type" "shift")
4813 (set_attr "maybe_var_shift" "yes")])
4815 (define_insn "*ashrsi3_64"
4816 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4818 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4819 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4820 (clobber (reg:SI CA_REGNO))]
4823 [(set_attr "type" "shift")
4824 (set_attr "maybe_var_shift" "yes")])
4826 (define_insn_and_split "*ashr<mode>3_dot"
4827 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4828 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4829 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4831 (clobber (match_scratch:GPR 0 "=r,r"))
4832 (clobber (reg:GPR CA_REGNO))]
4833 "<MODE>mode == Pmode"
4835 sra<wd>%I2. %0,%1,%<hH>2
4837 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4838 [(parallel [(set (match_dup 0)
4839 (ashiftrt:GPR (match_dup 1)
4841 (clobber (reg:GPR CA_REGNO))])
4843 (compare:CC (match_dup 0)
4846 [(set_attr "type" "shift")
4847 (set_attr "maybe_var_shift" "yes")
4848 (set_attr "dot" "yes")
4849 (set_attr "length" "4,8")])
4851 (define_insn_and_split "*ashr<mode>3_dot2"
4852 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4853 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4854 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4856 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4857 (ashiftrt:GPR (match_dup 1)
4859 (clobber (reg:GPR CA_REGNO))]
4860 "<MODE>mode == Pmode"
4862 sra<wd>%I2. %0,%1,%<hH>2
4864 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4865 [(parallel [(set (match_dup 0)
4866 (ashiftrt:GPR (match_dup 1)
4868 (clobber (reg:GPR CA_REGNO))])
4870 (compare:CC (match_dup 0)
4873 [(set_attr "type" "shift")
4874 (set_attr "maybe_var_shift" "yes")
4875 (set_attr "dot" "yes")
4876 (set_attr "length" "4,8")])
4878 ;; Builtins to replace a division to generate FRE reciprocal estimate
4879 ;; instructions and the necessary fixup instructions
4880 (define_expand "recip<mode>3"
4881 [(match_operand:RECIPF 0 "gpc_reg_operand")
4882 (match_operand:RECIPF 1 "gpc_reg_operand")
4883 (match_operand:RECIPF 2 "gpc_reg_operand")]
4884 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4886 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4890 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4891 ;; hardware division. This is only done before register allocation and with
4892 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4893 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4894 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4896 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4897 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4898 (match_operand 2 "gpc_reg_operand")))]
4899 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4900 && can_create_pseudo_p () && flag_finite_math_only
4901 && !flag_trapping_math && flag_reciprocal_math"
4904 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4908 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4909 ;; appropriate fixup.
4910 (define_expand "rsqrt<mode>2"
4911 [(match_operand:RECIPF 0 "gpc_reg_operand")
4912 (match_operand:RECIPF 1 "gpc_reg_operand")]
4913 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4915 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4919 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4920 ;; modes here, and also add in conditional vsx/power8-vector support to access
4921 ;; values in the traditional Altivec registers if the appropriate
4922 ;; -mupper-regs-{df,sf} option is enabled.
4924 (define_expand "abs<mode>2"
4925 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4926 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4930 (define_insn "*abs<mode>2_fpr"
4931 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4932 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
4937 [(set_attr "type" "fpsimple")])
4939 (define_insn "*nabs<mode>2_fpr"
4940 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4943 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))))]
4948 [(set_attr "type" "fpsimple")])
4950 (define_expand "neg<mode>2"
4951 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4952 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4956 (define_insn "*neg<mode>2_fpr"
4957 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4958 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
4963 [(set_attr "type" "fpsimple")])
4965 (define_expand "add<mode>3"
4966 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4967 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4968 (match_operand:SFDF 2 "gpc_reg_operand")))]
4972 (define_insn "*add<mode>3_fpr"
4973 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4974 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa")
4975 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
4979 xsadd<sd>p %x0,%x1,%x2"
4980 [(set_attr "type" "fp")
4981 (set_attr "isa" "*,<Fisa>")])
4983 (define_expand "sub<mode>3"
4984 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4985 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4986 (match_operand:SFDF 2 "gpc_reg_operand")))]
4990 (define_insn "*sub<mode>3_fpr"
4991 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
4992 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
4993 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
4997 xssub<sd>p %x0,%x1,%x2"
4998 [(set_attr "type" "fp")
4999 (set_attr "isa" "*,<Fisa>")])
5001 (define_expand "mul<mode>3"
5002 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5003 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5004 (match_operand:SFDF 2 "gpc_reg_operand")))]
5008 (define_insn "*mul<mode>3_fpr"
5009 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5010 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa")
5011 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5015 xsmul<sd>p %x0,%x1,%x2"
5016 [(set_attr "type" "dmul")
5017 (set_attr "isa" "*,<Fisa>")])
5019 (define_expand "div<mode>3"
5020 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5021 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5022 (match_operand:SFDF 2 "gpc_reg_operand")))]
5025 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
5026 && can_create_pseudo_p () && flag_finite_math_only
5027 && !flag_trapping_math && flag_reciprocal_math)
5029 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
5034 (define_insn "*div<mode>3_fpr"
5035 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5036 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5037 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5041 xsdiv<sd>p %x0,%x1,%x2"
5042 [(set_attr "type" "<sd>div")
5043 (set_attr "isa" "*,<Fisa>")])
5045 (define_insn "*sqrt<mode>2_internal"
5046 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5047 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5048 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
5051 xssqrt<sd>p %x0,%x1"
5052 [(set_attr "type" "<sd>sqrt")
5053 (set_attr "isa" "*,<Fisa>")])
5055 (define_expand "sqrt<mode>2"
5056 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5057 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
5058 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
5060 if (<MODE>mode == SFmode
5061 && TARGET_RECIP_PRECISION
5062 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
5063 && !optimize_function_for_size_p (cfun)
5064 && flag_finite_math_only && !flag_trapping_math
5065 && flag_unsafe_math_optimizations)
5067 rs6000_emit_swsqrt (operands[0], operands[1], 0);
5072 ;; Floating point reciprocal approximation
5073 (define_insn "fre<sd>"
5074 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5075 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
5081 [(set_attr "type" "fp")
5082 (set_attr "isa" "*,<Fisa>")])
5084 (define_expand "fmod<mode>3"
5085 [(use (match_operand:SFDF 0 "gpc_reg_operand"))
5086 (use (match_operand:SFDF 1 "gpc_reg_operand"))
5087 (use (match_operand:SFDF 2 "gpc_reg_operand"))]
5090 && flag_unsafe_math_optimizations"
5092 rtx div = gen_reg_rtx (<MODE>mode);
5093 emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
5095 rtx friz = gen_reg_rtx (<MODE>mode);
5096 emit_insn (gen_btrunc<mode>2 (friz, div));
5098 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], friz, operands[1]));
5102 (define_expand "remainder<mode>3"
5103 [(use (match_operand:SFDF 0 "gpc_reg_operand"))
5104 (use (match_operand:SFDF 1 "gpc_reg_operand"))
5105 (use (match_operand:SFDF 2 "gpc_reg_operand"))]
5108 && flag_unsafe_math_optimizations"
5110 rtx div = gen_reg_rtx (<MODE>mode);
5111 emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
5113 rtx frin = gen_reg_rtx (<MODE>mode);
5114 emit_insn (gen_round<mode>2 (frin, div));
5116 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], frin, operands[1]));
5120 (define_insn "*rsqrt<mode>2"
5121 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5122 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
5124 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
5127 xsrsqrte<sd>p %x0,%x1"
5128 [(set_attr "type" "fp")
5129 (set_attr "isa" "*,<Fisa>")])
5131 ;; Floating point comparisons
5132 (define_insn "*cmp<mode>_fpr"
5133 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
5134 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5135 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")))]
5139 xscmpudp %0,%x1,%x2"
5140 [(set_attr "type" "fpcompare")
5141 (set_attr "isa" "*,<Fisa>")])
5143 ;; Floating point conversions
5144 (define_expand "extendsfdf2"
5145 [(set (match_operand:DF 0 "gpc_reg_operand")
5146 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
5149 if (HONOR_SNANS (SFmode))
5150 operands[1] = force_reg (SFmode, operands[1]);
5153 (define_insn_and_split "*extendsfdf2_fpr"
5154 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
5155 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
5156 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
5162 xscpsgndp %x0,%x1,%x1
5165 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
5168 emit_note (NOTE_INSN_DELETED);
5171 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
5172 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
5174 (define_insn "*extendsfdf2_snan"
5175 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
5176 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
5177 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
5181 [(set_attr "type" "fp")
5182 (set_attr "isa" "*,p8v")])
5184 (define_expand "truncdfsf2"
5185 [(set (match_operand:SF 0 "gpc_reg_operand")
5186 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
5190 (define_insn "*truncdfsf2_fpr"
5191 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
5192 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
5197 [(set_attr "type" "fp")
5198 (set_attr "isa" "*,p8v")])
5200 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
5201 ;; builtins.cc and optabs.cc that are not correct for IBM long double
5202 ;; when little-endian.
5203 (define_expand "signbit<mode>2"
5205 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
5207 (subreg:DI (match_dup 2) 0))
5210 (set (match_operand:SI 0 "gpc_reg_operand")
5213 && (!FLOAT128_IEEE_P (<MODE>mode)
5214 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
5216 if (FLOAT128_IEEE_P (<MODE>mode))
5218 rtx dest = operands[0];
5219 rtx src = operands[1];
5220 rtx tmp = gen_reg_rtx (DImode);
5221 rtx dest_di = gen_lowpart (DImode, dest);
5223 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
5224 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
5227 operands[2] = gen_reg_rtx (DFmode);
5228 operands[3] = gen_reg_rtx (DImode);
5229 if (TARGET_POWERPC64)
5231 operands[4] = gen_reg_rtx (DImode);
5232 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
5233 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
5234 WORDS_BIG_ENDIAN ? 4 : 0);
5238 operands[4] = gen_reg_rtx (SImode);
5239 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
5240 WORDS_BIG_ENDIAN ? 0 : 4);
5241 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
5245 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
5246 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
5247 ;; register allocator would typically move the entire _Float128 item to GPRs (2
5248 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
5250 ;; After register allocation, if the _Float128 had originally been in GPRs, the
5251 ;; split allows the post reload phases to eliminate the move, and do the shift
5252 ;; directly with the register that contains the signbit.
5253 (define_insn_and_split "@signbit<mode>2_dm"
5254 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5255 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
5257 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5261 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
5265 operands[2] = gen_highpart (DImode, operands[1]);
5267 [(set_attr "type" "mfvsr,*")])
5269 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
5270 ;; register and then doing a direct move if the value comes from memory. On
5271 ;; little endian, we have to load the 2nd double-word to get the sign bit.
5272 (define_insn_and_split "*signbit<mode>2_dm_mem"
5273 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
5274 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
5276 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5282 rtx dest = operands[0];
5283 rtx src = operands[1];
5284 rtx addr = XEXP (src, 0);
5286 if (WORDS_BIG_ENDIAN)
5287 operands[2] = adjust_address (src, DImode, 0);
5289 else if (REG_P (addr) || SUBREG_P (addr))
5290 operands[2] = adjust_address (src, DImode, 8);
5292 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
5293 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
5294 operands[2] = adjust_address (src, DImode, 8);
5298 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
5299 emit_insn (gen_rtx_SET (tmp, addr));
5300 operands[2] = change_address (src, DImode,
5301 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
5305 (define_expand "copysign<mode>3"
5307 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
5309 (neg:SFDF (abs:SFDF (match_dup 1))))
5310 (set (match_operand:SFDF 0 "gpc_reg_operand")
5311 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5316 && ((TARGET_PPC_GFXOPT
5317 && !HONOR_NANS (<MODE>mode)
5318 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5320 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5322 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5324 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5329 operands[3] = gen_reg_rtx (<MODE>mode);
5330 operands[4] = gen_reg_rtx (<MODE>mode);
5331 operands[5] = CONST0_RTX (<MODE>mode);
5334 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5335 ;; compiler from optimizing -0.0
5336 (define_insn "copysign<mode>3_fcpsgn"
5337 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5338 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")
5339 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa")]
5341 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5344 xscpsgndp %x0,%x2,%x1"
5345 [(set_attr "type" "fpsimple")])
5347 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5348 ;; fsel instruction and some auxiliary computations. Then we just have a
5349 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5351 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5352 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5353 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5354 ;; define_splits to make them if made by combine. On VSX machines we have the
5355 ;; min/max instructions.
5357 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5358 ;; to allow either DF/SF to use only traditional registers.
5360 (define_expand "s<minmax><mode>3"
5361 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5362 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5363 (match_operand:SFDF 2 "gpc_reg_operand")))]
5366 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5370 (define_insn "*s<minmax><mode>3_vsx"
5371 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
5372 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "wa")
5373 (match_operand:SFDF 2 "vsx_register_operand" "wa")))]
5374 "TARGET_VSX && TARGET_HARD_FLOAT"
5376 return (TARGET_P9_MINMAX
5377 ? "xs<minmax>cdp %x0,%x1,%x2"
5378 : "xs<minmax>dp %x0,%x1,%x2");
5380 [(set_attr "type" "fp")])
5382 ;; Min/max for ISA 3.1 IEEE 128-bit floating point
5383 (define_insn "s<minmax><mode>3"
5384 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
5386 (match_operand:IEEE128 1 "altivec_register_operand" "v")
5387 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
5388 "TARGET_POWER10 && TARGET_FLOAT128_HW"
5389 "xs<minmax>cqp %0,%1,%2"
5390 [(set_attr "type" "vecfloat")
5391 (set_attr "size" "128")])
5393 ;; The conditional move instructions allow us to perform max and min operations
5394 ;; even when we don't have the appropriate max/min instruction using the FSEL
5397 (define_insn_and_split "*s<minmax><mode>3_fpr"
5398 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5399 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5400 (match_operand:SFDF 2 "gpc_reg_operand")))]
5401 "!TARGET_VSX && TARGET_MINMAX"
5406 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5410 (define_expand "mov<mode>cc"
5411 [(set (match_operand:GPR 0 "gpc_reg_operand")
5412 (if_then_else:GPR (match_operand 1 "comparison_operator")
5413 (match_operand:GPR 2 "gpc_reg_operand")
5414 (match_operand:GPR 3 "gpc_reg_operand")))]
5417 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5423 ;; We use the BASE_REGS for the isel input operands because, if rA is
5424 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5425 ;; because we may switch the operands and rB may end up being rA.
5427 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5428 ;; leave out the mode in operand 4 and use one pattern, but reload can
5429 ;; change the mode underneath our feet and then gets confused trying
5430 ;; to reload the value.
5431 (define_mode_iterator CCANY [CC CCUNS])
5432 (define_insn "isel_<CCANY:mode>_<GPR:mode>"
5433 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5435 (match_operator 1 "scc_comparison_operator"
5436 [(match_operand:CCANY 4 "cc_reg_operand" "y,y")
5438 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5439 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5442 [(set_attr "type" "isel")])
5444 ;; These patterns can be useful for combine; they let combine know that
5445 ;; isel can handle reversed comparisons so long as the operands are
5448 (define_insn "*isel_reversed_<CCANY:mode>_<GPR:mode>"
5449 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5451 (match_operator 1 "scc_rev_comparison_operator"
5452 [(match_operand:CCANY 4 "cc_reg_operand" "y,y")
5454 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5455 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5458 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5459 return "isel %0,%3,%2,%j1";
5461 [(set_attr "type" "isel")])
5463 ; Set Boolean Condition (Reverse)
5464 (define_insn "setbc_<CCANY:mode>_<GPR:mode>"
5465 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5466 (match_operator:GPR 1 "scc_comparison_operator"
5467 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5471 [(set_attr "type" "isel")])
5473 (define_insn "*setbcr_<CCANY:mode>_<GPR:mode>"
5474 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5475 (match_operator:GPR 1 "scc_rev_comparison_operator"
5476 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5480 [(set_attr "type" "isel")])
5482 ; Set Negative Boolean Condition (Reverse)
5483 (define_insn "*setnbc_<CCANY:mode>_<GPR:mode>"
5484 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5485 (neg:GPR (match_operator:GPR 1 "scc_comparison_operator"
5486 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5490 [(set_attr "type" "isel")])
5492 (define_insn "*setnbcr_<CCANY:mode>_<GPR:mode>"
5493 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5494 (neg:GPR (match_operator:GPR 1 "scc_rev_comparison_operator"
5495 [(match_operand:CCANY 2 "cc_reg_operand" "y")
5499 [(set_attr "type" "isel")])
5501 ;; Floating point conditional move
5502 (define_expand "mov<mode>cc"
5503 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5504 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5505 (match_operand:SFDF 2 "gpc_reg_operand")
5506 (match_operand:SFDF 3 "gpc_reg_operand")))]
5507 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5509 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5515 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5516 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5518 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5519 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5520 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5521 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5522 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5524 [(set_attr "type" "fp")])
5526 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5527 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa")
5529 (match_operator:CCFP 1 "fpmask_comparison_operator"
5530 [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa")
5531 (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")])
5532 (match_operand:SFDF 4 "vsx_register_operand" "wa,wa")
5533 (match_operand:SFDF 5 "vsx_register_operand" "wa,wa")))
5534 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5539 (if_then_else:V2DI (match_dup 1)
5543 (if_then_else:SFDF (ne (match_dup 6)
5548 if (GET_CODE (operands[6]) == SCRATCH)
5549 operands[6] = gen_reg_rtx (V2DImode);
5551 operands[7] = CONSTM1_RTX (V2DImode);
5552 operands[8] = CONST0_RTX (V2DImode);
5554 [(set_attr "length" "8")
5555 (set_attr "type" "vecperm")])
5557 ;; Handle inverting the fpmask comparisons.
5558 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5559 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa")
5561 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5562 [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa")
5563 (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")])
5564 (match_operand:SFDF 4 "vsx_register_operand" "wa,wa")
5565 (match_operand:SFDF 5 "vsx_register_operand" "wa,wa")))
5566 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5571 (if_then_else:V2DI (match_dup 9)
5575 (if_then_else:SFDF (ne (match_dup 6)
5580 rtx op1 = operands[1];
5581 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5583 if (GET_CODE (operands[6]) == SCRATCH)
5584 operands[6] = gen_reg_rtx (V2DImode);
5586 operands[7] = CONSTM1_RTX (V2DImode);
5587 operands[8] = CONST0_RTX (V2DImode);
5589 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5591 [(set_attr "length" "8")
5592 (set_attr "type" "vecperm")])
5594 (define_insn "*fpmask<mode>"
5595 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5597 (match_operator:CCFP 1 "fpmask_comparison_operator"
5598 [(match_operand:SFDF 2 "vsx_register_operand" "wa")
5599 (match_operand:SFDF 3 "vsx_register_operand" "wa")])
5600 (match_operand:V2DI 4 "all_ones_constant" "")
5601 (match_operand:V2DI 5 "zero_constant" "")))]
5603 "xscmp%V1dp %x0,%x2,%x3"
5604 [(set_attr "type" "fpcompare")])
5606 (define_insn "*xxsel<mode>"
5607 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
5608 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5609 (match_operand:V2DI 2 "zero_constant" ""))
5610 (match_operand:SFDF 3 "vsx_register_operand" "wa")
5611 (match_operand:SFDF 4 "vsx_register_operand" "wa")))]
5613 "xxsel %x0,%x4,%x3,%x1"
5614 [(set_attr "type" "vecmove")])
5616 ;; Support for ISA 3.1 IEEE 128-bit conditional move. The mode used in the
5617 ;; comparison must be the same as used in the move.
5618 (define_expand "mov<mode>cc"
5619 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
5620 (if_then_else:IEEE128 (match_operand 1 "comparison_operator")
5621 (match_operand:IEEE128 2 "gpc_reg_operand")
5622 (match_operand:IEEE128 3 "gpc_reg_operand")))]
5623 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5625 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5631 (define_insn_and_split "*mov<mode>cc_p10"
5632 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
5633 (if_then_else:IEEE128
5634 (match_operator:CCFP 1 "fpmask_comparison_operator"
5635 [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
5636 (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
5637 (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
5638 (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
5639 (clobber (match_scratch:V2DI 6 "=0,&v"))]
5640 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5644 (if_then_else:V2DI (match_dup 1)
5648 (if_then_else:IEEE128 (ne (match_dup 6)
5653 if (GET_CODE (operands[6]) == SCRATCH)
5654 operands[6] = gen_reg_rtx (V2DImode);
5656 operands[7] = CONSTM1_RTX (V2DImode);
5657 operands[8] = CONST0_RTX (V2DImode);
5659 [(set_attr "length" "8")
5660 (set_attr "type" "vecperm")])
5662 ;; Handle inverting the fpmask comparisons.
5663 (define_insn_and_split "*mov<mode>cc_invert_p10"
5664 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
5665 (if_then_else:IEEE128
5666 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5667 [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
5668 (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
5669 (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
5670 (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
5671 (clobber (match_scratch:V2DI 6 "=0,&v"))]
5672 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5676 (if_then_else:V2DI (match_dup 9)
5680 (if_then_else:IEEE128 (ne (match_dup 6)
5685 rtx op1 = operands[1];
5686 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5688 if (GET_CODE (operands[6]) == SCRATCH)
5689 operands[6] = gen_reg_rtx (V2DImode);
5691 operands[7] = CONSTM1_RTX (V2DImode);
5692 operands[8] = CONST0_RTX (V2DImode);
5694 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5696 [(set_attr "length" "8")
5697 (set_attr "type" "vecperm")])
5699 (define_insn "*fpmask<mode>"
5700 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
5702 (match_operator:CCFP 1 "fpmask_comparison_operator"
5703 [(match_operand:IEEE128 2 "altivec_register_operand" "v")
5704 (match_operand:IEEE128 3 "altivec_register_operand" "v")])
5705 (match_operand:V2DI 4 "all_ones_constant" "")
5706 (match_operand:V2DI 5 "zero_constant" "")))]
5707 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5708 "xscmp%V1qp %0,%2,%3"
5709 [(set_attr "type" "fpcompare")])
5711 (define_insn "*xxsel<mode>"
5712 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
5713 (if_then_else:IEEE128
5714 (ne (match_operand:V2DI 1 "altivec_register_operand" "v")
5715 (match_operand:V2DI 2 "zero_constant" ""))
5716 (match_operand:IEEE128 3 "altivec_register_operand" "v")
5717 (match_operand:IEEE128 4 "altivec_register_operand" "v")))]
5718 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
5719 "xxsel %x0,%x4,%x3,%x1"
5720 [(set_attr "type" "vecmove")])
5723 ;; Conversions to and from floating-point.
5725 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5726 ; don't want to support putting SImode in FPR registers.
5727 (define_insn "lfiwax"
5728 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5729 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5731 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5737 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5738 (set_attr "isa" "*,p8v,p8v,p9v")])
5740 ; This split must be run before register allocation because it allocates the
5741 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5742 ; it earlier to allow for the combiner to merge insns together where it might
5743 ; not be needed and also in case the insns are deleted as dead code.
5745 (define_insn_and_split "floatsi<mode>2_lfiwax"
5746 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5747 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5748 (clobber (match_scratch:DI 2 "=d,wa"))]
5749 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5750 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5755 rtx dest = operands[0];
5756 rtx src = operands[1];
5759 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5760 tmp = convert_to_mode (DImode, src, false);
5764 if (GET_CODE (tmp) == SCRATCH)
5765 tmp = gen_reg_rtx (DImode);
5768 src = rs6000_force_indexed_or_indirect_mem (src);
5769 emit_insn (gen_lfiwax (tmp, src));
5773 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5774 emit_move_insn (stack, src);
5775 emit_insn (gen_lfiwax (tmp, stack));
5778 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5781 [(set_attr "length" "12")
5782 (set_attr "type" "fpload")])
5784 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5785 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5788 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5789 (clobber (match_scratch:DI 2 "=d,wa"))]
5790 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5795 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5796 if (GET_CODE (operands[2]) == SCRATCH)
5797 operands[2] = gen_reg_rtx (DImode);
5798 if (TARGET_P8_VECTOR)
5799 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5801 emit_insn (gen_lfiwax (operands[2], operands[1]));
5802 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5805 [(set_attr "length" "8")
5806 (set_attr "type" "fpload")])
5808 (define_insn_and_split "floatsi<SFDF:mode>2_lfiwax_<QHI:mode>_mem_zext"
5809 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5812 (match_operand:QHI 1 "indexed_or_indirect_operand" "Z,Z"))))
5813 (clobber (match_scratch:DI 2 "=d,wa"))]
5814 "TARGET_HARD_FLOAT && <SI_CONVERT_FP> && TARGET_P9_VECTOR
5815 && TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5820 if (GET_CODE (operands[2]) == SCRATCH)
5821 operands[2] = gen_reg_rtx (DImode);
5822 emit_insn (gen_zero_extendhidi2 (operands[2], operands[1]));
5823 emit_insn (gen_floatdi<SFDF:mode>2 (operands[0], operands[2]));
5826 [(set_attr "length" "8")
5827 (set_attr "type" "fpload")])
5829 (define_insn "lfiwzx"
5830 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5831 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5833 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5838 xxextractuw %x0,%x1,4"
5839 [(set_attr "type" "fpload,fpload,mtvsr,vecexts")
5840 (set_attr "isa" "*,p8v,p8v,p9v")])
5842 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5843 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5844 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5845 (clobber (match_scratch:DI 2 "=d,wa"))]
5846 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5851 rtx dest = operands[0];
5852 rtx src = operands[1];
5855 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5856 tmp = convert_to_mode (DImode, src, true);
5860 if (GET_CODE (tmp) == SCRATCH)
5861 tmp = gen_reg_rtx (DImode);
5864 src = rs6000_force_indexed_or_indirect_mem (src);
5865 emit_insn (gen_lfiwzx (tmp, src));
5869 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5870 emit_move_insn (stack, src);
5871 emit_insn (gen_lfiwzx (tmp, stack));
5874 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5877 [(set_attr "length" "12")
5878 (set_attr "type" "fpload")])
5880 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5881 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
5882 (unsigned_float:SFDF
5884 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5885 (clobber (match_scratch:DI 2 "=d,wa"))]
5886 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5891 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5892 if (GET_CODE (operands[2]) == SCRATCH)
5893 operands[2] = gen_reg_rtx (DImode);
5894 if (TARGET_P8_VECTOR)
5895 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5897 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5898 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5901 [(set_attr "length" "8")
5902 (set_attr "type" "fpload")])
5904 ; For each of these conversions, there is a define_expand, a define_insn
5905 ; with a '#' template, and a define_split (with C code). The idea is
5906 ; to allow constant folding with the template of the define_insn,
5907 ; then to have the insns split later (between sched1 and final).
5909 (define_expand "floatsidf2"
5910 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5911 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5914 (clobber (match_dup 4))
5915 (clobber (match_dup 5))
5916 (clobber (match_dup 6))])]
5919 if (TARGET_LFIWAX && TARGET_FCFID)
5921 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5924 else if (TARGET_FCFID)
5926 rtx dreg = operands[1];
5928 dreg = force_reg (SImode, dreg);
5929 dreg = convert_to_mode (DImode, dreg, false);
5930 emit_insn (gen_floatdidf2 (operands[0], dreg));
5934 if (!REG_P (operands[1]))
5935 operands[1] = force_reg (SImode, operands[1]);
5936 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5937 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5938 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5939 operands[5] = gen_reg_rtx (DFmode);
5940 operands[6] = gen_reg_rtx (SImode);
5943 (define_insn_and_split "*floatsidf2_internal"
5944 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5945 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5946 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5947 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5948 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5949 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5950 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5951 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5956 rtx lowword, highword;
5957 gcc_assert (MEM_P (operands[4]));
5958 highword = adjust_address (operands[4], SImode, 0);
5959 lowword = adjust_address (operands[4], SImode, 4);
5960 if (! WORDS_BIG_ENDIAN)
5961 std::swap (lowword, highword);
5963 emit_insn (gen_xorsi3 (operands[6], operands[1],
5964 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5965 emit_move_insn (lowword, operands[6]);
5966 emit_move_insn (highword, operands[2]);
5967 emit_move_insn (operands[5], operands[4]);
5968 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5971 [(set_attr "length" "24")
5972 (set_attr "type" "fp")])
5974 ;; If we don't have a direct conversion to single precision, don't enable this
5975 ;; conversion for 32-bit without fast math, because we don't have the insn to
5976 ;; generate the fixup swizzle to avoid double rounding problems.
5977 (define_expand "floatunssisf2"
5978 [(set (match_operand:SF 0 "gpc_reg_operand")
5979 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5981 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5983 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5985 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5987 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5992 rtx dreg = operands[1];
5994 dreg = force_reg (SImode, dreg);
5995 dreg = convert_to_mode (DImode, dreg, true);
5996 emit_insn (gen_floatdisf2 (operands[0], dreg));
6001 (define_expand "floatunssidf2"
6002 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
6003 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
6006 (clobber (match_dup 4))
6007 (clobber (match_dup 5))])]
6010 if (TARGET_LFIWZX && TARGET_FCFID)
6012 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
6015 else if (TARGET_FCFID)
6017 rtx dreg = operands[1];
6019 dreg = force_reg (SImode, dreg);
6020 dreg = convert_to_mode (DImode, dreg, true);
6021 emit_insn (gen_floatdidf2 (operands[0], dreg));
6025 if (!REG_P (operands[1]))
6026 operands[1] = force_reg (SImode, operands[1]);
6027 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
6028 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
6029 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
6030 operands[5] = gen_reg_rtx (DFmode);
6033 (define_insn_and_split "*floatunssidf2_internal"
6034 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
6035 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
6036 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
6037 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
6038 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
6039 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
6040 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
6041 && !(TARGET_FCFID && TARGET_POWERPC64)"
6046 rtx lowword, highword;
6047 gcc_assert (MEM_P (operands[4]));
6048 highword = adjust_address (operands[4], SImode, 0);
6049 lowword = adjust_address (operands[4], SImode, 4);
6050 if (! WORDS_BIG_ENDIAN)
6051 std::swap (lowword, highword);
6053 emit_move_insn (lowword, operands[1]);
6054 emit_move_insn (highword, operands[2]);
6055 emit_move_insn (operands[5], operands[4]);
6056 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
6059 [(set_attr "length" "20")
6060 (set_attr "type" "fp")])
6062 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
6063 ;; vector registers. These insns favor doing the sign/zero extension in
6064 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
6065 ;; extension and then a direct move.
6067 (define_expand "float<QHI:mode><SFDF:mode>2"
6068 [(parallel [(set (match_operand:SFDF 0 "vsx_register_operand")
6070 (match_operand:QHI 1 "input_operand")))
6071 (clobber (match_scratch:DI 2))
6072 (clobber (match_scratch:DI 3))
6073 (clobber (match_scratch:<QHI:MODE> 4))])]
6074 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6076 if (MEM_P (operands[1]))
6077 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
6080 (define_insn_and_split "*float<QHI:mode><SFDF:mode>2_internal"
6081 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa,wa,wa")
6083 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
6084 (clobber (match_scratch:DI 2 "=v,wa,v"))
6085 (clobber (match_scratch:DI 3 "=X,r,X"))
6086 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
6087 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6089 "&& reload_completed"
6092 rtx result = operands[0];
6093 rtx input = operands[1];
6094 rtx di = operands[2];
6098 rtx tmp = operands[3];
6099 if (altivec_register_operand (input, <QHI:MODE>mode))
6100 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6101 else if (GET_CODE (tmp) == SCRATCH)
6102 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6105 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
6106 emit_move_insn (di, tmp);
6111 rtx tmp = operands[4];
6112 emit_move_insn (tmp, input);
6113 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
6116 emit_insn (gen_floatdi<SFDF:mode>2 (result, di));
6119 [(set_attr "isa" "p9v,*,p9v")])
6121 (define_expand "floatuns<QHI:mode><SFDF:mode>2"
6122 [(parallel [(set (match_operand:SFDF 0 "vsx_register_operand")
6123 (unsigned_float:SFDF
6124 (match_operand:QHI 1 "input_operand")))
6125 (clobber (match_scratch:DI 2))
6126 (clobber (match_scratch:DI 3))])]
6127 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6129 if (MEM_P (operands[1]))
6130 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
6133 (define_insn_and_split "*floatuns<QHI:mode><SFDF:mode>2_internal"
6134 [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa,wa,wa")
6135 (unsigned_float:SFDF
6136 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
6137 (clobber (match_scratch:DI 2 "=v,wa,wa"))
6138 (clobber (match_scratch:DI 3 "=X,r,X"))]
6139 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
6141 "&& reload_completed"
6144 rtx result = operands[0];
6145 rtx input = operands[1];
6146 rtx di = operands[2];
6148 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
6149 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
6152 rtx tmp = operands[3];
6153 if (GET_CODE (tmp) == SCRATCH)
6154 emit_insn (gen_extend<QHI:mode>di2 (di, input));
6157 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
6158 emit_move_insn (di, tmp);
6162 emit_insn (gen_floatdi<SFDF:mode>2 (result, di));
6165 [(set_attr "isa" "p9v,*,p9v")])
6167 (define_expand "fix_trunc<mode>si2"
6168 [(set (match_operand:SI 0 "gpc_reg_operand")
6169 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
6172 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
6174 rtx src = force_reg (<MODE>mode, operands[1]);
6177 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
6180 rtx tmp = gen_reg_rtx (DImode);
6181 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
6182 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
6189 ; Like the convert to float patterns, this insn must be split before
6190 ; register allocation so that it can allocate the memory slot if it
6192 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
6193 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6194 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6195 (clobber (match_scratch:DI 2 "=d"))]
6196 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
6197 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
6202 rtx dest = operands[0];
6203 rtx src = operands[1];
6204 rtx tmp = operands[2];
6206 if (GET_CODE (tmp) == SCRATCH)
6207 tmp = gen_reg_rtx (DImode);
6209 emit_insn (gen_fctiwz_<mode> (tmp, src));
6210 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
6212 dest = rs6000_force_indexed_or_indirect_mem (dest);
6213 emit_insn (gen_stfiwx (dest, tmp));
6216 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
6218 dest = gen_lowpart (DImode, dest);
6219 emit_move_insn (dest, tmp);
6224 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6225 emit_insn (gen_stfiwx (stack, tmp));
6226 emit_move_insn (dest, stack);
6230 [(set_attr "length" "12")
6231 (set_attr "type" "fp")])
6233 (define_insn_and_split "fix_trunc<mode>si2_internal"
6234 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
6235 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
6236 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
6237 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
6239 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
6245 gcc_assert (MEM_P (operands[3]));
6246 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
6248 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
6249 emit_move_insn (operands[3], operands[2]);
6250 emit_move_insn (operands[0], lowword);
6253 [(set_attr "length" "16")
6254 (set_attr "type" "fp")])
6256 (define_expand "fix_trunc<mode>di2"
6257 [(set (match_operand:DI 0 "gpc_reg_operand")
6258 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
6259 "TARGET_HARD_FLOAT && TARGET_FCFID"
6262 (define_insn "*fix_trunc<mode>di2_fctidz"
6263 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6264 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6265 "TARGET_HARD_FLOAT && TARGET_FCFID"
6269 [(set_attr "type" "fp")])
6271 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
6272 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
6273 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
6274 ;; values can go in VSX registers. Keeping the direct move part through
6275 ;; register allocation prevents the register allocator from doing a direct move
6276 ;; of the SImode value to a GPR, and then a store/load.
6277 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
6278 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
6279 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
6280 (clobber (match_scratch:SI 2 "=X,X,wa"))]
6281 "TARGET_DIRECT_MOVE"
6284 xscvdp<su>xws %x0,%x1
6286 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
6288 (any_fix:SI (match_dup 1)))
6292 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
6294 [(set_attr "type" "fp")
6295 (set_attr "length" "4,4,8")
6296 (set_attr "isa" "p9v,p9v,*")])
6298 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
6299 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
6300 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6301 "TARGET_DIRECT_MOVE"
6304 xscvdp<su>xws %x0,%x1"
6305 [(set_attr "type" "fp")])
6307 ;; Keep the convert and store together through register allocation to prevent
6308 ;; the register allocator from getting clever and doing a direct move to a GPR
6309 ;; and then store for reg+offset stores.
6310 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
6311 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
6312 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
6313 (clobber (match_scratch:SI 2 "=wa"))]
6314 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
6316 "&& reload_completed"
6318 (any_fix:SI (match_dup 1)))
6322 operands[3] = (<QHSI:MODE>mode == SImode
6324 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
6327 (define_expand "fixuns_trunc<mode>si2"
6328 [(set (match_operand:SI 0 "gpc_reg_operand")
6329 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
6330 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
6332 if (!TARGET_P8_VECTOR)
6334 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
6339 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
6340 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6341 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6342 (clobber (match_scratch:DI 2 "=d"))]
6343 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
6344 && TARGET_STFIWX && can_create_pseudo_p ()
6345 && !TARGET_P8_VECTOR"
6350 rtx dest = operands[0];
6351 rtx src = operands[1];
6352 rtx tmp = operands[2];
6354 if (GET_CODE (tmp) == SCRATCH)
6355 tmp = gen_reg_rtx (DImode);
6357 emit_insn (gen_fctiwuz_<mode> (tmp, src));
6360 dest = rs6000_force_indexed_or_indirect_mem (dest);
6361 emit_insn (gen_stfiwx (dest, tmp));
6364 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
6366 dest = gen_lowpart (DImode, dest);
6367 emit_move_insn (dest, tmp);
6372 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6373 emit_insn (gen_stfiwx (stack, tmp));
6374 emit_move_insn (dest, stack);
6378 [(set_attr "length" "12")
6379 (set_attr "type" "fp")])
6381 (define_insn "fixuns_trunc<mode>di2"
6382 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6383 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
6384 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
6388 [(set_attr "type" "fp")])
6390 (define_insn "rs6000_mtfsb0"
6391 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6395 [(set_attr "type" "fp")])
6397 (define_insn "rs6000_mtfsb1"
6398 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6402 [(set_attr "type" "fp")])
6404 (define_insn "rs6000_mffscrn"
6405 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6406 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
6410 [(set_attr "type" "fp")])
6412 (define_insn "rs6000_mffscrni"
6413 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6414 (unspec_volatile:DF [(match_operand:SI 1 "const_0_to_3_operand" "n")]
6418 [(set_attr "type" "fp")])
6420 (define_insn "rs6000_mffscdrn"
6421 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6422 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
6423 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
6426 [(set_attr "type" "fp")])
6428 (define_expand "rs6000_set_fpscr_rn"
6429 [(match_operand:SI 0 "reg_or_cint_operand")]
6432 rtx tmp_df = gen_reg_rtx (DFmode);
6434 /* The floating point rounding control bits are FPSCR[62:63]. Put the
6435 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
6438 if (const_0_to_3_operand (operands[0], VOIDmode))
6439 emit_insn (gen_rs6000_mffscrni (tmp_df, operands[0]));
6442 rtx op0 = convert_to_mode (DImode, operands[0], false);
6443 rtx src_df = simplify_gen_subreg (DFmode, op0, DImode, 0);
6444 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
6449 if (CONST_INT_P (operands[0]))
6451 if ((INTVAL (operands[0]) & 0x1) == 0x1)
6452 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
6454 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
6456 if ((INTVAL (operands[0]) & 0x2) == 0x2)
6457 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
6459 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
6463 rtx tmp_rn = gen_reg_rtx (DImode);
6464 rtx tmp_di = gen_reg_rtx (DImode);
6466 /* Extract new RN mode from operand. */
6467 rtx op0 = convert_to_mode (DImode, operands[0], false);
6468 emit_insn (gen_anddi3 (tmp_rn, op0, GEN_INT (3)));
6470 /* Insert new RN mode into FSCPR. */
6471 emit_insn (gen_rs6000_mffs (tmp_df));
6472 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6473 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
6474 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6476 /* Need to write to field k=15. The fields are [0:15]. Hence with
6477 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
6478 8-bit field[0:7]. Need to set the bit that corresponds to the
6479 value of i that you want [0:7]. */
6480 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6481 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
6486 (define_expand "rs6000_set_fpscr_drn"
6487 [(match_operand:DI 0 "gpc_reg_operand")]
6490 rtx tmp_df = gen_reg_rtx (DFmode);
6492 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
6493 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
6496 rtx src_df = gen_reg_rtx (DFmode);
6498 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
6499 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
6500 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6504 rtx tmp_rn = gen_reg_rtx (DImode);
6505 rtx tmp_di = gen_reg_rtx (DImode);
6507 /* Extract new DRN mode from operand. */
6508 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6509 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6511 /* Insert new RN mode into FSCPR. */
6512 emit_insn (gen_rs6000_mffs (tmp_df));
6513 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6514 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6515 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6517 /* Need to write to field 7. The fields are [0:15]. The equation to
6518 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6519 i to 0x1 to get field 7 where i selects the field. */
6520 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6521 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6526 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6527 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6528 ;; because the first makes it clear that operand 0 is not live
6529 ;; before the instruction.
6530 (define_insn "fctiwz_<mode>"
6531 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6533 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))]
6539 [(set_attr "type" "fp")])
6541 (define_insn "fctiwuz_<mode>"
6542 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6543 (unspec:DI [(unsigned_fix:SI
6544 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa"))]
6546 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6550 [(set_attr "type" "fp")])
6552 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6553 ;; since the friz instruction does not truncate the value if the floating
6554 ;; point value is < LONG_MIN or > LONG_MAX.
6555 (define_insn "*friz"
6556 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6557 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6558 "TARGET_HARD_FLOAT && TARGET_FPRND
6559 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6563 [(set_attr "type" "fp")])
6565 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6566 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6567 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6568 ;; extend it, store it back on the stack from the GPR, load it back into the
6569 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6570 ;; disable using store and load to sign/zero extend the value.
6571 (define_insn_and_split "*round32<mode>2_fprs"
6572 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6574 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6575 (clobber (match_scratch:DI 2 "=d"))
6576 (clobber (match_scratch:DI 3 "=d"))]
6578 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6579 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6584 rtx dest = operands[0];
6585 rtx src = operands[1];
6586 rtx tmp1 = operands[2];
6587 rtx tmp2 = operands[3];
6588 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6590 if (GET_CODE (tmp1) == SCRATCH)
6591 tmp1 = gen_reg_rtx (DImode);
6592 if (GET_CODE (tmp2) == SCRATCH)
6593 tmp2 = gen_reg_rtx (DImode);
6595 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6596 emit_insn (gen_stfiwx (stack, tmp1));
6597 emit_insn (gen_lfiwax (tmp2, stack));
6598 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6601 [(set_attr "type" "fpload")
6602 (set_attr "length" "16")])
6604 (define_insn_and_split "*roundu32<mode>2_fprs"
6605 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6606 (unsigned_float:SFDF
6607 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6608 (clobber (match_scratch:DI 2 "=d"))
6609 (clobber (match_scratch:DI 3 "=d"))]
6611 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6612 && can_create_pseudo_p ()"
6617 rtx dest = operands[0];
6618 rtx src = operands[1];
6619 rtx tmp1 = operands[2];
6620 rtx tmp2 = operands[3];
6621 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6623 if (GET_CODE (tmp1) == SCRATCH)
6624 tmp1 = gen_reg_rtx (DImode);
6625 if (GET_CODE (tmp2) == SCRATCH)
6626 tmp2 = gen_reg_rtx (DImode);
6628 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6629 emit_insn (gen_stfiwx (stack, tmp1));
6630 emit_insn (gen_lfiwzx (tmp2, stack));
6631 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6634 [(set_attr "type" "fpload")
6635 (set_attr "length" "16")])
6637 ;; No VSX equivalent to fctid
6638 (define_insn "lrint<mode>di2"
6639 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6640 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6642 "TARGET_HARD_FLOAT && TARGET_FPRND"
6644 [(set_attr "type" "fp")])
6646 (define_insn "btrunc<mode>2"
6647 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6648 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6650 "TARGET_HARD_FLOAT && TARGET_FPRND"
6654 [(set_attr "type" "fp")])
6656 (define_insn "ceil<mode>2"
6657 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6658 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6660 "TARGET_HARD_FLOAT && TARGET_FPRND"
6664 [(set_attr "type" "fp")])
6666 (define_insn "floor<mode>2"
6667 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
6668 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
6670 "TARGET_HARD_FLOAT && TARGET_FPRND"
6674 [(set_attr "type" "fp")])
6676 ;; No VSX equivalent to frin
6677 (define_insn "round<mode>2"
6678 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6679 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6681 "TARGET_HARD_FLOAT && TARGET_FPRND"
6683 [(set_attr "type" "fp")])
6685 (define_insn "*xsrdpi<mode>2"
6686 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=wa")
6687 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "wa")]
6689 "TARGET_HARD_FLOAT && TARGET_VSX"
6691 [(set_attr "type" "fp")])
6693 (define_expand "lround<mode>di2"
6695 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6697 (set (match_operand:DI 0 "gpc_reg_operand")
6698 (unspec:DI [(match_dup 2)]
6700 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6702 operands[2] = gen_reg_rtx (<MODE>mode);
6705 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6706 (define_insn "stfiwx"
6707 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6708 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6714 [(set_attr "type" "fpstore")
6715 (set_attr "isa" "*,p8v")])
6717 ;; If we don't have a direct conversion to single precision, don't enable this
6718 ;; conversion for 32-bit without fast math, because we don't have the insn to
6719 ;; generate the fixup swizzle to avoid double rounding problems.
6720 (define_expand "floatsisf2"
6721 [(set (match_operand:SF 0 "gpc_reg_operand")
6722 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6724 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6726 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6728 if (TARGET_FCFIDS && TARGET_LFIWAX)
6730 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6733 else if (TARGET_FCFID && TARGET_LFIWAX)
6735 rtx dfreg = gen_reg_rtx (DFmode);
6736 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6737 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6742 rtx dreg = operands[1];
6744 dreg = force_reg (SImode, dreg);
6745 dreg = convert_to_mode (DImode, dreg, false);
6746 emit_insn (gen_floatdisf2 (operands[0], dreg));
6751 (define_insn "floatdidf2"
6752 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6753 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6754 "TARGET_FCFID && TARGET_HARD_FLOAT"
6758 [(set_attr "type" "fp")])
6760 (define_insn "floatti<mode>2"
6761 [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v")
6762 (float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))]
6765 return "xscvsqqp %0,%1";
6767 [(set_attr "type" "fp")])
6769 (define_insn "floatunsti<mode>2"
6770 [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v")
6771 (unsigned_float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))]
6774 return "xscvuqqp %0,%1";
6776 [(set_attr "type" "fp")])
6778 (define_insn "fix_trunc<mode>ti2"
6779 [(set (match_operand:TI 0 "vsx_register_operand" "=v")
6780 (fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))]
6783 return "xscvqpsqz %0,%1";
6785 [(set_attr "type" "fp")])
6787 (define_insn "fixuns_trunc<mode>ti2"
6788 [(set (match_operand:TI 0 "vsx_register_operand" "=v")
6789 (unsigned_fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))]
6792 return "xscvqpuqz %0,%1";
6794 [(set_attr "type" "fp")])
6796 ; Allow the combiner to merge source memory operands to the conversion so that
6797 ; the optimizer/register allocator doesn't try to load the value too early in a
6798 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6799 ; hit. We will split after reload to avoid the trip through the GPRs
6801 (define_insn_and_split "*floatdidf2_mem"
6802 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6803 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6804 (clobber (match_scratch:DI 2 "=d,wa"))]
6805 "TARGET_HARD_FLOAT && TARGET_FCFID"
6807 "&& reload_completed"
6808 [(set (match_dup 2) (match_dup 1))
6809 (set (match_dup 0) (float:DF (match_dup 2)))]
6811 [(set_attr "length" "8")
6812 (set_attr "type" "fpload")])
6814 (define_expand "floatunsdidf2"
6815 [(set (match_operand:DF 0 "gpc_reg_operand")
6817 (match_operand:DI 1 "gpc_reg_operand")))]
6818 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6821 (define_insn "*floatunsdidf2_fcfidu"
6822 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6823 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6824 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6828 [(set_attr "type" "fp")])
6830 (define_insn_and_split "*floatunsdidf2_mem"
6831 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6832 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6833 (clobber (match_scratch:DI 2 "=d,wa"))]
6834 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6836 "&& reload_completed"
6837 [(set (match_dup 2) (match_dup 1))
6838 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6840 [(set_attr "length" "8")
6841 (set_attr "type" "fpload")])
6843 (define_expand "floatdisf2"
6844 [(set (match_operand:SF 0 "gpc_reg_operand")
6845 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6846 "TARGET_FCFID && TARGET_HARD_FLOAT
6847 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6851 rtx val = operands[1];
6852 if (!flag_unsafe_math_optimizations)
6854 rtx label = gen_label_rtx ();
6855 val = gen_reg_rtx (DImode);
6856 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6859 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6864 (define_insn "floatdisf2_fcfids"
6865 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6866 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6867 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6871 [(set_attr "type" "fp")
6872 (set_attr "isa" "*,p8v")])
6874 (define_insn_and_split "*floatdisf2_mem"
6875 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6876 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6877 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6878 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6880 "&& reload_completed"
6883 emit_move_insn (operands[2], operands[1]);
6884 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6887 [(set_attr "length" "8")
6888 (set_attr "isa" "*,p8v,p8v")])
6890 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6891 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6892 ;; from double rounding.
6893 ;; Instead of creating a new cpu type for two FP operations, just use fp
6894 (define_insn_and_split "floatdisf2_internal1"
6895 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6896 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6897 (clobber (match_scratch:DF 2 "=d"))]
6898 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6900 "&& reload_completed"
6902 (float:DF (match_dup 1)))
6904 (float_truncate:SF (match_dup 2)))]
6906 [(set_attr "length" "8")
6907 (set_attr "type" "fp")])
6909 ;; Twiddles bits to avoid double rounding.
6910 ;; Bits that might be truncated when converting to DFmode are replaced
6911 ;; by a bit that won't be lost at that stage, but is below the SFmode
6912 ;; rounding position.
6913 (define_expand "floatdisf2_internal2"
6914 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6916 (clobber (reg:DI CA_REGNO))])
6917 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6919 (set (match_dup 3) (plus:DI (match_dup 3)
6921 (set (match_dup 0) (plus:DI (match_dup 0)
6923 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6925 (set (match_dup 0) (ior:DI (match_dup 0)
6927 (set (match_dup 0) (and:DI (match_dup 0)
6929 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6930 (label_ref (match_operand:DI 2 ""))
6932 (set (match_dup 0) (match_dup 1))]
6933 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6935 operands[3] = gen_reg_rtx (DImode);
6936 operands[4] = gen_reg_rtx (CCUNSmode);
6939 (define_expand "floatunsdisf2"
6940 [(set (match_operand:SF 0 "gpc_reg_operand")
6941 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6942 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6945 (define_insn "floatunsdisf2_fcfidus"
6946 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6947 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6948 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6952 [(set_attr "type" "fp")
6953 (set_attr "isa" "*,p8v")])
6955 (define_insn_and_split "*floatunsdisf2_mem"
6956 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6957 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6958 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6959 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6961 "&& reload_completed"
6964 emit_move_insn (operands[2], operands[1]);
6965 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6968 [(set_attr "type" "fpload")
6969 (set_attr "length" "8")
6970 (set_attr "isa" "*,p8v,p8v")])
6972 ;; int fegetround(void)
6974 ;; This expansion for the C99 function only expands for compatible
6975 ;; target libcs, because it needs to return one of FE_DOWNWARD,
6976 ;; FE_TONEAREST, FE_TOWARDZERO or FE_UPWARD with the values as defined
6977 ;; by the target libc, and since the libc is free to choose the values
6978 ;; (and they may differ from the hardware) and the expander needs to
6979 ;; know then beforehand, this expanded only expands for target libcs
6980 ;; that it can handle the values is knows.
6981 ;; Because of these restriction, this only expands on the desired
6982 ;; case and fallback to a call to libc otherwise.
6983 (define_expand "fegetroundsi"
6984 [(set (match_operand:SI 0 "gpc_reg_operand")
6985 (unspec_volatile:SI [(const_int 0)] UNSPECV_MFFSL))]
6991 rtx tmp_df = gen_reg_rtx (DFmode);
6992 emit_insn (gen_rs6000_mffsl (tmp_df));
6994 rtx tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6995 rtx tmp_di_2 = gen_reg_rtx (DImode);
6996 emit_insn (gen_anddi3 (tmp_di_2, tmp_di, GEN_INT (3)));
6997 rtx tmp_si = gen_reg_rtx (SImode);
6998 tmp_si = gen_lowpart (SImode, tmp_di_2);
6999 emit_move_insn (operands[0], tmp_si);
7003 ;; int feclearexcept(int excepts)
7005 ;; This expansion for the C99 function only works when EXCEPTS is a
7006 ;; constant known at compile time and specifies any one of
7007 ;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags.
7008 ;; It doesn't handle values out of range, and always returns 0.
7009 ;; Note that FE_INVALID is unsupported because it maps to more than
7010 ;; one bit of the FPSCR register.
7011 ;; The FE_* are defined in the target libc, and since they are free to
7012 ;; choose the values and the expand needs to know them beforehand,
7013 ;; this expander only expands for target libcs that it can handle the
7015 ;; Because of these restrictions, this only expands on the desired
7016 ;; cases and fallback to a call to libc on any other case.
7017 (define_expand "feclearexceptsi"
7018 [(use (match_operand:SI 1 "const_int_operand" "n"))
7019 (set (match_operand:SI 0 "gpc_reg_operand")
7026 unsigned int fe = INTVAL (operands[1]);
7027 if (fe != (fe & 0x1e000000))
7030 if (fe & 0x02000000) /* FE_INEXACT */
7031 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 6)));
7032 if (fe & 0x04000000) /* FE_DIVBYZERO */
7033 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 5)));
7034 if (fe & 0x08000000) /* FE_UNDERFLOW */
7035 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 4)));
7036 if (fe & 0x10000000) /* FE_OVERFLOW */
7037 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 3)));
7039 emit_move_insn (operands[0], const0_rtx);
7043 ;; int feraiseexcept(int excepts)
7045 ;; This expansion for the C99 function only works when excepts is a
7046 ;; constant known at compile time and specifies any one of
7047 ;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags.
7048 ;; It doesn't handle values out of range, and always returns 0.
7049 ;; Note that FE_INVALID is unsupported because it maps to more than
7050 ;; one bit of the FPSCR register.
7051 ;; The FE_* are defined in the target libc, and since they are free to
7052 ;; choose the values and the expand needs to know them beforehand,
7053 ;; this expander only expands for target libcs that it can handle the
7055 ;; Because of these restrictions, this only expands on the desired
7056 ;; cases and fallback to a call to libc on any other case.
7057 (define_expand "feraiseexceptsi"
7058 [(use (match_operand:SI 1 "const_int_operand" "n"))
7059 (set (match_operand:SI 0 "gpc_reg_operand")
7066 unsigned int fe = INTVAL (operands[1]);
7067 if (fe != (fe & 0x1e000000))
7070 if (fe & 0x02000000) /* FE_INEXACT */
7071 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 6)));
7072 if (fe & 0x04000000) /* FE_DIVBYZERO */
7073 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 5)));
7074 if (fe & 0x08000000) /* FE_UNDERFLOW */
7075 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 4)));
7076 if (fe & 0x10000000) /* FE_OVERFLOW */
7077 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 3)));
7079 emit_move_insn (operands[0], const0_rtx);
7083 ;; Define the TImode operations that can be done in a small number
7084 ;; of instructions. The & constraints are to prevent the register
7085 ;; allocator from allocating registers that overlap with the inputs
7086 ;; (for example, having an input in 7,8 and an output in 6,7). We
7087 ;; also allow for the output being the same as one of the inputs.
7089 (define_expand "addti3"
7090 [(set (match_operand:TI 0 "gpc_reg_operand")
7091 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
7092 (match_operand:TI 2 "reg_or_short_operand")))]
7095 rtx lo0 = gen_lowpart (DImode, operands[0]);
7096 rtx lo1 = gen_lowpart (DImode, operands[1]);
7097 rtx lo2 = gen_lowpart (DImode, operands[2]);
7098 rtx hi0 = gen_highpart (DImode, operands[0]);
7099 rtx hi1 = gen_highpart (DImode, operands[1]);
7100 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
7102 if (!reg_or_short_operand (lo2, DImode))
7103 lo2 = force_reg (DImode, lo2);
7104 if (!adde_operand (hi2, DImode))
7105 hi2 = force_reg (DImode, hi2);
7107 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
7108 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
7112 (define_expand "subti3"
7113 [(set (match_operand:TI 0 "gpc_reg_operand")
7114 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
7115 (match_operand:TI 2 "gpc_reg_operand")))]
7118 rtx lo0 = gen_lowpart (DImode, operands[0]);
7119 rtx lo1 = gen_lowpart (DImode, operands[1]);
7120 rtx lo2 = gen_lowpart (DImode, operands[2]);
7121 rtx hi0 = gen_highpart (DImode, operands[0]);
7122 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
7123 rtx hi2 = gen_highpart (DImode, operands[2]);
7125 if (!reg_or_short_operand (lo1, DImode))
7126 lo1 = force_reg (DImode, lo1);
7127 if (!adde_operand (hi1, DImode))
7128 hi1 = force_reg (DImode, hi1);
7130 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
7131 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
7135 ;; 128-bit logical operations expanders
7137 (define_expand "and<mode>3"
7138 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7139 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7140 (match_operand:BOOL_128 2 "vlogical_operand")))]
7144 (define_expand "ior<mode>3"
7145 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7146 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7147 (match_operand:BOOL_128 2 "vlogical_operand")))]
7151 (define_expand "xor<mode>3"
7152 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7153 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7154 (match_operand:BOOL_128 2 "vlogical_operand")))]
7158 (define_expand "nor<mode>3"
7159 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7161 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
7162 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7166 (define_expand "andc<mode>3"
7167 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7169 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
7170 (match_operand:BOOL_128 1 "vlogical_operand")))]
7174 ;; Power8 vector logical instructions.
7175 (define_expand "eqv<mode>3"
7176 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7178 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
7179 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7180 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7183 ;; Rewrite nand into canonical form
7184 (define_expand "nand<mode>3"
7185 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7187 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
7188 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
7189 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7192 ;; The canonical form is to have the negated element first, so we need to
7193 ;; reverse arguments.
7194 (define_expand "orc<mode>3"
7195 [(set (match_operand:BOOL_128 0 "vlogical_operand")
7197 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
7198 (match_operand:BOOL_128 1 "vlogical_operand")))]
7199 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
7202 ;; 128-bit logical operations insns and split operations
7203 (define_insn_and_split "*and<mode>3_internal"
7204 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7206 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7207 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
7210 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7211 return "xxland %x0,%x1,%x2";
7213 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7214 return "vand %0,%1,%2";
7218 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7221 rs6000_split_logical (operands, AND, false, false, false);
7226 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7227 (const_string "veclogical")
7228 (const_string "integer")))
7229 (set (attr "length")
7231 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7234 (match_test "TARGET_POWERPC64")
7236 (const_string "16"))))])
7239 (define_insn_and_split "*bool<mode>3_internal"
7240 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7241 (match_operator:BOOL_128 3 "boolean_or_operator"
7242 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
7243 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
7246 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7247 return "xxl%q3 %x0,%x1,%x2";
7249 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7250 return "v%q3 %0,%1,%2";
7254 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7257 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
7262 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7263 (const_string "veclogical")
7264 (const_string "integer")))
7265 (set (attr "length")
7267 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7270 (match_test "TARGET_POWERPC64")
7272 (const_string "16"))))])
7275 (define_insn_and_split "*boolc<mode>3_internal1"
7276 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7277 (match_operator:BOOL_128 3 "boolean_operator"
7279 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
7280 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
7281 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7283 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7284 return "xxl%q3 %x0,%x1,%x2";
7286 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7287 return "v%q3 %0,%1,%2";
7291 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7292 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7295 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
7300 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7301 (const_string "veclogical")
7302 (const_string "integer")))
7303 (set (attr "length")
7305 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7308 (match_test "TARGET_POWERPC64")
7310 (const_string "16"))))])
7312 (define_insn_and_split "*boolc<mode>3_internal2"
7313 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7314 (match_operator:TI2 3 "boolean_operator"
7316 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
7317 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
7318 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7320 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7323 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
7326 [(set_attr "type" "integer")
7327 (set (attr "length")
7329 (match_test "TARGET_POWERPC64")
7331 (const_string "16")))])
7334 (define_insn_and_split "*boolcc<mode>3_internal1"
7335 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7336 (match_operator:BOOL_128 3 "boolean_operator"
7338 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
7340 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
7341 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
7343 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7344 return "xxl%q3 %x0,%x1,%x2";
7346 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7347 return "v%q3 %0,%1,%2";
7351 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
7352 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7355 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7360 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7361 (const_string "veclogical")
7362 (const_string "integer")))
7363 (set (attr "length")
7365 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7368 (match_test "TARGET_POWERPC64")
7370 (const_string "16"))))])
7372 (define_insn_and_split "*boolcc<mode>3_internal2"
7373 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7374 (match_operator:TI2 3 "boolean_operator"
7376 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
7378 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
7379 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7381 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
7384 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
7387 [(set_attr "type" "integer")
7388 (set (attr "length")
7390 (match_test "TARGET_POWERPC64")
7392 (const_string "16")))])
7396 (define_insn_and_split "*eqv<mode>3_internal1"
7397 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7400 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
7401 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
7404 if (vsx_register_operand (operands[0], <MODE>mode))
7405 return "xxleqv %x0,%x1,%x2";
7409 "TARGET_P8_VECTOR && reload_completed
7410 && int_reg_operand (operands[0], <MODE>mode)"
7413 rs6000_split_logical (operands, XOR, true, false, false);
7418 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7419 (const_string "veclogical")
7420 (const_string "integer")))
7421 (set (attr "length")
7423 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7426 (match_test "TARGET_POWERPC64")
7428 (const_string "16"))))])
7430 (define_insn_and_split "*eqv<mode>3_internal2"
7431 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
7434 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
7435 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
7438 "reload_completed && !TARGET_P8_VECTOR"
7441 rs6000_split_logical (operands, XOR, true, false, false);
7444 [(set_attr "type" "integer")
7445 (set (attr "length")
7447 (match_test "TARGET_POWERPC64")
7449 (const_string "16")))])
7451 ;; 128-bit one's complement
7452 (define_insn_and_split "one_cmpl<mode>2"
7453 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
7455 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
7458 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
7459 return "xxlnor %x0,%x1,%x1";
7461 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
7462 return "vnor %0,%1,%1";
7466 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
7469 rs6000_split_logical (operands, NOT, false, false, false);
7474 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7475 (const_string "veclogical")
7476 (const_string "integer")))
7477 (set (attr "length")
7479 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
7482 (match_test "TARGET_POWERPC64")
7484 (const_string "16"))))])
7487 ;; Now define ways of moving data around.
7489 ;; Set up a register with a value from the GOT table
7491 (define_expand "movsi_got"
7492 [(set (match_operand:SI 0 "gpc_reg_operand")
7493 (unspec:SI [(match_operand:SI 1 "got_operand")
7494 (match_dup 2)] UNSPEC_MOVSI_GOT))]
7495 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7497 if (GET_CODE (operands[1]) == CONST)
7499 rtx offset = const0_rtx;
7500 HOST_WIDE_INT value;
7502 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
7503 value = INTVAL (offset);
7506 rtx tmp = (!can_create_pseudo_p ()
7508 : gen_reg_rtx (Pmode));
7509 emit_insn (gen_movsi_got (tmp, operands[1]));
7510 emit_insn (gen_addsi3 (operands[0], tmp, offset));
7515 operands[2] = rs6000_got_register (operands[1]);
7518 (define_insn "*movsi_got_internal"
7519 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7520 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7521 (match_operand:SI 2 "gpc_reg_operand" "b")]
7523 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
7524 "lwz %0,%a1@got(%2)"
7525 [(set_attr "type" "load")])
7527 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
7528 ;; didn't get allocated to a hard register.
7530 [(set (match_operand:SI 0 "gpc_reg_operand")
7531 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
7532 (match_operand:SI 2 "memory_operand")]
7534 "DEFAULT_ABI == ABI_V4
7536 && reload_completed"
7537 [(set (match_dup 0) (match_dup 2))
7538 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
7543 ;; LWZ LFIWZX LXSIWZX
7544 ;; STW STFIWX STXSIWX
7546 ;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
7547 ;; XXLXOR 0 XXLORC -1 P9 const
7551 (define_insn "*movsi_internal1"
7552 [(set (match_operand:SI 0 "nonimmediate_operand"
7561 (match_operand:SI 1 "input_operand"
7570 "gpc_reg_operand (operands[0], SImode)
7571 || gpc_reg_operand (operands[1], SImode)"
7599 load, fpload, fpload,
7600 store, fpstore, fpstore,
7602 veclogical, vecsimple, vecsimple, vecsimple,
7603 veclogical, veclogical, vecsimple,
7625 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
7626 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
7628 ;; Because SF values are actually stored as DF values within the vector
7629 ;; registers, we need to convert the value to the vector SF format when
7630 ;; we need to use the bits in a union or similar cases. We only need
7631 ;; to do this transformation when the value is a vector register. Loads,
7632 ;; stores, and transfers within GPRs are assumed to be safe.
7634 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
7635 ;; no alternatives, because the call is created as part of secondary_reload,
7636 ;; and operand #2's register class is used to allocate the temporary register.
7637 ;; This function is called before reload, and it creates the temporary as
7640 ;; MR LWZ LFIWZX LXSIWZX STW
7641 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
7644 (define_insn_and_split "movsi_from_sf"
7645 [(set (match_operand:SI 0 "nonimmediate_operand"
7646 "=r, r, ?*d, ?*v, m,
7649 (unspec:SI [(match_operand:SF 1 "input_operand"
7654 (clobber (match_scratch:V4SF 2
7658 "TARGET_NO_SF_SUBREG
7659 && (register_operand (operands[0], SImode)
7660 || register_operand (operands[1], SFmode))"
7673 "&& reload_completed
7674 && int_reg_operand (operands[0], SImode)
7675 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7678 rtx op0 = operands[0];
7679 rtx op1 = operands[1];
7680 rtx op2 = operands[2];
7681 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7682 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7684 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7685 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7689 "*, load, fpload, fpload, store,
7690 fpstore, fpstore, fpstore, mfvsr, fp,
7698 *, p9v, p8v, p8v, p8v,
7701 ;; movsi_from_sf with zero extension
7703 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7706 (define_insn_and_split "*movdi_from_sf_zero_ext"
7707 [(set (match_operand:DI 0 "gpc_reg_operand"
7708 "=r, r, ?*d, ?*v, r,
7711 (unspec:SI [(match_operand:SF 1 "input_operand"
7714 UNSPEC_SI_FROM_SF)))
7715 (clobber (match_scratch:V4SF 2
7718 "TARGET_DIRECT_MOVE_64BIT
7719 && (register_operand (operands[0], DImode)
7720 || register_operand (operands[1], SImode))"
7729 "&& reload_completed
7730 && register_operand (operands[0], DImode)
7731 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7734 rtx op0 = operands[0];
7735 rtx op1 = operands[1];
7736 rtx op2 = operands[2];
7737 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7739 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7740 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7744 "*, load, fpload, fpload, two,
7750 "*, *, p8v, p8v, p8v,
7753 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7754 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7755 ;; conversion explicitly since that doesn't work in most cases if the input
7756 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7757 ;; former handles cases where the input will not fit in a SFmode, and the
7758 ;; latter assumes the value has already been rounded.
7759 (define_insn "*movsi_from_df"
7760 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7761 (unspec:SI [(float_truncate:SF
7762 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7763 UNSPEC_SI_FROM_SF))]
7764 "TARGET_NO_SF_SUBREG"
7766 [(set_attr "type" "fp")])
7768 ;; Split a load of a large constant into the appropriate two-insn
7772 [(set (match_operand:SI 0 "gpc_reg_operand")
7773 (match_operand:SI 1 "const_int_operand"))]
7774 "num_insns_constant (operands[1], SImode) > 1"
7777 if (rs6000_emit_set_const (operands[0], operands[1]))
7783 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7785 [(set (match_operand:DI 0 "altivec_register_operand")
7786 (match_operand:DI 1 "xxspltib_constant_split"))]
7787 "TARGET_P9_VECTOR && reload_completed"
7790 rtx op0 = operands[0];
7791 rtx op1 = operands[1];
7792 int r = REGNO (op0);
7793 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7795 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7796 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7800 (define_insn "*mov<mode>_internal2"
7801 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7802 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7804 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7810 [(set_attr "type" "cmp,logical,cmp")
7811 (set_attr "dot" "yes")
7812 (set_attr "length" "4,4,8")])
7815 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7816 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7818 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7820 [(set (match_dup 0) (match_dup 1))
7822 (compare:CC (match_dup 0)
7826 (define_expand "mov<mode>"
7827 [(set (match_operand:INT 0 "general_operand")
7828 (match_operand:INT 1 "any_operand"))]
7831 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7835 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7836 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7837 ;; MTVSRWZ MF%1 MT%1 NOP
7838 (define_insn "*mov<mode>_internal"
7839 [(set (match_operand:QHI 0 "nonimmediate_operand"
7840 "=r, r, wa, m, ?Z, r,
7841 wa, wa, wa, v, ?v, r,
7843 (match_operand:QHI 1 "input_operand"
7844 "r, m, ?Z, r, wa, i,
7845 wa, O, wM, wB, wS, wa,
7847 "gpc_reg_operand (operands[0], <MODE>mode)
7848 || gpc_reg_operand (operands[1], <MODE>mode)"
7867 "*, load, fpload, store, fpstore, *,
7868 vecsimple, vecperm, vecperm, vecperm, vecperm, mfvsr,
7869 mtvsr, mfjmpr, mtjmpr, *")
7875 "*, *, p9v, *, p9v, *,
7876 p9v, p9v, p9v, p9v, p9v, p9v,
7880 ;; Here is how to move condition codes around. When we store CC data in
7881 ;; an integer register or memory, we store just the high-order 4 bits.
7882 ;; This lets us not shift in the most common case of CR0.
7883 (define_expand "movcc"
7884 [(set (match_operand:CC 0 "nonimmediate_operand")
7885 (match_operand:CC 1 "nonimmediate_operand"))]
7889 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7891 (define_insn "*movcc_<mode>"
7892 [(set (match_operand:CC_any 0 "nonimmediate_operand"
7893 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7894 (match_operand:CC_any 1 "general_operand"
7895 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7896 "register_operand (operands[0], <MODE>mode)
7897 || register_operand (operands[1], <MODE>mode)"
7901 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7904 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7911 [(set_attr_alternative "type"
7912 [(const_string "cr_logical")
7913 (const_string "mtcr")
7914 (const_string "mtcr")
7915 (const_string "cr_logical")
7916 (if_then_else (match_test "TARGET_MFCRF")
7917 (const_string "mfcrf") (const_string "mfcr"))
7918 (if_then_else (match_test "TARGET_MFCRF")
7919 (const_string "mfcrf") (const_string "mfcr"))
7920 (const_string "integer")
7921 (const_string "integer")
7922 (const_string "mfjmpr")
7923 (const_string "mtjmpr")
7924 (const_string "load")
7925 (const_string "store")])
7926 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7928 ;; For floating-point, we normally deal with the floating-point registers
7929 ;; unless -msoft-float is used. The sole exception is that parameter passing
7930 ;; can produce floating-point values in fixed-point registers. Unless the
7931 ;; value is a simple constant or already in memory, we deal with this by
7932 ;; allocating memory and copying the value explicitly via that memory location.
7934 ;; Move 32-bit binary/decimal floating point
7935 (define_expand "mov<mode>"
7936 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7937 (match_operand:FMOVE32 1 "any_operand"))]
7940 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7945 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7946 (match_operand:FMOVE32 1 "const_double_operand"))]
7948 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7949 || (SUBREG_P (operands[0])
7950 && REG_P (SUBREG_REG (operands[0]))
7951 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7952 [(set (match_dup 2) (match_dup 3))]
7956 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7958 if (! TARGET_POWERPC64)
7959 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7961 operands[2] = gen_lowpart (SImode, operands[0]);
7963 operands[3] = gen_int_mode (l, SImode);
7966 ;; Originally, we tried to keep movsf and movsd common, but the differences
7967 ;; addressing was making it rather difficult to hide with mode attributes. In
7968 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7969 ;; before the VSX stores meant that the register allocator would tend to do a
7970 ;; direct move to the GPR (which involves conversion from scalar to
7971 ;; vector/memory formats) to save values in the traditional Altivec registers,
7972 ;; while SDmode had problems on power6 if the GPR store was not first due to
7973 ;; the power6 not having an integer store operation.
7975 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7976 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7977 ;; MR MT<x> MF<x> NOP XXSPLTIDP
7979 (define_insn "movsf_hardfloat"
7980 [(set (match_operand:SF 0 "nonimmediate_operand"
7981 "=!r, f, v, wa, m, wY,
7982 Z, m, wa, !r, f, wa,
7983 !r, *c*l, !r, *h, wa")
7984 (match_operand:SF 1 "input_operand"
7988 "(register_operand (operands[0], SFmode)
7989 || register_operand (operands[1], SFmode))
7990 && TARGET_HARD_FLOAT
7991 && (TARGET_ALLOW_SF_SUBREG
7992 || valid_sf_si_move (operands[0], operands[1], SFmode))"
8005 xscpsgndp %x0,%x1,%x1
8012 "load, fpload, fpload, fpload, fpstore, fpstore,
8013 fpstore, store, veclogical, integer, fpsimple, fpsimple,
8014 *, mtjmpr, mfjmpr, *, vecperm")
8016 "*, *, p9v, p8v, *, p9v,
8019 (set_attr "prefixed"
8024 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
8025 ;; FMR MR MT%0 MF%1 NOP
8026 (define_insn "movsd_hardfloat"
8027 [(set (match_operand:SD 0 "nonimmediate_operand"
8028 "=!r, d, m, ?Z, ?d, ?r,
8029 f, !r, *c*l, !r, *h")
8030 (match_operand:SD 1 "input_operand"
8031 "m, ?Z, r, wx, r, d,
8033 "(register_operand (operands[0], SDmode)
8034 || register_operand (operands[1], SDmode))
8035 && TARGET_HARD_FLOAT"
8049 "load, fpload, store, fpstore, mtvsr, mfvsr,
8050 fpsimple, *, mtjmpr, mfjmpr, *")
8052 "*, p7, *, *, p8v, p8v,
8055 ;; MR MT%0 MF%0 LWZ STW LI
8056 ;; LIS G-const. F/n-const NOP
8057 (define_insn "*mov<mode>_softfloat"
8058 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
8059 "=r, *c*l, r, r, m, r,
8062 (match_operand:FMOVE32 1 "input_operand"
8066 "(gpc_reg_operand (operands[0], <MODE>mode)
8067 || gpc_reg_operand (operands[1], <MODE>mode))
8068 && TARGET_SOFT_FLOAT"
8081 "*, mtjmpr, mfjmpr, load, store, *,
8088 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
8089 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
8091 ;; Because SF values are actually stored as DF values within the vector
8092 ;; registers, we need to convert the value to the vector SF format when
8093 ;; we need to use the bits in a union or similar cases. We only need
8094 ;; to do this transformation when the value is a vector register. Loads,
8095 ;; stores, and transfers within GPRs are assumed to be safe.
8097 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
8098 ;; no alternatives, because the call is created as part of secondary_reload,
8099 ;; and operand #2's register class is used to allocate the temporary register.
8100 ;; This function is called before reload, and it creates the temporary as
8103 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
8104 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
8105 (define_insn_and_split "movsf_from_si"
8106 [(set (match_operand:SF 0 "nonimmediate_operand"
8107 "=!r, f, v, wa, m, Z,
8109 (unspec:SF [(match_operand:SI 1 "input_operand"
8113 (clobber (match_scratch:DI 2
8116 "TARGET_NO_SF_SUBREG
8117 && (register_operand (operands[0], SFmode)
8118 || register_operand (operands[1], SImode))"
8131 "&& reload_completed
8132 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
8133 && int_reg_operand_not_pseudo (operands[1], SImode)"
8136 rtx op0 = operands[0];
8137 rtx op1 = operands[1];
8138 rtx op2 = operands[2];
8139 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
8141 /* Move SF value to upper 32-bits for xscvspdpn. */
8142 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8143 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8144 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8151 "load, fpload, fpload, fpload, store, fpstore,
8152 fpstore, vecfloat, mfvsr, *")
8154 "*, *, p9v, p8v, *, *,
8155 p8v, p8v, p8v, *")])
8157 ;; For extracting high part element from DImode register like:
8158 ;; {%1:SF=unspec[r122:DI>>0x20#0] 86;clobber scratch;}
8159 ;; split it before reload with "and mask" to avoid generating shift right
8160 ;; 32 bit then shift left 32 bit.
8161 (define_insn_and_split "movsf_from_si2"
8162 [(set (match_operand:SF 0 "gpc_reg_operand" "=wa")
8166 (match_operand:DI 1 "input_operand" "r")
8170 (clobber (match_scratch:DI 2 "=r"))]
8171 "TARGET_NO_SF_SUBREG"
8176 if (GET_CODE (operands[2]) == SCRATCH)
8177 operands[2] = gen_reg_rtx (DImode);
8179 rtx mask = GEN_INT (HOST_WIDE_INT_M1U << 32);
8180 emit_insn (gen_anddi3 (operands[2], operands[1], mask));
8181 emit_insn (gen_p8_mtvsrd_sf (operands[0], operands[2]));
8182 emit_insn (gen_vsx_xscvspdpn_directmove (operands[0], operands[0]));
8185 [(set_attr "length" "12")
8186 (set_attr "type" "vecfloat")
8187 (set_attr "isa" "p8v")])
8189 ;; Move 64-bit binary/decimal floating point
8190 (define_expand "mov<mode>"
8191 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
8192 (match_operand:FMOVE64 1 "any_operand"))]
8195 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8200 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8201 (match_operand:FMOVE64 1 "const_int_operand"))]
8202 "! TARGET_POWERPC64 && reload_completed
8203 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8204 || (SUBREG_P (operands[0])
8205 && REG_P (SUBREG_REG (operands[0]))
8206 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8207 [(set (match_dup 2) (match_dup 4))
8208 (set (match_dup 3) (match_dup 1))]
8210 int endian = (WORDS_BIG_ENDIAN == 0);
8211 HOST_WIDE_INT value = INTVAL (operands[1]);
8213 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8214 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8215 operands[4] = GEN_INT (value >> 32);
8216 operands[1] = GEN_INT (sext_hwi (value, 32));
8220 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8221 (match_operand:FMOVE64 1 "const_double_operand"))]
8222 "! TARGET_POWERPC64 && reload_completed
8223 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8224 || (SUBREG_P (operands[0])
8225 && REG_P (SUBREG_REG (operands[0]))
8226 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8227 [(set (match_dup 2) (match_dup 4))
8228 (set (match_dup 3) (match_dup 5))]
8230 int endian = (WORDS_BIG_ENDIAN == 0);
8233 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8235 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
8236 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
8237 operands[4] = gen_int_mode (l[endian], SImode);
8238 operands[5] = gen_int_mode (l[1 - endian], SImode);
8242 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
8243 (match_operand:FMOVE64 1 "const_double_operand"))]
8244 "TARGET_POWERPC64 && reload_completed
8245 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
8246 || (SUBREG_P (operands[0])
8247 && REG_P (SUBREG_REG (operands[0]))
8248 && REGNO (SUBREG_REG (operands[0])) <= 31))"
8249 [(set (match_dup 2) (match_dup 3))]
8251 int endian = (WORDS_BIG_ENDIAN == 0);
8255 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
8257 operands[2] = gen_lowpart (DImode, operands[0]);
8258 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
8259 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
8260 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
8262 operands[3] = gen_int_mode (val, DImode);
8265 ;; Don't have reload use general registers to load a constant. It is
8266 ;; less efficient than loading the constant into an FP register, since
8267 ;; it will probably be used there.
8269 ;; The move constraints are ordered to prefer floating point registers before
8270 ;; general purpose registers to avoid doing a store and a load to get the value
8271 ;; into a floating point register when it is needed for a floating point
8272 ;; operation. Prefer traditional floating point registers over VSX registers,
8273 ;; since the D-form version of the memory instructions does not need a GPR for
8274 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
8277 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
8278 ;; except for 0.0 which can be created on VSX with an xor instruction.
8280 ;; STFD LFD FMR LXSD STXSD
8281 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
8282 ;; LWZ STW MR XXSPLTIDP
8285 (define_insn "*mov<mode>_hardfloat32"
8286 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8287 "=m, d, d, <f64_p9>, wY,
8288 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
8290 (match_operand:FMOVE64 1 "input_operand"
8291 "d, m, d, wY, <f64_p9>,
8292 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
8294 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
8295 && (gpc_reg_operand (operands[0], <MODE>mode)
8296 || gpc_reg_operand (operands[1], <MODE>mode))"
8313 "fpstore, fpload, fpsimple, fpload, fpstore,
8314 fpload, fpstore, veclogical, veclogical, two,
8315 store, load, two, vecperm")
8316 (set_attr "size" "64")
8325 (set_attr "prefixed"
8330 ;; STW LWZ MR G-const H-const F-const
8332 (define_insn "*mov<mode>_softfloat32"
8333 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8334 "=Y, r, r, r, r, r")
8336 (match_operand:FMOVE64 1 "input_operand"
8337 "r, Y, r, G, H, F"))]
8340 && (gpc_reg_operand (operands[0], <MODE>mode)
8341 || gpc_reg_operand (operands[1], <MODE>mode))"
8344 "store, load, two, *, *, *")
8347 "8, 8, 8, 8, 12, 16")])
8349 ; ld/std require word-aligned displacements -> 'Y' constraint.
8350 ; List Y->r and r->Y before r->r for reload.
8352 ;; STFD LFD FMR LXSD STXSD
8353 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
8354 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
8355 ;; NOP MFVSRD MTVSRD XXSPLTIDP
8357 (define_insn "*mov<mode>_hardfloat64"
8358 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8359 "=m, d, d, <f64_p9>, wY,
8360 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
8361 YZ, r, !r, *c*l, !r,
8362 *h, r, <f64_dm>, wa")
8363 (match_operand:FMOVE64 1 "input_operand"
8364 "d, m, d, wY, <f64_p9>,
8365 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
8367 0, <f64_dm>, r, eP"))]
8368 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
8369 && (gpc_reg_operand (operands[0], <MODE>mode)
8370 || gpc_reg_operand (operands[1], <MODE>mode))"
8392 "fpstore, fpload, fpsimple, fpload, fpstore,
8393 fpload, fpstore, veclogical, veclogical, integer,
8394 store, load, *, mtjmpr, mfjmpr,
8395 *, mfvsr, mtvsr, vecperm")
8396 (set_attr "size" "64")
8402 (set_attr "prefixed"
8408 ;; STD LD MR MT<SPR> MF<SPR> G-const
8409 ;; H-const F-const Special
8411 (define_insn "*mov<mode>_softfloat64"
8412 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
8413 "=Y, r, r, *c*l, r, r,
8416 (match_operand:FMOVE64 1 "input_operand"
8420 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
8421 && (gpc_reg_operand (operands[0], <MODE>mode)
8422 || gpc_reg_operand (operands[1], <MODE>mode))"
8434 "store, load, *, mtjmpr, mfjmpr, *,
8441 ;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
8442 ;; constants that look like DFmode floating point values where both elements
8443 ;; are the same. The constant has to be expressible as a SFmode constant that
8444 ;; is not a SFmode denormal value.
8446 ;; We don't need splitters for the 128-bit types, since the function
8447 ;; rs6000_output_move_128bit handles the generation of XXSPLTIDP.
8448 (define_insn "xxspltidp_<mode>_internal"
8449 [(set (match_operand:SFDF 0 "register_operand" "=wa")
8450 (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
8451 UNSPEC_XXSPLTIDP_CONST))]
8454 [(set_attr "type" "vecperm")
8455 (set_attr "prefixed" "yes")])
8457 (define_insn "xxspltiw_<mode>_internal"
8458 [(set (match_operand:SFDF 0 "register_operand" "=wa")
8459 (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
8460 UNSPEC_XXSPLTIW_CONST))]
8463 [(set_attr "type" "vecperm")
8464 (set_attr "prefixed" "yes")])
8467 [(set (match_operand:SFDF 0 "vsx_register_operand")
8468 (match_operand:SFDF 1 "vsx_prefixed_constant"))]
8472 rtx dest = operands[0];
8473 rtx src = operands[1];
8474 vec_const_128bit_type vsx_const;
8476 if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const))
8479 unsigned imm = constant_generates_xxspltidp (&vsx_const);
8482 emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm)));
8486 imm = constant_generates_xxspltiw (&vsx_const);
8489 emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm)));
8497 (define_expand "mov<mode>"
8498 [(set (match_operand:FMOVE128 0 "general_operand")
8499 (match_operand:FMOVE128 1 "any_operand"))]
8502 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
8506 ;; It's important to list Y->r and r->Y before r->r because otherwise
8507 ;; reload, given m->r, will try to pick r->r and reload it, which
8508 ;; doesn't make progress.
8510 ;; We can't split little endian direct moves of TDmode, because the words are
8511 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
8512 ;; problematical. Don't allow direct move for this case.
8514 ;; FPR load FPR store FPR move FPR zero GPR load
8515 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
8517 (define_insn_and_split "*mov<mode>_64bit_dm"
8518 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
8522 (match_operand:FMOVE128_FPR 1 "input_operand"
8523 "d, m, d, <zero_fp>, r,
8524 <zero_fp>, Y, r, d, r"))]
8526 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
8527 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
8528 && (gpc_reg_operand (operands[0], <MODE>mode)
8529 || gpc_reg_operand (operands[1], <MODE>mode))"
8531 "&& reload_completed"
8534 rs6000_split_multireg_move (operands[0], operands[1]);
8537 [(set_attr "length" "8")
8538 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
8539 (set_attr "max_prefixed_insns" "2")
8540 (set_attr "num_insns" "2")])
8542 (define_insn_and_split "*movtd_64bit_nodm"
8543 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
8544 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
8545 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
8546 && (gpc_reg_operand (operands[0], TDmode)
8547 || gpc_reg_operand (operands[1], TDmode))"
8549 "&& reload_completed"
8552 rs6000_split_multireg_move (operands[0], operands[1]);
8555 [(set_attr "length" "8,8,8,12,12,8")
8556 (set_attr "max_prefixed_insns" "2")
8557 (set_attr "num_insns" "2,2,2,3,3,2")])
8559 (define_insn_and_split "*mov<mode>_32bit"
8560 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
8561 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
8562 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
8563 && (FLOAT128_2REG_P (<MODE>mode)
8564 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
8565 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
8566 && (gpc_reg_operand (operands[0], <MODE>mode)
8567 || gpc_reg_operand (operands[1], <MODE>mode))"
8569 "&& reload_completed"
8572 rs6000_split_multireg_move (operands[0], operands[1]);
8575 [(set_attr "length" "8,8,8,8,20,20,16")])
8577 (define_insn_and_split "*mov<mode>_softfloat"
8578 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
8579 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
8581 && (gpc_reg_operand (operands[0], <MODE>mode)
8582 || gpc_reg_operand (operands[1], <MODE>mode))"
8584 "&& reload_completed"
8587 rs6000_split_multireg_move (operands[0], operands[1]);
8590 [(set_attr_alternative "length"
8591 [(if_then_else (match_test "TARGET_POWERPC64")
8593 (const_string "16"))
8594 (if_then_else (match_test "TARGET_POWERPC64")
8596 (const_string "16"))
8597 (if_then_else (match_test "TARGET_POWERPC64")
8599 (const_string "32"))
8600 (if_then_else (match_test "TARGET_POWERPC64")
8602 (const_string "16"))])])
8604 (define_expand "@extenddf<mode>2"
8605 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8606 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
8607 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8609 if (FLOAT128_IEEE_P (<MODE>mode))
8610 rs6000_expand_float128_convert (operands[0], operands[1], false);
8611 else if (TARGET_VSX)
8612 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
8615 rtx zero = gen_reg_rtx (DFmode);
8616 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
8618 emit_insn (gen_extenddf2_fprs (<MODE>mode,
8619 operands[0], operands[1], zero));
8624 ;; Allow memory operands for the source to be created by the combiner.
8625 (define_insn_and_split "@extenddf<mode>2_fprs"
8626 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
8627 (float_extend:IBM128
8628 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
8629 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
8630 "!TARGET_VSX && TARGET_HARD_FLOAT
8631 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
8633 "&& reload_completed"
8634 [(set (match_dup 3) (match_dup 1))
8635 (set (match_dup 4) (match_dup 2))]
8637 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8638 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8640 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8641 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8644 (define_insn_and_split "@extenddf<mode>2_vsx"
8645 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
8646 (float_extend:IBM128
8647 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
8648 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
8650 "&& reload_completed"
8651 [(set (match_dup 2) (match_dup 1))
8652 (set (match_dup 3) (match_dup 4))]
8654 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8655 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8657 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8658 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8659 operands[4] = CONST0_RTX (DFmode);
8662 (define_expand "extendsf<mode>2"
8663 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8664 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
8665 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8667 if (FLOAT128_IEEE_P (<MODE>mode))
8668 rs6000_expand_float128_convert (operands[0], operands[1], false);
8671 rtx tmp = gen_reg_rtx (DFmode);
8672 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8673 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
8678 (define_expand "trunc<mode>df2"
8679 [(set (match_operand:DF 0 "gpc_reg_operand")
8680 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8681 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8683 if (FLOAT128_IEEE_P (<MODE>mode))
8685 rs6000_expand_float128_convert (operands[0], operands[1], false);
8690 (define_insn_and_split "trunc<mode>df2_internal1"
8691 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8693 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
8694 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
8695 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8699 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8702 emit_note (NOTE_INSN_DELETED);
8705 [(set_attr "type" "fpsimple")])
8707 (define_insn "trunc<mode>df2_internal2"
8708 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8709 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8710 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8711 && TARGET_LONG_DOUBLE_128"
8713 [(set_attr "type" "fp")])
8715 (define_expand "trunc<mode>sf2"
8716 [(set (match_operand:SF 0 "gpc_reg_operand")
8717 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8718 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8720 if (FLOAT128_IEEE_P (<MODE>mode))
8721 rs6000_expand_float128_convert (operands[0], operands[1], false);
8724 rtx tmp = gen_reg_rtx (DFmode);
8725 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
8726 emit_insn (gen_truncdfsf2 (operands[0], tmp));
8731 (define_expand "floatsi<mode>2"
8732 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8733 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
8734 (clobber (match_scratch:DI 2))])]
8735 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8737 rtx op0 = operands[0];
8738 rtx op1 = operands[1];
8740 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8742 else if (FLOAT128_IEEE_P (<MODE>mode))
8744 rs6000_expand_float128_convert (op0, op1, false);
8749 rtx tmp = gen_reg_rtx (DFmode);
8750 expand_float (tmp, op1, false);
8751 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8756 ; fadd, but rounding towards zero.
8757 ; This is probably not the optimal code sequence.
8758 (define_insn "fix_trunc_helper<mode>"
8759 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8760 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8761 UNSPEC_FIX_TRUNC_TF))
8762 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8763 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8764 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8765 [(set_attr "type" "fp")
8766 (set_attr "length" "20")])
8768 (define_expand "fix_trunc<mode>si2"
8769 [(set (match_operand:SI 0 "gpc_reg_operand")
8770 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8771 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8773 rtx op0 = operands[0];
8774 rtx op1 = operands[1];
8776 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8780 if (FLOAT128_IEEE_P (<MODE>mode))
8781 rs6000_expand_float128_convert (op0, op1, false);
8783 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8788 (define_expand "@fix_trunc<mode>si2_fprs"
8789 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8790 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8791 (clobber (match_dup 2))
8792 (clobber (match_dup 3))
8793 (clobber (match_dup 4))
8794 (clobber (match_dup 5))])]
8795 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8797 operands[2] = gen_reg_rtx (DFmode);
8798 operands[3] = gen_reg_rtx (DFmode);
8799 operands[4] = gen_reg_rtx (DImode);
8800 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8803 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8804 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8805 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8806 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8807 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8808 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8809 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8810 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8816 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8819 gcc_assert (MEM_P (operands[5]));
8820 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8822 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8823 emit_move_insn (operands[5], operands[4]);
8824 emit_move_insn (operands[0], lowword);
8828 (define_expand "fix_trunc<mode>di2"
8829 [(set (match_operand:DI 0 "gpc_reg_operand")
8830 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8831 "TARGET_FLOAT128_TYPE"
8833 if (!TARGET_FLOAT128_HW)
8835 rs6000_expand_float128_convert (operands[0], operands[1], false);
8840 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8841 [(set (match_operand:SDI 0 "gpc_reg_operand")
8842 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8843 "TARGET_FLOAT128_TYPE"
8845 rs6000_expand_float128_convert (operands[0], operands[1], true);
8849 (define_expand "floatdi<mode>2"
8850 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8851 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8852 "TARGET_FLOAT128_TYPE"
8854 if (!TARGET_FLOAT128_HW)
8856 rs6000_expand_float128_convert (operands[0], operands[1], false);
8861 (define_expand "floatunsdi<IEEE128:mode>2"
8862 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8863 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8864 "TARGET_FLOAT128_TYPE"
8866 if (!TARGET_FLOAT128_HW)
8868 rs6000_expand_float128_convert (operands[0], operands[1], true);
8873 (define_expand "floatuns<IEEE128:mode>2"
8874 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8875 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8876 "TARGET_FLOAT128_TYPE"
8878 rtx op0 = operands[0];
8879 rtx op1 = operands[1];
8881 if (TARGET_FLOAT128_HW)
8882 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8884 rs6000_expand_float128_convert (op0, op1, true);
8888 (define_expand "neg<mode>2"
8889 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8890 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8891 "FLOAT128_IEEE_P (<MODE>mode)
8892 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8894 if (FLOAT128_IEEE_P (<MODE>mode))
8896 if (TARGET_FLOAT128_HW)
8897 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8898 else if (TARGET_FLOAT128_TYPE)
8899 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8900 operands[0], operands[1]));
8903 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8904 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8906 operands[1], <MODE>mode);
8908 if (target && !rtx_equal_p (target, operands[0]))
8909 emit_move_insn (operands[0], target);
8915 (define_insn "neg<mode>2_internal"
8916 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8917 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8918 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8920 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8921 return "fneg %L0,%L1\;fneg %0,%1";
8923 return "fneg %0,%1\;fneg %L0,%L1";
8925 [(set_attr "type" "fpsimple")
8926 (set_attr "length" "8")])
8928 (define_expand "abs<mode>2"
8929 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8930 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8931 "FLOAT128_IEEE_P (<MODE>mode)
8932 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8936 if (FLOAT128_IEEE_P (<MODE>mode))
8938 if (TARGET_FLOAT128_HW)
8940 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8943 else if (TARGET_FLOAT128_TYPE)
8945 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8946 operands[0], operands[1]));
8953 label = gen_label_rtx ();
8954 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8959 (define_expand "@abs<mode>2_internal"
8960 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8961 (match_operand:IBM128 1 "gpc_reg_operand"))
8962 (set (match_dup 3) (match_dup 5))
8963 (set (match_dup 5) (abs:DF (match_dup 5)))
8964 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8965 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8966 (label_ref (match_operand 2 ""))
8968 (set (match_dup 6) (neg:DF (match_dup 6)))]
8969 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8971 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8972 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8973 operands[3] = gen_reg_rtx (DFmode);
8974 operands[4] = gen_reg_rtx (CCFPmode);
8975 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8976 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8980 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8983 (define_expand "ieee_128bit_negative_zero"
8984 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8985 "TARGET_FLOAT128_TYPE"
8987 rtvec v = rtvec_alloc (16);
8990 for (i = 0; i < 16; i++)
8991 RTVEC_ELT (v, i) = const0_rtx;
8993 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8994 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8996 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
9000 ;; IEEE 128-bit negate
9002 ;; We have 2 insns here for negate and absolute value. The first uses
9003 ;; match_scratch so that phases like combine can recognize neg/abs as generic
9004 ;; insns, and second insn after the first split pass loads up the bit to
9005 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
9006 ;; neg/abs to create the constant just once.
9008 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
9009 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9010 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9011 (clobber (match_scratch:V16QI 2 "=v"))]
9012 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9015 [(parallel [(set (match_dup 0)
9016 (neg:IEEE128 (match_dup 1)))
9017 (use (match_dup 2))])]
9019 if (GET_CODE (operands[2]) == SCRATCH)
9020 operands[2] = gen_reg_rtx (V16QImode);
9022 operands[3] = gen_reg_rtx (V16QImode);
9023 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9025 [(set_attr "length" "8")
9026 (set_attr "type" "vecsimple")])
9028 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
9029 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9030 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9031 (use (match_operand:V16QI 2 "register_operand" "v"))]
9032 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9033 "xxlxor %x0,%x1,%x2"
9034 [(set_attr "type" "veclogical")])
9036 ;; IEEE 128-bit absolute value
9037 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
9038 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9039 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9040 (clobber (match_scratch:V16QI 2 "=v"))]
9041 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
9044 [(parallel [(set (match_dup 0)
9045 (abs:IEEE128 (match_dup 1)))
9046 (use (match_dup 2))])]
9048 if (GET_CODE (operands[2]) == SCRATCH)
9049 operands[2] = gen_reg_rtx (V16QImode);
9051 operands[3] = gen_reg_rtx (V16QImode);
9052 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9054 [(set_attr "length" "8")
9055 (set_attr "type" "vecsimple")])
9057 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
9058 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9059 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
9060 (use (match_operand:V16QI 2 "register_operand" "v"))]
9061 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9062 "xxlandc %x0,%x1,%x2"
9063 [(set_attr "type" "veclogical")])
9065 ;; IEEE 128-bit negative absolute value
9066 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
9067 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9070 (match_operand:IEEE128 1 "register_operand" "wa"))))
9071 (clobber (match_scratch:V16QI 2 "=v"))]
9072 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
9073 && FLOAT128_IEEE_P (<MODE>mode)"
9076 [(parallel [(set (match_dup 0)
9077 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
9078 (use (match_dup 2))])]
9080 if (GET_CODE (operands[2]) == SCRATCH)
9081 operands[2] = gen_reg_rtx (V16QImode);
9083 operands[3] = gen_reg_rtx (V16QImode);
9084 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
9086 [(set_attr "length" "8")
9087 (set_attr "type" "vecsimple")])
9089 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
9090 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
9093 (match_operand:IEEE128 1 "register_operand" "wa"))))
9094 (use (match_operand:V16QI 2 "register_operand" "v"))]
9095 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9097 [(set_attr "type" "veclogical")])
9099 ;; Float128 conversion functions. These expand to library function calls.
9100 ;; We use expand to convert from IBM double double to IEEE 128-bit
9101 ;; and trunc for the opposite.
9102 (define_expand "extendiftf2"
9103 [(set (match_operand:TF 0 "gpc_reg_operand")
9104 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
9105 "TARGET_FLOAT128_TYPE"
9107 rs6000_expand_float128_convert (operands[0], operands[1], false);
9111 (define_expand "extendifkf2"
9112 [(set (match_operand:KF 0 "gpc_reg_operand")
9113 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
9114 "TARGET_FLOAT128_TYPE"
9116 rs6000_expand_float128_convert (operands[0], operands[1], false);
9120 (define_expand "extendtfkf2"
9121 [(set (match_operand:KF 0 "gpc_reg_operand")
9122 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
9123 "TARGET_FLOAT128_TYPE"
9125 rs6000_expand_float128_convert (operands[0], operands[1], false);
9129 (define_expand "extendtfif2"
9130 [(set (match_operand:IF 0 "gpc_reg_operand")
9131 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
9132 "TARGET_FLOAT128_TYPE"
9134 rs6000_expand_float128_convert (operands[0], operands[1], false);
9138 (define_expand "trunciftf2"
9139 [(set (match_operand:TF 0 "gpc_reg_operand")
9140 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
9141 "TARGET_FLOAT128_TYPE"
9143 rs6000_expand_float128_convert (operands[0], operands[1], false);
9147 (define_expand "truncifkf2"
9148 [(set (match_operand:KF 0 "gpc_reg_operand")
9149 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
9150 "TARGET_FLOAT128_TYPE"
9152 rs6000_expand_float128_convert (operands[0], operands[1], false);
9156 (define_expand "trunckftf2"
9157 [(set (match_operand:TF 0 "gpc_reg_operand")
9158 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
9159 "TARGET_FLOAT128_TYPE"
9161 rs6000_expand_float128_convert (operands[0], operands[1], false);
9165 (define_expand "trunctfif2"
9166 [(set (match_operand:IF 0 "gpc_reg_operand")
9167 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
9168 "TARGET_FLOAT128_TYPE"
9170 rs6000_expand_float128_convert (operands[0], operands[1], false);
9174 (define_insn_and_split "*extend<mode>tf2_internal"
9175 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
9177 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
9178 "TARGET_FLOAT128_TYPE
9179 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
9181 "&& reload_completed"
9182 [(set (match_dup 0) (match_dup 2))]
9184 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
9187 (define_insn_and_split "*extendtf<mode>2_internal"
9188 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
9190 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
9191 "TARGET_FLOAT128_TYPE
9192 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
9194 "&& reload_completed"
9195 [(set (match_dup 0) (match_dup 2))]
9197 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
9201 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
9202 ;; must have 3 arguments, and scratch register constraint must be a single
9205 ;; Reload patterns to support gpr load/store with misaligned mem.
9206 ;; and multiple gpr load/store at offset >= 0xfffc
9207 (define_expand "reload_<mode>_store"
9208 [(parallel [(match_operand 0 "memory_operand" "=m")
9209 (match_operand 1 "gpc_reg_operand" "r")
9210 (match_operand:GPR 2 "register_operand" "=&b")])]
9213 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
9217 (define_expand "reload_<mode>_load"
9218 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
9219 (match_operand 1 "memory_operand" "m")
9220 (match_operand:GPR 2 "register_operand" "=b")])]
9223 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
9228 ;; Reload patterns for various types using the vector registers. We may need
9229 ;; an additional base register to convert the reg+offset addressing to reg+reg
9230 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
9231 ;; index register for gpr registers.
9232 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
9233 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
9234 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
9235 (match_operand:P 2 "register_operand" "=b")])]
9238 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
9242 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
9243 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
9244 (match_operand:RELOAD 1 "memory_operand" "m")
9245 (match_operand:P 2 "register_operand" "=b")])]
9248 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
9253 ;; Reload sometimes tries to move the address to a GPR, and can generate
9254 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
9255 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
9257 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
9258 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9259 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
9260 (match_operand:P 2 "reg_or_cint_operand" "rI"))
9262 "TARGET_ALTIVEC && reload_completed"
9264 "&& reload_completed"
9266 (plus:P (match_dup 1)
9269 (and:P (match_dup 0)
9272 ;; Power8 merge instructions to allow direct move to/from floating point
9273 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
9274 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
9275 ;; value, since it is allocated in reload and not all of the flow information
9276 ;; is setup for it. We have two patterns to do the two moves between gprs and
9277 ;; fprs. There isn't a dependancy between the two, but we could potentially
9278 ;; schedule other instructions between the two instructions.
9280 (define_insn "p8_fmrgow_<mode>"
9281 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
9283 (match_operand:DF 1 "register_operand" "d")
9284 (match_operand:DF 2 "register_operand" "d")]
9285 UNSPEC_P8V_FMRGOW))]
9286 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9288 [(set_attr "type" "fpsimple")])
9290 (define_insn "p8_mtvsrwz"
9291 [(set (match_operand:DF 0 "register_operand" "=d")
9292 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
9293 UNSPEC_P8V_MTVSRWZ))]
9294 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9296 [(set_attr "type" "mtvsr")])
9298 (define_insn "p8_mtvsrwz_v16qisi2"
9299 [(set (match_operand:V16QI 0 "register_operand" "=wa")
9300 (unspec:V16QI [(match_operand:SI 1 "register_operand" "r")]
9301 UNSPEC_P8V_MTVSRWZ))]
9302 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9304 [(set_attr "type" "mtvsr")])
9306 (define_insn "p8_mtvsrd_v16qidi2"
9307 [(set (match_operand:V16QI 0 "register_operand" "=wa")
9308 (unspec:V16QI [(match_operand:DI 1 "register_operand" "r")]
9309 UNSPEC_P8V_MTVSRD))]
9310 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9312 [(set_attr "type" "mtvsr")])
9314 (define_insn_and_split "reload_fpr_from_gpr<mode>"
9315 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
9316 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
9317 UNSPEC_P8V_RELOAD_FROM_GPR))
9318 (clobber (match_operand:IF 2 "register_operand" "=d"))]
9319 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9321 "&& reload_completed"
9324 rtx dest = operands[0];
9325 rtx src = operands[1];
9326 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
9327 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
9328 rtx gpr_hi_reg = gen_highpart (SImode, src);
9329 rtx gpr_lo_reg = gen_lowpart (SImode, src);
9331 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
9332 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
9333 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
9336 [(set_attr "length" "12")
9337 (set_attr "type" "three")])
9339 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
9340 (define_insn "p8_mtvsrd_df"
9341 [(set (match_operand:DF 0 "register_operand" "=wa")
9342 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
9343 UNSPEC_P8V_MTVSRD))]
9344 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9346 [(set_attr "type" "mtvsr")])
9348 (define_insn "p8_xxpermdi_<mode>"
9349 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
9350 (unspec:FMOVE128_GPR [
9351 (match_operand:DF 1 "register_operand" "wa")
9352 (match_operand:DF 2 "register_operand" "wa")]
9353 UNSPEC_P8V_XXPERMDI))]
9354 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9355 "xxpermdi %x0,%x1,%x2,0"
9356 [(set_attr "type" "vecperm")])
9358 (define_insn_and_split "reload_vsx_from_gpr<mode>"
9359 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
9360 (unspec:FMOVE128_GPR
9361 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
9362 UNSPEC_P8V_RELOAD_FROM_GPR))
9363 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
9364 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9366 "&& reload_completed"
9369 rtx dest = operands[0];
9370 rtx src = operands[1];
9371 /* You might think that we could use op0 as one temp and a DF clobber
9372 as op2, but you'd be wrong. Secondary reload move patterns don't
9373 check for overlap of the clobber and the destination. */
9374 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
9375 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
9376 rtx gpr_hi_reg = gen_highpart (DImode, src);
9377 rtx gpr_lo_reg = gen_lowpart (DImode, src);
9379 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
9380 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
9381 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
9384 [(set_attr "length" "12")
9385 (set_attr "type" "three")])
9388 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
9389 (match_operand:FMOVE128_GPR 1 "input_operand"))]
9391 && (int_reg_operand (operands[0], <MODE>mode)
9392 || int_reg_operand (operands[1], <MODE>mode))
9393 && (!TARGET_DIRECT_MOVE_128
9394 || (!vsx_register_operand (operands[0], <MODE>mode)
9395 && !vsx_register_operand (operands[1], <MODE>mode)))"
9398 rs6000_split_multireg_move (operands[0], operands[1]);
9402 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
9403 ;; type is stored internally as double precision in the VSX registers, we have
9404 ;; to convert it from the vector format.
9405 (define_insn "p8_mtvsrd_sf"
9406 [(set (match_operand:SF 0 "register_operand" "=wa")
9407 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
9408 UNSPEC_P8V_MTVSRD))]
9409 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9411 [(set_attr "type" "mtvsr")])
9413 (define_insn_and_split "reload_vsx_from_gprsf"
9414 [(set (match_operand:SF 0 "register_operand" "=wa")
9415 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
9416 UNSPEC_P8V_RELOAD_FROM_GPR))
9417 (clobber (match_operand:DI 2 "register_operand" "=r"))]
9418 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9420 "&& reload_completed"
9423 rtx op0 = operands[0];
9424 rtx op1 = operands[1];
9425 rtx op2 = operands[2];
9426 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
9428 /* Move SF value to upper 32-bits for xscvspdpn. */
9429 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
9430 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
9431 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
9434 [(set_attr "length" "8")
9435 (set_attr "type" "two")])
9437 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
9438 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
9439 ;; and then doing a move of that.
9440 (define_insn "p8_mfvsrd_3_<mode>"
9441 [(set (match_operand:DF 0 "register_operand" "=r")
9442 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
9443 UNSPEC_P8V_RELOAD_FROM_VSX))]
9444 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9446 [(set_attr "type" "mfvsr")])
9448 (define_insn_and_split "reload_gpr_from_vsx<mode>"
9449 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
9450 (unspec:FMOVE128_GPR
9451 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
9452 UNSPEC_P8V_RELOAD_FROM_VSX))
9453 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
9454 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9456 "&& reload_completed"
9459 rtx dest = operands[0];
9460 rtx src = operands[1];
9461 rtx tmp = operands[2];
9462 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
9463 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
9465 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
9466 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
9467 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
9470 [(set_attr "length" "12")
9471 (set_attr "type" "three")])
9473 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
9474 ;; type is stored internally as double precision, we have to convert it to the
9477 (define_insn_and_split "reload_gpr_from_vsxsf"
9478 [(set (match_operand:SF 0 "register_operand" "=r")
9479 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
9480 UNSPEC_P8V_RELOAD_FROM_VSX))
9481 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
9482 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9484 "&& reload_completed"
9487 rtx op0 = operands[0];
9488 rtx op1 = operands[1];
9489 rtx op2 = operands[2];
9490 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
9491 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
9493 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
9494 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
9497 [(set_attr "length" "8")
9498 (set_attr "type" "two")
9499 (set_attr "isa" "p8v")])
9501 ;; Next come the multi-word integer load and store and the load and store
9504 ;; List r->r after r->Y, otherwise reload will try to reload a
9505 ;; non-offsettable address by using r->r which won't make progress.
9506 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
9507 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
9509 ;; GPR store GPR load GPR move FPR store FPR load FPR move
9510 ;; GPR const AVX store AVX store AVX load AVX load VSX move
9511 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
9514 (define_insn "*movdi_internal32"
9515 [(set (match_operand:DI 0 "nonimmediate_operand"
9516 "=Y, r, r, m, ^d, ^d,
9517 r, wY, Z, ^v, $v, ^wa,
9518 wa, wa, v, wa, *i, v,
9520 (match_operand:DI 1 "input_operand"
9521 "r, Y, r, ^d, m, ^d,
9522 IJKnF, ^v, $v, wY, Z, ^wa,
9523 Oj, wM, OjwM, Oj, wM, wS,
9526 && (gpc_reg_operand (operands[0], DImode)
9527 || gpc_reg_operand (operands[1], DImode))"
9549 "store, load, *, fpstore, fpload, fpsimple,
9550 *, fpstore, fpstore, fpload, fpload, veclogical,
9551 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
9553 (set_attr "size" "64")
9561 *, p9v, p7v, p9v, p7v, *,
9562 p9v, p9v, p7v, *, *, p7v,
9566 [(set (match_operand:DI 0 "gpc_reg_operand")
9567 (match_operand:DI 1 "const_int_operand"))]
9568 "! TARGET_POWERPC64 && reload_completed
9569 && gpr_or_gpr_p (operands[0], operands[1])
9570 && !direct_move_p (operands[0], operands[1])"
9571 [(set (match_dup 2) (match_dup 4))
9572 (set (match_dup 3) (match_dup 1))]
9574 HOST_WIDE_INT value = INTVAL (operands[1]);
9575 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9577 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9579 operands[4] = GEN_INT (value >> 32);
9580 operands[1] = GEN_INT (sext_hwi (value, 32));
9584 [(set (match_operand:DIFD 0 "nonimmediate_operand")
9585 (match_operand:DIFD 1 "input_operand"))]
9586 "reload_completed && !TARGET_POWERPC64
9587 && gpr_or_gpr_p (operands[0], operands[1])
9588 && !direct_move_p (operands[0], operands[1])"
9591 rs6000_split_multireg_move (operands[0], operands[1]);
9595 ;; GPR store GPR load GPR move
9596 ;; GPR li GPR lis GPR pli GPR #
9597 ;; FPR store FPR load FPR move
9598 ;; AVX store AVX store AVX load AVX load VSX move
9599 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1
9600 ;; P9 const AVX const
9601 ;; From SPR To SPR SPR<->SPR
9602 ;; VSX->GPR GPR->VSX
9603 (define_insn "*movdi_internal64"
9604 [(set (match_operand:DI 0 "nonimmediate_operand"
9613 (match_operand:DI 1 "input_operand"
9618 Oj, wM, OjwM, Oj, wM,
9623 && (gpc_reg_operand (operands[0], DImode)
9624 || gpc_reg_operand (operands[1], DImode))"
9656 fpstore, fpload, fpsimple,
9657 fpstore, fpstore, fpload, fpload, veclogical,
9658 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
9659 vecsimple, vecsimple,
9662 (set_attr "size" "64")
9676 p9v, p7v, p9v, p7v, *,
9677 p9v, p9v, p7v, *, *,
9682 ; Some DImode loads are best done as a load of -1 followed by a mask
9685 [(set (match_operand:DI 0 "int_reg_operand")
9686 (match_operand:DI 1 "const_int_operand"))]
9688 && num_insns_constant (operands[1], DImode) > 1
9689 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
9690 && rs6000_is_valid_and_mask (operands[1], DImode)"
9694 (and:DI (match_dup 0)
9698 ;; Split a load of a large constant into the appropriate five-instruction
9699 ;; sequence. Handle anything in a constant number of insns.
9700 ;; When non-easy constants can go in the TOC, this should use
9701 ;; easy_fp_constant predicate.
9703 [(set (match_operand:DI 0 "int_reg_operand")
9704 (match_operand:DI 1 "const_int_operand"))]
9705 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9708 if (rs6000_emit_set_const (operands[0], operands[1]))
9715 [(set (match_operand:DI 0 "altivec_register_operand")
9716 (match_operand:DI 1 "s5bit_cint_operand"))]
9717 "TARGET_VSX && reload_completed"
9720 rtx op0 = operands[0];
9721 rtx op1 = operands[1];
9722 int r = REGNO (op0);
9723 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9725 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9726 if (op1 != const0_rtx && op1 != constm1_rtx)
9728 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9729 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9734 ;; Split integer constants that can be loaded with XXSPLTIB and a
9735 ;; sign extend operation.
9737 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
9738 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
9739 "TARGET_P9_VECTOR && reload_completed"
9742 rtx op0 = operands[0];
9743 rtx op1 = operands[1];
9744 int r = REGNO (op0);
9745 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9747 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9748 if (<MODE>mode == DImode)
9749 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9750 else if (<MODE>mode == SImode)
9751 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9752 else if (<MODE>mode == HImode)
9754 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9755 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9761 ;; TImode/PTImode is similar, except that we usually want to compute the
9762 ;; address into a register and use lsi/stsi (the exception is during reload).
9764 (define_insn "*mov<mode>_string"
9765 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9766 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9768 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9769 && (gpc_reg_operand (operands[0], <MODE>mode)
9770 || gpc_reg_operand (operands[1], <MODE>mode))"
9772 [(set_attr "type" "store,store,load,load,*,*")
9773 (set_attr "update" "yes")
9774 (set_attr "indexed" "yes")
9775 (set_attr "cell_micro" "conditional")])
9777 (define_insn "*mov<mode>_ppc64"
9778 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9779 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9780 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9781 && (gpc_reg_operand (operands[0], <MODE>mode)
9782 || gpc_reg_operand (operands[1], <MODE>mode)))"
9784 return rs6000_output_move_128bit (operands);
9786 [(set_attr "type" "store,store,load,load,*,*")
9787 (set_attr "length" "8")
9788 (set_attr "max_prefixed_insns" "2")])
9791 [(set (match_operand:TI2 0 "int_reg_operand")
9792 (match_operand:TI2 1 "const_scalar_int_operand"))]
9794 && (VECTOR_MEM_NONE_P (<MODE>mode)
9795 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9796 [(set (match_dup 2) (match_dup 4))
9797 (set (match_dup 3) (match_dup 5))]
9799 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9801 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9803 if (CONST_WIDE_INT_P (operands[1]))
9805 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9806 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9808 else if (CONST_INT_P (operands[1]))
9810 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9811 operands[5] = operands[1];
9818 [(set (match_operand:TI2 0 "nonimmediate_operand")
9819 (match_operand:TI2 1 "input_operand"))]
9821 && gpr_or_gpr_p (operands[0], operands[1])
9822 && !direct_move_p (operands[0], operands[1])
9823 && !quad_load_store_p (operands[0], operands[1])"
9826 rs6000_split_multireg_move (operands[0], operands[1]);
9830 (define_expand "setmemsi"
9831 [(parallel [(set (match_operand:BLK 0 "")
9832 (match_operand 2 "const_int_operand"))
9833 (use (match_operand:SI 1 ""))
9834 (use (match_operand:SI 3 ""))])]
9837 /* If value to set is not zero, use the library routine. */
9838 if (operands[2] != const0_rtx)
9841 if (expand_block_clear (operands))
9847 ;; String compare N insn.
9848 ;; Argument 0 is the target (result)
9849 ;; Argument 1 is the destination
9850 ;; Argument 2 is the source
9851 ;; Argument 3 is the length
9852 ;; Argument 4 is the alignment
9854 (define_expand "cmpstrnsi"
9855 [(parallel [(set (match_operand:SI 0)
9856 (compare:SI (match_operand:BLK 1)
9857 (match_operand:BLK 2)))
9858 (use (match_operand:SI 3))
9859 (use (match_operand:SI 4))])]
9860 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9862 if (optimize_insn_for_size_p ())
9865 if (expand_strn_compare (operands, 0))
9871 ;; String compare insn.
9872 ;; Argument 0 is the target (result)
9873 ;; Argument 1 is the destination
9874 ;; Argument 2 is the source
9875 ;; Argument 3 is the alignment
9877 (define_expand "cmpstrsi"
9878 [(parallel [(set (match_operand:SI 0)
9879 (compare:SI (match_operand:BLK 1)
9880 (match_operand:BLK 2)))
9881 (use (match_operand:SI 3))])]
9882 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9884 if (optimize_insn_for_size_p ())
9887 if (expand_strn_compare (operands, 1))
9893 ;; Block compare insn.
9894 ;; Argument 0 is the target (result)
9895 ;; Argument 1 is the destination
9896 ;; Argument 2 is the source
9897 ;; Argument 3 is the length
9898 ;; Argument 4 is the alignment
9900 (define_expand "cmpmemsi"
9901 [(parallel [(set (match_operand:SI 0)
9902 (compare:SI (match_operand:BLK 1)
9903 (match_operand:BLK 2)))
9904 (use (match_operand:SI 3))
9905 (use (match_operand:SI 4))])]
9908 if (expand_block_compare (operands))
9914 ;; String/block copy insn (source and destination must not overlap).
9915 ;; Argument 0 is the destination
9916 ;; Argument 1 is the source
9917 ;; Argument 2 is the length
9918 ;; Argument 3 is the alignment
9920 (define_expand "cpymemsi"
9921 [(parallel [(set (match_operand:BLK 0 "")
9922 (match_operand:BLK 1 ""))
9923 (use (match_operand:SI 2 ""))
9924 (use (match_operand:SI 3 ""))])]
9927 if (expand_block_move (operands, false))
9933 ;; String/block move insn (source and destination may overlap).
9934 ;; Argument 0 is the destination
9935 ;; Argument 1 is the source
9936 ;; Argument 2 is the length
9937 ;; Argument 3 is the alignment
9939 (define_expand "movmemsi"
9940 [(parallel [(set (match_operand:BLK 0 "")
9941 (match_operand:BLK 1 ""))
9942 (use (match_operand:SI 2 ""))
9943 (use (match_operand:SI 3 ""))])]
9946 if (expand_block_move (operands, true))
9953 ;; Define insns that do load or store with update. Some of these we can
9954 ;; get by using pre-decrement or pre-increment, but the hardware can also
9955 ;; do cases where the increment is not the size of the object.
9957 ;; In all these cases, we use operands 0 and 1 for the register being
9958 ;; incremented because those are the operands that local-alloc will
9959 ;; tie and these are the pair most likely to be tieable (and the ones
9960 ;; that will benefit the most).
9962 (define_insn "*movdi_update1"
9963 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9964 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9965 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9966 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9967 (plus:P (match_dup 1) (match_dup 2)))]
9968 "TARGET_POWERPC64 && TARGET_UPDATE
9969 && (!avoiding_indexed_address_p (DImode)
9970 || !gpc_reg_operand (operands[2], Pmode))"
9974 [(set_attr "type" "load")
9975 (set_attr "update" "yes")
9976 (set_attr "indexed" "yes,no")])
9978 (define_insn "movdi_<mode>_update"
9979 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9980 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9981 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9982 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9983 (plus:P (match_dup 1) (match_dup 2)))]
9984 "TARGET_POWERPC64 && TARGET_UPDATE
9985 && (!avoiding_indexed_address_p (DImode)
9986 || !gpc_reg_operand (operands[2], Pmode)
9987 || (REG_P (operands[0])
9988 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9992 [(set_attr "type" "store")
9993 (set_attr "update" "yes")
9994 (set_attr "indexed" "yes,no")])
9996 ;; This pattern is only conditional on TARGET_64BIT, as it is
9997 ;; needed for stack allocation, even if the user passes -mno-update.
9998 (define_insn "movdi_update_stack"
9999 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
10000 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
10001 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
10002 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
10003 (plus:DI (match_dup 1) (match_dup 2)))]
10008 [(set_attr "type" "store")
10009 (set_attr "update" "yes")
10010 (set_attr "indexed" "yes,no")])
10012 (define_insn "*movsi_update1"
10013 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
10014 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10015 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10016 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10017 (plus:P (match_dup 1) (match_dup 2)))]
10019 && (!avoiding_indexed_address_p (SImode)
10020 || !gpc_reg_operand (operands[2], Pmode))"
10024 [(set_attr "type" "load")
10025 (set_attr "update" "yes")
10026 (set_attr "indexed" "yes,no")])
10028 (define_insn "*movsi_update2"
10029 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
10031 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
10032 (match_operand:P 2 "gpc_reg_operand" "r")))))
10033 (set (match_operand:P 0 "gpc_reg_operand" "=b")
10034 (plus:P (match_dup 1) (match_dup 2)))]
10035 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
10037 [(set_attr "type" "load")
10038 (set_attr "sign_extend" "yes")
10039 (set_attr "update" "yes")
10040 (set_attr "indexed" "yes")])
10042 (define_insn "movsi_<mode>_update"
10043 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10044 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10045 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
10046 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10047 (plus:P (match_dup 1) (match_dup 2)))]
10049 && (!avoiding_indexed_address_p (SImode)
10050 || !gpc_reg_operand (operands[2], Pmode)
10051 || (REG_P (operands[0])
10052 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
10056 [(set_attr "type" "store")
10057 (set_attr "update" "yes")
10058 (set_attr "indexed" "yes,no")])
10060 ;; This is an unconditional pattern; needed for stack allocation, even
10061 ;; if the user passes -mno-update.
10062 (define_insn "movsi_update_stack"
10063 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
10064 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
10065 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
10066 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
10067 (plus:SI (match_dup 1) (match_dup 2)))]
10072 [(set_attr "type" "store")
10073 (set_attr "update" "yes")
10074 (set_attr "indexed" "yes,no")])
10076 (define_insn "*movhi_update1"
10077 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
10078 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10079 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10080 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10081 (plus:P (match_dup 1) (match_dup 2)))]
10083 && (!avoiding_indexed_address_p (HImode)
10084 || !gpc_reg_operand (operands[2], SImode))"
10088 [(set_attr "type" "load")
10089 (set_attr "update" "yes")
10090 (set_attr "indexed" "yes,no")])
10092 (define_insn "*movhi_update2"
10093 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
10095 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10096 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10097 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10098 (plus:P (match_dup 1) (match_dup 2)))]
10100 && (!avoiding_indexed_address_p (HImode)
10101 || !gpc_reg_operand (operands[2], Pmode))"
10105 [(set_attr "type" "load")
10106 (set_attr "update" "yes")
10107 (set_attr "indexed" "yes,no")])
10109 (define_insn "*movhi_update3"
10110 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
10112 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10113 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10114 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10115 (plus:P (match_dup 1) (match_dup 2)))]
10117 && !(avoiding_indexed_address_p (HImode)
10118 && gpc_reg_operand (operands[2], Pmode))"
10122 [(set_attr "type" "load")
10123 (set_attr "sign_extend" "yes")
10124 (set_attr "update" "yes")
10125 (set_attr "indexed" "yes,no")])
10127 (define_insn "*movhi_update4"
10128 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10129 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10130 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
10131 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10132 (plus:P (match_dup 1) (match_dup 2)))]
10134 && (!avoiding_indexed_address_p (HImode)
10135 || !gpc_reg_operand (operands[2], Pmode))"
10139 [(set_attr "type" "store")
10140 (set_attr "update" "yes")
10141 (set_attr "indexed" "yes,no")])
10143 (define_insn "*movqi_update1"
10144 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
10145 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10146 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10147 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10148 (plus:P (match_dup 1) (match_dup 2)))]
10150 && (!avoiding_indexed_address_p (QImode)
10151 || !gpc_reg_operand (operands[2], Pmode))"
10155 [(set_attr "type" "load")
10156 (set_attr "update" "yes")
10157 (set_attr "indexed" "yes,no")])
10159 (define_insn "*movqi_update2"
10160 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
10162 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10163 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
10164 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10165 (plus:P (match_dup 1) (match_dup 2)))]
10167 && (!avoiding_indexed_address_p (QImode)
10168 || !gpc_reg_operand (operands[2], Pmode))"
10172 [(set_attr "type" "load")
10173 (set_attr "update" "yes")
10174 (set_attr "indexed" "yes,no")])
10176 (define_insn "*movqi_update3"
10177 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10178 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10179 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
10180 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10181 (plus:P (match_dup 1) (match_dup 2)))]
10183 && (!avoiding_indexed_address_p (QImode)
10184 || !gpc_reg_operand (operands[2], Pmode))"
10188 [(set_attr "type" "store")
10189 (set_attr "update" "yes")
10190 (set_attr "indexed" "yes,no")])
10192 (define_insn "*mov<SFDF:mode>_update1"
10193 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=d,d")
10194 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10195 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10196 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10197 (plus:P (match_dup 1) (match_dup 2)))]
10198 "TARGET_HARD_FLOAT && TARGET_UPDATE
10199 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
10200 || !gpc_reg_operand (operands[2], Pmode))"
10204 [(set_attr "type" "fpload")
10205 (set_attr "update" "yes")
10206 (set_attr "indexed" "yes,no")
10207 (set_attr "size" "<SFDF:bits>")])
10209 (define_insn "*mov<SFDF:mode>_update2"
10210 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10211 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10212 (match_operand:SFDF 3 "gpc_reg_operand" "d,d"))
10213 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10214 (plus:P (match_dup 1) (match_dup 2)))]
10215 "TARGET_HARD_FLOAT && TARGET_UPDATE
10216 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
10217 || !gpc_reg_operand (operands[2], Pmode))"
10220 stf<sd>u %3,%2(%0)"
10221 [(set_attr "type" "fpstore")
10222 (set_attr "update" "yes")
10223 (set_attr "indexed" "yes,no")
10224 (set_attr "size" "<SFDF:bits>")])
10226 (define_insn "*movsf_update3"
10227 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
10228 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10229 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
10230 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10231 (plus:P (match_dup 1) (match_dup 2)))]
10232 "TARGET_SOFT_FLOAT && TARGET_UPDATE
10233 && (!avoiding_indexed_address_p (SFmode)
10234 || !gpc_reg_operand (operands[2], Pmode))"
10238 [(set_attr "type" "load")
10239 (set_attr "update" "yes")
10240 (set_attr "indexed" "yes,no")])
10242 (define_insn "*movsf_update4"
10243 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
10244 (match_operand:P 2 "reg_or_short_operand" "r,I")))
10245 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
10246 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
10247 (plus:P (match_dup 1) (match_dup 2)))]
10248 "TARGET_SOFT_FLOAT && TARGET_UPDATE
10249 && (!avoiding_indexed_address_p (SFmode)
10250 || !gpc_reg_operand (operands[2], Pmode))"
10254 [(set_attr "type" "store")
10255 (set_attr "update" "yes")
10256 (set_attr "indexed" "yes,no")])
10259 ;; After inserting conditional returns we can sometimes have
10260 ;; unnecessary register moves. Unfortunately we cannot have a
10261 ;; modeless peephole here, because some single SImode sets have early
10262 ;; clobber outputs. Although those sets expand to multi-ppc-insn
10263 ;; sequences, using get_attr_length here will smash the operands
10264 ;; array. Neither is there an early_cobbler_p predicate.
10265 ;; Also this optimization interferes with scalars going into
10266 ;; altivec registers (the code does reloading through the FPRs).
10268 [(set (match_operand:DF 0 "gpc_reg_operand")
10269 (match_operand:DF 1 "any_operand"))
10270 (set (match_operand:DF 2 "gpc_reg_operand")
10273 && peep2_reg_dead_p (2, operands[0])"
10274 [(set (match_dup 2) (match_dup 1))])
10277 [(set (match_operand:SF 0 "gpc_reg_operand")
10278 (match_operand:SF 1 "any_operand"))
10279 (set (match_operand:SF 2 "gpc_reg_operand")
10282 && peep2_reg_dead_p (2, operands[0])"
10283 [(set (match_dup 2) (match_dup 1))])
10288 (define_insn "*tls_gd_pcrel<bits>"
10289 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10290 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10293 "HAVE_AS_TLS && TARGET_ELF"
10294 "la %0,%1@got@tlsgd@pcrel"
10295 [(set_attr "prefixed" "yes")])
10297 (define_insn_and_split "*tls_gd<bits>"
10298 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10299 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10300 (match_operand:P 2 "gpc_reg_operand" "b")]
10302 "HAVE_AS_TLS && TARGET_ELF"
10303 "addi %0,%2,%1@got@tlsgd"
10304 "&& TARGET_CMODEL != CMODEL_SMALL"
10305 [(set (match_dup 3)
10307 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
10309 (lo_sum:P (match_dup 3)
10310 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
10312 operands[3] = gen_reg_rtx (<MODE>mode);
10314 [(set (attr "length")
10315 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10319 (define_insn "*tls_gd_high<bits>"
10320 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10322 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
10323 (match_operand:P 2 "gpc_reg_operand" "b")]
10325 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10326 "addis %0,%2,%1@got@tlsgd@ha")
10328 (define_insn "*tls_gd_low<bits>"
10329 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10330 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10331 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
10332 (match_operand:P 3 "gpc_reg_operand" "b")]
10334 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10335 "addi %0,%1,%2@got@tlsgd@l")
10337 (define_insn "*tls_ld_pcrel<bits>"
10338 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10339 (unspec:P [(const_int 0)]
10341 "HAVE_AS_TLS && TARGET_ELF"
10342 "la %0,%&@got@tlsld@pcrel"
10343 [(set_attr "prefixed" "yes")])
10345 (define_insn_and_split "*tls_ld<bits>"
10346 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10347 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
10349 "HAVE_AS_TLS && TARGET_ELF"
10350 "addi %0,%1,%&@got@tlsld"
10351 "&& TARGET_CMODEL != CMODEL_SMALL"
10352 [(set (match_dup 2)
10354 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
10356 (lo_sum:P (match_dup 2)
10357 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
10359 operands[2] = gen_reg_rtx (<MODE>mode);
10361 [(set (attr "length")
10362 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10366 (define_insn "*tls_ld_high<bits>"
10367 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10369 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
10371 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10372 "addis %0,%1,%&@got@tlsld@ha")
10374 (define_insn "*tls_ld_low<bits>"
10375 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10376 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10377 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
10379 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10380 "addi %0,%1,%&@got@tlsld@l")
10382 (define_insn "tls_dtprel_<bits>"
10383 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10384 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10385 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10386 UNSPEC_TLSDTPREL))]
10388 "addi %0,%1,%2@dtprel"
10389 [(set (attr "prefixed")
10390 (if_then_else (match_test "rs6000_tls_size == 16")
10391 (const_string "no")
10392 (const_string "yes")))])
10394 (define_insn "tls_dtprel_ha_<bits>"
10395 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10396 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10397 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10398 UNSPEC_TLSDTPRELHA))]
10400 "addis %0,%1,%2@dtprel@ha")
10402 (define_insn "tls_dtprel_lo_<bits>"
10403 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10404 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10405 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10406 UNSPEC_TLSDTPRELLO))]
10408 "addi %0,%1,%2@dtprel@l")
10410 (define_insn_and_split "tls_got_dtprel_<bits>"
10411 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10412 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10413 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10414 UNSPEC_TLSGOTDTPREL))]
10416 "<ptrload> %0,%2@got@dtprel(%1)"
10417 "&& TARGET_CMODEL != CMODEL_SMALL"
10418 [(set (match_dup 3)
10420 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10422 (lo_sum:P (match_dup 3)
10423 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10425 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10427 [(set (attr "length")
10428 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10432 (define_insn "*tls_got_dtprel_high<bits>"
10433 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10435 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10436 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10437 UNSPEC_TLSGOTDTPREL)))]
10438 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10439 "addis %0,%1,%2@got@dtprel@ha")
10441 (define_insn "*tls_got_dtprel_low<bits>"
10442 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10443 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10444 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
10445 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10446 UNSPEC_TLSGOTDTPREL)))]
10447 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10448 "<ptrload> %0,%2@got@dtprel@l(%1)")
10450 (define_insn "tls_tprel_<bits>"
10451 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10452 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10453 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10456 "addi %0,%1,%2@tprel"
10457 [(set (attr "prefixed")
10458 (if_then_else (match_test "rs6000_tls_size == 16")
10459 (const_string "no")
10460 (const_string "yes")))])
10462 (define_insn "tls_tprel_ha_<bits>"
10463 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10464 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10465 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10466 UNSPEC_TLSTPRELHA))]
10468 "addis %0,%1,%2@tprel@ha")
10470 (define_insn "tls_tprel_lo_<bits>"
10471 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10472 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10473 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10474 UNSPEC_TLSTPRELLO))]
10476 "addi %0,%1,%2@tprel@l")
10478 (define_insn "*tls_got_tprel_pcrel_<bits>"
10479 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10480 (unspec:P [(const_int 0)
10481 (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
10482 UNSPEC_TLSGOTTPREL))]
10484 "<ptrload> %0,%1@got@tprel@pcrel"
10485 [(set_attr "prefixed" "yes")])
10487 ;; "b" output constraint here and on tls_tls input to support linker tls
10488 ;; optimization. The linker may edit the instructions emitted by a
10489 ;; tls_got_tprel/tls_tls pair to addis,addi.
10490 (define_insn_and_split "tls_got_tprel_<bits>"
10491 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10492 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10493 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10494 UNSPEC_TLSGOTTPREL))]
10496 "<ptrload> %0,%2@got@tprel(%1)"
10497 "&& TARGET_CMODEL != CMODEL_SMALL"
10498 [(set (match_dup 3)
10500 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10502 (lo_sum:P (match_dup 3)
10503 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10505 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10507 [(set (attr "length")
10508 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10512 (define_insn "*tls_got_tprel_high<bits>"
10513 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10515 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10516 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10517 UNSPEC_TLSGOTTPREL)))]
10518 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10519 "addis %0,%1,%2@got@tprel@ha")
10521 (define_insn "*tls_got_tprel_low<bits>"
10522 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10523 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10524 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
10525 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10526 UNSPEC_TLSGOTTPREL)))]
10527 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10528 "<ptrload> %0,%2@got@tprel@l(%1)")
10530 (define_insn "tls_tls_pcrel_<bits>"
10531 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10532 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10533 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10534 UNSPEC_TLSTLS_PCREL))]
10535 "TARGET_ELF && HAVE_AS_TLS"
10536 "add %0,%1,%2@tls@pcrel")
10538 (define_insn "tls_tls_<bits>"
10539 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10540 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10541 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
10543 "TARGET_ELF && HAVE_AS_TLS"
10544 "add %0,%1,%2@tls")
10546 (define_expand "tls_get_tpointer"
10547 [(set (match_operand:SI 0 "gpc_reg_operand")
10548 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10549 "TARGET_XCOFF && HAVE_AS_TLS"
10551 emit_insn (gen_tls_get_tpointer_internal ());
10552 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10556 (define_insn "tls_get_tpointer_internal"
10558 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10559 (clobber (reg:SI LR_REGNO))]
10560 "TARGET_XCOFF && HAVE_AS_TLS"
10561 "bla .__get_tpointer")
10563 (define_expand "tls_get_addr<mode>"
10564 [(set (match_operand:P 0 "gpc_reg_operand")
10565 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
10566 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
10567 "TARGET_XCOFF && HAVE_AS_TLS"
10569 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10570 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10571 emit_insn (gen_tls_get_addr_internal<mode> ());
10572 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10576 (define_insn "tls_get_addr_internal<mode>"
10578 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10579 (clobber (reg:P 0))
10580 (clobber (reg:P 4))
10581 (clobber (reg:P 5))
10582 (clobber (reg:P 11))
10583 (clobber (reg:CC CR0_REGNO))
10584 (clobber (reg:P LR_REGNO))]
10585 "TARGET_XCOFF && HAVE_AS_TLS"
10586 "bla .__tls_get_addr")
10588 ;; Next come insns related to the calling sequence.
10590 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10591 ;; We move the back-chain and decrement the stack pointer.
10593 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
10594 ;; constant alloca, using that predicate will force the generic code to put
10595 ;; the constant size into a register before calling the expander.
10597 ;; As a result the expander would not have the constant size information
10598 ;; in those cases and would have to generate less efficient code.
10600 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10601 ;; the constant size. The value is forced into a register if necessary.
10603 (define_expand "allocate_stack"
10604 [(set (match_operand 0 "gpc_reg_operand")
10605 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
10607 (minus (reg 1) (match_dup 1)))]
10610 rtx chain = gen_reg_rtx (Pmode);
10611 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10613 rtx insn, par, set, mem;
10615 /* By allowing reg_or_cint_operand as the predicate we can get
10616 better code for stack-clash-protection because we do not lose
10617 size information. But the rest of the code expects the operand
10618 to be reg_or_short_operand. If it isn't, then force it into
10620 rtx orig_op1 = operands[1];
10621 if (!reg_or_short_operand (operands[1], Pmode))
10622 operands[1] = force_reg (Pmode, operands[1]);
10624 emit_move_insn (chain, stack_bot);
10626 /* Check stack bounds if necessary. */
10627 if (crtl->limit_stack)
10630 available = expand_binop (Pmode, sub_optab,
10631 stack_pointer_rtx, stack_limit_rtx,
10632 NULL_RTX, 1, OPTAB_WIDEN);
10633 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10636 /* Allocate and probe if requested.
10637 This may look similar to the loop we use for prologue allocations,
10638 but it is critically different. For the former we know the loop
10639 will iterate, but do not know that generally here. The former
10640 uses that knowledge to rotate the loop. Combining them would be
10641 possible with some performance cost. */
10642 if (flag_stack_clash_protection)
10644 rtx rounded_size, last_addr, residual;
10645 HOST_WIDE_INT probe_interval;
10646 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10647 &residual, &probe_interval,
10650 /* We do occasionally get in here with constant sizes, we might
10651 as well do a reasonable job when we obviously can. */
10652 if (rounded_size != const0_rtx)
10654 rtx loop_lab, end_loop;
10655 bool rotated = CONST_INT_P (rounded_size);
10656 rtx update = GEN_INT (-probe_interval);
10657 if (probe_interval > 32768)
10658 update = force_reg (Pmode, update);
10660 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10661 last_addr, rotated);
10664 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10668 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
10671 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10672 last_addr, rotated);
10675 /* Now handle residuals. We just have to set operands[1] correctly
10676 and let the rest of the expander run. */
10677 operands[1] = residual;
10680 if (!(CONST_INT_P (operands[1])
10681 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
10683 operands[1] = force_reg (Pmode, operands[1]);
10684 neg_op0 = gen_reg_rtx (Pmode);
10685 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
10688 neg_op0 = GEN_INT (-INTVAL (operands[1]));
10690 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10691 : gen_movdi_update_stack))
10692 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10694 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10695 it now and set the alias set/attributes. The above gen_*_update
10696 calls will generate a PARALLEL with the MEM set being the first
10698 par = PATTERN (insn);
10699 gcc_assert (GET_CODE (par) == PARALLEL);
10700 set = XVECEXP (par, 0, 0);
10701 gcc_assert (GET_CODE (set) == SET);
10702 mem = SET_DEST (set);
10703 gcc_assert (MEM_P (mem));
10704 MEM_NOTRAP_P (mem) = 1;
10705 set_mem_alias_set (mem, get_frame_alias_set ());
10707 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10711 ;; These patterns say how to save and restore the stack pointer. We need not
10712 ;; save the stack pointer at function level since we are careful to
10713 ;; preserve the backchain. At block level, we have to restore the backchain
10714 ;; when we restore the stack pointer.
10716 ;; For nonlocal gotos, we must save both the stack pointer and its
10717 ;; backchain and restore both. Note that in the nonlocal case, the
10718 ;; save area is a memory location.
10720 (define_expand "save_stack_function"
10721 [(match_operand 0 "any_operand")
10722 (match_operand 1 "any_operand")]
10726 (define_expand "restore_stack_function"
10727 [(match_operand 0 "any_operand")
10728 (match_operand 1 "any_operand")]
10732 ;; Adjust stack pointer (op0) to a new value (op1).
10733 ;; First copy old stack backchain to new location, and ensure that the
10734 ;; scheduler won't reorder the sp assignment before the backchain write.
10735 (define_expand "restore_stack_block"
10736 [(set (match_dup 2) (match_dup 3))
10737 (set (match_dup 4) (match_dup 2))
10739 (set (match_operand 0 "register_operand")
10740 (match_operand 1 "register_operand"))]
10745 operands[1] = force_reg (Pmode, operands[1]);
10746 operands[2] = gen_reg_rtx (Pmode);
10747 operands[3] = gen_frame_mem (Pmode, operands[0]);
10748 operands[4] = gen_frame_mem (Pmode, operands[1]);
10749 p = rtvec_alloc (1);
10750 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10752 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10755 (define_expand "save_stack_nonlocal"
10756 [(set (match_dup 3) (match_dup 4))
10757 (set (match_operand 0 "memory_operand") (match_dup 3))
10758 (set (match_dup 2) (match_operand 1 "register_operand"))]
10761 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10763 /* Copy the backchain to the first word, sp to the second. */
10764 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10765 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10766 operands[3] = gen_reg_rtx (Pmode);
10767 operands[4] = gen_frame_mem (Pmode, operands[1]);
10770 (define_expand "restore_stack_nonlocal"
10771 [(set (match_dup 2) (match_operand 1 "memory_operand"))
10772 (set (match_dup 3) (match_dup 4))
10773 (set (match_dup 5) (match_dup 2))
10775 (set (match_operand 0 "register_operand") (match_dup 3))]
10778 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10781 /* Restore the backchain from the first word, sp from the second. */
10782 operands[2] = gen_reg_rtx (Pmode);
10783 operands[3] = gen_reg_rtx (Pmode);
10784 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10785 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10786 operands[5] = gen_frame_mem (Pmode, operands[3]);
10787 p = rtvec_alloc (1);
10788 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10790 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10793 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10794 ;; to the symbol or label.
10795 (define_insn "*pcrel_local_addr"
10796 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10797 (match_operand:DI 1 "pcrel_local_address"))]
10800 [(set_attr "prefixed" "yes")])
10802 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10803 ;; program are both defined in the main program, the linker will optimize this
10804 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10805 ;; the dynamic linker and loaded up. Print_operand_address will append a
10806 ;; @got@pcrel to the symbol.
10807 (define_insn "*pcrel_extern_addr"
10808 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10809 (match_operand:DI 1 "pcrel_external_address"))]
10812 [(set_attr "prefixed" "yes")
10813 (set_attr "type" "load")
10814 (set_attr "loads_external_address" "yes")])
10816 ;; TOC register handling.
10818 ;; Code to initialize the TOC register...
10820 (define_insn "load_toc_aix_si"
10821 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10822 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10823 (use (reg:SI 2))])]
10824 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10827 extern int need_toc_init;
10829 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10830 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10831 operands[2] = gen_rtx_REG (Pmode, 2);
10832 return "lwz %0,%1(%2)";
10834 [(set_attr "type" "load")
10835 (set_attr "update" "no")
10836 (set_attr "indexed" "no")])
10838 (define_insn "load_toc_aix_di"
10839 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10840 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10841 (use (reg:DI 2))])]
10842 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10845 extern int need_toc_init;
10847 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10848 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10850 strcat (buf, "@toc");
10851 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10852 operands[2] = gen_rtx_REG (Pmode, 2);
10853 return "ld %0,%1(%2)";
10855 [(set_attr "type" "load")
10856 (set_attr "update" "no")
10857 (set_attr "indexed" "no")])
10859 (define_insn "load_toc_v4_pic_si"
10860 [(set (reg:SI LR_REGNO)
10861 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10862 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10863 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10864 [(set_attr "type" "branch")])
10866 (define_expand "load_toc_v4_PIC_1"
10867 [(parallel [(set (reg:SI LR_REGNO)
10868 (match_operand:SI 0 "immediate_operand" "s"))
10869 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10870 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10871 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10874 (define_insn "load_toc_v4_PIC_1_normal"
10875 [(set (reg:SI LR_REGNO)
10876 (match_operand:SI 0 "immediate_operand" "s"))
10877 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10878 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10879 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10880 "bcl 20,31,%0\n%0:"
10881 [(set_attr "type" "branch")
10882 (set_attr "cannot_copy" "yes")])
10884 (define_insn "load_toc_v4_PIC_1_476"
10885 [(set (reg:SI LR_REGNO)
10886 (match_operand:SI 0 "immediate_operand" "s"))
10887 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10888 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10889 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10892 static char templ[32];
10894 get_ppc476_thunk_name (name);
10895 sprintf (templ, "bl %s\n%%0:", name);
10898 [(set_attr "type" "branch")
10899 (set_attr "cannot_copy" "yes")])
10901 (define_expand "load_toc_v4_PIC_1b"
10902 [(parallel [(set (reg:SI LR_REGNO)
10903 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10904 (label_ref (match_operand 1 ""))]
10907 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10910 (define_insn "load_toc_v4_PIC_1b_normal"
10911 [(set (reg:SI LR_REGNO)
10912 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10913 (label_ref (match_operand 1 "" ""))]
10916 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10917 "bcl 20,31,$+8\;.long %0-$"
10918 [(set_attr "type" "branch")
10919 (set_attr "length" "8")])
10921 (define_insn "load_toc_v4_PIC_1b_476"
10922 [(set (reg:SI LR_REGNO)
10923 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10924 (label_ref (match_operand 1 "" ""))]
10927 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10930 static char templ[32];
10932 get_ppc476_thunk_name (name);
10933 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10936 [(set_attr "type" "branch")
10937 (set_attr "length" "16")])
10939 (define_insn "load_toc_v4_PIC_2"
10940 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10942 (match_operand:SI 1 "gpc_reg_operand" "b")
10944 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10945 (match_operand:SI 3 "immediate_operand" "s"))))))]
10946 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10948 [(set_attr "type" "load")])
10950 (define_insn "load_toc_v4_PIC_3b"
10951 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10953 (match_operand:SI 1 "gpc_reg_operand" "b")
10956 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10957 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10958 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10959 "addis %0,%1,%2-%3@ha")
10961 (define_insn "load_toc_v4_PIC_3c"
10962 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10964 (match_operand:SI 1 "gpc_reg_operand" "b")
10966 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10967 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10968 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10969 "addi %0,%1,%2-%3@l")
10971 ;; If the TOC is shared over a translation unit, as happens with all
10972 ;; the kinds of PIC that we support, we need to restore the TOC
10973 ;; pointer only when jumping over units of translation.
10974 ;; On Darwin, we need to reload the picbase.
10976 (define_expand "builtin_setjmp_receiver"
10977 [(use (label_ref (match_operand 0 "")))]
10978 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10979 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10980 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10983 if (DEFAULT_ABI == ABI_DARWIN)
10985 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10986 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10990 crtl->uses_pic_offset_table = 1;
10991 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10992 CODE_LABEL_NUMBER (operands[0]));
10993 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10995 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10996 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10997 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10998 picrtx, tmplabrtx));
11002 rs6000_emit_load_toc_table (FALSE);
11006 ;; Largetoc support
11007 (define_insn "*largetoc_high"
11008 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
11010 (unspec [(match_operand:DI 1 "" "")
11011 (match_operand:DI 2 "gpc_reg_operand" "b")]
11013 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11014 "addis %0,%2,%1@toc@ha")
11016 (define_insn "*largetoc_high_aix<mode>"
11017 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
11019 (unspec [(match_operand:P 1 "" "")
11020 (match_operand:P 2 "gpc_reg_operand" "b")]
11022 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11023 "addis %0,%1@u(%2)")
11025 (define_insn "*largetoc_high_plus"
11026 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
11029 (unspec [(match_operand:DI 1 "" "")
11030 (match_operand:DI 2 "gpc_reg_operand" "b")]
11032 (match_operand:DI 3 "add_cint_operand" "n"))))]
11033 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11034 "addis %0,%2,%1+%3@toc@ha")
11036 (define_insn "*largetoc_high_plus_aix<mode>"
11037 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
11040 (unspec [(match_operand:P 1 "" "")
11041 (match_operand:P 2 "gpc_reg_operand" "b")]
11043 (match_operand:P 3 "add_cint_operand" "n"))))]
11044 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11045 "addis %0,%1+%3@u(%2)")
11047 (define_insn "*largetoc_low"
11048 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11049 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
11050 (match_operand:DI 2 "" "")))]
11051 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11054 (define_insn "*largetoc_low_aix<mode>"
11055 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11056 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
11057 (match_operand:P 2 "" "")))]
11058 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11061 (define_insn_and_split "*tocref<mode>"
11062 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
11063 (match_operand:P 1 "small_toc_ref" "R"))]
11065 && legitimate_constant_pool_address_p (operands[1], QImode, false)"
11067 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
11068 [(set (match_dup 0) (high:P (match_dup 1)))
11069 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
11071 ;; Elf specific ways of loading addresses for non-PIC code.
11072 ;; The output of this could be r0, but we make a very strong
11073 ;; preference for a base register because it will usually
11074 ;; be needed there.
11075 (define_insn "elf_high"
11076 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
11077 (high:SI (match_operand 1 "" "")))]
11078 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
11081 (define_insn "elf_low"
11082 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11083 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
11084 (match_operand 2 "" "")))]
11085 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
11088 (define_insn "*pltseq_tocsave_<mode>"
11089 [(set (match_operand:P 0 "memory_operand" "=m")
11090 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
11091 (match_operand:P 2 "symbol_ref_operand" "s")
11092 (match_operand:P 3 "" "")]
11095 && DEFAULT_ABI == ABI_ELFv2"
11097 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
11100 (define_insn "*pltseq_plt16_ha_<mode>"
11101 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11102 (unspec:P [(match_operand:P 1 "" "")
11103 (match_operand:P 2 "symbol_ref_operand" "s")
11104 (match_operand:P 3 "" "")]
11108 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
11111 (define_insn "*pltseq_plt16_lo_<mode>"
11112 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11113 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
11114 (match_operand:P 2 "symbol_ref_operand" "s")
11115 (match_operand:P 3 "" "")]
11116 UNSPECV_PLT16_LO))]
11119 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
11121 [(set_attr "type" "load")])
11123 (define_insn "*pltseq_mtctr_<mode>"
11124 [(set (match_operand:P 0 "register_operand" "=c")
11125 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
11126 (match_operand:P 2 "symbol_ref_operand" "s")
11127 (match_operand:P 3 "" "")]
11131 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
11134 (define_insn "*pltseq_plt_pcrel<mode>"
11135 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11136 (unspec_volatile:P [(match_operand:P 1 "" "")
11137 (match_operand:P 2 "symbol_ref_operand" "s")
11138 (match_operand:P 3 "" "")]
11139 UNSPECV_PLT_PCREL))]
11140 "HAVE_AS_PLTSEQ && TARGET_ELF
11141 && rs6000_pcrel_p ()"
11143 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
11145 [(set_attr "type" "load")
11146 (set_attr "length" "12")])
11148 ;; Call and call_value insns
11149 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
11150 (define_expand "call"
11151 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
11152 (match_operand 1 ""))
11153 (use (match_operand 2 ""))
11154 (clobber (reg:SI LR_REGNO))])]
11158 if (MACHOPIC_INDIRECT)
11159 operands[0] = machopic_indirect_call_target (operands[0]);
11162 gcc_assert (MEM_P (operands[0]));
11164 operands[0] = XEXP (operands[0], 0);
11166 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11167 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11168 else if (DEFAULT_ABI == ABI_V4)
11169 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
11170 else if (DEFAULT_ABI == ABI_DARWIN)
11171 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
11173 gcc_unreachable ();
11178 (define_expand "call_value"
11179 [(parallel [(set (match_operand 0 "")
11180 (call (mem:SI (match_operand 1 "address_operand"))
11181 (match_operand 2 "")))
11182 (use (match_operand 3 ""))
11183 (clobber (reg:SI LR_REGNO))])]
11187 if (MACHOPIC_INDIRECT)
11188 operands[1] = machopic_indirect_call_target (operands[1]);
11191 gcc_assert (MEM_P (operands[1]));
11193 operands[1] = XEXP (operands[1], 0);
11195 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11196 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
11197 else if (DEFAULT_ABI == ABI_V4)
11198 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
11199 else if (DEFAULT_ABI == ABI_DARWIN)
11200 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
11202 gcc_unreachable ();
11207 ;; Call to function in current module. No TOC pointer reload needed.
11208 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
11209 ;; either the function was not prototyped, or it was prototyped as a
11210 ;; variable argument function. It is > 0 if FP registers were passed
11211 ;; and < 0 if they were not.
11213 (define_insn "*call_local<mode>"
11214 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
11216 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11217 (clobber (reg:P LR_REGNO))]
11218 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11220 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11221 output_asm_insn ("crxor 6,6,6", operands);
11223 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11224 output_asm_insn ("creqv 6,6,6", operands);
11226 if (rs6000_pcrel_p ())
11227 return "bl %z0@notoc";
11228 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
11230 [(set_attr "type" "branch")
11231 (set_attr "length" "4,8")])
11233 (define_insn "*call_value_local<mode>"
11234 [(set (match_operand 0 "" "")
11235 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
11236 (match_operand 2)))
11237 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11238 (clobber (reg:P LR_REGNO))]
11239 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11241 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11242 output_asm_insn ("crxor 6,6,6", operands);
11244 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11245 output_asm_insn ("creqv 6,6,6", operands);
11247 if (rs6000_pcrel_p ())
11248 return "bl %z1@notoc";
11249 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
11251 [(set_attr "type" "branch")
11252 (set_attr "length" "4,8")])
11255 ;; A function pointer under System V is just a normal pointer
11256 ;; operands[0] is the function pointer
11257 ;; operands[1] is the tls call arg
11258 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
11259 ;; which indicates how to set cr1
11261 (define_insn "*call_indirect_nonlocal_sysv<mode>"
11262 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11264 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11265 (clobber (reg:P LR_REGNO))]
11266 "DEFAULT_ABI == ABI_V4
11267 || DEFAULT_ABI == ABI_DARWIN"
11269 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11270 output_asm_insn ("crxor 6,6,6", operands);
11272 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11273 output_asm_insn ("creqv 6,6,6", operands);
11275 return rs6000_indirect_call_template (operands, 0);
11277 [(set_attr "type" "jmpreg")
11278 (set (attr "length")
11279 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11280 (match_test "which_alternative != 1"))
11281 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11282 (const_string "12")
11283 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11284 (match_test "which_alternative != 1"))
11285 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11286 (const_string "8")]
11287 (const_string "4")))])
11289 (define_insn "*call_nonlocal_sysv<mode>"
11290 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11292 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11293 (clobber (reg:P LR_REGNO))]
11294 "(DEFAULT_ABI == ABI_DARWIN
11295 || (DEFAULT_ABI == ABI_V4
11296 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
11298 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11299 output_asm_insn ("crxor 6,6,6", operands);
11301 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11302 output_asm_insn ("creqv 6,6,6", operands);
11304 return rs6000_call_template (operands, 0);
11306 [(set_attr "type" "branch,branch")
11307 (set_attr "length" "4,8")])
11309 (define_insn "*call_nonlocal_sysv_secure<mode>"
11310 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11312 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11313 (use (match_operand:SI 3 "register_operand" "r,r"))
11314 (clobber (reg:P LR_REGNO))]
11315 "(DEFAULT_ABI == ABI_V4
11316 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11317 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11319 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11320 output_asm_insn ("crxor 6,6,6", operands);
11322 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11323 output_asm_insn ("creqv 6,6,6", operands);
11325 return rs6000_call_template (operands, 0);
11327 [(set_attr "type" "branch,branch")
11328 (set_attr "length" "4,8")])
11330 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11331 [(set (match_operand 0 "" "")
11332 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11333 (match_operand:P 2 "unspec_tls" "")))
11334 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11335 (clobber (reg:P LR_REGNO))]
11336 "DEFAULT_ABI == ABI_V4
11337 || DEFAULT_ABI == ABI_DARWIN"
11339 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11340 output_asm_insn ("crxor 6,6,6", operands);
11342 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11343 output_asm_insn ("creqv 6,6,6", operands);
11345 return rs6000_indirect_call_template (operands, 1);
11347 [(set_attr "type" "jmpreg")
11348 (set (attr "length")
11350 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11353 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11354 (match_test "which_alternative != 1"))
11358 (define_insn "*call_value_nonlocal_sysv<mode>"
11359 [(set (match_operand 0 "" "")
11360 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11361 (match_operand:P 2 "unspec_tls" "")))
11362 (use (match_operand:SI 3 "immediate_operand" "n"))
11363 (clobber (reg:P LR_REGNO))]
11364 "(DEFAULT_ABI == ABI_DARWIN
11365 || (DEFAULT_ABI == ABI_V4
11366 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11368 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11369 output_asm_insn ("crxor 6,6,6", operands);
11371 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11372 output_asm_insn ("creqv 6,6,6", operands);
11374 return rs6000_call_template (operands, 1);
11376 [(set_attr "type" "branch")
11377 (set (attr "length")
11378 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11382 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11383 [(set (match_operand 0 "" "")
11384 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11385 (match_operand:P 2 "unspec_tls" "")))
11386 (use (match_operand:SI 3 "immediate_operand" "n"))
11387 (use (match_operand:SI 4 "register_operand" "r"))
11388 (clobber (reg:P LR_REGNO))]
11389 "(DEFAULT_ABI == ABI_V4
11390 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11391 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11393 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11394 output_asm_insn ("crxor 6,6,6", operands);
11396 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11397 output_asm_insn ("creqv 6,6,6", operands);
11399 return rs6000_call_template (operands, 1);
11401 [(set_attr "type" "branch")
11402 (set (attr "length")
11403 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
11407 ;; Call to AIX abi function which may be in another module.
11408 ;; Restore the TOC pointer (r2) after the call.
11410 (define_insn "*call_nonlocal_aix<mode>"
11411 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11413 (use (match_operand:SI 2 "immediate_operand" "n"))
11414 (clobber (reg:P LR_REGNO))]
11415 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11416 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11418 return rs6000_call_template (operands, 0);
11420 [(set_attr "type" "branch")
11421 (set (attr "length")
11422 (if_then_else (match_test "rs6000_pcrel_p ()")
11426 (define_insn "*call_value_nonlocal_aix<mode>"
11427 [(set (match_operand 0 "" "")
11428 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11429 (match_operand:P 2 "unspec_tls" "")))
11430 (use (match_operand:SI 3 "immediate_operand" "n"))
11431 (clobber (reg:P LR_REGNO))]
11432 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11433 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11435 return rs6000_call_template (operands, 1);
11437 [(set_attr "type" "branch")
11438 (set (attr "length")
11439 (if_then_else (match_test "rs6000_pcrel_p ()")
11443 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11444 ;; Operand0 is the addresss of the function to call
11445 ;; Operand3 is the location in the function descriptor to load r2 from
11446 ;; Operand4 is the offset of the stack location holding the current TOC pointer
11448 (define_insn "*call_indirect_aix<mode>"
11449 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11451 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11452 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
11453 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
11454 (clobber (reg:P LR_REGNO))]
11455 "DEFAULT_ABI == ABI_AIX"
11457 return rs6000_indirect_call_template (operands, 0);
11459 [(set_attr "type" "jmpreg")
11460 (set (attr "length")
11461 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11462 (match_test "which_alternative != 1"))
11463 (const_string "16")
11464 (const_string "12")))])
11466 (define_insn "*call_value_indirect_aix<mode>"
11467 [(set (match_operand 0 "" "")
11468 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11469 (match_operand:P 2 "unspec_tls" "")))
11470 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11471 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
11472 (set (reg:P TOC_REGNUM)
11473 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
11475 (clobber (reg:P LR_REGNO))]
11476 "DEFAULT_ABI == ABI_AIX"
11478 return rs6000_indirect_call_template (operands, 1);
11480 [(set_attr "type" "jmpreg")
11481 (set (attr "length")
11482 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11483 (match_test "which_alternative != 1"))
11484 (const_string "16")
11485 (const_string "12")))])
11487 ;; Call to indirect functions with the ELFv2 ABI.
11488 ;; Operand0 is the addresss of the function to call
11489 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11491 (define_insn "*call_indirect_elfv2<mode>"
11492 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11494 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11495 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
11496 (clobber (reg:P LR_REGNO))]
11497 "DEFAULT_ABI == ABI_ELFv2"
11499 return rs6000_indirect_call_template (operands, 0);
11501 [(set_attr "type" "jmpreg")
11502 (set (attr "length")
11503 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11504 (match_test "which_alternative != 1"))
11505 (const_string "12")
11506 (const_string "8")))])
11508 (define_insn "*call_indirect_pcrel<mode>"
11509 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11511 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11512 (clobber (reg:P LR_REGNO))]
11513 "rs6000_pcrel_p ()"
11515 return rs6000_indirect_call_template (operands, 0);
11517 [(set_attr "type" "jmpreg")
11518 (set (attr "length")
11519 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11520 (match_test "which_alternative != 1"))
11522 (const_string "4")))])
11524 (define_insn "*call_value_indirect_elfv2<mode>"
11525 [(set (match_operand 0 "" "")
11526 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11527 (match_operand:P 2 "unspec_tls" "")))
11528 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11529 (set (reg:P TOC_REGNUM)
11530 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
11532 (clobber (reg:P LR_REGNO))]
11533 "DEFAULT_ABI == ABI_ELFv2"
11535 return rs6000_indirect_call_template (operands, 1);
11537 [(set_attr "type" "jmpreg")
11538 (set (attr "length")
11539 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11540 (match_test "which_alternative != 1"))
11541 (const_string "12")
11542 (const_string "8")))])
11544 (define_insn "*call_value_indirect_pcrel<mode>"
11545 [(set (match_operand 0 "" "")
11546 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11547 (match_operand:P 2 "unspec_tls" "")))
11548 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11549 (clobber (reg:P LR_REGNO))]
11550 "rs6000_pcrel_p ()"
11552 return rs6000_indirect_call_template (operands, 1);
11554 [(set_attr "type" "jmpreg")
11555 (set (attr "length")
11556 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11557 (match_test "which_alternative != 1"))
11559 (const_string "4")))])
11561 ;; Call subroutine returning any type.
11562 (define_expand "untyped_call"
11563 [(parallel [(call (match_operand 0 "")
11565 (match_operand 1 "")
11566 (match_operand 2 "")])]
11571 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11573 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
11574 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
11575 emit_insn (gen_blockage ());
11577 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11579 rtx set = XVECEXP (operands[2], 0, i);
11580 emit_move_insn (SET_DEST (set), SET_SRC (set));
11583 /* The optimizer does not know that the call sets the function value
11584 registers we stored in the result block. We avoid problems by
11585 claiming that all hard registers are used and clobbered at this
11587 emit_insn (gen_blockage ());
11592 ;; sibling call patterns
11593 (define_expand "sibcall"
11594 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
11595 (match_operand 1 ""))
11596 (use (match_operand 2 ""))
11601 if (MACHOPIC_INDIRECT)
11602 operands[0] = machopic_indirect_call_target (operands[0]);
11605 gcc_assert (MEM_P (operands[0]));
11606 gcc_assert (CONST_INT_P (operands[1]));
11608 operands[0] = XEXP (operands[0], 0);
11610 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11611 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11612 else if (DEFAULT_ABI == ABI_V4)
11613 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
11614 else if (DEFAULT_ABI == ABI_DARWIN)
11615 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
11617 gcc_unreachable ();
11622 (define_expand "sibcall_value"
11623 [(parallel [(set (match_operand 0 "register_operand")
11624 (call (mem:SI (match_operand 1 "address_operand"))
11625 (match_operand 2 "")))
11626 (use (match_operand 3 ""))
11631 if (MACHOPIC_INDIRECT)
11632 operands[1] = machopic_indirect_call_target (operands[1]);
11635 gcc_assert (MEM_P (operands[1]));
11636 gcc_assert (CONST_INT_P (operands[2]));
11638 operands[1] = XEXP (operands[1], 0);
11640 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11641 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11642 else if (DEFAULT_ABI == ABI_V4)
11643 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
11644 else if (DEFAULT_ABI == ABI_DARWIN)
11645 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
11647 gcc_unreachable ();
11652 (define_insn "*sibcall_local<mode>"
11653 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
11655 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11657 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11659 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11660 output_asm_insn ("crxor 6,6,6", operands);
11662 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11663 output_asm_insn ("creqv 6,6,6", operands);
11665 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11667 [(set_attr "type" "branch")
11668 (set_attr "length" "4,8")])
11670 (define_insn "*sibcall_value_local<mode>"
11671 [(set (match_operand 0 "" "")
11672 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
11673 (match_operand 2)))
11674 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11676 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11678 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11679 output_asm_insn ("crxor 6,6,6", operands);
11681 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11682 output_asm_insn ("creqv 6,6,6", operands);
11684 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11686 [(set_attr "type" "branch")
11687 (set_attr "length" "4,8")])
11689 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11690 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11692 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11694 "DEFAULT_ABI == ABI_V4
11695 || DEFAULT_ABI == ABI_DARWIN"
11697 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11698 output_asm_insn ("crxor 6,6,6", operands);
11700 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11701 output_asm_insn ("creqv 6,6,6", operands);
11703 return rs6000_indirect_sibcall_template (operands, 0);
11705 [(set_attr "type" "jmpreg")
11706 (set (attr "length")
11707 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11708 (match_test "which_alternative != 1"))
11709 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11710 (const_string "12")
11711 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11712 (match_test "which_alternative != 1"))
11713 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11714 (const_string "8")]
11715 (const_string "4")))])
11717 (define_insn "*sibcall_nonlocal_sysv<mode>"
11718 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11720 (use (match_operand 2 "immediate_operand" "O,n"))
11722 "(DEFAULT_ABI == ABI_DARWIN
11723 || DEFAULT_ABI == ABI_V4)
11724 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11726 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11727 output_asm_insn ("crxor 6,6,6", operands);
11729 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11730 output_asm_insn ("creqv 6,6,6", operands);
11732 return rs6000_sibcall_template (operands, 0);
11734 [(set_attr "type" "branch")
11735 (set_attr "length" "4,8")])
11737 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11738 [(set (match_operand 0 "" "")
11739 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11740 (match_operand 2)))
11741 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11743 "DEFAULT_ABI == ABI_V4
11744 || DEFAULT_ABI == ABI_DARWIN"
11746 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11747 output_asm_insn ("crxor 6,6,6", operands);
11749 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11750 output_asm_insn ("creqv 6,6,6", operands);
11752 return rs6000_indirect_sibcall_template (operands, 1);
11754 [(set_attr "type" "jmpreg")
11755 (set (attr "length")
11756 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11757 (match_test "which_alternative != 1"))
11758 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11759 (const_string "12")
11760 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11761 (match_test "which_alternative != 1"))
11762 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11763 (const_string "8")]
11764 (const_string "4")))])
11766 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11767 [(set (match_operand 0 "" "")
11768 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11769 (match_operand 2)))
11770 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11772 "(DEFAULT_ABI == ABI_DARWIN
11773 || DEFAULT_ABI == ABI_V4)
11774 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11776 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11777 output_asm_insn ("crxor 6,6,6", operands);
11779 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11780 output_asm_insn ("creqv 6,6,6", operands);
11782 return rs6000_sibcall_template (operands, 1);
11784 [(set_attr "type" "branch")
11785 (set_attr "length" "4,8")])
11787 ;; AIX ABI sibling call patterns.
11789 (define_insn "*sibcall_aix<mode>"
11790 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11793 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11795 if (which_alternative == 0)
11796 return rs6000_sibcall_template (operands, 0);
11800 [(set_attr "type" "branch")])
11802 (define_insn "*sibcall_value_aix<mode>"
11803 [(set (match_operand 0 "" "")
11804 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11805 (match_operand 2)))
11807 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11809 if (which_alternative == 0)
11810 return rs6000_sibcall_template (operands, 1);
11814 [(set_attr "type" "branch")])
11816 (define_expand "sibcall_epilogue"
11817 [(use (const_int 0))]
11820 if (!TARGET_SCHED_PROLOG)
11821 emit_insn (gen_blockage ());
11822 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11826 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11827 ;; all of memory. This blocks insns from being moved across this point.
11829 (define_insn "blockage"
11830 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11833 [(set_attr "length" "0")])
11835 (define_expand "probe_stack_address"
11836 [(use (match_operand 0 "address_operand"))]
11839 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11840 MEM_VOLATILE_P (operands[0]) = 1;
11843 emit_insn (gen_probe_stack_di (operands[0]));
11845 emit_insn (gen_probe_stack_si (operands[0]));
11849 (define_insn "probe_stack_<mode>"
11850 [(set (match_operand:P 0 "memory_operand" "=m")
11851 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11854 operands[1] = gen_rtx_REG (Pmode, 0);
11855 return "st<wd>%U0%X0 %1,%0";
11857 [(set_attr "type" "store")
11858 (set (attr "update")
11859 (if_then_else (match_operand 0 "update_address_mem")
11860 (const_string "yes")
11861 (const_string "no")))
11862 (set (attr "indexed")
11863 (if_then_else (match_operand 0 "indexed_address_mem")
11864 (const_string "yes")
11865 (const_string "no")))])
11867 (define_insn "probe_stack_range<P:mode>"
11868 [(set (match_operand:P 0 "register_operand" "=&r")
11869 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11870 (match_operand:P 2 "register_operand" "r")
11871 (match_operand:P 3 "register_operand" "r")]
11872 UNSPECV_PROBE_STACK_RANGE))]
11874 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11875 [(set_attr "type" "three")])
11877 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11878 ;; signed & unsigned, and one type of branch.
11880 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11881 ;; insns, and branches.
11883 (define_expand "cbranch<mode>4"
11884 [(use (match_operator 0 "comparison_operator"
11885 [(match_operand:GPR 1 "gpc_reg_operand")
11886 (match_operand:GPR 2 "reg_or_short_operand")]))
11887 (use (match_operand 3))]
11890 /* Take care of the possibility that operands[2] might be negative but
11891 this might be a logical operation. That insn doesn't exist. */
11892 if (CONST_INT_P (operands[2])
11893 && INTVAL (operands[2]) < 0)
11895 operands[2] = force_reg (<MODE>mode, operands[2]);
11896 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11897 GET_MODE (operands[0]),
11898 operands[1], operands[2]);
11901 rs6000_emit_cbranch (<MODE>mode, operands);
11905 (define_expand "cbranch<mode>4"
11906 [(use (match_operator 0 "comparison_operator"
11907 [(match_operand:FP 1 "gpc_reg_operand")
11908 (match_operand:FP 2 "gpc_reg_operand")]))
11909 (use (match_operand 3))]
11912 rs6000_emit_cbranch (<MODE>mode, operands);
11916 (define_expand "cbranchcc4"
11918 (if_then_else (match_operator 0 "branch_comparison_operator"
11919 [(match_operand 1 "cc_reg_operand")
11920 (match_operand 2 "zero_constant")])
11921 (label_ref (match_operand 3))
11926 (define_expand "cstore<mode>4_signed"
11927 [(use (match_operator 1 "signed_comparison_operator"
11928 [(match_operand:P 2 "gpc_reg_operand")
11929 (match_operand:P 3 "gpc_reg_operand")]))
11930 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11933 enum rtx_code cond_code = GET_CODE (operands[1]);
11935 rtx op0 = operands[0];
11936 rtx op1 = operands[2];
11937 rtx op2 = operands[3];
11939 if (cond_code == GE || cond_code == LT)
11941 cond_code = swap_condition (cond_code);
11942 std::swap (op1, op2);
11945 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11946 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11947 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11949 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11950 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11951 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11953 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11955 if (cond_code == LE)
11956 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11959 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11960 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11961 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11967 (define_expand "cstore<mode>4_unsigned"
11968 [(use (match_operator 1 "unsigned_comparison_operator"
11969 [(match_operand:P 2 "gpc_reg_operand")
11970 (match_operand:P 3 "reg_or_short_operand")]))
11971 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11974 enum rtx_code cond_code = GET_CODE (operands[1]);
11976 rtx op0 = operands[0];
11977 rtx op1 = operands[2];
11978 rtx op2 = operands[3];
11980 if (cond_code == GEU || cond_code == LTU)
11982 cond_code = swap_condition (cond_code);
11983 std::swap (op1, op2);
11986 if (!gpc_reg_operand (op1, <MODE>mode))
11987 op1 = force_reg (<MODE>mode, op1);
11988 if (!reg_or_short_operand (op2, <MODE>mode))
11989 op2 = force_reg (<MODE>mode, op2);
11991 rtx tmp = gen_reg_rtx (<MODE>mode);
11992 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11994 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11995 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11997 if (cond_code == LEU)
11998 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
12000 emit_insn (gen_neg<mode>2 (op0, tmp2));
12005 (define_expand "cstore_si_as_di"
12006 [(use (match_operator 1 "unsigned_comparison_operator"
12007 [(match_operand:SI 2 "gpc_reg_operand")
12008 (match_operand:SI 3 "reg_or_short_operand")]))
12009 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
12012 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
12013 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
12015 operands[2] = force_reg (SImode, operands[2]);
12016 operands[3] = force_reg (SImode, operands[3]);
12017 rtx op1 = gen_reg_rtx (DImode);
12018 rtx op2 = gen_reg_rtx (DImode);
12019 convert_move (op1, operands[2], uns_flag);
12020 convert_move (op2, operands[3], uns_flag);
12022 if (cond_code == GT || cond_code == LE)
12024 cond_code = swap_condition (cond_code);
12025 std::swap (op1, op2);
12028 rtx tmp = gen_reg_rtx (DImode);
12029 rtx tmp2 = gen_reg_rtx (DImode);
12030 emit_insn (gen_subdi3 (tmp, op1, op2));
12031 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
12037 gcc_unreachable ();
12042 tmp3 = gen_reg_rtx (DImode);
12043 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
12047 convert_move (operands[0], tmp3, 1);
12052 (define_expand "cstore<mode>4_signed_imm"
12053 [(use (match_operator 1 "signed_comparison_operator"
12054 [(match_operand:GPR 2 "gpc_reg_operand")
12055 (match_operand:GPR 3 "immediate_operand")]))
12056 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12059 bool invert = false;
12061 enum rtx_code cond_code = GET_CODE (operands[1]);
12063 rtx op0 = operands[0];
12064 rtx op1 = operands[2];
12065 HOST_WIDE_INT val = INTVAL (operands[3]);
12067 if (cond_code == GE || cond_code == GT)
12069 cond_code = reverse_condition (cond_code);
12073 if (cond_code == LE)
12076 rtx tmp = gen_reg_rtx (<MODE>mode);
12077 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
12078 rtx x = gen_reg_rtx (<MODE>mode);
12080 emit_insn (gen_and<mode>3 (x, op1, tmp));
12082 emit_insn (gen_ior<mode>3 (x, op1, tmp));
12086 rtx tmp = gen_reg_rtx (<MODE>mode);
12087 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
12091 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
12092 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
12097 (define_expand "cstore<mode>4_unsigned_imm"
12098 [(use (match_operator 1 "unsigned_comparison_operator"
12099 [(match_operand:GPR 2 "gpc_reg_operand")
12100 (match_operand:GPR 3 "immediate_operand")]))
12101 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12104 bool invert = false;
12106 enum rtx_code cond_code = GET_CODE (operands[1]);
12108 rtx op0 = operands[0];
12109 rtx op1 = operands[2];
12110 HOST_WIDE_INT val = INTVAL (operands[3]);
12112 if (cond_code == GEU || cond_code == GTU)
12114 cond_code = reverse_condition (cond_code);
12118 if (cond_code == LEU)
12121 rtx tmp = gen_reg_rtx (<MODE>mode);
12122 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12123 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
12124 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
12125 rtx x = gen_reg_rtx (<MODE>mode);
12127 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
12129 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
12133 rtx tmp = gen_reg_rtx (<MODE>mode);
12134 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
12138 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
12139 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
12144 (define_expand "cstore<mode>4"
12145 [(use (match_operator 1 "comparison_operator"
12146 [(match_operand:GPR 2 "gpc_reg_operand")
12147 (match_operand:GPR 3 "reg_or_short_operand")]))
12148 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
12151 /* Everything is best done with setbc[r] if available. */
12152 if (TARGET_POWER10 && TARGET_ISEL)
12154 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
12158 /* Expanding EQ and NE directly to some machine instructions does not help
12159 but does hurt combine. So don't. */
12160 if (GET_CODE (operands[1]) == EQ)
12161 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
12162 else if (<MODE>mode == Pmode
12163 && GET_CODE (operands[1]) == NE)
12164 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
12165 else if (GET_CODE (operands[1]) == NE)
12167 rtx tmp = gen_reg_rtx (<MODE>mode);
12168 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
12169 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12172 /* If ISEL is fast, expand to it. */
12173 else if (TARGET_ISEL)
12174 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
12176 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
12177 etc. combinations magically work out just right. */
12178 else if (<MODE>mode == Pmode
12179 && unsigned_comparison_operator (operands[1], VOIDmode))
12180 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
12181 operands[2], operands[3]));
12183 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
12184 else if (<MODE>mode == SImode && Pmode == DImode)
12185 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
12186 operands[2], operands[3]));
12188 /* For signed comparisons against a constant, we can do some simple
12190 else if (signed_comparison_operator (operands[1], VOIDmode)
12191 && CONST_INT_P (operands[3]))
12192 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
12193 operands[2], operands[3]));
12195 /* And similarly for unsigned comparisons. */
12196 else if (unsigned_comparison_operator (operands[1], VOIDmode)
12197 && CONST_INT_P (operands[3]))
12198 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
12199 operands[2], operands[3]));
12201 /* We also do not want to use mfcr for signed comparisons. */
12202 else if (<MODE>mode == Pmode
12203 && signed_comparison_operator (operands[1], VOIDmode))
12204 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
12205 operands[2], operands[3]));
12207 /* Everything else, use the mfcr brute force. */
12209 rs6000_emit_sCOND (<MODE>mode, operands);
12214 (define_expand "cstore<mode>4"
12215 [(use (match_operator 1 "comparison_operator"
12216 [(match_operand:FP 2 "gpc_reg_operand")
12217 (match_operand:FP 3 "gpc_reg_operand")]))
12218 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
12221 rs6000_emit_sCOND (<MODE>mode, operands);
12226 (define_expand "stack_protect_set"
12227 [(match_operand 0 "memory_operand")
12228 (match_operand 1 "memory_operand")]
12231 if (rs6000_stack_protector_guard == SSP_TLS)
12233 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
12234 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
12235 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
12236 operands[1] = gen_rtx_MEM (Pmode, addr);
12240 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
12242 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
12247 (define_insn "stack_protect_setsi"
12248 [(set (match_operand:SI 0 "memory_operand" "=m")
12249 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
12250 (set (match_scratch:SI 2 "=&r") (const_int 0))]
12252 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
12253 [(set_attr "type" "three")
12254 (set_attr "length" "12")])
12256 ;; We can't use the prefixed attribute here because there are two memory
12257 ;; instructions. We can't split the insn due to the fact that this operation
12258 ;; needs to be done in one piece.
12259 (define_insn "stack_protect_setdi"
12260 [(set (match_operand:DI 0 "memory_operand" "=Y")
12261 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
12262 (set (match_scratch:DI 2 "=&r") (const_int 0))]
12265 if (prefixed_memory (operands[1], DImode))
12266 output_asm_insn ("pld %2,%1", operands);
12268 output_asm_insn ("ld%U1%X1 %2,%1", operands);
12270 if (prefixed_memory (operands[0], DImode))
12271 output_asm_insn ("pstd %2,%0", operands);
12273 output_asm_insn ("std%U0%X0 %2,%0", operands);
12277 [(set_attr "type" "three")
12279 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
12280 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
12281 ;; the LI 0 at the end.
12282 (set_attr "prefixed" "no")
12283 (set_attr "num_insns" "3")
12284 (set (attr "length")
12285 (cond [(and (match_operand 0 "prefixed_memory")
12286 (match_operand 1 "prefixed_memory"))
12289 (ior (match_operand 0 "prefixed_memory")
12290 (match_operand 1 "prefixed_memory"))
12295 (define_expand "stack_protect_test"
12296 [(match_operand 0 "memory_operand")
12297 (match_operand 1 "memory_operand")
12298 (match_operand 2 "")]
12301 rtx guard = operands[1];
12303 if (rs6000_stack_protector_guard == SSP_TLS)
12305 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
12306 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
12307 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
12308 guard = gen_rtx_MEM (Pmode, addr);
12311 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
12312 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
12313 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
12314 emit_jump_insn (jump);
12319 (define_insn "stack_protect_testsi"
12320 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
12321 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
12322 (match_operand:SI 2 "memory_operand" "m,m")]
12324 (set (match_scratch:SI 4 "=r,r") (const_int 0))
12325 (clobber (match_scratch:SI 3 "=&r,&r"))]
12328 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
12329 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
12330 [(set_attr "length" "16,20")])
12332 ;; We can't use the prefixed attribute here because there are two memory
12333 ;; instructions. We can't split the insn due to the fact that this operation
12334 ;; needs to be done in one piece.
12335 (define_insn "stack_protect_testdi"
12336 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
12337 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
12338 (match_operand:DI 2 "memory_operand" "Y,Y")]
12340 (set (match_scratch:DI 4 "=r,r") (const_int 0))
12341 (clobber (match_scratch:DI 3 "=&r,&r"))]
12344 if (prefixed_memory (operands[1], DImode))
12345 output_asm_insn ("pld %3,%1", operands);
12347 output_asm_insn ("ld%U1%X1 %3,%1", operands);
12349 if (prefixed_memory (operands[2], DImode))
12350 output_asm_insn ("pld %4,%2", operands);
12352 output_asm_insn ("ld%U2%X2 %4,%2", operands);
12354 if (which_alternative == 0)
12355 output_asm_insn ("xor. %3,%3,%4", operands);
12357 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
12361 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
12362 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
12363 ;; 8 bytes to do the test.
12364 [(set_attr "prefixed" "no")
12365 (set_attr "num_insns" "4,5")
12366 (set (attr "length")
12367 (cond [(and (match_operand 1 "prefixed_memory")
12368 (match_operand 2 "prefixed_memory"))
12369 (if_then_else (eq_attr "alternative" "0")
12373 (ior (match_operand 1 "prefixed_memory")
12374 (match_operand 2 "prefixed_memory"))
12375 (if_then_else (eq_attr "alternative" "0")
12379 (if_then_else (eq_attr "alternative" "0")
12381 (const_int 20))))])
12384 ;; Here are the actual compare insns.
12385 (define_insn "*cmp<mode>_signed"
12386 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12387 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
12388 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
12390 "cmp<wd>%I2 %0,%1,%2"
12391 [(set_attr "type" "cmp")])
12393 (define_insn "*cmp<mode>_unsigned"
12394 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
12395 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
12396 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
12398 "cmpl<wd>%I2 %0,%1,%2"
12399 [(set_attr "type" "cmp")])
12401 ;; If we are comparing a register for equality with a large constant,
12402 ;; we can do this with an XOR followed by a compare. But this is profitable
12403 ;; only if the large constant is only used for the comparison (and in this
12404 ;; case we already have a register to reuse as scratch).
12406 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
12407 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
12410 [(set (match_operand:SI 0 "register_operand")
12411 (match_operand:SI 1 "logical_const_operand"))
12412 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
12414 (match_operand:SI 2 "logical_const_operand")]))
12415 (set (match_operand:CC 4 "cc_reg_operand")
12416 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
12419 (if_then_else (match_operator 6 "equality_operator"
12420 [(match_dup 4) (const_int 0)])
12421 (match_operand 7 "")
12422 (match_operand 8 "")))]
12423 "peep2_reg_dead_p (3, operands[0])
12424 && peep2_reg_dead_p (4, operands[4])
12425 && REGNO (operands[0]) != REGNO (operands[5])"
12426 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12427 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12428 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12431 /* Get the constant we are comparing against, and see what it looks like
12432 when sign-extended from 16 to 32 bits. Then see what constant we could
12433 XOR with SEXTC to get the sign-extended value. */
12434 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12436 operands[1], operands[2]);
12437 HOST_WIDE_INT c = INTVAL (cnst);
12438 HOST_WIDE_INT sextc = sext_hwi (c, 16);
12439 HOST_WIDE_INT xorv = c ^ sextc;
12441 operands[9] = GEN_INT (xorv);
12442 operands[10] = GEN_INT (sextc);
12445 ;; Only need to compare second words if first words equal
12446 (define_insn "*cmp<mode>_internal1"
12447 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12448 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12449 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12450 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12451 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
12452 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12453 [(set_attr "type" "fpcompare")
12454 (set_attr "length" "12")])
12456 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
12457 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12458 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12459 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12460 (clobber (match_scratch:DF 3 "=d"))
12461 (clobber (match_scratch:DF 4 "=d"))
12462 (clobber (match_scratch:DF 5 "=d"))
12463 (clobber (match_scratch:DF 6 "=d"))
12464 (clobber (match_scratch:DF 7 "=d"))
12465 (clobber (match_scratch:DF 8 "=d"))
12466 (clobber (match_scratch:DF 9 "=d"))
12467 (clobber (match_scratch:DF 10 "=d"))
12468 (clobber (match_scratch:GPR 11 "=b"))]
12469 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
12470 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
12472 "&& reload_completed"
12473 [(set (match_dup 3) (match_dup 14))
12474 (set (match_dup 4) (match_dup 15))
12475 (set (match_dup 9) (abs:DF (match_dup 5)))
12476 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12477 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12478 (label_ref (match_dup 12))
12480 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12481 (set (pc) (label_ref (match_dup 13)))
12483 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12484 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12485 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12486 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12489 REAL_VALUE_TYPE rv;
12490 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12491 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12493 operands[5] = simplify_gen_subreg (DFmode, operands[1],
12494 <IBM128:MODE>mode, hi_word);
12495 operands[6] = simplify_gen_subreg (DFmode, operands[1],
12496 <IBM128:MODE>mode, lo_word);
12497 operands[7] = simplify_gen_subreg (DFmode, operands[2],
12498 <IBM128:MODE>mode, hi_word);
12499 operands[8] = simplify_gen_subreg (DFmode, operands[2],
12500 <IBM128:MODE>mode, lo_word);
12501 operands[12] = gen_label_rtx ();
12502 operands[13] = gen_label_rtx ();
12504 operands[14] = force_const_mem (DFmode,
12505 const_double_from_real_value (rv, DFmode));
12506 operands[15] = force_const_mem (DFmode,
12507 const_double_from_real_value (dconst0,
12512 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12513 operands[14] = gen_const_mem (DFmode, tocref);
12514 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12515 operands[15] = gen_const_mem (DFmode, tocref);
12516 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12517 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12521 ;; Now we have the scc insns. We can do some combinations because of the
12522 ;; way the machine works.
12524 ;; Note that this is probably faster if we can put an insn between the
12525 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12526 ;; cases the insns below which don't use an intermediate CR field will
12527 ;; be used instead.
12528 (define_insn "set<mode>_cc"
12529 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12530 (match_operator:GPR 1 "scc_comparison_operator"
12531 [(match_operand 2 "cc_reg_operand" "y")
12534 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12535 [(set (attr "type")
12536 (cond [(match_test "TARGET_MFCRF")
12537 (const_string "mfcrf")
12539 (const_string "mfcr")))
12540 (set_attr "length" "8")])
12543 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
12544 (define_code_attr UNS [(eq "CC")
12546 (lt "CC") (ltu "CCUNS")
12547 (gt "CC") (gtu "CCUNS")
12548 (le "CC") (leu "CCUNS")
12549 (ge "CC") (geu "CCUNS")])
12550 (define_code_attr UNSu_ [(eq "")
12555 (ge "") (geu "u_")])
12556 (define_code_attr UNSIK [(eq "I")
12561 (ge "I") (geu "K")])
12563 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
12564 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12565 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
12566 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
12567 (clobber (match_scratch:GPR 3 "=r"))
12568 (clobber (match_scratch:GPR 4 "=r"))
12569 (clobber (match_scratch:<UNS> 5 "=y"))]
12570 "!TARGET_POWER10 && TARGET_ISEL
12571 && !(<CODE> == EQ && operands[2] == const0_rtx)
12572 && !(<CODE> == NE && operands[2] == const0_rtx
12573 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
12578 rtx_code code = <CODE>;
12579 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
12581 HOST_WIDE_INT val = INTVAL (operands[2]);
12582 if (code == LT && val != -0x8000)
12587 if (code == GT && val != 0x7fff)
12592 if (code == LTU && val != 0)
12597 if (code == GTU && val != 0xffff)
12602 operands[2] = GEN_INT (val);
12605 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
12606 operands[3] = const0_rtx;
12609 if (GET_CODE (operands[3]) == SCRATCH)
12610 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
12611 emit_move_insn (operands[3], const0_rtx);
12614 if (GET_CODE (operands[4]) == SCRATCH)
12615 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12616 emit_move_insn (operands[4], const1_rtx);
12618 if (GET_CODE (operands[5]) == SCRATCH)
12619 operands[5] = gen_reg_rtx (<UNS>mode);
12621 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12622 emit_insn (gen_rtx_SET (operands[5], c1));
12624 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12625 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12626 emit_move_insn (operands[0], x);
12630 [(set (attr "cost")
12631 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12633 || <CODE> == LE || <CODE> == GE
12634 || <CODE> == LEU || <CODE> == GEU")
12636 (const_string "10")))])
12638 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12641 (define_expand "eq<mode>3"
12643 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12644 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12645 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12646 (clobber (match_scratch:GPR 3 "=r"))
12647 (clobber (match_scratch:GPR 4 "=r"))])]
12650 if (TARGET_POWER10)
12652 rtx cc = gen_reg_rtx (CCmode);
12653 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12654 emit_insn (gen_rtx_SET (cc, compare));
12655 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
12656 emit_insn (gen_setbc_cc_<mode> (operands[0], eq, cc));
12660 if (TARGET_ISEL && operands[2] != const0_rtx)
12662 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12668 (define_insn_and_split "*eq<mode>3"
12669 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12670 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12671 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12672 (clobber (match_scratch:GPR 3 "=r"))
12673 (clobber (match_scratch:GPR 4 "=r"))]
12674 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12677 [(set (match_dup 4)
12678 (clz:GPR (match_dup 3)))
12680 (lshiftrt:GPR (match_dup 4)
12683 operands[3] = rs6000_emit_eqne (<MODE>mode,
12684 operands[1], operands[2], operands[3]);
12686 if (GET_CODE (operands[4]) == SCRATCH)
12687 operands[4] = gen_reg_rtx (<MODE>mode);
12689 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12691 [(set (attr "length")
12692 (if_then_else (match_test "operands[2] == const0_rtx")
12694 (const_string "12")))])
12696 (define_expand "ne<mode>3"
12698 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12699 (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12700 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12701 (clobber (match_scratch:GPR 3 "=r"))
12702 (clobber (match_scratch:GPR 4 "=r"))
12703 (clobber (reg:GPR CA_REGNO))])]
12706 if (TARGET_POWER10)
12708 rtx cc = gen_reg_rtx (CCmode);
12709 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12710 emit_insn (gen_rtx_SET (cc, compare));
12711 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
12712 emit_insn (gen_setbc_cc_<mode> (operands[0], ne, cc));
12716 if (<MODE>mode != Pmode)
12718 rtx x = gen_reg_rtx (<MODE>mode);
12719 emit_insn (gen_eq<mode>3 (x, operands[1], operands[2]));
12720 emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx));
12724 if (TARGET_ISEL && operands[2] != const0_rtx)
12726 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12732 (define_insn_and_split "*ne<mode>3"
12733 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12734 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12735 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12736 (clobber (match_scratch:P 3 "=r"))
12737 (clobber (match_scratch:P 4 "=r"))
12738 (clobber (reg:P CA_REGNO))]
12739 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12742 [(parallel [(set (match_dup 4)
12743 (plus:P (match_dup 3)
12745 (set (reg:P CA_REGNO)
12746 (ne:P (match_dup 3)
12748 (parallel [(set (match_dup 0)
12749 (plus:P (plus:P (not:P (match_dup 4))
12752 (clobber (reg:P CA_REGNO))])]
12754 operands[3] = rs6000_emit_eqne (<MODE>mode,
12755 operands[1], operands[2], operands[3]);
12757 if (GET_CODE (operands[4]) == SCRATCH)
12758 operands[4] = gen_reg_rtx (<MODE>mode);
12760 [(set (attr "length")
12761 (if_then_else (match_test "operands[2] == const0_rtx")
12763 (const_string "12")))])
12765 (define_insn_and_split "*neg_eq_<mode>"
12766 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12767 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12768 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12769 (clobber (match_scratch:P 3 "=r"))
12770 (clobber (match_scratch:P 4 "=r"))
12771 (clobber (reg:P CA_REGNO))]
12775 [(parallel [(set (match_dup 4)
12776 (plus:P (match_dup 3)
12778 (set (reg:P CA_REGNO)
12779 (ne:P (match_dup 3)
12781 (parallel [(set (match_dup 0)
12782 (plus:P (reg:P CA_REGNO)
12784 (clobber (reg:P CA_REGNO))])]
12786 operands[3] = rs6000_emit_eqne (<MODE>mode,
12787 operands[1], operands[2], operands[3]);
12789 if (GET_CODE (operands[4]) == SCRATCH)
12790 operands[4] = gen_reg_rtx (<MODE>mode);
12792 [(set (attr "length")
12793 (if_then_else (match_test "operands[2] == const0_rtx")
12795 (const_string "12")))])
12797 (define_insn_and_split "*neg_ne_<mode>"
12798 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12799 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12800 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12801 (clobber (match_scratch:P 3 "=r"))
12802 (clobber (match_scratch:P 4 "=r"))
12803 (clobber (reg:P CA_REGNO))]
12807 [(parallel [(set (match_dup 4)
12808 (neg:P (match_dup 3)))
12809 (set (reg:P CA_REGNO)
12810 (eq:P (match_dup 3)
12812 (parallel [(set (match_dup 0)
12813 (plus:P (reg:P CA_REGNO)
12815 (clobber (reg:P CA_REGNO))])]
12817 operands[3] = rs6000_emit_eqne (<MODE>mode,
12818 operands[1], operands[2], operands[3]);
12820 if (GET_CODE (operands[4]) == SCRATCH)
12821 operands[4] = gen_reg_rtx (<MODE>mode);
12823 [(set (attr "length")
12824 (if_then_else (match_test "operands[2] == const0_rtx")
12826 (const_string "12")))])
12828 (define_insn_and_split "*plus_eq_<mode>"
12829 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12830 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12831 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12832 (match_operand:P 3 "gpc_reg_operand" "r")))
12833 (clobber (match_scratch:P 4 "=r"))
12834 (clobber (match_scratch:P 5 "=r"))
12835 (clobber (reg:P CA_REGNO))]
12839 [(parallel [(set (match_dup 5)
12840 (neg:P (match_dup 4)))
12841 (set (reg:P CA_REGNO)
12842 (eq:P (match_dup 4)
12844 (parallel [(set (match_dup 0)
12845 (plus:P (match_dup 3)
12847 (clobber (reg:P CA_REGNO))])]
12849 operands[4] = rs6000_emit_eqne (<MODE>mode,
12850 operands[1], operands[2], operands[4]);
12852 if (GET_CODE (operands[5]) == SCRATCH)
12853 operands[5] = gen_reg_rtx (<MODE>mode);
12855 [(set (attr "length")
12856 (if_then_else (match_test "operands[2] == const0_rtx")
12858 (const_string "12")))])
12860 (define_insn_and_split "*plus_ne_<mode>"
12861 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12862 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12863 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12864 (match_operand:P 3 "gpc_reg_operand" "r")))
12865 (clobber (match_scratch:P 4 "=r"))
12866 (clobber (match_scratch:P 5 "=r"))
12867 (clobber (reg:P CA_REGNO))]
12871 [(parallel [(set (match_dup 5)
12872 (plus:P (match_dup 4)
12874 (set (reg:P CA_REGNO)
12875 (ne:P (match_dup 4)
12877 (parallel [(set (match_dup 0)
12878 (plus:P (match_dup 3)
12880 (clobber (reg:P CA_REGNO))])]
12882 operands[4] = rs6000_emit_eqne (<MODE>mode,
12883 operands[1], operands[2], operands[4]);
12885 if (GET_CODE (operands[5]) == SCRATCH)
12886 operands[5] = gen_reg_rtx (<MODE>mode);
12888 [(set (attr "length")
12889 (if_then_else (match_test "operands[2] == const0_rtx")
12891 (const_string "12")))])
12893 (define_insn_and_split "*minus_eq_<mode>"
12894 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12895 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12896 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12897 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12898 (clobber (match_scratch:P 4 "=r"))
12899 (clobber (match_scratch:P 5 "=r"))
12900 (clobber (reg:P CA_REGNO))]
12904 [(parallel [(set (match_dup 5)
12905 (plus:P (match_dup 4)
12907 (set (reg:P CA_REGNO)
12908 (ne:P (match_dup 4)
12910 (parallel [(set (match_dup 0)
12911 (plus:P (plus:P (match_dup 3)
12914 (clobber (reg:P CA_REGNO))])]
12916 operands[4] = rs6000_emit_eqne (<MODE>mode,
12917 operands[1], operands[2], operands[4]);
12919 if (GET_CODE (operands[5]) == SCRATCH)
12920 operands[5] = gen_reg_rtx (<MODE>mode);
12922 [(set (attr "length")
12923 (if_then_else (match_test "operands[2] == const0_rtx")
12925 (const_string "12")))])
12927 (define_insn_and_split "*minus_ne_<mode>"
12928 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12929 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12930 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12931 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12932 (clobber (match_scratch:P 4 "=r"))
12933 (clobber (match_scratch:P 5 "=r"))
12934 (clobber (reg:P CA_REGNO))]
12938 [(parallel [(set (match_dup 5)
12939 (neg:P (match_dup 4)))
12940 (set (reg:P CA_REGNO)
12941 (eq:P (match_dup 4)
12943 (parallel [(set (match_dup 0)
12944 (plus:P (plus:P (match_dup 3)
12947 (clobber (reg:P CA_REGNO))])]
12949 operands[4] = rs6000_emit_eqne (<MODE>mode,
12950 operands[1], operands[2], operands[4]);
12952 if (GET_CODE (operands[5]) == SCRATCH)
12953 operands[5] = gen_reg_rtx (<MODE>mode);
12955 [(set (attr "length")
12956 (if_then_else (match_test "operands[2] == const0_rtx")
12958 (const_string "12")))])
12960 (define_insn_and_split "*eqsi3_ext<mode>"
12961 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12962 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12963 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12964 (clobber (match_scratch:SI 3 "=r"))
12965 (clobber (match_scratch:SI 4 "=r"))]
12969 [(set (match_dup 4)
12970 (clz:SI (match_dup 3)))
12973 (lshiftrt:SI (match_dup 4)
12976 operands[3] = rs6000_emit_eqne (SImode,
12977 operands[1], operands[2], operands[3]);
12979 if (GET_CODE (operands[4]) == SCRATCH)
12980 operands[4] = gen_reg_rtx (SImode);
12982 [(set (attr "length")
12983 (if_then_else (match_test "operands[2] == const0_rtx")
12985 (const_string "12")))])
12987 (define_insn_and_split "*nesi3_ext<mode>"
12988 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12989 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12990 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12991 (clobber (match_scratch:SI 3 "=r"))
12992 (clobber (match_scratch:SI 4 "=r"))
12993 (clobber (match_scratch:EXTSI 5 "=r"))]
12997 [(set (match_dup 4)
12998 (clz:SI (match_dup 3)))
13001 (lshiftrt:SI (match_dup 4)
13004 (xor:EXTSI (match_dup 5)
13007 operands[3] = rs6000_emit_eqne (SImode,
13008 operands[1], operands[2], operands[3]);
13010 if (GET_CODE (operands[4]) == SCRATCH)
13011 operands[4] = gen_reg_rtx (SImode);
13012 if (GET_CODE (operands[5]) == SCRATCH)
13013 operands[5] = gen_reg_rtx (<MODE>mode);
13015 [(set (attr "length")
13016 (if_then_else (match_test "operands[2] == const0_rtx")
13017 (const_string "12")
13018 (const_string "16")))])
13021 (define_code_iterator fp_rev [ordered ne unle unge])
13022 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
13024 (define_insn_and_split "*<code><mode>_cc"
13025 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13026 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
13028 "!flag_finite_math_only"
13033 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
13034 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
13035 rtx tmp = gen_reg_rtx (<MODE>mode);
13036 emit_move_insn (tmp, eq);
13037 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
13040 [(set_attr "length" "12")])
13042 (define_insn_and_split "*<code><mode>_cc"
13043 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13044 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
13046 "!flag_finite_math_only"
13051 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
13053 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
13056 [(set_attr "length" "12")])
13058 ;; Conditional branches.
13059 ;; These either are a single bc insn, or a bc around a b.
13061 (define_insn "*cbranch"
13063 (if_then_else (match_operator 1 "branch_comparison_operator"
13064 [(match_operand 2 "cc_reg_operand" "y")
13066 (label_ref (match_operand 0))
13070 return output_cbranch (operands[1], "%l0", 0, insn);
13072 [(set_attr "type" "branch")
13073 (set (attr "length")
13074 (if_then_else (and (ge (minus (match_dup 0) (pc))
13075 (const_int -32768))
13076 (lt (minus (match_dup 0) (pc))
13077 (const_int 32764)))
13081 (define_insn_and_split "*cbranch_2insn"
13083 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
13084 [(match_operand 2 "cc_reg_operand" "y")
13086 (label_ref (match_operand 0))
13088 "!flag_finite_math_only"
13093 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
13095 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
13097 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
13098 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
13099 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
13100 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
13104 profile_probability prob
13105 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
13107 add_reg_br_prob_note (get_last_insn (), prob);
13112 [(set_attr "type" "branch")
13113 (set (attr "length")
13114 (if_then_else (and (ge (minus (match_dup 0) (pc))
13115 (const_int -32764))
13116 (lt (minus (match_dup 0) (pc))
13117 (const_int 32760)))
13121 ;; Conditional return.
13122 (define_insn "*creturn"
13124 (if_then_else (match_operator 0 "branch_comparison_operator"
13125 [(match_operand 1 "cc_reg_operand" "y")
13131 return output_cbranch (operands[0], NULL, 0, insn);
13133 [(set_attr "type" "jmpreg")])
13135 ;; Logic on condition register values.
13137 ; This pattern matches things like
13138 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
13139 ; (eq:SI (reg:CCFP 68) (const_int 0)))
13141 ; which are generated by the branch logic.
13142 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
13144 (define_insn "@cceq_ior_compare_<mode>"
13145 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13146 (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
13147 [(match_operator:GPR 2
13148 "branch_positive_comparison_operator"
13150 "cc_reg_operand" "y,y")
13152 (match_operator:GPR 4
13153 "branch_positive_comparison_operator"
13155 "cc_reg_operand" "0,y")
13159 "cr%q1 %E0,%j2,%j4"
13160 [(set_attr "type" "cr_logical")
13161 (set_attr "cr_logical_3op" "no,yes")])
13163 ; Why is the constant -1 here, but 1 in the previous pattern?
13164 ; Because ~1 has all but the low bit set.
13165 (define_insn "cceq_ior_compare_complement"
13166 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13167 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
13168 [(not:SI (match_operator:SI 2
13169 "branch_positive_comparison_operator"
13171 "cc_reg_operand" "y,y")
13173 (match_operator:SI 4
13174 "branch_positive_comparison_operator"
13176 "cc_reg_operand" "0,y")
13180 "cr%q1 %E0,%j2,%j4"
13181 [(set_attr "type" "cr_logical")
13182 (set_attr "cr_logical_3op" "no,yes")])
13184 (define_insn "@cceq_rev_compare_<mode>"
13185 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
13186 (compare:CCEQ (match_operator:GPR 1
13187 "branch_positive_comparison_operator"
13189 "cc_reg_operand" "0,y")
13194 [(set_attr "type" "cr_logical")
13195 (set_attr "cr_logical_3op" "no,yes")])
13197 ;; If we are comparing the result of two comparisons, this can be done
13198 ;; using creqv or crxor.
13200 (define_insn_and_split ""
13201 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
13202 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
13203 [(match_operand 2 "cc_reg_operand" "y")
13205 (match_operator 3 "branch_comparison_operator"
13206 [(match_operand 4 "cc_reg_operand" "y")
13211 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
13214 int positive_1, positive_2;
13216 positive_1 = branch_positive_comparison_operator (operands[1],
13217 GET_MODE (operands[1]));
13218 positive_2 = branch_positive_comparison_operator (operands[3],
13219 GET_MODE (operands[3]));
13222 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
13223 GET_CODE (operands[1])),
13225 operands[2], const0_rtx);
13226 else if (GET_MODE (operands[1]) != SImode)
13227 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
13228 operands[2], const0_rtx);
13231 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
13232 GET_CODE (operands[3])),
13234 operands[4], const0_rtx);
13235 else if (GET_MODE (operands[3]) != SImode)
13236 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
13237 operands[4], const0_rtx);
13239 if (positive_1 == positive_2)
13241 operands[1] = gen_rtx_NOT (SImode, operands[1]);
13242 operands[5] = constm1_rtx;
13246 operands[5] = const1_rtx;
13250 ;; Unconditional branch and return.
13252 (define_insn "jump"
13254 (label_ref (match_operand 0)))]
13257 [(set_attr "type" "branch")])
13259 (define_insn "<return_str>return"
13263 [(set_attr "type" "jmpreg")])
13265 (define_expand "indirect_jump"
13266 [(set (pc) (match_operand 0 "register_operand"))]
13269 if (!rs6000_speculate_indirect_jumps) {
13270 rtx ccreg = gen_reg_rtx (CCmode);
13271 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
13276 (define_insn "*indirect_jump<mode>"
13278 (match_operand:P 0 "register_operand" "c,*l"))]
13279 "rs6000_speculate_indirect_jumps"
13281 [(set_attr "type" "jmpreg")])
13283 (define_insn "@indirect_jump<mode>_nospec"
13284 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
13285 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
13286 "!rs6000_speculate_indirect_jumps"
13287 "crset %E1\;beq%T0- %1\;b $"
13288 [(set_attr "type" "jmpreg")
13289 (set_attr "length" "12")])
13291 ;; Table jump for switch statements:
13292 (define_expand "tablejump"
13293 [(use (match_operand 0))
13294 (use (label_ref (match_operand 1)))]
13297 if (rs6000_speculate_indirect_jumps)
13299 if (rs6000_relative_jumptables)
13300 emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1]));
13302 emit_jump_insn (gen_tablejump_absolute (Pmode, operands[0],
13307 rtx ccreg = gen_reg_rtx (CCmode);
13309 if (rs6000_relative_jumptables)
13310 jump = gen_tablejump_nospec (Pmode, operands[0], operands[1], ccreg);
13312 jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1],
13314 emit_jump_insn (jump);
13319 (define_expand "@tablejump<mode>_normal"
13320 [(use (match_operand:SI 0))
13321 (use (match_operand:P 1))]
13322 "rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
13324 rtx off = force_reg (SImode, operands[0]);
13325 if (<MODE>mode != SImode)
13327 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
13328 off = gen_reg_rtx (Pmode);
13329 emit_move_insn (off, src);
13332 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
13333 rtx addr = gen_reg_rtx (Pmode);
13335 emit_insn (gen_add<mode>3 (addr, off, lab));
13336 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
13340 (define_expand "@tablejump<mode>_absolute"
13341 [(use (match_operand:P 0))
13342 (use (match_operand:P 1))]
13343 "rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
13345 rtx addr = gen_reg_rtx (Pmode);
13346 emit_move_insn (addr, operands[0]);
13348 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1]));
13352 (define_expand "@tablejump<mode>_nospec"
13353 [(use (match_operand:SI 0))
13354 (use (match_operand:P 1))
13355 (use (match_operand:CC 2))]
13356 "!rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
13358 rtx off = force_reg (SImode, operands[0]);
13359 if (<MODE>mode != SImode)
13361 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
13362 off = gen_reg_rtx (Pmode);
13363 emit_move_insn (off, src);
13366 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1]));
13367 rtx addr = gen_reg_rtx (Pmode);
13369 emit_insn (gen_add<mode>3 (addr, off, lab));
13370 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
13375 (define_expand "@tablejump<mode>_absolute_nospec"
13376 [(use (match_operand:P 0))
13377 (use (match_operand:P 1))
13378 (use (match_operand:CC 2))]
13379 "!rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
13381 rtx addr = gen_reg_rtx (Pmode);
13382 emit_move_insn (addr, operands[0]);
13384 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1],
13389 (define_insn "@tablejump<mode>_insn_normal"
13391 (match_operand:P 0 "register_operand" "c,*l"))
13392 (use (label_ref (match_operand 1)))]
13393 "rs6000_speculate_indirect_jumps"
13395 [(set_attr "type" "jmpreg")])
13397 (define_insn "@tablejump<mode>_insn_nospec"
13399 (match_operand:P 0 "register_operand" "c,*l"))
13400 (use (label_ref (match_operand 1)))
13401 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
13402 "!rs6000_speculate_indirect_jumps"
13403 "crset %E2\;beq%T0- %2\;b $"
13404 [(set_attr "type" "jmpreg")
13405 (set_attr "length" "12")])
13408 [(unspec [(const_int 0)] UNSPEC_NOP)]
13412 (define_insn "group_ending_nop"
13413 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
13416 operands[0] = gen_rtx_REG (Pmode,
13417 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
13418 return "ori %0,%0,0";
13421 (define_insn "speculation_barrier"
13422 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
13425 operands[0] = gen_rtx_REG (Pmode, 31);
13426 return "ori %0,%0,0";
13429 ;; Define the subtract-one-and-jump insns, starting with the template
13430 ;; so loop.c knows what to generate.
13432 (define_expand "doloop_end"
13433 [(use (match_operand 0)) ; loop pseudo
13434 (use (match_operand 1))] ; label
13437 if (GET_MODE (operands[0]) != Pmode)
13440 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
13444 (define_expand "@ctr<mode>"
13445 [(parallel [(set (pc)
13446 (if_then_else (ne (match_operand:P 0 "register_operand")
13448 (label_ref (match_operand 1))
13451 (plus:P (match_dup 0)
13453 (clobber (match_scratch:CC 2))
13454 (clobber (match_scratch:P 3))])]
13458 ;; We need to be able to do this for any operand, including MEM, or we
13459 ;; will cause reload to blow up since we don't allow output reloads on
13461 ;; For the length attribute to be calculated correctly, the
13462 ;; label MUST be operand 0.
13463 ;; rs6000_legitimate_combined_insn prevents combine creating any of
13464 ;; the ctr<mode> insns.
13466 (define_code_iterator eqne [eq ne])
13467 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
13468 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
13470 (define_insn "<bd>_<mode>"
13472 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13474 (label_ref (match_operand 0))
13476 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
13477 (plus:P (match_dup 1)
13479 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13480 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13483 if (which_alternative != 0)
13485 else if (get_attr_length (insn) == 4)
13488 return "<bd_neg> $+8\;b %l0";
13490 [(set_attr "type" "branch")
13491 (set_attr_alternative "length"
13492 [(if_then_else (and (ge (minus (match_dup 0) (pc))
13493 (const_int -32768))
13494 (lt (minus (match_dup 0) (pc))
13495 (const_int 32764)))
13498 (const_string "16")
13499 (const_string "20")
13500 (const_string "20")])])
13502 ;; Now the splitter if we could not allocate the CTR register
13505 (if_then_else (match_operator 2 "comparison_operator"
13506 [(match_operand:P 1 "gpc_reg_operand")
13509 (match_operand 6)))
13510 (set (match_operand:P 0 "nonimmediate_operand")
13511 (plus:P (match_dup 1)
13513 (clobber (match_scratch:CC 3))
13514 (clobber (match_scratch:P 4))]
13517 (if_then_else (match_dup 7)
13521 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
13523 emit_insn (gen_rtx_SET (operands[3],
13524 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
13525 if (int_reg_operand (operands[0], <MODE>mode))
13526 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
13529 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
13530 emit_move_insn (operands[0], operands[4]);
13532 /* No DONE so branch comes from the pattern. */
13535 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
13536 ;; Note that in the case of long branches we have to decompose this into
13537 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
13538 ;; and the CR bit, which means there is no way to conveniently invert the
13539 ;; comparison as is done with plain bdnz/bdz.
13541 (define_insn "<bd>tf_<mode>"
13545 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13547 (match_operator 3 "branch_comparison_operator"
13548 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
13550 (label_ref (match_operand 0))
13552 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
13553 (plus:P (match_dup 1)
13555 (clobber (match_scratch:P 5 "=X,X,&r,r"))
13556 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
13557 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
13560 if (which_alternative != 0)
13562 else if (get_attr_length (insn) == 4)
13564 if (branch_positive_comparison_operator (operands[3],
13565 GET_MODE (operands[3])))
13566 return "<bd>t %j3,%l0";
13568 return "<bd>f %j3,%l0";
13572 static char seq[96];
13573 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
13574 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
13578 [(set_attr "type" "branch")
13579 (set_attr_alternative "length"
13580 [(if_then_else (and (ge (minus (match_dup 0) (pc))
13581 (const_int -32768))
13582 (lt (minus (match_dup 0) (pc))
13583 (const_int 32764)))
13586 (const_string "16")
13587 (const_string "20")
13588 (const_string "20")])])
13590 ;; Now the splitter if we could not allocate the CTR register
13595 (match_operator 1 "comparison_operator"
13596 [(match_operand:P 0 "gpc_reg_operand")
13598 (match_operator 3 "branch_comparison_operator"
13599 [(match_operand 2 "cc_reg_operand")
13602 (match_operand 5)))
13603 (set (match_operand:P 6 "nonimmediate_operand")
13604 (plus:P (match_dup 0)
13606 (clobber (match_scratch:P 7))
13607 (clobber (match_scratch:CC 8))
13608 (clobber (match_scratch:CCEQ 9))]
13612 rtx ctr = operands[0];
13613 rtx ctrcmp = operands[1];
13614 rtx ccin = operands[2];
13615 rtx cccmp = operands[3];
13616 rtx dst1 = operands[4];
13617 rtx dst2 = operands[5];
13618 rtx ctrout = operands[6];
13619 rtx ctrtmp = operands[7];
13620 enum rtx_code cmpcode = GET_CODE (ctrcmp);
13621 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
13623 cmpcode = reverse_condition (cmpcode);
13624 /* Generate crand/crandc here. */
13625 emit_insn (gen_rtx_SET (operands[8],
13626 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
13627 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
13629 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
13631 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
13632 operands[8], cccmp, ccin));
13634 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
13635 operands[8], cccmp, ccin));
13636 if (int_reg_operand (ctrout, <MODE>mode))
13637 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
13640 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
13641 emit_move_insn (ctrout, ctrtmp);
13643 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
13644 emit_jump_insn (gen_rtx_SET (pc_rtx,
13645 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
13651 (define_insn "trap"
13652 [(trap_if (const_int 1) (const_int 0))]
13655 [(set_attr "type" "trap")])
13657 (define_expand "ctrap<mode>4"
13658 [(trap_if (match_operator 0 "ordered_comparison_operator"
13659 [(match_operand:GPR 1 "register_operand")
13660 (match_operand:GPR 2 "reg_or_short_operand")])
13661 (match_operand 3 "zero_constant" ""))]
13666 [(trap_if (match_operator 0 "ordered_comparison_operator"
13667 [(match_operand:GPR 1 "register_operand" "r")
13668 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13671 "t<wd>%V0%I2 %1,%2"
13672 [(set_attr "type" "trap")])
13674 ;; Insns related to generating the function prologue and epilogue.
13676 (define_expand "prologue"
13677 [(use (const_int 0))]
13680 rs6000_emit_prologue ();
13681 if (!TARGET_SCHED_PROLOG)
13682 emit_insn (gen_blockage ());
13686 (define_insn "*movesi_from_cr_one"
13687 [(match_parallel 0 "mfcr_operation"
13688 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13689 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13690 (match_operand 3 "immediate_operand" "n")]
13691 UNSPEC_MOVESI_FROM_CR))])]
13696 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13698 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13699 operands[4] = GEN_INT (mask);
13700 output_asm_insn ("mfcr %1,%4", operands);
13704 [(set_attr "type" "mfcrf")])
13706 ;; Don't include the volatile CRs since their values are not used wrt CR save
13707 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13708 ;; prologue past an insn (early exit test) that defines a register used in the
13710 (define_insn "prologue_movesi_from_cr"
13711 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13712 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13713 (reg:CC CR4_REGNO)]
13714 UNSPEC_MOVESI_FROM_CR))]
13717 [(set_attr "type" "mfcr")])
13719 (define_insn "*crsave"
13720 [(match_parallel 0 "crsave_operation"
13721 [(set (match_operand:SI 1 "memory_operand" "=m")
13722 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13725 [(set_attr "type" "store")])
13727 (define_insn "*stmw"
13728 [(match_parallel 0 "stmw_operation"
13729 [(set (match_operand:SI 1 "memory_operand" "=m")
13730 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13733 [(set_attr "type" "store")
13734 (set_attr "update" "yes")
13735 (set_attr "indexed" "yes")])
13737 ; The following comment applies to:
13741 ; return_and_restore_gpregs*
13742 ; return_and_restore_fpregs*
13743 ; return_and_restore_fpregs_aix*
13745 ; The out-of-line save / restore functions expects one input argument.
13746 ; Since those are not standard call_insn's, we must avoid using
13747 ; MATCH_OPERAND for that argument. That way the register rename
13748 ; optimization will not try to rename this register.
13749 ; Each pattern is repeated for each possible register number used in
13750 ; various ABIs (r11, r1, and for some functions r12)
13752 (define_insn "*save_gpregs_<mode>_r11"
13753 [(match_parallel 0 "any_parallel_operand"
13754 [(clobber (reg:P LR_REGNO))
13755 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13757 (set (match_operand:P 2 "memory_operand" "=m")
13758 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13761 [(set_attr "type" "branch")])
13763 (define_insn "*save_gpregs_<mode>_r12"
13764 [(match_parallel 0 "any_parallel_operand"
13765 [(clobber (reg:P LR_REGNO))
13766 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13768 (set (match_operand:P 2 "memory_operand" "=m")
13769 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13772 [(set_attr "type" "branch")])
13774 (define_insn "*save_gpregs_<mode>_r1"
13775 [(match_parallel 0 "any_parallel_operand"
13776 [(clobber (reg:P LR_REGNO))
13777 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13779 (set (match_operand:P 2 "memory_operand" "=m")
13780 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13783 [(set_attr "type" "branch")])
13785 (define_insn "*save_fpregs_<mode>_r11"
13786 [(match_parallel 0 "any_parallel_operand"
13787 [(clobber (reg:P LR_REGNO))
13788 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13790 (set (match_operand:DF 2 "memory_operand" "=m")
13791 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13794 [(set_attr "type" "branch")])
13796 (define_insn "*save_fpregs_<mode>_r12"
13797 [(match_parallel 0 "any_parallel_operand"
13798 [(clobber (reg:P LR_REGNO))
13799 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13801 (set (match_operand:DF 2 "memory_operand" "=m")
13802 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13805 [(set_attr "type" "branch")])
13807 (define_insn "*save_fpregs_<mode>_r1"
13808 [(match_parallel 0 "any_parallel_operand"
13809 [(clobber (reg:P LR_REGNO))
13810 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13812 (set (match_operand:DF 2 "memory_operand" "=m")
13813 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13816 [(set_attr "type" "branch")])
13818 ; This is to explain that changes to the stack pointer should
13819 ; not be moved over loads from or stores to stack memory.
13820 (define_insn "stack_tie"
13821 [(match_parallel 0 "tie_operand"
13822 [(set (mem:BLK (reg 1)) (const_int 0))])]
13825 [(set_attr "length" "0")])
13827 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13828 ; stay behind all restores from the stack, it cannot be reordered to before
13829 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13830 (define_insn "stack_restore_tie"
13831 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13832 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13833 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13834 (set (mem:BLK (scratch)) (const_int 0))]
13839 [(set_attr "type" "*,add")])
13841 (define_expand "epilogue"
13842 [(use (const_int 0))]
13845 if (!TARGET_SCHED_PROLOG)
13846 emit_insn (gen_blockage ());
13847 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13851 ; On some processors, doing the mtcrf one CC register at a time is
13852 ; faster (like on the 604e). On others, doing them all at once is
13853 ; faster; for instance, on the 601 and 750.
13855 (define_expand "movsi_to_cr_one"
13856 [(set (match_operand:CC 0 "cc_reg_operand")
13857 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13858 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13860 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13862 (define_insn "*movsi_to_cr"
13863 [(match_parallel 0 "mtcrf_operation"
13864 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13865 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13866 (match_operand 3 "immediate_operand" "n")]
13867 UNSPEC_MOVESI_TO_CR))])]
13872 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13873 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13874 operands[4] = GEN_INT (mask);
13875 return "mtcrf %4,%2";
13877 [(set_attr "type" "mtcr")])
13879 (define_insn "*mtcrfsi"
13880 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13881 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13882 (match_operand 2 "immediate_operand" "n")]
13883 UNSPEC_MOVESI_TO_CR))]
13884 "REG_P (operands[0])
13885 && CR_REGNO_P (REGNO (operands[0]))
13886 && CONST_INT_P (operands[2])
13887 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13889 [(set_attr "type" "mtcr")])
13891 ; The load-multiple instructions have similar properties.
13892 ; Note that "load_multiple" is a name known to the machine-independent
13893 ; code that actually corresponds to the PowerPC load-string.
13895 (define_insn "*lmw"
13896 [(match_parallel 0 "lmw_operation"
13897 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13898 (match_operand:SI 2 "memory_operand" "m"))])]
13901 [(set_attr "type" "load")
13902 (set_attr "update" "yes")
13903 (set_attr "indexed" "yes")
13904 (set_attr "cell_micro" "always")])
13906 ; FIXME: "any_parallel_operand" is a bit flexible...
13908 ; The following comment applies to:
13912 ; return_and_restore_gpregs*
13913 ; return_and_restore_fpregs*
13914 ; return_and_restore_fpregs_aix*
13916 ; The out-of-line save / restore functions expects one input argument.
13917 ; Since those are not standard call_insn's, we must avoid using
13918 ; MATCH_OPERAND for that argument. That way the register rename
13919 ; optimization will not try to rename this register.
13920 ; Each pattern is repeated for each possible register number used in
13921 ; various ABIs (r11, r1, and for some functions r12)
13923 (define_insn "*restore_gpregs_<mode>_r11"
13924 [(match_parallel 0 "any_parallel_operand"
13925 [(clobber (reg:P LR_REGNO))
13926 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13928 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13929 (match_operand:P 3 "memory_operand" "m"))])]
13932 [(set_attr "type" "branch")])
13934 (define_insn "*restore_gpregs_<mode>_r12"
13935 [(match_parallel 0 "any_parallel_operand"
13936 [(clobber (reg:P LR_REGNO))
13937 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13939 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13940 (match_operand:P 3 "memory_operand" "m"))])]
13943 [(set_attr "type" "branch")])
13945 (define_insn "*restore_gpregs_<mode>_r1"
13946 [(match_parallel 0 "any_parallel_operand"
13947 [(clobber (reg:P LR_REGNO))
13948 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13950 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13951 (match_operand:P 3 "memory_operand" "m"))])]
13954 [(set_attr "type" "branch")])
13956 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13957 [(match_parallel 0 "any_parallel_operand"
13959 (clobber (reg:P LR_REGNO))
13960 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13962 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13963 (match_operand:P 3 "memory_operand" "m"))])]
13966 [(set_attr "type" "branch")])
13968 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13969 [(match_parallel 0 "any_parallel_operand"
13971 (clobber (reg:P LR_REGNO))
13972 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13974 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13975 (match_operand:P 3 "memory_operand" "m"))])]
13978 [(set_attr "type" "branch")])
13980 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13981 [(match_parallel 0 "any_parallel_operand"
13983 (clobber (reg:P LR_REGNO))
13984 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13986 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13987 (match_operand:P 3 "memory_operand" "m"))])]
13990 [(set_attr "type" "branch")])
13992 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13993 [(match_parallel 0 "any_parallel_operand"
13995 (clobber (reg:P LR_REGNO))
13996 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13998 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13999 (match_operand:DF 3 "memory_operand" "m"))])]
14002 [(set_attr "type" "branch")])
14004 (define_insn "*return_and_restore_fpregs_<mode>_r12"
14005 [(match_parallel 0 "any_parallel_operand"
14007 (clobber (reg:P LR_REGNO))
14008 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14010 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14011 (match_operand:DF 3 "memory_operand" "m"))])]
14014 [(set_attr "type" "branch")])
14016 (define_insn "*return_and_restore_fpregs_<mode>_r1"
14017 [(match_parallel 0 "any_parallel_operand"
14019 (clobber (reg:P LR_REGNO))
14020 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14022 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14023 (match_operand:DF 3 "memory_operand" "m"))])]
14026 [(set_attr "type" "branch")])
14028 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
14029 [(match_parallel 0 "any_parallel_operand"
14031 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14033 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14034 (match_operand:DF 3 "memory_operand" "m"))])]
14037 [(set_attr "type" "branch")])
14039 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
14040 [(match_parallel 0 "any_parallel_operand"
14042 (use (match_operand:P 1 "symbol_ref_operand" "s"))
14044 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
14045 (match_operand:DF 3 "memory_operand" "m"))])]
14048 [(set_attr "type" "branch")])
14050 ; This is used in compiling the unwind routines.
14051 (define_expand "eh_return"
14052 [(use (match_operand 0 "general_operand"))]
14055 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
14059 ; We can't expand this before we know where the link register is stored.
14060 (define_insn_and_split "@eh_set_lr_<mode>"
14061 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
14062 (clobber (match_scratch:P 1 "=&b"))]
14068 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
14072 (define_insn "prefetch"
14073 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
14074 (match_operand:SI 1 "const_int_operand" "n")
14075 (match_operand:SI 2 "const_int_operand" "n"))]
14080 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
14081 AIX does not support the dcbtstt and dcbtt extended mnemonics.
14082 The AIX assembler does not support the three operand form of dcbt
14083 and dcbtst on Power 7 (-mpwr7). */
14084 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
14086 if (REG_P (operands[0]))
14088 if (INTVAL (operands[1]) == 0)
14089 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
14091 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
14095 if (INTVAL (operands[1]) == 0)
14096 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
14098 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
14101 [(set_attr "type" "load")])
14103 ;; Handle -fsplit-stack.
14105 (define_expand "split_stack_prologue"
14109 rs6000_expand_split_stack_prologue ();
14113 (define_expand "load_split_stack_limit"
14114 [(set (match_operand 0)
14115 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
14118 emit_insn (gen_rtx_SET (operands[0],
14119 gen_rtx_UNSPEC (Pmode,
14120 gen_rtvec (1, const0_rtx),
14121 UNSPEC_STACK_CHECK)));
14125 (define_insn "load_split_stack_limit_di"
14126 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
14127 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
14129 "ld %0,-0x7040(13)"
14130 [(set_attr "type" "load")
14131 (set_attr "update" "no")
14132 (set_attr "indexed" "no")])
14134 (define_insn "load_split_stack_limit_si"
14135 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14136 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
14138 "lwz %0,-0x7020(2)"
14139 [(set_attr "type" "load")
14140 (set_attr "update" "no")
14141 (set_attr "indexed" "no")])
14143 ;; A return instruction which the middle-end doesn't see.
14144 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
14145 ;; after the call to __morestack.
14146 (define_insn "split_stack_return"
14147 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
14150 [(set_attr "type" "jmpreg")])
14152 ;; If there are operand 0 bytes available on the stack, jump to
14154 (define_expand "split_stack_space_check"
14155 [(set (match_dup 2)
14156 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
14158 (minus (reg STACK_POINTER_REGNUM)
14159 (match_operand 0)))
14160 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
14161 (set (pc) (if_then_else
14162 (geu (match_dup 4) (const_int 0))
14163 (label_ref (match_operand 1))
14167 rs6000_split_stack_space_check (operands[0], operands[1]);
14171 (define_insn "bpermd_<mode>"
14172 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
14173 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
14174 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
14177 [(set_attr "type" "popcnt")])
14180 ;; Builtin fma support. Handle
14181 ;; Note that the conditions for expansion are in the FMA_F iterator.
14183 (define_expand "fma<mode>4"
14184 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14186 (match_operand:FMA_F 1 "gpc_reg_operand")
14187 (match_operand:FMA_F 2 "gpc_reg_operand")
14188 (match_operand:FMA_F 3 "gpc_reg_operand")))]
14192 (define_insn "*fma<mode>4_fpr"
14193 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14195 (match_operand:SFDF 1 "gpc_reg_operand" "%d,wa,wa")
14196 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14197 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa")))]
14198 "TARGET_HARD_FLOAT"
14200 fmadd<s> %0,%1,%2,%3
14201 xsmadda<sd>p %x0,%x1,%x2
14202 xsmaddm<sd>p %x0,%x1,%x3"
14203 [(set_attr "type" "fp")
14204 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14206 ; Altivec only has fma and nfms.
14207 (define_expand "fms<mode>4"
14208 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14210 (match_operand:FMA_F 1 "gpc_reg_operand")
14211 (match_operand:FMA_F 2 "gpc_reg_operand")
14212 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14213 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14216 (define_insn "*fms<mode>4_fpr"
14217 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14219 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14220 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14221 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa"))))]
14222 "TARGET_HARD_FLOAT"
14224 fmsub<s> %0,%1,%2,%3
14225 xsmsuba<sd>p %x0,%x1,%x2
14226 xsmsubm<sd>p %x0,%x1,%x3"
14227 [(set_attr "type" "fp")
14228 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14230 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
14231 (define_expand "fnma<mode>4"
14232 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14235 (match_operand:FMA_F 1 "gpc_reg_operand")
14236 (match_operand:FMA_F 2 "gpc_reg_operand")
14237 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
14238 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
14241 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
14242 (define_expand "fnms<mode>4"
14243 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14246 (match_operand:FMA_F 1 "gpc_reg_operand")
14247 (match_operand:FMA_F 2 "gpc_reg_operand")
14248 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14249 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14252 ; Not an official optab name, but used from builtins.
14253 (define_expand "nfma<mode>4"
14254 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14257 (match_operand:FMA_F 1 "gpc_reg_operand")
14258 (match_operand:FMA_F 2 "gpc_reg_operand")
14259 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
14260 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14263 (define_insn "*nfma<mode>4_fpr"
14264 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14267 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14268 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14269 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa"))))]
14270 "TARGET_HARD_FLOAT"
14272 fnmadd<s> %0,%1,%2,%3
14273 xsnmadda<sd>p %x0,%x1,%x2
14274 xsnmaddm<sd>p %x0,%x1,%x3"
14275 [(set_attr "type" "fp")
14276 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14278 ; Not an official optab name, but used from builtins.
14279 (define_expand "nfms<mode>4"
14280 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
14283 (match_operand:FMA_F 1 "gpc_reg_operand")
14284 (match_operand:FMA_F 2 "gpc_reg_operand")
14285 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
14289 (define_insn "*nfmssf4_fpr"
14290 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa,wa")
14293 (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")
14294 (match_operand:SFDF 2 "gpc_reg_operand" "d,wa,0")
14296 (match_operand:SFDF 3 "gpc_reg_operand" "d,0,wa")))))]
14297 "TARGET_HARD_FLOAT"
14299 fnmsub<s> %0,%1,%2,%3
14300 xsnmsuba<sd>p %x0,%x1,%x2
14301 xsnmsubm<sd>p %x0,%x1,%x3"
14302 [(set_attr "type" "fp")
14303 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14305 (define_expand "rs6000_get_timebase"
14306 [(use (match_operand:DI 0 "gpc_reg_operand"))]
14309 if (TARGET_POWERPC64)
14310 emit_insn (gen_rs6000_mftb_di (operands[0]));
14312 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
14316 (define_insn "rs6000_get_timebase_ppc32"
14317 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
14318 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
14319 (clobber (match_scratch:SI 1 "=r"))
14320 (clobber (match_scratch:CC 2 "=y"))]
14321 "!TARGET_POWERPC64"
14323 if (WORDS_BIG_ENDIAN)
14326 return "mfspr %0,269\;"
14334 return "mftbu %0\;"
14343 return "mfspr %L0,269\;"
14351 return "mftbu %L0\;"
14358 [(set_attr "length" "20")])
14360 (define_insn "rs6000_mftb_<mode>"
14361 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
14362 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
14366 return "mfspr %0,268";
14372 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
14373 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
14374 (define_insn "rs6000_mffsl_hw"
14375 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
14376 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
14377 "TARGET_HARD_FLOAT"
14380 (define_expand "rs6000_mffsl"
14381 [(set (match_operand:DF 0 "gpc_reg_operand")
14382 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
14383 "TARGET_HARD_FLOAT"
14385 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
14386 otherwise fall back to the older mffs instruction to emulate the mffsl
14389 if (!TARGET_P9_MISC)
14391 rtx tmp1 = gen_reg_rtx (DFmode);
14393 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
14394 instruction using the mffs instruction and masking the result. */
14395 emit_insn (gen_rs6000_mffs (tmp1));
14397 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
14398 rtx tmp2 = gen_reg_rtx (DImode);
14399 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
14401 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
14402 emit_move_insn (operands[0], tmp2df);
14406 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
14410 (define_insn "rs6000_mffs"
14411 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
14412 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
14413 "TARGET_HARD_FLOAT"
14416 (define_insn "rs6000_mtfsf"
14417 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
14418 (match_operand:DF 1 "gpc_reg_operand" "d")]
14420 "TARGET_HARD_FLOAT"
14423 (define_insn "rs6000_mtfsf_hi"
14424 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
14425 (match_operand:DF 1 "gpc_reg_operand" "d")]
14427 "TARGET_HARD_FLOAT"
14431 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
14432 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
14433 ;; register that is being loaded. The fused ops must be physically adjacent.
14435 ;; On Power8 GPR loads, we try to use the register that is being load. The
14436 ;; peephole2 then gathers any other fused possibilities that it can find after
14437 ;; register allocation. If power9 fusion is selected, we also fuse floating
14438 ;; point loads/stores.
14440 ;; Find cases where the addis that feeds into a load instruction is either used
14441 ;; once or is the same as the target register, and replace it with the fusion
14445 [(set (match_operand:P 0 "base_reg_operand")
14446 (match_operand:P 1 "fusion_gpr_addis"))
14447 (set (match_operand:INT1 2 "base_reg_operand")
14448 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
14450 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
14454 expand_fusion_gpr_load (operands);
14458 ;; Fusion insn, created by the define_peephole2 above (and eventually by
14461 (define_insn "*fusion_gpr_load_<mode>"
14462 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
14463 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
14464 UNSPEC_FUSION_GPR))]
14467 return emit_fusion_gpr_load (operands[0], operands[1]);
14469 [(set_attr "type" "load")
14470 (set_attr "length" "8")])
14473 ;; Optimize cases where we want to do a D-form load (register+offset) on
14474 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14479 ;; and we change this to:
14484 [(match_scratch:P 0 "b")
14485 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14486 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14487 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14489 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14490 [(set (match_dup 0)
14495 rtx tmp_reg = operands[0];
14496 rtx mem = operands[2];
14497 rtx addr = XEXP (mem, 0);
14498 rtx add_op0, add_op1, new_addr;
14500 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14501 add_op0 = XEXP (addr, 0);
14502 add_op1 = XEXP (addr, 1);
14503 gcc_assert (REG_P (add_op0));
14504 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14506 operands[4] = add_op1;
14507 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
14510 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14511 ;; Altivec register, and the register allocator has generated:
14515 ;; and we change this to:
14520 [(match_scratch:P 0 "b")
14521 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14522 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14523 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14525 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14526 [(set (match_dup 0)
14531 rtx tmp_reg = operands[0];
14532 rtx mem = operands[3];
14533 rtx addr = XEXP (mem, 0);
14534 rtx add_op0, add_op1, new_addr;
14536 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14537 add_op0 = XEXP (addr, 0);
14538 add_op1 = XEXP (addr, 1);
14539 gcc_assert (REG_P (add_op0));
14540 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14542 operands[4] = add_op1;
14543 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
14547 ;; Miscellaneous ISA 2.06 (power7) instructions
14548 (define_insn "addg6s"
14549 [(set (match_operand:SI 0 "register_operand" "=r")
14550 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14551 (match_operand:SI 2 "register_operand" "r")]
14555 [(set_attr "type" "integer")])
14557 (define_insn "cdtbcd"
14558 [(set (match_operand:SI 0 "register_operand" "=r")
14559 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14563 [(set_attr "type" "integer")])
14565 (define_insn "cbcdtd"
14566 [(set (match_operand:SI 0 "register_operand" "=r")
14567 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14571 [(set_attr "type" "integer")])
14573 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14576 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14577 (UNSPEC_DIVEU "eu")])
14579 (define_insn "div<div_extend>_<mode>"
14580 [(set (match_operand:GPR 0 "register_operand" "=r")
14581 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14582 (match_operand:GPR 2 "register_operand" "r")]
14583 UNSPEC_DIV_EXTEND))]
14585 "div<wd><div_extend> %0,%1,%2"
14586 [(set_attr "type" "div")
14587 (set_attr "size" "<bits>")])
14590 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14592 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14593 (define_mode_attr FP128_64 [(TF "DF")
14598 (define_expand "unpack<mode>"
14599 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
14601 [(match_operand:FMOVE128 1 "register_operand")
14602 (match_operand:QI 2 "const_0_to_1_operand")]
14603 UNSPEC_UNPACK_128BIT))]
14604 "FLOAT128_2REG_P (<MODE>mode)"
14607 (define_insn_and_split "unpack<mode>_dm"
14608 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14610 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14611 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14612 UNSPEC_UNPACK_128BIT))]
14613 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14615 "&& reload_completed"
14616 [(set (match_dup 0) (match_dup 3))]
14618 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14620 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14622 emit_note (NOTE_INSN_DELETED);
14626 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14628 [(set_attr "type" "fp,fpstore,mtvsr,mfvsr,store")])
14630 (define_insn_and_split "unpack<mode>_nodm"
14631 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,m")
14633 [(match_operand:FMOVE128 1 "register_operand" "d,d,r")
14634 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i")]
14635 UNSPEC_UNPACK_128BIT))]
14636 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14638 "&& reload_completed"
14639 [(set (match_dup 0) (match_dup 3))]
14641 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14643 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14645 emit_note (NOTE_INSN_DELETED);
14649 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14651 [(set_attr "type" "fp,fpstore,store")])
14653 (define_expand "pack<mode>"
14654 [(use (match_operand:FMOVE128 0 "register_operand"))
14655 (use (match_operand:<FP128_64> 1 "register_operand"))
14656 (use (match_operand:<FP128_64> 2 "register_operand"))]
14657 "FLOAT128_2REG_P (<MODE>mode)"
14659 if (TARGET_HARD_FLOAT)
14660 emit_insn (gen_pack<mode>_hard (operands[0], operands[1], operands[2]));
14662 emit_insn (gen_pack<mode>_soft (operands[0], operands[1], operands[2]));
14666 (define_insn_and_split "pack<mode>_hard"
14667 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
14669 [(match_operand:<FP128_64> 1 "register_operand" "d")
14670 (match_operand:<FP128_64> 2 "register_operand" "d")]
14671 UNSPEC_PACK_128BIT))]
14672 "FLOAT128_2REG_P (<MODE>mode) && TARGET_HARD_FLOAT"
14674 "&& reload_completed"
14675 [(set (match_dup 3) (match_dup 1))
14676 (set (match_dup 4) (match_dup 2))]
14678 unsigned dest_hi = REGNO (operands[0]);
14679 unsigned dest_lo = dest_hi + 1;
14681 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14682 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14684 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14685 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14687 [(set_attr "type" "fp")
14688 (set_attr "length" "8")])
14690 (define_insn_and_split "pack<mode>_soft"
14691 [(set (match_operand:FMOVE128 0 "register_operand" "=&r")
14693 [(match_operand:<FP128_64> 1 "register_operand" "r")
14694 (match_operand:<FP128_64> 2 "register_operand" "r")]
14695 UNSPEC_PACK_128BIT))]
14696 "FLOAT128_2REG_P (<MODE>mode) && TARGET_SOFT_FLOAT"
14698 "&& reload_completed"
14699 [(set (match_dup 3) (match_dup 1))
14700 (set (match_dup 4) (match_dup 2))]
14702 unsigned dest_hi = REGNO (operands[0]);
14703 unsigned dest_lo = dest_hi + (TARGET_POWERPC64 ? 1 : 2);
14705 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14706 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14708 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14709 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14711 [(set_attr "type" "integer")
14712 (set (attr "length")
14714 (match_test "TARGET_POWERPC64")
14716 (const_string "16")))])
14718 (define_insn "unpack<mode>"
14719 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14720 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14721 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14722 UNSPEC_UNPACK_128BIT))]
14723 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14725 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14726 return ASM_COMMENT_START " xxpermdi to same register";
14728 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14729 return "xxpermdi %x0,%x1,%x1,%3";
14731 [(set_attr "type" "vecperm")])
14733 (define_insn "pack<mode>"
14734 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14735 (unspec:FMOVE128_VSX
14736 [(match_operand:DI 1 "register_operand" "wa")
14737 (match_operand:DI 2 "register_operand" "wa")]
14738 UNSPEC_PACK_128BIT))]
14740 "xxpermdi %x0,%x1,%x2,0"
14741 [(set_attr "type" "vecperm")])
14745 ;; ISA 2.08 IEEE 128-bit floating point support.
14747 (define_insn "add<mode>3"
14748 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14750 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14751 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14752 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14754 [(set_attr "type" "vecfloat")
14755 (set_attr "size" "128")])
14757 (define_insn "sub<mode>3"
14758 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14760 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14761 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14762 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14764 [(set_attr "type" "vecfloat")
14765 (set_attr "size" "128")])
14767 (define_insn "mul<mode>3"
14768 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14770 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14771 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14772 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14774 [(set_attr "type" "qmul")
14775 (set_attr "size" "128")])
14777 (define_insn "div<mode>3"
14778 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14780 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14781 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14782 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14784 [(set_attr "type" "vecdiv")
14785 (set_attr "size" "128")])
14787 (define_insn "sqrt<mode>2"
14788 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14790 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14791 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14793 [(set_attr "type" "vecdiv")
14794 (set_attr "size" "128")])
14796 (define_expand "copysign<mode>3"
14797 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14798 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14799 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14800 "FLOAT128_IEEE_P (<MODE>mode)"
14802 if (TARGET_FLOAT128_HW)
14803 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14806 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14811 (define_insn "copysign<mode>3_hard"
14812 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14814 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14815 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14817 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14818 "xscpsgnqp %0,%2,%1"
14819 [(set_attr "type" "vecmove")
14820 (set_attr "size" "128")])
14822 (define_insn "copysign<mode>3_soft"
14823 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14825 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14826 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14828 (clobber (match_scratch:IEEE128 3 "=&v"))]
14829 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14830 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14831 [(set_attr "type" "veccomplex")
14832 (set_attr "length" "8")])
14834 (define_insn "@neg<mode>2_hw"
14835 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14837 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14838 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14840 [(set_attr "type" "vecmove")
14841 (set_attr "size" "128")])
14844 (define_insn "@abs<mode>2_hw"
14845 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14847 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14848 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14850 [(set_attr "type" "vecmove")
14851 (set_attr "size" "128")])
14854 (define_insn "*nabs<mode>2_hw"
14855 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14858 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14859 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14861 [(set_attr "type" "vecmove")
14862 (set_attr "size" "128")])
14864 ;; Initially don't worry about doing fusion
14865 (define_insn "fma<mode>4_hw"
14866 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14868 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14869 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14870 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14871 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14872 "xsmaddqp %0,%1,%2"
14873 [(set_attr "type" "qmul")
14874 (set_attr "size" "128")])
14876 (define_insn "*fms<mode>4_hw"
14877 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14879 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14880 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14882 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14883 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14884 "xsmsubqp %0,%1,%2"
14885 [(set_attr "type" "qmul")
14886 (set_attr "size" "128")])
14888 (define_insn "*nfma<mode>4_hw"
14889 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14892 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14893 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14894 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14895 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14896 "xsnmaddqp %0,%1,%2"
14897 [(set_attr "type" "qmul")
14898 (set_attr "size" "128")])
14900 (define_insn "*nfms<mode>4_hw"
14901 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14904 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14905 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14907 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14908 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14909 "xsnmsubqp %0,%1,%2"
14910 [(set_attr "type" "qmul")
14911 (set_attr "size" "128")])
14913 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14914 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14915 (float_extend:IEEE128
14916 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14917 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14919 [(set_attr "type" "vecfloat")
14920 (set_attr "size" "128")])
14922 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14923 ;; point is a simple copy.
14924 (define_insn_and_split "extendkftf2"
14925 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14926 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14927 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14931 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14934 emit_note (NOTE_INSN_DELETED);
14937 [(set_attr "type" "*,veclogical")
14938 (set_attr "length" "0,4")])
14940 (define_insn_and_split "trunctfkf2"
14941 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14942 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14943 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14947 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14950 emit_note (NOTE_INSN_DELETED);
14953 [(set_attr "type" "*,veclogical")
14954 (set_attr "length" "0,4")])
14956 (define_insn "trunc<mode>df2_hw"
14957 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14959 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14960 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14962 [(set_attr "type" "vecfloat")
14963 (set_attr "size" "128")])
14965 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14966 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14968 (define_insn_and_split "trunc<mode>sf2_hw"
14969 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14971 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14972 (clobber (match_scratch:DF 2 "=v"))]
14973 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14976 [(set (match_dup 2)
14977 (unspec:DF [(match_dup 1)]
14978 UNSPEC_TRUNC_ROUND_TO_ODD))
14980 (float_truncate:SF (match_dup 2)))]
14982 if (GET_CODE (operands[2]) == SCRATCH)
14983 operands[2] = gen_reg_rtx (DFmode);
14985 [(set_attr "type" "vecfloat")
14986 (set_attr "length" "8")
14987 (set_attr "isa" "p8v")])
14989 ;; Conversion between IEEE 128-bit and integer types
14991 ;; The fix function for DImode and SImode was declared earlier as a
14992 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14993 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14994 ;; unless we have the IEEE 128-bit hardware.
14996 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14997 ;; to provide a GPR target that used direct move and a conversion in the GPR
14998 ;; which works around QImode/HImode not being allowed in vector registers in
14999 ;; ISA 2.07 (power8).
15000 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
15001 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
15002 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15003 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15004 "xscvqp<su><wd>z %0,%1"
15005 [(set_attr "type" "vecfloat")
15006 (set_attr "size" "128")])
15008 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
15009 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
15011 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
15012 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15013 "xscvqp<su>wz %0,%1"
15014 [(set_attr "type" "vecfloat")
15015 (set_attr "size" "128")])
15017 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
15018 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
15019 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
15020 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
15022 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
15023 (clobber (match_scratch:QHSI 2 "=v"))]
15024 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15026 "&& reload_completed"
15027 [(set (match_dup 2)
15028 (any_fix:QHSI (match_dup 1)))
15032 (define_insn "float_<mode>di2_hw"
15033 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15034 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
15035 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15037 [(set_attr "type" "vecfloat")
15038 (set_attr "size" "128")])
15040 (define_insn_and_split "float_<mode>si2_hw"
15041 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15042 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
15043 (clobber (match_scratch:DI 2 "=v"))]
15044 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15047 [(set (match_dup 2)
15048 (sign_extend:DI (match_dup 1)))
15050 (float:IEEE128 (match_dup 2)))]
15052 if (GET_CODE (operands[2]) == SCRATCH)
15053 operands[2] = gen_reg_rtx (DImode);
15055 if (MEM_P (operands[1]))
15056 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
15059 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
15060 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
15061 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
15062 (clobber (match_scratch:DI 2 "=X,r,X"))]
15063 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15065 "&& reload_completed"
15068 rtx dest = operands[0];
15069 rtx src = operands[1];
15070 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
15072 if (altivec_register_operand (src, <QHI:MODE>mode))
15073 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
15074 else if (int_reg_operand (src, <QHI:MODE>mode))
15076 rtx ext_di = operands[2];
15077 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
15078 emit_move_insn (dest_di, ext_di);
15080 else if (MEM_P (src))
15082 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
15083 emit_move_insn (dest_qhi, src);
15084 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
15087 gcc_unreachable ();
15089 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
15092 [(set_attr "length" "8,12,12")
15093 (set_attr "type" "vecfloat")
15094 (set_attr "size" "128")])
15096 (define_insn "floatuns_<mode>di2_hw"
15097 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15098 (unsigned_float:IEEE128
15099 (match_operand:DI 1 "altivec_register_operand" "v")))]
15100 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15102 [(set_attr "type" "vecfloat")
15103 (set_attr "size" "128")])
15105 (define_insn_and_split "floatuns_<mode>si2_hw"
15106 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15107 (unsigned_float:IEEE128
15108 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
15109 (clobber (match_scratch:DI 2 "=v"))]
15110 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15113 [(set (match_dup 2)
15114 (zero_extend:DI (match_dup 1)))
15116 (float:IEEE128 (match_dup 2)))]
15118 if (GET_CODE (operands[2]) == SCRATCH)
15119 operands[2] = gen_reg_rtx (DImode);
15121 if (MEM_P (operands[1]))
15122 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
15125 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
15126 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
15127 (unsigned_float:IEEE128
15128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
15129 (clobber (match_scratch:DI 2 "=X,r,X"))]
15130 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15132 "&& reload_completed"
15135 rtx dest = operands[0];
15136 rtx src = operands[1];
15137 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
15139 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
15140 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
15141 else if (int_reg_operand (src, <QHI:MODE>mode))
15143 rtx ext_di = operands[2];
15144 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
15145 emit_move_insn (dest_di, ext_di);
15148 gcc_unreachable ();
15150 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
15153 [(set_attr "length" "8,12,8")
15154 (set_attr "type" "vecfloat")
15155 (set_attr "size" "128")])
15157 ;; IEEE 128-bit round to integer built-in functions
15158 (define_insn "floor<mode>2"
15159 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15161 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15163 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15165 [(set_attr "type" "vecfloat")
15166 (set_attr "size" "128")])
15168 (define_insn "ceil<mode>2"
15169 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15171 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15173 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15175 [(set_attr "type" "vecfloat")
15176 (set_attr "size" "128")])
15178 (define_insn "btrunc<mode>2"
15179 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15181 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15183 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15185 [(set_attr "type" "vecfloat")
15186 (set_attr "size" "128")])
15188 (define_insn "round<mode>2"
15189 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15191 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15193 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15195 [(set_attr "type" "vecfloat")
15196 (set_attr "size" "128")])
15198 ;; IEEE 128-bit instructions with round to odd semantics
15199 (define_insn "add<mode>3_odd"
15200 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15202 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15203 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15204 UNSPEC_ADD_ROUND_TO_ODD))]
15205 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15206 "xsaddqpo %0,%1,%2"
15207 [(set_attr "type" "vecfloat")
15208 (set_attr "size" "128")])
15210 (define_insn "sub<mode>3_odd"
15211 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15213 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15214 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15215 UNSPEC_SUB_ROUND_TO_ODD))]
15216 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15217 "xssubqpo %0,%1,%2"
15218 [(set_attr "type" "vecfloat")
15219 (set_attr "size" "128")])
15221 (define_insn "mul<mode>3_odd"
15222 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15224 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15225 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15226 UNSPEC_MUL_ROUND_TO_ODD))]
15227 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15228 "xsmulqpo %0,%1,%2"
15229 [(set_attr "type" "qmul")
15230 (set_attr "size" "128")])
15232 (define_insn "div<mode>3_odd"
15233 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15235 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15236 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
15237 UNSPEC_DIV_ROUND_TO_ODD))]
15238 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15239 "xsdivqpo %0,%1,%2"
15240 [(set_attr "type" "vecdiv")
15241 (set_attr "size" "128")])
15243 (define_insn "sqrt<mode>2_odd"
15244 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15246 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15247 UNSPEC_SQRT_ROUND_TO_ODD))]
15248 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15250 [(set_attr "type" "vecdiv")
15251 (set_attr "size" "128")])
15253 (define_insn "fma<mode>4_odd"
15254 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15256 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
15257 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15258 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
15259 UNSPEC_FMA_ROUND_TO_ODD))]
15260 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15261 "xsmaddqpo %0,%1,%2"
15262 [(set_attr "type" "qmul")
15263 (set_attr "size" "128")])
15265 (define_insn "*fms<mode>4_odd"
15266 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15268 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15269 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15271 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
15272 UNSPEC_FMA_ROUND_TO_ODD))]
15273 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15274 "xsmsubqpo %0,%1,%2"
15275 [(set_attr "type" "qmul")
15276 (set_attr "size" "128")])
15278 (define_insn "*nfma<mode>4_odd"
15279 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15282 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15283 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15284 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
15285 UNSPEC_FMA_ROUND_TO_ODD)))]
15286 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15287 "xsnmaddqpo %0,%1,%2"
15288 [(set_attr "type" "qmul")
15289 (set_attr "size" "128")])
15291 (define_insn "*nfms<mode>4_odd"
15292 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
15295 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
15296 (match_operand:IEEE128 2 "altivec_register_operand" "v")
15298 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
15299 UNSPEC_FMA_ROUND_TO_ODD)))]
15300 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15301 "xsnmsubqpo %0,%1,%2"
15302 [(set_attr "type" "qmul")
15303 (set_attr "size" "128")])
15305 (define_insn "trunc<mode>df2_odd"
15306 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
15307 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
15308 UNSPEC_TRUNC_ROUND_TO_ODD))]
15309 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15311 [(set_attr "type" "vecfloat")
15312 (set_attr "size" "128")])
15314 ;; IEEE 128-bit comparisons
15315 (define_insn "*cmp<mode>_hw"
15316 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
15317 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
15318 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
15319 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15320 "xscmpuqp %0,%1,%2"
15321 [(set_attr "type" "veccmp")
15322 (set_attr "size" "128")])
15324 ;; Miscellaneous ISA 3.0 (power9) instructions
15326 (define_expand "darn_32_<mode>"
15327 [(use (match_operand:GPR 0 "register_operand"))]
15330 emit_insn (gen_darn (<MODE>mode, operands[0], const0_rtx));
15334 (define_expand "darn_64_<mode>"
15335 [(use (match_operand:GPR 0 "register_operand"))]
15338 emit_insn (gen_darn (<MODE>mode, operands[0], const1_rtx));
15342 (define_expand "darn_raw_<mode>"
15343 [(use (match_operand:GPR 0 "register_operand"))]
15346 emit_insn (gen_darn (<MODE>mode, operands[0], const2_rtx));
15350 (define_insn "@darn<mode>"
15351 [(set (match_operand:GPR 0 "register_operand" "=r")
15352 (unspec_volatile:GPR [(match_operand 1 "const_int_operand" "n")]
15356 [(set_attr "type" "integer")])
15358 ;; Test byte within range.
15360 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15361 ;; represents a byte whose value is ignored in this context and
15362 ;; vv, the least significant byte, holds the byte value that is to
15363 ;; be tested for membership within the range specified by operand 2.
15364 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
15366 ;; Return in target register operand 0 a value of 1 if lo <= vv and
15367 ;; vv <= hi. Otherwise, set register operand 0 to 0.
15369 ;; Though the instructions to which this expansion maps operate on
15370 ;; 64-bit registers, the current implementation only operates on
15371 ;; SI-mode operands as the high-order bits provide no information
15372 ;; that is not already available in the low-order bits. To avoid the
15373 ;; costs of data widening operations, future enhancements might allow
15374 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15375 (define_expand "cmprb"
15376 [(set (match_dup 3)
15377 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15378 (match_operand:SI 2 "gpc_reg_operand" "r")]
15380 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15381 (if_then_else:SI (lt (match_dup 3)
15384 (if_then_else (gt (match_dup 3)
15390 operands[3] = gen_reg_rtx (CCmode);
15393 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15394 ;; represents a byte whose value is ignored in this context and
15395 ;; vv, the least significant byte, holds the byte value that is to
15396 ;; be tested for membership within the range specified by operand 2.
15397 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
15399 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
15400 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
15401 ;; 3 bits of the target CR register are all set to 0.
15402 (define_insn "*cmprb_internal"
15403 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15404 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15405 (match_operand:SI 2 "gpc_reg_operand" "r")]
15409 [(set_attr "type" "logical")])
15411 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
15412 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
15413 ;; if the GT bit (0x4) of condition register operand 1 is on.
15414 ;; Otherwise, set operand 0 to 0. Note that the result stored into
15415 ;; register operand 0 is non-zero iff either the LT or GT bits are on
15416 ;; within condition register operand 1.
15417 (define_insn "setb_signed"
15418 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
15419 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
15422 (if_then_else (gt (match_dup 1)
15428 [(set_attr "type" "logical")])
15430 (define_insn "setb_unsigned"
15431 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
15432 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
15435 (if_then_else (gtu (match_dup 1)
15441 [(set_attr "type" "logical")])
15443 ;; Test byte within two ranges.
15445 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15446 ;; represents a byte whose value is ignored in this context and
15447 ;; vv, the least significant byte, holds the byte value that is to
15448 ;; be tested for membership within the range specified by operand 2.
15449 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
15451 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
15452 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
15455 ;; Though the instructions to which this expansion maps operate on
15456 ;; 64-bit registers, the current implementation only operates on
15457 ;; SI-mode operands as the high-order bits provide no information
15458 ;; that is not already available in the low-order bits. To avoid the
15459 ;; costs of data widening operations, future enhancements might allow
15460 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15461 (define_expand "cmprb2"
15462 [(set (match_dup 3)
15463 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15464 (match_operand:SI 2 "gpc_reg_operand" "r")]
15466 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15467 (if_then_else:SI (lt (match_dup 3)
15470 (if_then_else (gt (match_dup 3)
15476 operands[3] = gen_reg_rtx (CCmode);
15479 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15480 ;; represents a byte whose value is ignored in this context and
15481 ;; vv, the least significant byte, holds the byte value that is to
15482 ;; be tested for membership within the ranges specified by operand 2.
15483 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
15485 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
15486 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
15487 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
15488 ;; CR register are all set to 0.
15489 (define_insn "*cmprb2_internal"
15490 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15491 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15492 (match_operand:SI 2 "gpc_reg_operand" "r")]
15496 [(set_attr "type" "logical")])
15498 ;; Test byte membership within set of 8 bytes.
15500 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15501 ;; represents a byte whose value is ignored in this context and
15502 ;; vv, the least significant byte, holds the byte value that is to
15503 ;; be tested for membership within the set specified by operand 2.
15504 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
15506 ;; Return in target register operand 0 a value of 1 if vv equals one
15507 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
15508 ;; register operand 0 to 0. Note that the 8 byte values held within
15509 ;; operand 2 need not be unique.
15511 ;; Though the instructions to which this expansion maps operate on
15512 ;; 64-bit registers, the current implementation requires that operands
15513 ;; 0 and 1 have mode SI as the high-order bits provide no information
15514 ;; that is not already available in the low-order bits. To avoid the
15515 ;; costs of data widening operations, future enhancements might allow
15516 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
15517 (define_expand "cmpeqb"
15518 [(set (match_dup 3)
15519 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15520 (match_operand:DI 2 "gpc_reg_operand" "r")]
15522 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
15523 (if_then_else:SI (lt (match_dup 3)
15526 (if_then_else (gt (match_dup 3)
15530 "TARGET_P9_MISC && TARGET_64BIT"
15532 operands[3] = gen_reg_rtx (CCmode);
15535 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
15536 ;; represents a byte whose value is ignored in this context and
15537 ;; vv, the least significant byte, holds the byte value that is to
15538 ;; be tested for membership within the set specified by operand 2.
15539 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
15541 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
15542 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
15543 ;; set the GT bit to zero. The other 3 bits of the target CR register
15544 ;; are all set to 0.
15545 (define_insn "*cmpeqb_internal"
15546 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
15547 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
15548 (match_operand:DI 2 "gpc_reg_operand" "r")]
15550 "TARGET_P9_MISC && TARGET_64BIT"
15552 [(set_attr "type" "logical")])
15555 ;; ROP mitigation instructions.
15557 (define_insn "hashst"
15558 [(set (match_operand:DI 0 "simple_offsettable_mem_operand" "=m")
15559 (unspec_volatile:DI [(match_operand:DI 1 "int_reg_operand" "r")]
15561 "TARGET_POWER10 && rs6000_rop_protect"
15563 static char templ[32];
15564 const char *p = rs6000_privileged ? "p" : "";
15565 sprintf (templ, "hashst%s %%1,%%0", p);
15568 [(set_attr "type" "store")])
15570 (define_insn "hashchk"
15571 [(unspec_volatile [(match_operand:DI 0 "int_reg_operand" "r")
15572 (match_operand:DI 1 "simple_offsettable_mem_operand" "m")]
15574 "TARGET_POWER10 && rs6000_rop_protect"
15576 static char templ[32];
15577 const char *p = rs6000_privileged ? "p" : "";
15578 sprintf (templ, "hashchk%s %%0,%%1", p);
15581 [(set_attr "type" "load")])
15584 (include "sync.md")
15585 (include "vector.md")
15587 (include "altivec.md")
15590 (include "crypto.md")
15592 (include "fusion.md")
15593 (include "pcrel-opt.md")