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")])
7769 (define_code_iterator eqne [eq ne])
7771 ;; "i == C" ==> "rotl(i,N) == rotl(C,N)"
7772 (define_insn_and_split "*rotate_on_cmpdi"
7774 (if_then_else (eqne (match_operand:DI
1 "gpc_reg_operand" "r")
7775 (match_operand:DI
2 "const_int_operand" "n"))
7776 (label_ref (match_operand
0 ""))
7778 (clobber (match_scratch:DI
3 "=r"))
7779 (clobber (match_scratch:CCUNS
4 "=y"))]
7780 "TARGET_POWERPC64 && num_insns_constant (operands[
2], DImode) >
1
7781 && (can_be_rotated_to_positive_16bits (INTVAL (operands[
2]))
7782 || can_be_rotated_to_negative_15bits (INTVAL (operands[
2])))"
7788 unsigned HOST_WIDE_INT C = INTVAL (operands[
2]);
7792 if (!can_be_rotated_to_lowbits (C,
16, &rot))
7796 bool res = can_be_rotated_to_lowbits (~C,
15, &rot);
7800 rtx n = GEN_INT (rot);
7802 /* i' = rotl (i, n) */
7803 rtx op0 = can_create_pseudo_p () ? gen_reg_rtx (DImode) : operands[
3];
7804 emit_insn (gen_rtx_SET (op0, gen_rtx_ROTATE (DImode, operands[
1], n)));
7806 /* C' = rotl (C, n) */
7807 rtx op1 = GEN_INT ((C << rot) | (C >> (HOST_BITS_PER_WIDE_INT - rot)));
7810 machine_mode comp_mode = sgn ? CCmode : CCUNSmode;
7811 rtx cc = can_create_pseudo_p () ? gen_reg_rtx (comp_mode) : operands[
4];
7812 PUT_MODE (cc, comp_mode);
7813 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (comp_mode, op0, op1)));
7814 rtx cmp = gen_rtx_<eqne:CODE> (CCmode, cc, const0_rtx);
7815 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[
0]);
7816 emit_jump_insn (gen_rtx_SET (pc_rtx,
7817 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
7820 /* Keep the probability info for the prediction of the branch insn. */
7821 rtx note = find_reg_note (curr_insn, REG_BR_PROB,
0);
7824 profile_probability prob
7825 = profile_probability::from_reg_br_prob_note (XINT (note,
0));
7827 add_reg_br_prob_note (get_last_insn (), prob);
7833 ;; Split a load of a large constant into the appropriate two-insn
7837 [(set (match_operand:SI
0 "gpc_reg_operand")
7838 (match_operand:SI
1 "const_int_operand"))]
7839 "num_insns_constant (operands[
1], SImode) >
1"
7842 if (rs6000_emit_set_const (operands[
0], operands[
1]))
7848 ;; Split loading -
128.
.127 to use XXSPLITB and VEXTSW2D
7850 [(set (match_operand:DI
0 "altivec_register_operand")
7851 (match_operand:DI
1 "xxspltib_constant_split"))]
7852 "TARGET_P9_VECTOR && reload_completed"
7855 rtx op0 = operands[
0];
7856 rtx op1 = operands[
1];
7857 int r = REGNO (op0);
7858 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7860 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7861 emit_insn (gen_vsx_sign_extend_qi_si (operands[
0], op0_v16qi));
7865 (define_insn "*mov<mode>_internal2"
7866 [(set (match_operand:CC
2 "cc_reg_operand" "=y,x,?y")
7867 (compare:CC (match_operand:P
1 "gpc_reg_operand" "
0,r,r")
7869 (set (match_operand:P
0 "gpc_reg_operand" "=r,r,r") (match_dup
1))]
7875 [(set_attr "type" "cmp,logical,cmp")
7876 (set_attr "dot" "yes")
7877 (set_attr "length" "
4,
4,
8")])
7880 [(set (match_operand:CC
2 "cc_reg_not_cr0_operand")
7881 (compare:CC (match_operand:P
1 "gpc_reg_operand")
7883 (set (match_operand:P
0 "gpc_reg_operand") (match_dup
1))]
7885 [(set (match_dup
0) (match_dup
1))
7887 (compare:CC (match_dup
0)
7891 (define_expand "mov<mode>"
7892 [(set (match_operand:INT
0 "general_operand")
7893 (match_operand:INT
1 "any_operand"))]
7896 rs6000_emit_move (operands[
0], operands[
1], <MODE>mode);
7900 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7901 ;; XXLOR load
0 load -
1 VSPLTI* # MFVSRWZ
7902 ;; MTVSRWZ MF%
1 MT%
1 NOP
7903 (define_insn "*mov<mode>_internal"
7904 [(set (match_operand:QHI
0 "nonimmediate_operand"
7905 "=r, r, wa, m, ?Z, r,
7906 wa, wa, wa, v, ?v, r,
7908 (match_operand:QHI
1 "input_operand"
7909 "r, m, ?Z, r, wa, i,
7910 wa, O, wM, wB, wS, wa,
7912 "gpc_reg_operand (operands[
0], <MODE>mode)
7913 || gpc_reg_operand (operands[
1], <MODE>mode)"
7932 "*, load, fpload, store, fpstore, *,
7933 vecsimple, vecperm, vecperm, vecperm, vecperm, mfvsr,
7934 mtvsr, mfjmpr, mtjmpr, *")
7940 "*, *, p9v, *, p9v, *,
7941 p9v, p9v, p9v, p9v, p9v, p9v,
7945 ;; Here is how to move condition codes around. When we store CC data in
7946 ;; an integer register or memory, we store just the high-order
4 bits.
7947 ;; This lets us not shift in the most common case of CR0.
7948 (define_expand "movcc"
7949 [(set (match_operand:CC
0 "nonimmediate_operand")
7950 (match_operand:CC
1 "nonimmediate_operand"))]
7954 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7956 (define_insn "*movcc_<mode>"
7957 [(set (match_operand:CC_any
0 "nonimmediate_operand"
7958 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7959 (match_operand:CC_any
1 "general_operand"
7960 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7961 "register_operand (operands[
0], <MODE>mode)
7962 || register_operand (operands[
1], <MODE>mode)"
7966 rlwinm %
1,%
1,%F0,
0xffffffff\;mtcrf %R0,%
1\;rlwinm %
1,%
1,%f0,
0xffffffff
7969 mfcr %
0%Q1\;rlwinm %
0,%
0,%f1,
0xf0000000
7976 [(set_attr_alternative "type"
7977 [(const_string "cr_logical")
7978 (const_string "mtcr")
7979 (const_string "mtcr")
7980 (const_string "cr_logical")
7981 (if_then_else (match_test "TARGET_MFCRF")
7982 (const_string "mfcrf") (const_string "mfcr"))
7983 (if_then_else (match_test "TARGET_MFCRF")
7984 (const_string "mfcrf") (const_string "mfcr"))
7985 (const_string "integer")
7986 (const_string "integer")
7987 (const_string "mfjmpr")
7988 (const_string "mtjmpr")
7989 (const_string "load")
7990 (const_string "store")])
7991 (set_attr "length" "*,*,
12,*,*,
8,*,*,*,*,*,*")])
7993 ;; For floating-point, we normally deal with the floating-point registers
7994 ;; unless -msoft-float is used. The sole exception is that parameter passing
7995 ;; can produce floating-point values in fixed-point registers. Unless the
7996 ;; value is a simple constant or already in memory, we deal with this by
7997 ;; allocating memory and copying the value explicitly via that memory location.
7999 ;; Move
32-bit binary/decimal floating point
8000 (define_expand "mov<mode>"
8001 [(set (match_operand:FMOVE32
0 "nonimmediate_operand")
8002 (match_operand:FMOVE32
1 "any_operand"))]
8005 rs6000_emit_move (operands[
0], operands[
1], <MODE>mode);
8010 [(set (match_operand:FMOVE32
0 "gpc_reg_operand")
8011 (match_operand:FMOVE32
1 "const_double_operand"))]
8013 && ((REG_P (operands[
0]) && REGNO (operands[
0]) <=
31)
8014 || (SUBREG_P (operands[
0])
8015 && REG_P (SUBREG_REG (operands[
0]))
8016 && REGNO (SUBREG_REG (operands[
0])) <=
31))"
8017 [(set (match_dup
2) (match_dup
3))]
8021 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[
1]), l);
8023 if (! TARGET_POWERPC64)
8024 operands[
2] = operand_subword (operands[
0],
0,
0, <MODE>mode);
8026 operands[
2] = gen_lowpart (SImode, operands[
0]);
8028 operands[
3] = gen_int_mode (l, SImode);
8031 ;; Originally, we tried to keep movsf and movsd common, but the differences
8032 ;; addressing was making it rather difficult to hide with mode attributes. In
8033 ;; particular for SFmode, on ISA
2.07 (power8) systems, having the GPR store
8034 ;; before the VSX stores meant that the register allocator would tend to do a
8035 ;; direct move to the GPR (which involves conversion from scalar to
8036 ;; vector/memory formats) to save values in the traditional Altivec registers,
8037 ;; while SDmode had problems on power6 if the GPR store was not first due to
8038 ;; the power6 not having an integer store operation.
8040 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
8041 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
8042 ;; MR MT<x> MF<x> NOP XXSPLTIDP
8044 (define_insn "movsf_hardfloat"
8045 [(set (match_operand:SF
0 "nonimmediate_operand"
8046 "=!r, f, v, wa, m, wY,
8047 Z, m, wa, !r, f, wa,
8048 !r, *c*l, !r, *h, wa")
8049 (match_operand:SF
1 "input_operand"
8053 "(register_operand (operands[
0], SFmode)
8054 || register_operand (operands[
1], SFmode))
8055 && TARGET_HARD_FLOAT
8056 && (TARGET_ALLOW_SF_SUBREG
8057 || valid_sf_si_move (operands[
0], operands[
1], SFmode))"
8070 xscpsgndp %x0,%x1,%x1
8077 "load, fpload, fpload, fpload, fpstore, fpstore,
8078 fpstore, store, veclogical, integer, fpsimple, fpsimple,
8079 *, mtjmpr, mfjmpr, *, vecperm")
8081 "*, *, p9v, p8v, *, p9v,
8084 (set_attr "prefixed"
8089 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
8090 ;; FMR MR MT%
0 MF%
1 NOP
8091 (define_insn "movsd_hardfloat"
8092 [(set (match_operand:SD
0 "nonimmediate_operand"
8093 "=!r, d, m, ?Z, ?d, ?r,
8094 f, !r, *c*l, !r, *h")
8095 (match_operand:SD
1 "input_operand"
8096 "m, ?Z, r, wx, r, d,
8098 "(register_operand (operands[
0], SDmode)
8099 || register_operand (operands[
1], SDmode))
8100 && TARGET_HARD_FLOAT"
8114 "load, fpload, store, fpstore, mtvsr, mfvsr,
8115 fpsimple, *, mtjmpr, mfjmpr, *")
8117 "*, p7, *, *, p8v, p8v,
8120 ;; MR MT%
0 MF%
0 LWZ STW LI
8121 ;; LIS G-const. F/n-const NOP
8122 (define_insn "*mov<mode>_softfloat"
8123 [(set (match_operand:FMOVE32
0 "nonimmediate_operand"
8124 "=r, *c*l, r, r, m, r,
8127 (match_operand:FMOVE32
1 "input_operand"
8131 "(gpc_reg_operand (operands[
0], <MODE>mode)
8132 || gpc_reg_operand (operands[
1], <MODE>mode))
8133 && TARGET_SOFT_FLOAT"
8146 "*, mtjmpr, mfjmpr, load, store, *,
8153 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
8154 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...)
0))
8156 ;; Because SF values are actually stored as DF values within the vector
8157 ;; registers, we need to convert the value to the vector SF format when
8158 ;; we need to use the bits in a union or similar cases. We only need
8159 ;; to do this transformation when the value is a vector register. Loads,
8160 ;; stores, and transfers within GPRs are assumed to be safe.
8162 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
8163 ;; no alternatives, because the call is created as part of secondary_reload,
8164 ;; and operand #
2's register class is used to allocate the temporary register.
8165 ;; This function is called before reload, and it creates the temporary as
8168 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
8169 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
8170 (define_insn_and_split "movsf_from_si"
8171 [(set (match_operand:SF
0 "nonimmediate_operand"
8172 "=!r, f, v, wa, m, Z,
8174 (unspec:SF [(match_operand:SI
1 "input_operand"
8178 (clobber (match_scratch:DI
2
8181 "TARGET_NO_SF_SUBREG
8182 && (register_operand (operands[
0], SFmode)
8183 || register_operand (operands[
1], SImode))"
8196 "&& reload_completed
8197 && vsx_reg_sfsubreg_ok (operands[
0], SFmode)
8198 && int_reg_operand_not_pseudo (operands[
1], SImode)"
8201 rtx op0 = operands[
0];
8202 rtx op1 = operands[
1];
8203 rtx op2 = operands[
2];
8204 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
8206 /* Move SF value to upper
32-bits for xscvspdpn. */
8207 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (
32)));
8208 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8209 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8216 "load, fpload, fpload, fpload, store, fpstore,
8217 fpstore, vecfloat, mfvsr, *")
8219 "*, *, p9v, p8v, *, *,
8220 p8v, p8v, p8v, *")])
8222 ;; For extracting high part element from DImode register like:
8223 ;; {%
1:SF=unspec[r122:DI>>
0x20#
0]
86;clobber scratch;}
8224 ;; split it before reload with "and mask" to avoid generating shift right
8225 ;;
32 bit then shift left
32 bit.
8226 (define_insn_and_split "movsf_from_si2"
8227 [(set (match_operand:SF
0 "gpc_reg_operand" "=wa")
8231 (match_operand:DI
1 "input_operand" "r")
8235 (clobber (match_scratch:DI
2 "=r"))]
8236 "TARGET_NO_SF_SUBREG"
8241 if (GET_CODE (operands[
2]) == SCRATCH)
8242 operands[
2] = gen_reg_rtx (DImode);
8244 rtx mask = GEN_INT (HOST_WIDE_INT_M1U <<
32);
8245 emit_insn (gen_anddi3 (operands[
2], operands[
1], mask));
8246 emit_insn (gen_p8_mtvsrd_sf (operands[
0], operands[
2]));
8247 emit_insn (gen_vsx_xscvspdpn_directmove (operands[
0], operands[
0]));
8250 [(set_attr "length" "
12")
8251 (set_attr "type" "vecfloat")
8252 (set_attr "isa" "p8v")])
8254 ;; Move
64-bit binary/decimal floating point
8255 (define_expand "mov<mode>"
8256 [(set (match_operand:FMOVE64
0 "nonimmediate_operand")
8257 (match_operand:FMOVE64
1 "any_operand"))]
8260 rs6000_emit_move (operands[
0], operands[
1], <MODE>mode);
8265 [(set (match_operand:FMOVE64
0 "gpc_reg_operand")
8266 (match_operand:FMOVE64
1 "const_int_operand"))]
8267 "! TARGET_POWERPC64 && reload_completed
8268 && ((REG_P (operands[
0]) && REGNO (operands[
0]) <=
31)
8269 || (SUBREG_P (operands[
0])
8270 && REG_P (SUBREG_REG (operands[
0]))
8271 && REGNO (SUBREG_REG (operands[
0])) <=
31))"
8272 [(set (match_dup
2) (match_dup
4))
8273 (set (match_dup
3) (match_dup
1))]
8275 int endian = (WORDS_BIG_ENDIAN ==
0);
8276 HOST_WIDE_INT value = INTVAL (operands[
1]);
8278 operands[
2] = operand_subword (operands[
0], endian,
0, <MODE>mode);
8279 operands[
3] = operand_subword (operands[
0],
1 - endian,
0, <MODE>mode);
8280 operands[
4] = GEN_INT (value >>
32);
8281 operands[
1] = GEN_INT (sext_hwi (value,
32));
8285 [(set (match_operand:FMOVE64
0 "gpc_reg_operand")
8286 (match_operand:FMOVE64
1 "const_double_operand"))]
8287 "! TARGET_POWERPC64 && reload_completed
8288 && ((REG_P (operands[
0]) && REGNO (operands[
0]) <=
31)
8289 || (SUBREG_P (operands[
0])
8290 && REG_P (SUBREG_REG (operands[
0]))
8291 && REGNO (SUBREG_REG (operands[
0])) <=
31))"
8292 [(set (match_dup
2) (match_dup
4))
8293 (set (match_dup
3) (match_dup
5))]
8295 int endian = (WORDS_BIG_ENDIAN ==
0);
8298 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[
1]), l);
8300 operands[
2] = operand_subword (operands[
0], endian,
0, <MODE>mode);
8301 operands[
3] = operand_subword (operands[
0],
1 - endian,
0, <MODE>mode);
8302 operands[
4] = gen_int_mode (l[endian], SImode);
8303 operands[
5] = gen_int_mode (l[
1 - endian], SImode);
8307 [(set (match_operand:FMOVE64
0 "gpc_reg_operand")
8308 (match_operand:FMOVE64
1 "const_double_operand"))]
8309 "TARGET_POWERPC64 && reload_completed
8310 && ((REG_P (operands[
0]) && REGNO (operands[
0]) <=
31)
8311 || (SUBREG_P (operands[
0])
8312 && REG_P (SUBREG_REG (operands[
0]))
8313 && REGNO (SUBREG_REG (operands[
0])) <=
31))"
8314 [(set (match_dup
2) (match_dup
3))]
8316 int endian = (WORDS_BIG_ENDIAN ==
0);
8320 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[
1]), l);
8322 operands[
2] = gen_lowpart (DImode, operands[
0]);
8323 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
8324 val = ((HOST_WIDE_INT)(unsigned long)l[endian] <<
32
8325 | ((HOST_WIDE_INT)(unsigned long)l[
1 - endian]));
8327 operands[
3] = gen_int_mode (val, DImode);
8330 ;; Don't have reload use general registers to load a constant. It is
8331 ;; less efficient than loading the constant into an FP register, since
8332 ;; it will probably be used there.
8334 ;; The move constraints are ordered to prefer floating point registers before
8335 ;; general purpose registers to avoid doing a store and a load to get the value
8336 ;; into a floating point register when it is needed for a floating point
8337 ;; operation. Prefer traditional floating point registers over VSX registers,
8338 ;; since the D-form version of the memory instructions does not need a GPR for
8339 ;; reloading. ISA
3.0 (power9) adds D-form addressing for scalars to Altivec
8342 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
8343 ;; except for
0.0 which can be created on VSX with an xor instruction.
8345 ;; STFD LFD FMR LXSD STXSD
8346 ;; LXSD STXSD XXLOR XXLXOR GPR<-
0
8347 ;; LWZ STW MR XXSPLTIDP
8350 (define_insn "*mov<mode>_hardfloat32"
8351 [(set (match_operand:FMOVE64
0 "nonimmediate_operand"
8352 "=m, d, d, <f64_p9>, wY,
8353 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
8355 (match_operand:FMOVE64
1 "input_operand"
8356 "d, m, d, wY, <f64_p9>,
8357 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
8359 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
8360 && (gpc_reg_operand (operands[
0], <MODE>mode)
8361 || gpc_reg_operand (operands[
1], <MODE>mode))"
8378 "fpstore, fpload, fpsimple, fpload, fpstore,
8379 fpload, fpstore, veclogical, veclogical, two,
8380 store, load, two, vecperm")
8381 (set_attr "size" "
64")
8390 (set_attr "prefixed"
8395 ;; STW LWZ MR G-const H-const F-const
8397 (define_insn "*mov<mode>_softfloat32"
8398 [(set (match_operand:FMOVE64
0 "nonimmediate_operand"
8399 "=Y, r, r, r, r, r")
8401 (match_operand:FMOVE64
1 "input_operand"
8402 "r, Y, r, G, H, F"))]
8405 && (gpc_reg_operand (operands[
0], <MODE>mode)
8406 || gpc_reg_operand (operands[
1], <MODE>mode))"
8409 "store, load, two, *, *, *")
8412 "
8,
8,
8,
8,
12,
16")])
8414 ; ld/std require word-aligned displacements -> 'Y' constraint.
8415 ; List Y->r and r->Y before r->r for reload.
8417 ;; STFD LFD FMR LXSD STXSD
8418 ;; LXSDX STXSDX XXLOR XXLXOR LI
0
8419 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
8420 ;; NOP MFVSRD MTVSRD XXSPLTIDP
8422 (define_insn "*mov<mode>_hardfloat64"
8423 [(set (match_operand:FMOVE64
0 "nonimmediate_operand"
8424 "=m, d, d, <f64_p9>, wY,
8425 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
8426 YZ, r, !r, *c*l, !r,
8427 *h, r, <f64_dm>, wa")
8428 (match_operand:FMOVE64
1 "input_operand"
8429 "d, m, d, wY, <f64_p9>,
8430 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
8432 0, <f64_dm>, r, eP"))]
8433 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
8434 && (gpc_reg_operand (operands[
0], <MODE>mode)
8435 || gpc_reg_operand (operands[
1], <MODE>mode))"
8457 "fpstore, fpload, fpsimple, fpload, fpstore,
8458 fpload, fpstore, veclogical, veclogical, integer,
8459 store, load, *, mtjmpr, mfjmpr,
8460 *, mfvsr, mtvsr, vecperm")
8461 (set_attr "size" "
64")
8467 (set_attr "prefixed"
8473 ;; STD LD MR MT<SPR> MF<SPR> G-const
8474 ;; H-const F-const Special
8476 (define_insn "*mov<mode>_softfloat64"
8477 [(set (match_operand:FMOVE64
0 "nonimmediate_operand"
8478 "=Y, r, r, *c*l, r, r,
8481 (match_operand:FMOVE64
1 "input_operand"
8485 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
8486 && (gpc_reg_operand (operands[
0], <MODE>mode)
8487 || gpc_reg_operand (operands[
1], <MODE>mode))"
8499 "store, load, *, mtjmpr, mfjmpr, *,
8506 ;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
8507 ;; constants that look like DFmode floating point values where both elements
8508 ;; are the same. The constant has to be expressible as a SFmode constant that
8509 ;; is not a SFmode denormal value.
8511 ;; We don't need splitters for the
128-bit types, since the function
8512 ;; rs6000_output_move_128bit handles the generation of XXSPLTIDP.
8513 (define_insn "xxspltidp_<mode>_internal"
8514 [(set (match_operand:SFDF
0 "register_operand" "=wa")
8515 (unspec:SFDF [(match_operand:SI
1 "c32bit_cint_operand" "n")]
8516 UNSPEC_XXSPLTIDP_CONST))]
8519 [(set_attr "type" "vecperm")
8520 (set_attr "prefixed" "yes")])
8522 (define_insn "xxspltiw_<mode>_internal"
8523 [(set (match_operand:SFDF
0 "register_operand" "=wa")
8524 (unspec:SFDF [(match_operand:SI
1 "c32bit_cint_operand" "n")]
8525 UNSPEC_XXSPLTIW_CONST))]
8528 [(set_attr "type" "vecperm")
8529 (set_attr "prefixed" "yes")])
8532 [(set (match_operand:SFDF
0 "vsx_register_operand")
8533 (match_operand:SFDF
1 "vsx_prefixed_constant"))]
8537 rtx dest = operands[
0];
8538 rtx src = operands[
1];
8539 vec_const_128bit_type vsx_const;
8541 if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const))
8544 unsigned imm = constant_generates_xxspltidp (&vsx_const);
8547 emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm)));
8551 imm = constant_generates_xxspltiw (&vsx_const);
8554 emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm)));
8562 (define_expand "mov<mode>"
8563 [(set (match_operand:FMOVE128
0 "general_operand")
8564 (match_operand:FMOVE128
1 "any_operand"))]
8567 rs6000_emit_move (operands[
0], operands[
1], <MODE>mode);
8571 ;; It's important to list Y->r and r->Y before r->r because otherwise
8572 ;; reload, given m->r, will try to pick r->r and reload it, which
8573 ;; doesn't make progress.
8575 ;; We can't split little endian direct moves of TDmode, because the words are
8576 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
8577 ;; problematical. Don't allow direct move for this case.
8579 ;; FPR load FPR store FPR move FPR zero GPR load
8580 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
8582 (define_insn_and_split "*mov<mode>_64bit_dm"
8583 [(set (match_operand:FMOVE128_FPR
0 "nonimmediate_operand"
8587 (match_operand:FMOVE128_FPR
1 "input_operand"
8588 "d, m, d, <zero_fp>, r,
8589 <zero_fp>, Y, r, d, r"))]
8591 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
8592 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
8593 && (gpc_reg_operand (operands[
0], <MODE>mode)
8594 || gpc_reg_operand (operands[
1], <MODE>mode))"
8596 "&& reload_completed"
8599 rs6000_split_multireg_move (operands[
0], operands[
1]);
8602 [(set_attr "length" "
8")
8603 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
8604 (set_attr "max_prefixed_insns" "
2")
8605 (set_attr "num_insns" "
2")])
8607 (define_insn_and_split "*movtd_64bit_nodm"
8608 [(set (match_operand:TD
0 "nonimmediate_operand" "=m,d,d,Y,r,r")
8609 (match_operand:TD
1 "input_operand" "d,m,d,r,Y,r"))]
8610 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
8611 && (gpc_reg_operand (operands[
0], TDmode)
8612 || gpc_reg_operand (operands[
1], TDmode))"
8614 "&& reload_completed"
8617 rs6000_split_multireg_move (operands[
0], operands[
1]);
8620 [(set_attr "length" "
8,
8,
8,
12,
12,
8")
8621 (set_attr "max_prefixed_insns" "
2")
8622 (set_attr "num_insns" "
2,
2,
2,
3,
3,
2")])
8624 (define_insn_and_split "*mov<mode>_32bit"
8625 [(set (match_operand:FMOVE128_FPR
0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
8626 (match_operand:FMOVE128_FPR
1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
8627 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
8628 && (FLOAT128_2REG_P (<MODE>mode)
8629 || int_reg_operand_not_pseudo (operands[
0], <MODE>mode)
8630 || int_reg_operand_not_pseudo (operands[
1], <MODE>mode))
8631 && (gpc_reg_operand (operands[
0], <MODE>mode)
8632 || gpc_reg_operand (operands[
1], <MODE>mode))"
8634 "&& reload_completed"
8637 rs6000_split_multireg_move (operands[
0], operands[
1]);
8640 [(set_attr "length" "
8,
8,
8,
8,
20,
20,
16")])
8642 (define_insn_and_split "*mov<mode>_softfloat"
8643 [(set (match_operand:FMOVE128
0 "nonimmediate_operand" "=Y,r,r,r")
8644 (match_operand:FMOVE128
1 "input_operand" "r,Y,F,r"))]
8646 && (gpc_reg_operand (operands[
0], <MODE>mode)
8647 || gpc_reg_operand (operands[
1], <MODE>mode))"
8649 "&& reload_completed"
8652 rs6000_split_multireg_move (operands[
0], operands[
1]);
8655 [(set_attr_alternative "length"
8656 [(if_then_else (match_test "TARGET_POWERPC64")
8658 (const_string "
16"))
8659 (if_then_else (match_test "TARGET_POWERPC64")
8661 (const_string "
16"))
8662 (if_then_else (match_test "TARGET_POWERPC64")
8664 (const_string "
32"))
8665 (if_then_else (match_test "TARGET_POWERPC64")
8667 (const_string "
16"))])])
8669 (define_expand "@extenddf<mode>
2"
8670 [(set (match_operand:FLOAT128
0 "gpc_reg_operand")
8671 (float_extend:FLOAT128 (match_operand:DF
1 "gpc_reg_operand")))]
8672 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8674 if (FLOAT128_IEEE_P (<MODE>mode))
8675 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8676 else if (TARGET_VSX)
8677 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[
0], operands[
1]));
8680 rtx zero = gen_reg_rtx (DFmode);
8681 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
8683 emit_insn (gen_extenddf2_fprs (<MODE>mode,
8684 operands[
0], operands[
1], zero));
8689 ;; Allow memory operands for the source to be created by the combiner.
8690 (define_insn_and_split "@extenddf<mode>
2_fprs"
8691 [(set (match_operand:IBM128
0 "gpc_reg_operand" "=d,d,&d")
8692 (float_extend:IBM128
8693 (match_operand:DF
1 "nonimmediate_operand" "d,m,d")))
8694 (use (match_operand:DF
2 "nonimmediate_operand" "m,m,d"))]
8695 "!TARGET_VSX && TARGET_HARD_FLOAT
8696 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
8698 "&& reload_completed"
8699 [(set (match_dup
3) (match_dup
1))
8700 (set (match_dup
4) (match_dup
2))]
8702 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) :
0;
8703 const int hi_word = LONG_DOUBLE_LARGE_FIRST ?
0 : GET_MODE_SIZE (DFmode);
8705 operands[
3] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, hi_word);
8706 operands[
4] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, lo_word);
8709 (define_insn_and_split "@extenddf<mode>
2_vsx"
8710 [(set (match_operand:IBM128
0 "gpc_reg_operand" "=d,d")
8711 (float_extend:IBM128
8712 (match_operand:DF
1 "nonimmediate_operand" "wa,m")))]
8713 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
8715 "&& reload_completed"
8716 [(set (match_dup
2) (match_dup
1))
8717 (set (match_dup
3) (match_dup
4))]
8719 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) :
0;
8720 const int hi_word = LONG_DOUBLE_LARGE_FIRST ?
0 : GET_MODE_SIZE (DFmode);
8722 operands[
2] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, hi_word);
8723 operands[
3] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, lo_word);
8724 operands[
4] = CONST0_RTX (DFmode);
8727 (define_expand "extendsf<mode>
2"
8728 [(set (match_operand:FLOAT128
0 "gpc_reg_operand")
8729 (float_extend:FLOAT128 (match_operand:SF
1 "gpc_reg_operand")))]
8730 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8732 if (FLOAT128_IEEE_P (<MODE>mode))
8733 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8736 rtx tmp = gen_reg_rtx (DFmode);
8737 emit_insn (gen_extendsfdf2 (tmp, operands[
1]));
8738 emit_insn (gen_extenddf<mode>
2 (operands[
0], tmp));
8743 (define_expand "trunc<mode>df2"
8744 [(set (match_operand:DF
0 "gpc_reg_operand")
8745 (float_truncate:DF (match_operand:FLOAT128
1 "gpc_reg_operand")))]
8746 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8748 if (FLOAT128_IEEE_P (<MODE>mode))
8750 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8755 (define_insn_and_split "trunc<mode>df2_internal1"
8756 [(set (match_operand:DF
0 "gpc_reg_operand" "=d,?d")
8758 (match_operand:IBM128
1 "gpc_reg_operand" "
0,d")))]
8759 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
8760 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8764 "&& reload_completed && REGNO (operands[
0]) == REGNO (operands[
1])"
8767 emit_note (NOTE_INSN_DELETED);
8770 [(set_attr "type" "fpsimple")])
8772 (define_insn "trunc<mode>df2_internal2"
8773 [(set (match_operand:DF
0 "gpc_reg_operand" "=d")
8774 (float_truncate:DF (match_operand:IBM128
1 "gpc_reg_operand" "d")))]
8775 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8776 && TARGET_LONG_DOUBLE_128"
8778 [(set_attr "type" "fp")])
8780 (define_expand "trunc<mode>sf2"
8781 [(set (match_operand:SF
0 "gpc_reg_operand")
8782 (float_truncate:SF (match_operand:FLOAT128
1 "gpc_reg_operand")))]
8783 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8785 if (FLOAT128_IEEE_P (<MODE>mode))
8786 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8789 rtx tmp = gen_reg_rtx (DFmode);
8790 emit_insn (gen_trunc<mode>df2 (tmp, operands[
1]));
8791 emit_insn (gen_truncdfsf2 (operands[
0], tmp));
8796 (define_expand "floatsi<mode>
2"
8797 [(parallel [(set (match_operand:FLOAT128
0 "gpc_reg_operand")
8798 (float:FLOAT128 (match_operand:SI
1 "gpc_reg_operand")))
8799 (clobber (match_scratch:DI
2))])]
8800 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8802 rtx op0 = operands[
0];
8803 rtx op1 = operands[
1];
8805 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8807 else if (FLOAT128_IEEE_P (<MODE>mode))
8809 rs6000_expand_float128_convert (op0, op1, false);
8814 rtx tmp = gen_reg_rtx (DFmode);
8815 expand_float (tmp, op1, false);
8816 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8821 ; fadd, but rounding towards zero.
8822 ; This is probably not the optimal code sequence.
8823 (define_insn "fix_trunc_helper<mode>"
8824 [(set (match_operand:DF
0 "gpc_reg_operand" "=d")
8825 (unspec:DF [(match_operand:IBM128
1 "gpc_reg_operand" "d")]
8826 UNSPEC_FIX_TRUNC_TF))
8827 (clobber (match_operand:DF
2 "gpc_reg_operand" "=&d"))]
8828 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8829 "mffs %
2\n\tmtfsb
1 31\n\tmtfsb
0 30\n\tfadd %
0,%
1,%L1
\n\tmtfsf
1,%
2"
8830 [(set_attr "type" "fp")
8831 (set_attr "length" "
20")])
8833 (define_expand "fix_trunc<mode>si2"
8834 [(set (match_operand:SI
0 "gpc_reg_operand")
8835 (fix:SI (match_operand:FLOAT128
1 "gpc_reg_operand")))]
8836 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8838 rtx op0 = operands[
0];
8839 rtx op1 = operands[
1];
8841 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8845 if (FLOAT128_IEEE_P (<MODE>mode))
8846 rs6000_expand_float128_convert (op0, op1, false);
8848 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8853 (define_expand "@fix_trunc<mode>si2_fprs"
8854 [(parallel [(set (match_operand:SI
0 "gpc_reg_operand")
8855 (fix:SI (match_operand:IBM128
1 "gpc_reg_operand")))
8856 (clobber (match_dup
2))
8857 (clobber (match_dup
3))
8858 (clobber (match_dup
4))
8859 (clobber (match_dup
5))])]
8860 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8862 operands[
2] = gen_reg_rtx (DFmode);
8863 operands[
3] = gen_reg_rtx (DFmode);
8864 operands[
4] = gen_reg_rtx (DImode);
8865 operands[
5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8868 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8869 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
8870 (fix:SI (match_operand:IBM128
1 "gpc_reg_operand" "d")))
8871 (clobber (match_operand:DF
2 "gpc_reg_operand" "=d"))
8872 (clobber (match_operand:DF
3 "gpc_reg_operand" "=&d"))
8873 (clobber (match_operand:DI
4 "gpc_reg_operand" "=d"))
8874 (clobber (match_operand:DI
5 "offsettable_mem_operand" "=o"))]
8875 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8881 emit_insn (gen_fix_trunc_helper<mode> (operands[
2], operands[
1],
8884 gcc_assert (MEM_P (operands[
5]));
8885 lowword = adjust_address (operands[
5], SImode, WORDS_BIG_ENDIAN ?
4 :
0);
8887 emit_insn (gen_fctiwz_df (operands[
4], operands[
2]));
8888 emit_move_insn (operands[
5], operands[
4]);
8889 emit_move_insn (operands[
0], lowword);
8893 (define_expand "fix_trunc<mode>di2"
8894 [(set (match_operand:DI
0 "gpc_reg_operand")
8895 (fix:DI (match_operand:IEEE128
1 "gpc_reg_operand")))]
8896 "TARGET_FLOAT128_TYPE"
8898 if (!TARGET_FLOAT128_HW)
8900 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8905 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>
2"
8906 [(set (match_operand:SDI
0 "gpc_reg_operand")
8907 (unsigned_fix:SDI (match_operand:IEEE128
1 "gpc_reg_operand")))]
8908 "TARGET_FLOAT128_TYPE"
8910 rs6000_expand_float128_convert (operands[
0], operands[
1], true);
8914 (define_expand "floatdi<mode>
2"
8915 [(set (match_operand:IEEE128
0 "gpc_reg_operand")
8916 (float:IEEE128 (match_operand:DI
1 "gpc_reg_operand")))]
8917 "TARGET_FLOAT128_TYPE"
8919 if (!TARGET_FLOAT128_HW)
8921 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8926 (define_expand "floatunsdi<IEEE128:mode>
2"
8927 [(set (match_operand:IEEE128
0 "gpc_reg_operand")
8928 (unsigned_float:IEEE128 (match_operand:DI
1 "gpc_reg_operand")))]
8929 "TARGET_FLOAT128_TYPE"
8931 if (!TARGET_FLOAT128_HW)
8933 rs6000_expand_float128_convert (operands[
0], operands[
1], true);
8938 (define_expand "floatuns<IEEE128:mode>
2"
8939 [(set (match_operand:IEEE128
0 "gpc_reg_operand")
8940 (unsigned_float:IEEE128 (match_operand:SI
1 "gpc_reg_operand")))]
8941 "TARGET_FLOAT128_TYPE"
8943 rtx op0 = operands[
0];
8944 rtx op1 = operands[
1];
8946 if (TARGET_FLOAT128_HW)
8947 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8949 rs6000_expand_float128_convert (op0, op1, true);
8953 (define_expand "neg<mode>
2"
8954 [(set (match_operand:FLOAT128
0 "gpc_reg_operand")
8955 (neg:FLOAT128 (match_operand:FLOAT128
1 "gpc_reg_operand")))]
8956 "FLOAT128_IEEE_P (<MODE>mode)
8957 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8959 if (FLOAT128_IEEE_P (<MODE>mode))
8961 if (TARGET_FLOAT128_HW)
8962 emit_insn (gen_neg2_hw (<MODE>mode, operands[
0], operands[
1]));
8963 else if (TARGET_FLOAT128_TYPE)
8964 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8965 operands[
0], operands[
1]));
8968 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8969 rtx target = emit_library_call_value (libfunc, operands[
0], LCT_CONST,
8971 operands[
1], <MODE>mode);
8973 if (target && !rtx_equal_p (target, operands[
0]))
8974 emit_move_insn (operands[
0], target);
8980 (define_insn "neg<mode>
2_internal"
8981 [(set (match_operand:IBM128
0 "gpc_reg_operand" "=d")
8982 (neg:IBM128 (match_operand:IBM128
1 "gpc_reg_operand" "d")))]
8983 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8985 if (REGNO (operands[
0]) == REGNO (operands[
1]) +
1)
8986 return "fneg %L0,%L1\;fneg %
0,%
1";
8988 return "fneg %
0,%
1\;fneg %L0,%L1";
8990 [(set_attr "type" "fpsimple")
8991 (set_attr "length" "
8")])
8993 (define_expand "abs<mode>
2"
8994 [(set (match_operand:FLOAT128
0 "gpc_reg_operand")
8995 (abs:FLOAT128 (match_operand:FLOAT128
1 "gpc_reg_operand")))]
8996 "FLOAT128_IEEE_P (<MODE>mode)
8997 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
9001 if (FLOAT128_IEEE_P (<MODE>mode))
9003 if (TARGET_FLOAT128_HW)
9005 emit_insn (gen_abs2_hw (<MODE>mode, operands[
0], operands[
1]));
9008 else if (TARGET_FLOAT128_TYPE)
9010 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
9011 operands[
0], operands[
1]));
9018 label = gen_label_rtx ();
9019 emit_insn (gen_abs2_internal (<MODE>mode, operands[
0], operands[
1], label));
9024 (define_expand "@abs<mode>
2_internal"
9025 [(set (match_operand:IBM128
0 "gpc_reg_operand")
9026 (match_operand:IBM128
1 "gpc_reg_operand"))
9027 (set (match_dup
3) (match_dup
5))
9028 (set (match_dup
5) (abs:DF (match_dup
5)))
9029 (set (match_dup
4) (compare:CCFP (match_dup
3) (match_dup
5)))
9030 (set (pc) (if_then_else (eq (match_dup
4) (const_int
0))
9031 (label_ref (match_operand
2 ""))
9033 (set (match_dup
6) (neg:DF (match_dup
6)))]
9034 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
9036 const int hi_word = LONG_DOUBLE_LARGE_FIRST ?
0 : GET_MODE_SIZE (DFmode);
9037 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) :
0;
9038 operands[
3] = gen_reg_rtx (DFmode);
9039 operands[
4] = gen_reg_rtx (CCFPmode);
9040 operands[
5] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, hi_word);
9041 operands[
6] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, lo_word);
9045 ;; Generate IEEE
128-bit -
0.0 (
0x80000000000000000000000000000000) in a vector
9048 (define_expand "ieee_128bit_negative_zero"
9049 [(set (match_operand:V16QI
0 "register_operand") (match_dup
1))]
9050 "TARGET_FLOAT128_TYPE"
9052 rtvec v = rtvec_alloc (
16);
9055 for (i =
0; i <
16; i++)
9056 RTVEC_ELT (v, i) = const0_rtx;
9058 high = (BYTES_BIG_ENDIAN) ?
0 :
15;
9059 RTVEC_ELT (v, high) = gen_int_mode (
0x80, QImode);
9061 rs6000_expand_vector_init (operands[
0], gen_rtx_PARALLEL (V16QImode, v));
9065 ;; IEEE
128-bit negate
9067 ;; We have
2 insns here for negate and absolute value. The first uses
9068 ;; match_scratch so that phases like combine can recognize neg/abs as generic
9069 ;; insns, and second insn after the first split pass loads up the bit to
9070 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
9071 ;; neg/abs to create the constant just once.
9073 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>
2"
9074 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
9075 (neg:IEEE128 (match_operand:IEEE128
1 "register_operand" "wa")))
9076 (clobber (match_scratch:V16QI
2 "=v"))]
9077 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9080 [(parallel [(set (match_dup
0)
9081 (neg:IEEE128 (match_dup
1)))
9082 (use (match_dup
2))])]
9084 if (GET_CODE (operands[
2]) == SCRATCH)
9085 operands[
2] = gen_reg_rtx (V16QImode);
9087 operands[
3] = gen_reg_rtx (V16QImode);
9088 emit_insn (gen_ieee_128bit_negative_zero (operands[
2]));
9090 [(set_attr "length" "
8")
9091 (set_attr "type" "vecsimple")])
9093 (define_insn "*ieee_128bit_vsx_neg<mode>
2_internal"
9094 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
9095 (neg:IEEE128 (match_operand:IEEE128
1 "register_operand" "wa")))
9096 (use (match_operand:V16QI
2 "register_operand" "v"))]
9097 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9098 "xxlxor %x0,%x1,%x2"
9099 [(set_attr "type" "veclogical")])
9101 ;; IEEE
128-bit absolute value
9102 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>
2"
9103 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
9104 (abs:IEEE128 (match_operand:IEEE128
1 "register_operand" "wa")))
9105 (clobber (match_scratch:V16QI
2 "=v"))]
9106 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
9109 [(parallel [(set (match_dup
0)
9110 (abs:IEEE128 (match_dup
1)))
9111 (use (match_dup
2))])]
9113 if (GET_CODE (operands[
2]) == SCRATCH)
9114 operands[
2] = gen_reg_rtx (V16QImode);
9116 operands[
3] = gen_reg_rtx (V16QImode);
9117 emit_insn (gen_ieee_128bit_negative_zero (operands[
2]));
9119 [(set_attr "length" "
8")
9120 (set_attr "type" "vecsimple")])
9122 (define_insn "*ieee_128bit_vsx_abs<mode>
2_internal"
9123 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
9124 (abs:IEEE128 (match_operand:IEEE128
1 "register_operand" "wa")))
9125 (use (match_operand:V16QI
2 "register_operand" "v"))]
9126 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9127 "xxlandc %x0,%x1,%x2"
9128 [(set_attr "type" "veclogical")])
9130 ;; IEEE
128-bit negative absolute value
9131 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>
2"
9132 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
9135 (match_operand:IEEE128
1 "register_operand" "wa"))))
9136 (clobber (match_scratch:V16QI
2 "=v"))]
9137 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
9138 && FLOAT128_IEEE_P (<MODE>mode)"
9141 [(parallel [(set (match_dup
0)
9142 (neg:IEEE128 (abs:IEEE128 (match_dup
1))))
9143 (use (match_dup
2))])]
9145 if (GET_CODE (operands[
2]) == SCRATCH)
9146 operands[
2] = gen_reg_rtx (V16QImode);
9148 operands[
3] = gen_reg_rtx (V16QImode);
9149 emit_insn (gen_ieee_128bit_negative_zero (operands[
2]));
9151 [(set_attr "length" "
8")
9152 (set_attr "type" "vecsimple")])
9154 (define_insn "*ieee_128bit_vsx_nabs<mode>
2_internal"
9155 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
9158 (match_operand:IEEE128
1 "register_operand" "wa"))))
9159 (use (match_operand:V16QI
2 "register_operand" "v"))]
9160 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
9162 [(set_attr "type" "veclogical")])
9164 ;; Float128 conversion functions. These expand to library function calls.
9165 ;; We use expand to convert from IBM double double to IEEE
128-bit
9166 ;; and trunc for the opposite.
9167 (define_expand "extendiftf2"
9168 [(set (match_operand:TF
0 "gpc_reg_operand")
9169 (float_extend:TF (match_operand:IF
1 "gpc_reg_operand")))]
9170 "TARGET_FLOAT128_TYPE"
9172 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
9176 (define_expand "extendifkf2"
9177 [(set (match_operand:KF
0 "gpc_reg_operand")
9178 (float_extend:KF (match_operand:IF
1 "gpc_reg_operand")))]
9179 "TARGET_FLOAT128_TYPE"
9181 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
9185 (define_expand "extendtfkf2"
9186 [(set (match_operand:KF
0 "gpc_reg_operand")
9187 (float_extend:KF (match_operand:TF
1 "gpc_reg_operand")))]
9188 "TARGET_FLOAT128_TYPE"
9190 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
9194 (define_expand "extendtfif2"
9195 [(set (match_operand:IF
0 "gpc_reg_operand")
9196 (float_extend:IF (match_operand:TF
1 "gpc_reg_operand")))]
9197 "TARGET_FLOAT128_TYPE"
9199 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
9203 (define_expand "trunciftf2"
9204 [(set (match_operand:TF
0 "gpc_reg_operand")
9205 (float_truncate:TF (match_operand:IF
1 "gpc_reg_operand")))]
9206 "TARGET_FLOAT128_TYPE"
9208 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
9212 (define_expand "truncifkf2"
9213 [(set (match_operand:KF
0 "gpc_reg_operand")
9214 (float_truncate:KF (match_operand:IF
1 "gpc_reg_operand")))]
9215 "TARGET_FLOAT128_TYPE"
9217 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
9221 (define_expand "trunckftf2"
9222 [(set (match_operand:TF
0 "gpc_reg_operand")
9223 (float_truncate:TF (match_operand:KF
1 "gpc_reg_operand")))]
9224 "TARGET_FLOAT128_TYPE"
9226 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
9230 (define_expand "trunctfif2"
9231 [(set (match_operand:IF
0 "gpc_reg_operand")
9232 (float_truncate:IF (match_operand:TF
1 "gpc_reg_operand")))]
9233 "TARGET_FLOAT128_TYPE"
9235 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
9239 (define_insn_and_split "*extend<mode>tf2_internal"
9240 [(set (match_operand:TF
0 "gpc_reg_operand" "=<IFKF_reg>")
9242 (match_operand:IFKF
1 "gpc_reg_operand" "<IFKF_reg>")))]
9243 "TARGET_FLOAT128_TYPE
9244 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
9246 "&& reload_completed"
9247 [(set (match_dup
0) (match_dup
2))]
9249 operands[
2] = gen_rtx_REG (TFmode, REGNO (operands[
1]));
9252 (define_insn_and_split "*extendtf<mode>
2_internal"
9253 [(set (match_operand:IFKF
0 "gpc_reg_operand" "=<IFKF_reg>")
9255 (match_operand:TF
1 "gpc_reg_operand" "<IFKF_reg>")))]
9256 "TARGET_FLOAT128_TYPE
9257 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
9259 "&& reload_completed"
9260 [(set (match_dup
0) (match_dup
2))]
9262 operands[
2] = gen_rtx_REG (<MODE>mode, REGNO (operands[
1]));
9266 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
9267 ;; must have
3 arguments, and scratch register constraint must be a single
9270 ;; Reload patterns to support gpr load/store with misaligned mem.
9271 ;; and multiple gpr load/store at offset >=
0xfffc
9272 (define_expand "reload_<mode>_store"
9273 [(parallel [(match_operand
0 "memory_operand" "=m")
9274 (match_operand
1 "gpc_reg_operand" "r")
9275 (match_operand:GPR
2 "register_operand" "=&b")])]
9278 rs6000_secondary_reload_gpr (operands[
1], operands[
0], operands[
2], true);
9282 (define_expand "reload_<mode>_load"
9283 [(parallel [(match_operand
0 "gpc_reg_operand" "=r")
9284 (match_operand
1 "memory_operand" "m")
9285 (match_operand:GPR
2 "register_operand" "=b")])]
9288 rs6000_secondary_reload_gpr (operands[
0], operands[
1], operands[
2], false);
9293 ;; Reload patterns for various types using the vector registers. We may need
9294 ;; an additional base register to convert the reg+offset addressing to reg+reg
9295 ;; for vector registers and reg+reg or (reg+reg)&(-
16) addressing to just an
9296 ;; index register for gpr registers.
9297 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
9298 [(parallel [(match_operand:RELOAD
0 "memory_operand" "m")
9299 (match_operand:RELOAD
1 "gpc_reg_operand" "wa")
9300 (match_operand:P
2 "register_operand" "=b")])]
9303 rs6000_secondary_reload_inner (operands[
1], operands[
0], operands[
2], true);
9307 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
9308 [(parallel [(match_operand:RELOAD
0 "gpc_reg_operand" "wa")
9309 (match_operand:RELOAD
1 "memory_operand" "m")
9310 (match_operand:P
2 "register_operand" "=b")])]
9313 rs6000_secondary_reload_inner (operands[
0], operands[
1], operands[
2], false);
9318 ;; Reload sometimes tries to move the address to a GPR, and can generate
9319 ;; invalid RTL for addresses involving AND -
16. Allow addresses involving
9320 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -
16.
9322 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
9323 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9324 (and:P (plus:P (match_operand:P
1 "gpc_reg_operand" "r")
9325 (match_operand:P
2 "reg_or_cint_operand" "rI"))
9327 "TARGET_ALTIVEC && reload_completed"
9329 "&& reload_completed"
9331 (plus:P (match_dup
1)
9334 (and:P (match_dup
0)
9337 ;; Power8 merge instructions to allow direct move to/from floating point
9338 ;; registers in
32-bit mode. We use TF mode to get two registers to move the
9339 ;; individual
32-bit parts across. Subreg doesn't work too well on the TF
9340 ;; value, since it is allocated in reload and not all of the flow information
9341 ;; is setup for it. We have two patterns to do the two moves between gprs and
9342 ;; fprs. There isn't a dependancy between the two, but we could potentially
9343 ;; schedule other instructions between the two instructions.
9345 (define_insn "p8_fmrgow_<mode>"
9346 [(set (match_operand:FMOVE64X
0 "register_operand" "=d")
9348 (match_operand:DF
1 "register_operand" "d")
9349 (match_operand:DF
2 "register_operand" "d")]
9350 UNSPEC_P8V_FMRGOW))]
9351 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9353 [(set_attr "type" "fpsimple")])
9355 (define_insn "p8_mtvsrwz"
9356 [(set (match_operand:DF
0 "register_operand" "=d")
9357 (unspec:DF [(match_operand:SI
1 "register_operand" "r")]
9358 UNSPEC_P8V_MTVSRWZ))]
9359 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9361 [(set_attr "type" "mtvsr")])
9363 (define_insn "p8_mtvsrwz_v16qisi2"
9364 [(set (match_operand:V16QI
0 "register_operand" "=wa")
9365 (unspec:V16QI [(match_operand:SI
1 "register_operand" "r")]
9366 UNSPEC_P8V_MTVSRWZ))]
9367 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9369 [(set_attr "type" "mtvsr")])
9371 (define_insn "p8_mtvsrd_v16qidi2"
9372 [(set (match_operand:V16QI
0 "register_operand" "=wa")
9373 (unspec:V16QI [(match_operand:DI
1 "register_operand" "r")]
9374 UNSPEC_P8V_MTVSRD))]
9375 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9377 [(set_attr "type" "mtvsr")])
9379 (define_insn_and_split "reload_fpr_from_gpr<mode>"
9380 [(set (match_operand:FMOVE64X
0 "register_operand" "=d")
9381 (unspec:FMOVE64X [(match_operand:FMOVE64X
1 "register_operand" "r")]
9382 UNSPEC_P8V_RELOAD_FROM_GPR))
9383 (clobber (match_operand:IF
2 "register_operand" "=d"))]
9384 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9386 "&& reload_completed"
9389 rtx dest = operands[
0];
9390 rtx src = operands[
1];
9391 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[
2], IFmode,
0);
9392 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[
2], IFmode,
8);
9393 rtx gpr_hi_reg = gen_highpart (SImode, src);
9394 rtx gpr_lo_reg = gen_lowpart (SImode, src);
9396 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
9397 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
9398 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
9401 [(set_attr "length" "
12")
9402 (set_attr "type" "three")])
9404 ;; Move
128 bit values from GPRs to VSX registers in
64-bit mode
9405 (define_insn "p8_mtvsrd_df"
9406 [(set (match_operand:DF
0 "register_operand" "=wa")
9407 (unspec:DF [(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 "p8_xxpermdi_<mode>"
9414 [(set (match_operand:FMOVE128_GPR
0 "register_operand" "=wa")
9415 (unspec:FMOVE128_GPR [
9416 (match_operand:DF
1 "register_operand" "wa")
9417 (match_operand:DF
2 "register_operand" "wa")]
9418 UNSPEC_P8V_XXPERMDI))]
9419 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9420 "xxpermdi %x0,%x1,%x2,
0"
9421 [(set_attr "type" "vecperm")])
9423 (define_insn_and_split "reload_vsx_from_gpr<mode>"
9424 [(set (match_operand:FMOVE128_GPR
0 "register_operand" "=wa")
9425 (unspec:FMOVE128_GPR
9426 [(match_operand:FMOVE128_GPR
1 "register_operand" "r")]
9427 UNSPEC_P8V_RELOAD_FROM_GPR))
9428 (clobber (match_operand:IF
2 "register_operand" "=wa"))]
9429 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9431 "&& reload_completed"
9434 rtx dest = operands[
0];
9435 rtx src = operands[
1];
9436 /* You might think that we could use op0 as one temp and a DF clobber
9437 as op2, but you'd be wrong. Secondary reload move patterns don't
9438 check for overlap of the clobber and the destination. */
9439 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[
2], IFmode,
0);
9440 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[
2], IFmode,
8);
9441 rtx gpr_hi_reg = gen_highpart (DImode, src);
9442 rtx gpr_lo_reg = gen_lowpart (DImode, src);
9444 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
9445 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
9446 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
9449 [(set_attr "length" "
12")
9450 (set_attr "type" "three")])
9453 [(set (match_operand:FMOVE128_GPR
0 "nonimmediate_operand")
9454 (match_operand:FMOVE128_GPR
1 "input_operand"))]
9456 && (int_reg_operand (operands[
0], <MODE>mode)
9457 || int_reg_operand (operands[
1], <MODE>mode))
9458 && (!TARGET_DIRECT_MOVE_128
9459 || (!vsx_register_operand (operands[
0], <MODE>mode)
9460 && !vsx_register_operand (operands[
1], <MODE>mode)))"
9463 rs6000_split_multireg_move (operands[
0], operands[
1]);
9467 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
9468 ;; type is stored internally as double precision in the VSX registers, we have
9469 ;; to convert it from the vector format.
9470 (define_insn "p8_mtvsrd_sf"
9471 [(set (match_operand:SF
0 "register_operand" "=wa")
9472 (unspec:SF [(match_operand:DI
1 "register_operand" "r")]
9473 UNSPEC_P8V_MTVSRD))]
9474 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9476 [(set_attr "type" "mtvsr")])
9478 (define_insn_and_split "reload_vsx_from_gprsf"
9479 [(set (match_operand:SF
0 "register_operand" "=wa")
9480 (unspec:SF [(match_operand:SF
1 "register_operand" "r")]
9481 UNSPEC_P8V_RELOAD_FROM_GPR))
9482 (clobber (match_operand:DI
2 "register_operand" "=r"))]
9483 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9485 "&& reload_completed"
9488 rtx op0 = operands[
0];
9489 rtx op1 = operands[
1];
9490 rtx op2 = operands[
2];
9491 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode,
0);
9493 /* Move SF value to upper
32-bits for xscvspdpn. */
9494 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (
32)));
9495 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
9496 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
9499 [(set_attr "length" "
8")
9500 (set_attr "type" "two")])
9502 ;; Move
128 bit values from VSX registers to GPRs in
64-bit mode by doing a
9503 ;; normal
64-bit move, followed by an xxpermdi to get the bottom
64-bit value,
9504 ;; and then doing a move of that.
9505 (define_insn "p8_mfvsrd_3_<mode>"
9506 [(set (match_operand:DF
0 "register_operand" "=r")
9507 (unspec:DF [(match_operand:FMOVE128_GPR
1 "register_operand" "wa")]
9508 UNSPEC_P8V_RELOAD_FROM_VSX))]
9509 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9511 [(set_attr "type" "mfvsr")])
9513 (define_insn_and_split "reload_gpr_from_vsx<mode>"
9514 [(set (match_operand:FMOVE128_GPR
0 "register_operand" "=r")
9515 (unspec:FMOVE128_GPR
9516 [(match_operand:FMOVE128_GPR
1 "register_operand" "wa")]
9517 UNSPEC_P8V_RELOAD_FROM_VSX))
9518 (clobber (match_operand:FMOVE128_GPR
2 "register_operand" "=wa"))]
9519 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9521 "&& reload_completed"
9524 rtx dest = operands[
0];
9525 rtx src = operands[
1];
9526 rtx tmp = operands[
2];
9527 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
9528 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
9530 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
9531 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (
3)));
9532 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
9535 [(set_attr "length" "
12")
9536 (set_attr "type" "three")])
9538 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
9539 ;; type is stored internally as double precision, we have to convert it to the
9542 (define_insn_and_split "reload_gpr_from_vsxsf"
9543 [(set (match_operand:SF
0 "register_operand" "=r")
9544 (unspec:SF [(match_operand:SF
1 "register_operand" "wa")]
9545 UNSPEC_P8V_RELOAD_FROM_VSX))
9546 (clobber (match_operand:V4SF
2 "register_operand" "=wa"))]
9547 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
9549 "&& reload_completed"
9552 rtx op0 = operands[
0];
9553 rtx op1 = operands[
1];
9554 rtx op2 = operands[
2];
9555 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
9556 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
9558 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
9559 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
9562 [(set_attr "length" "
8")
9563 (set_attr "type" "two")
9564 (set_attr "isa" "p8v")])
9566 ;; Next come the multi-word integer load and store and the load and store
9569 ;; List r->r after r->Y, otherwise reload will try to reload a
9570 ;; non-offsettable address by using r->r which won't make progress.
9571 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
9572 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
9574 ;; GPR store GPR load GPR move FPR store FPR load FPR move
9575 ;; GPR const AVX store AVX store AVX load AVX load VSX move
9576 ;; P9
0 P9 -
1 AVX
0/-
1 VSX
0 VSX -
1 P9 const
9579 (define_insn "*movdi_internal32"
9580 [(set (match_operand:DI
0 "nonimmediate_operand"
9581 "=Y, r, r, m, ^d, ^d,
9582 r, wY, Z, ^v, $v, ^wa,
9583 wa, wa, v, wa, *i, v,
9585 (match_operand:DI
1 "input_operand"
9586 "r, Y, r, ^d, m, ^d,
9587 IJKnF, ^v, $v, wY, Z, ^wa,
9588 Oj, wM, OjwM, Oj, wM, wS,
9591 && (gpc_reg_operand (operands[
0], DImode)
9592 || gpc_reg_operand (operands[
1], DImode))"
9614 "store, load, *, fpstore, fpload, fpsimple,
9615 *, fpstore, fpstore, fpload, fpload, veclogical,
9616 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
9618 (set_attr "size" "
64")
9626 *, p9v, p7v, p9v, p7v, *,
9627 p9v, p9v, p7v, *, *, p7v,
9631 [(set (match_operand:DI
0 "gpc_reg_operand")
9632 (match_operand:DI
1 "const_int_operand"))]
9633 "! TARGET_POWERPC64 && reload_completed
9634 && gpr_or_gpr_p (operands[
0], operands[
1])
9635 && !direct_move_p (operands[
0], operands[
1])"
9636 [(set (match_dup
2) (match_dup
4))
9637 (set (match_dup
3) (match_dup
1))]
9639 HOST_WIDE_INT value = INTVAL (operands[
1]);
9640 operands[
2] = operand_subword_force (operands[
0], WORDS_BIG_ENDIAN ==
0,
9642 operands[
3] = operand_subword_force (operands[
0], WORDS_BIG_ENDIAN !=
0,
9644 operands[
4] = GEN_INT (value >>
32);
9645 operands[
1] = GEN_INT (sext_hwi (value,
32));
9649 [(set (match_operand:DIFD
0 "nonimmediate_operand")
9650 (match_operand:DIFD
1 "input_operand"))]
9651 "reload_completed && !TARGET_POWERPC64
9652 && gpr_or_gpr_p (operands[
0], operands[
1])
9653 && !direct_move_p (operands[
0], operands[
1])"
9656 rs6000_split_multireg_move (operands[
0], operands[
1]);
9660 ;; GPR store GPR load GPR move
9661 ;; GPR li GPR lis GPR pli GPR #
9662 ;; FPR store FPR load FPR move
9663 ;; AVX store AVX store AVX load AVX load VSX move
9664 ;; P9
0 P9 -
1 AVX
0/-
1 VSX
0 VSX -
1
9665 ;; P9 const AVX const
9666 ;; From SPR To SPR SPR<->SPR
9667 ;; VSX->GPR GPR->VSX
9668 (define_insn "*movdi_internal64"
9669 [(set (match_operand:DI
0 "nonimmediate_operand"
9678 (match_operand:DI
1 "input_operand"
9683 Oj, wM, OjwM, Oj, wM,
9688 && (gpc_reg_operand (operands[
0], DImode)
9689 || gpc_reg_operand (operands[
1], DImode))"
9721 fpstore, fpload, fpsimple,
9722 fpstore, fpstore, fpload, fpload, veclogical,
9723 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
9724 vecsimple, vecsimple,
9727 (set_attr "size" "
64")
9741 p9v, p7v, p9v, p7v, *,
9742 p9v, p9v, p7v, *, *,
9747 ; Some DImode loads are best done as a load of -
1 followed by a mask
9750 [(set (match_operand:DI
0 "int_reg_operand")
9751 (match_operand:DI
1 "const_int_operand"))]
9753 && num_insns_constant (operands[
1], DImode) >
1
9754 && !IN_RANGE (INTVAL (operands[
1]), -
0x80000000,
0xffffffff)
9755 && rs6000_is_valid_and_mask (operands[
1], DImode)"
9759 (and:DI (match_dup
0)
9763 ;; Split a load of a large constant into the appropriate five-instruction
9764 ;; sequence. Handle anything in a constant number of insns.
9765 ;; When non-easy constants can go in the TOC, this should use
9766 ;; easy_fp_constant predicate.
9768 [(set (match_operand:DI
0 "int_reg_operand")
9769 (match_operand:DI
1 "const_int_operand"))]
9770 "TARGET_POWERPC64 && num_insns_constant (operands[
1], DImode) >
1"
9773 if (rs6000_emit_set_const (operands[
0], operands[
1]))
9780 [(set (match_operand:DI
0 "altivec_register_operand")
9781 (match_operand:DI
1 "s5bit_cint_operand"))]
9782 "TARGET_VSX && reload_completed"
9785 rtx op0 = operands[
0];
9786 rtx op1 = operands[
1];
9787 int r = REGNO (op0);
9788 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9790 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9791 if (op1 != const0_rtx && op1 != constm1_rtx)
9793 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9794 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9799 ;; Split integer constants that can be loaded with XXSPLTIB and a
9800 ;; sign extend operation.
9802 [(set (match_operand:INT_ISA3
0 "altivec_register_operand")
9803 (match_operand:INT_ISA3
1 "xxspltib_constant_split"))]
9804 "TARGET_P9_VECTOR && reload_completed"
9807 rtx op0 = operands[
0];
9808 rtx op1 = operands[
1];
9809 int r = REGNO (op0);
9810 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9812 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9813 if (<MODE>mode == DImode)
9814 emit_insn (gen_vsx_sign_extend_qi_di (operands[
0], op0_v16qi));
9815 else if (<MODE>mode == SImode)
9816 emit_insn (gen_vsx_sign_extend_qi_si (operands[
0], op0_v16qi));
9817 else if (<MODE>mode == HImode)
9819 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9820 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9826 ;; TImode/PTImode is similar, except that we usually want to compute the
9827 ;; address into a register and use lsi/stsi (the exception is during reload).
9829 (define_insn "*mov<mode>_string"
9830 [(set (match_operand:TI2
0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9831 (match_operand:TI2
1 "input_operand" "r,r,Q,Y,r,n"))]
9833 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9834 && (gpc_reg_operand (operands[
0], <MODE>mode)
9835 || gpc_reg_operand (operands[
1], <MODE>mode))"
9837 [(set_attr "type" "store,store,load,load,*,*")
9838 (set_attr "update" "yes")
9839 (set_attr "indexed" "yes")
9840 (set_attr "cell_micro" "conditional")])
9842 (define_insn "*mov<mode>_ppc64"
9843 [(set (match_operand:TI2
0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9844 (match_operand:TI2
1 "input_operand" "r,r,wQ,Y,r,n"))]
9845 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9846 && (gpc_reg_operand (operands[
0], <MODE>mode)
9847 || gpc_reg_operand (operands[
1], <MODE>mode)))"
9849 return rs6000_output_move_128bit (operands);
9851 [(set_attr "type" "store,store,load,load,*,*")
9852 (set_attr "length" "
8")
9853 (set_attr "max_prefixed_insns" "
2")])
9856 [(set (match_operand:TI2
0 "int_reg_operand")
9857 (match_operand:TI2
1 "const_scalar_int_operand"))]
9859 && (VECTOR_MEM_NONE_P (<MODE>mode)
9860 || (reload_completed && INT_REGNO_P (REGNO (operands[
0]))))"
9861 [(set (match_dup
2) (match_dup
4))
9862 (set (match_dup
3) (match_dup
5))]
9864 operands[
2] = operand_subword_force (operands[
0], WORDS_BIG_ENDIAN ==
0,
9866 operands[
3] = operand_subword_force (operands[
0], WORDS_BIG_ENDIAN !=
0,
9868 if (CONST_WIDE_INT_P (operands[
1]))
9870 operands[
4] = GEN_INT (CONST_WIDE_INT_ELT (operands[
1],
1));
9871 operands[
5] = GEN_INT (CONST_WIDE_INT_ELT (operands[
1],
0));
9873 else if (CONST_INT_P (operands[
1]))
9875 operands[
4] = GEN_INT (- (INTVAL (operands[
1]) <
0));
9876 operands[
5] = operands[
1];
9883 [(set (match_operand:TI2
0 "nonimmediate_operand")
9884 (match_operand:TI2
1 "input_operand"))]
9886 && gpr_or_gpr_p (operands[
0], operands[
1])
9887 && !direct_move_p (operands[
0], operands[
1])
9888 && !quad_load_store_p (operands[
0], operands[
1])"
9891 rs6000_split_multireg_move (operands[
0], operands[
1]);
9895 (define_expand "setmemsi"
9896 [(parallel [(set (match_operand:BLK
0 "")
9897 (match_operand
2 "const_int_operand"))
9898 (use (match_operand:SI
1 ""))
9899 (use (match_operand:SI
3 ""))])]
9902 /* If value to set is not zero, use the library routine. */
9903 if (operands[
2] != const0_rtx)
9906 if (expand_block_clear (operands))
9912 ;; String compare N insn.
9913 ;; Argument
0 is the target (result)
9914 ;; Argument
1 is the destination
9915 ;; Argument
2 is the source
9916 ;; Argument
3 is the length
9917 ;; Argument
4 is the alignment
9919 (define_expand "cmpstrnsi"
9920 [(parallel [(set (match_operand:SI
0)
9921 (compare:SI (match_operand:BLK
1)
9922 (match_operand:BLK
2)))
9923 (use (match_operand:SI
3))
9924 (use (match_operand:SI
4))])]
9925 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9927 if (optimize_insn_for_size_p ())
9930 if (expand_strn_compare (operands,
0))
9936 ;; String compare insn.
9937 ;; Argument
0 is the target (result)
9938 ;; Argument
1 is the destination
9939 ;; Argument
2 is the source
9940 ;; Argument
3 is the alignment
9942 (define_expand "cmpstrsi"
9943 [(parallel [(set (match_operand:SI
0)
9944 (compare:SI (match_operand:BLK
1)
9945 (match_operand:BLK
2)))
9946 (use (match_operand:SI
3))])]
9947 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9949 if (optimize_insn_for_size_p ())
9952 if (expand_strn_compare (operands,
1))
9958 ;; Block compare insn.
9959 ;; Argument
0 is the target (result)
9960 ;; Argument
1 is the destination
9961 ;; Argument
2 is the source
9962 ;; Argument
3 is the length
9963 ;; Argument
4 is the alignment
9965 (define_expand "cmpmemsi"
9966 [(parallel [(set (match_operand:SI
0)
9967 (compare:SI (match_operand:BLK
1)
9968 (match_operand:BLK
2)))
9969 (use (match_operand:SI
3))
9970 (use (match_operand:SI
4))])]
9973 if (expand_block_compare (operands))
9979 ;; String/block copy insn (source and destination must not overlap).
9980 ;; Argument
0 is the destination
9981 ;; Argument
1 is the source
9982 ;; Argument
2 is the length
9983 ;; Argument
3 is the alignment
9985 (define_expand "cpymemsi"
9986 [(parallel [(set (match_operand:BLK
0 "")
9987 (match_operand:BLK
1 ""))
9988 (use (match_operand:SI
2 ""))
9989 (use (match_operand:SI
3 ""))])]
9992 if (expand_block_move (operands, false))
9998 ;; String/block move insn (source and destination may overlap).
9999 ;; Argument
0 is the destination
10000 ;; Argument
1 is the source
10001 ;; Argument
2 is the length
10002 ;; Argument
3 is the alignment
10004 (define_expand "movmemsi"
10005 [(parallel [(set (match_operand:BLK
0 "")
10006 (match_operand:BLK
1 ""))
10007 (use (match_operand:SI
2 ""))
10008 (use (match_operand:SI
3 ""))])]
10011 if (expand_block_move (operands, true))
10018 ;; Define insns that do load or store with update. Some of these we can
10019 ;; get by using pre-decrement or pre-increment, but the hardware can also
10020 ;; do cases where the increment is not the size of the object.
10022 ;; In all these cases, we use operands
0 and
1 for the register being
10023 ;; incremented because those are the operands that local-alloc will
10024 ;; tie and these are the pair most likely to be tieable (and the ones
10025 ;; that will benefit the most).
10027 (define_insn "*movdi_update1"
10028 [(set (match_operand:DI
3 "gpc_reg_operand" "=r,r")
10029 (mem:DI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10030 (match_operand:P
2 "reg_or_aligned_short_operand" "r,I"))))
10031 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10032 (plus:P (match_dup
1) (match_dup
2)))]
10033 "TARGET_POWERPC64 && TARGET_UPDATE
10034 && (!avoiding_indexed_address_p (DImode)
10035 || !gpc_reg_operand (operands[
2], Pmode))"
10039 [(set_attr "type" "load")
10040 (set_attr "update" "yes")
10041 (set_attr "indexed" "yes,no")])
10043 (define_insn "movdi_<mode>_update"
10044 [(set (mem:DI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10045 (match_operand:P
2 "reg_or_aligned_short_operand" "r,I")))
10046 (match_operand:DI
3 "gpc_reg_operand" "r,r"))
10047 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10048 (plus:P (match_dup
1) (match_dup
2)))]
10049 "TARGET_POWERPC64 && TARGET_UPDATE
10050 && (!avoiding_indexed_address_p (DImode)
10051 || !gpc_reg_operand (operands[
2], Pmode)
10052 || (REG_P (operands[
0])
10053 && REGNO (operands[
0]) == STACK_POINTER_REGNUM))"
10057 [(set_attr "type" "store")
10058 (set_attr "update" "yes")
10059 (set_attr "indexed" "yes,no")])
10061 ;; This pattern is only conditional on TARGET_64BIT, as it is
10062 ;; needed for stack allocation, even if the user passes -mno-update.
10063 (define_insn "movdi_update_stack"
10064 [(set (mem:DI (plus:DI (match_operand:DI
1 "gpc_reg_operand" "
0,
0")
10065 (match_operand:DI
2 "reg_or_aligned_short_operand" "r,I")))
10066 (match_operand:DI
3 "gpc_reg_operand" "r,r"))
10067 (set (match_operand:DI
0 "gpc_reg_operand" "=b,b")
10068 (plus:DI (match_dup
1) (match_dup
2)))]
10073 [(set_attr "type" "store")
10074 (set_attr "update" "yes")
10075 (set_attr "indexed" "yes,no")])
10077 (define_insn "*movsi_update1"
10078 [(set (match_operand:SI
3 "gpc_reg_operand" "=r,r")
10079 (mem:SI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10080 (match_operand:P
2 "reg_or_short_operand" "r,I"))))
10081 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10082 (plus:P (match_dup
1) (match_dup
2)))]
10084 && (!avoiding_indexed_address_p (SImode)
10085 || !gpc_reg_operand (operands[
2], Pmode))"
10089 [(set_attr "type" "load")
10090 (set_attr "update" "yes")
10091 (set_attr "indexed" "yes,no")])
10093 (define_insn "*movsi_update2"
10094 [(set (match_operand:EXTSI
3 "gpc_reg_operand" "=r")
10096 (mem:SI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0")
10097 (match_operand:P
2 "gpc_reg_operand" "r")))))
10098 (set (match_operand:P
0 "gpc_reg_operand" "=b")
10099 (plus:P (match_dup
1) (match_dup
2)))]
10100 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
10102 [(set_attr "type" "load")
10103 (set_attr "sign_extend" "yes")
10104 (set_attr "update" "yes")
10105 (set_attr "indexed" "yes")])
10107 (define_insn "movsi_<mode>_update"
10108 [(set (mem:SI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10109 (match_operand:P
2 "reg_or_short_operand" "r,I")))
10110 (match_operand:SI
3 "gpc_reg_operand" "r,r"))
10111 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10112 (plus:P (match_dup
1) (match_dup
2)))]
10114 && (!avoiding_indexed_address_p (SImode)
10115 || !gpc_reg_operand (operands[
2], Pmode)
10116 || (REG_P (operands[
0])
10117 && REGNO (operands[
0]) == STACK_POINTER_REGNUM))"
10121 [(set_attr "type" "store")
10122 (set_attr "update" "yes")
10123 (set_attr "indexed" "yes,no")])
10125 ;; This is an unconditional pattern; needed for stack allocation, even
10126 ;; if the user passes -mno-update.
10127 (define_insn "movsi_update_stack"
10128 [(set (mem:SI (plus:SI (match_operand:SI
1 "gpc_reg_operand" "
0,
0")
10129 (match_operand:SI
2 "reg_or_short_operand" "r,I")))
10130 (match_operand:SI
3 "gpc_reg_operand" "r,r"))
10131 (set (match_operand:SI
0 "gpc_reg_operand" "=b,b")
10132 (plus:SI (match_dup
1) (match_dup
2)))]
10137 [(set_attr "type" "store")
10138 (set_attr "update" "yes")
10139 (set_attr "indexed" "yes,no")])
10141 (define_insn "*movhi_update1"
10142 [(set (match_operand:HI
3 "gpc_reg_operand" "=r,r")
10143 (mem:HI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10144 (match_operand:P
2 "reg_or_short_operand" "r,I"))))
10145 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10146 (plus:P (match_dup
1) (match_dup
2)))]
10148 && (!avoiding_indexed_address_p (HImode)
10149 || !gpc_reg_operand (operands[
2], SImode))"
10153 [(set_attr "type" "load")
10154 (set_attr "update" "yes")
10155 (set_attr "indexed" "yes,no")])
10157 (define_insn "*movhi_update2"
10158 [(set (match_operand:EXTHI
3 "gpc_reg_operand" "=r,r")
10160 (mem:HI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10161 (match_operand:P
2 "reg_or_short_operand" "r,I")))))
10162 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10163 (plus:P (match_dup
1) (match_dup
2)))]
10165 && (!avoiding_indexed_address_p (HImode)
10166 || !gpc_reg_operand (operands[
2], Pmode))"
10170 [(set_attr "type" "load")
10171 (set_attr "update" "yes")
10172 (set_attr "indexed" "yes,no")])
10174 (define_insn "*movhi_update3"
10175 [(set (match_operand:EXTHI
3 "gpc_reg_operand" "=r,r")
10177 (mem:HI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10178 (match_operand:P
2 "reg_or_short_operand" "r,I")))))
10179 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10180 (plus:P (match_dup
1) (match_dup
2)))]
10182 && !(avoiding_indexed_address_p (HImode)
10183 && gpc_reg_operand (operands[
2], Pmode))"
10187 [(set_attr "type" "load")
10188 (set_attr "sign_extend" "yes")
10189 (set_attr "update" "yes")
10190 (set_attr "indexed" "yes,no")])
10192 (define_insn "*movhi_update4"
10193 [(set (mem:HI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10194 (match_operand:P
2 "reg_or_short_operand" "r,I")))
10195 (match_operand:HI
3 "gpc_reg_operand" "r,r"))
10196 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10197 (plus:P (match_dup
1) (match_dup
2)))]
10199 && (!avoiding_indexed_address_p (HImode)
10200 || !gpc_reg_operand (operands[
2], Pmode))"
10204 [(set_attr "type" "store")
10205 (set_attr "update" "yes")
10206 (set_attr "indexed" "yes,no")])
10208 (define_insn "*movqi_update1"
10209 [(set (match_operand:QI
3 "gpc_reg_operand" "=r,r")
10210 (mem:QI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10211 (match_operand:P
2 "reg_or_short_operand" "r,I"))))
10212 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10213 (plus:P (match_dup
1) (match_dup
2)))]
10215 && (!avoiding_indexed_address_p (QImode)
10216 || !gpc_reg_operand (operands[
2], Pmode))"
10220 [(set_attr "type" "load")
10221 (set_attr "update" "yes")
10222 (set_attr "indexed" "yes,no")])
10224 (define_insn "*movqi_update2"
10225 [(set (match_operand:EXTQI
3 "gpc_reg_operand" "=r,r")
10227 (mem:QI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10228 (match_operand:P
2 "reg_or_short_operand" "r,I")))))
10229 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10230 (plus:P (match_dup
1) (match_dup
2)))]
10232 && (!avoiding_indexed_address_p (QImode)
10233 || !gpc_reg_operand (operands[
2], Pmode))"
10237 [(set_attr "type" "load")
10238 (set_attr "update" "yes")
10239 (set_attr "indexed" "yes,no")])
10241 (define_insn "*movqi_update3"
10242 [(set (mem:QI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10243 (match_operand:P
2 "reg_or_short_operand" "r,I")))
10244 (match_operand:QI
3 "gpc_reg_operand" "r,r"))
10245 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10246 (plus:P (match_dup
1) (match_dup
2)))]
10248 && (!avoiding_indexed_address_p (QImode)
10249 || !gpc_reg_operand (operands[
2], Pmode))"
10253 [(set_attr "type" "store")
10254 (set_attr "update" "yes")
10255 (set_attr "indexed" "yes,no")])
10257 (define_insn "*mov<SFDF:mode>_update1"
10258 [(set (match_operand:SFDF
3 "gpc_reg_operand" "=d,d")
10259 (mem:SFDF (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10260 (match_operand:P
2 "reg_or_short_operand" "r,I"))))
10261 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10262 (plus:P (match_dup
1) (match_dup
2)))]
10263 "TARGET_HARD_FLOAT && TARGET_UPDATE
10264 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
10265 || !gpc_reg_operand (operands[
2], Pmode))"
10269 [(set_attr "type" "fpload")
10270 (set_attr "update" "yes")
10271 (set_attr "indexed" "yes,no")
10272 (set_attr "size" "<SFDF:bits>")])
10274 (define_insn "*mov<SFDF:mode>_update2"
10275 [(set (mem:SFDF (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10276 (match_operand:P
2 "reg_or_short_operand" "r,I")))
10277 (match_operand:SFDF
3 "gpc_reg_operand" "d,d"))
10278 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10279 (plus:P (match_dup
1) (match_dup
2)))]
10280 "TARGET_HARD_FLOAT && TARGET_UPDATE
10281 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
10282 || !gpc_reg_operand (operands[
2], Pmode))"
10285 stf<sd>u %
3,%
2(%
0)"
10286 [(set_attr "type" "fpstore")
10287 (set_attr "update" "yes")
10288 (set_attr "indexed" "yes,no")
10289 (set_attr "size" "<SFDF:bits>")])
10291 (define_insn "*movsf_update3"
10292 [(set (match_operand:SF
3 "gpc_reg_operand" "=r,r")
10293 (mem:SF (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10294 (match_operand:P
2 "reg_or_short_operand" "r,I"))))
10295 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10296 (plus:P (match_dup
1) (match_dup
2)))]
10297 "TARGET_SOFT_FLOAT && TARGET_UPDATE
10298 && (!avoiding_indexed_address_p (SFmode)
10299 || !gpc_reg_operand (operands[
2], Pmode))"
10303 [(set_attr "type" "load")
10304 (set_attr "update" "yes")
10305 (set_attr "indexed" "yes,no")])
10307 (define_insn "*movsf_update4"
10308 [(set (mem:SF (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
10309 (match_operand:P
2 "reg_or_short_operand" "r,I")))
10310 (match_operand:SF
3 "gpc_reg_operand" "r,r"))
10311 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
10312 (plus:P (match_dup
1) (match_dup
2)))]
10313 "TARGET_SOFT_FLOAT && TARGET_UPDATE
10314 && (!avoiding_indexed_address_p (SFmode)
10315 || !gpc_reg_operand (operands[
2], Pmode))"
10319 [(set_attr "type" "store")
10320 (set_attr "update" "yes")
10321 (set_attr "indexed" "yes,no")])
10324 ;; After inserting conditional returns we can sometimes have
10325 ;; unnecessary register moves. Unfortunately we cannot have a
10326 ;; modeless peephole here, because some single SImode sets have early
10327 ;; clobber outputs. Although those sets expand to multi-ppc-insn
10328 ;; sequences, using get_attr_length here will smash the operands
10329 ;; array. Neither is there an early_cobbler_p predicate.
10330 ;; Also this optimization interferes with scalars going into
10331 ;; altivec registers (the code does reloading through the FPRs).
10333 [(set (match_operand:DF
0 "gpc_reg_operand")
10334 (match_operand:DF
1 "any_operand"))
10335 (set (match_operand:DF
2 "gpc_reg_operand")
10338 && peep2_reg_dead_p (
2, operands[
0])"
10339 [(set (match_dup
2) (match_dup
1))])
10342 [(set (match_operand:SF
0 "gpc_reg_operand")
10343 (match_operand:SF
1 "any_operand"))
10344 (set (match_operand:SF
2 "gpc_reg_operand")
10347 && peep2_reg_dead_p (
2, operands[
0])"
10348 [(set (match_dup
2) (match_dup
1))])
10353 (define_insn "*tls_gd_pcrel<bits>"
10354 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10355 (unspec:P [(match_operand:P
1 "rs6000_tls_symbol_ref" "")
10358 "HAVE_AS_TLS && TARGET_ELF"
10359 "la %
0,%
1@got@tlsgd@pcrel"
10360 [(set_attr "prefixed" "yes")])
10362 (define_insn_and_split "*tls_gd<bits>"
10363 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10364 (unspec:P [(match_operand:P
1 "rs6000_tls_symbol_ref" "")
10365 (match_operand:P
2 "gpc_reg_operand" "b")]
10367 "HAVE_AS_TLS && TARGET_ELF"
10368 "addi %
0,%
2,%
1@got@tlsgd"
10369 "&& TARGET_CMODEL != CMODEL_SMALL"
10370 [(set (match_dup
3)
10372 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGD)))
10374 (lo_sum:P (match_dup
3)
10375 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGD)))]
10377 operands[
3] = gen_reg_rtx (<MODE>mode);
10379 [(set (attr "length")
10380 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10384 (define_insn "*tls_gd_high<bits>"
10385 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10387 (unspec:P [(match_operand:P
1 "rs6000_tls_symbol_ref" "")
10388 (match_operand:P
2 "gpc_reg_operand" "b")]
10390 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10391 "addis %
0,%
2,%
1@got@tlsgd@ha")
10393 (define_insn "*tls_gd_low<bits>"
10394 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10395 (lo_sum:P (match_operand:P
1 "gpc_reg_operand" "b")
10396 (unspec:P [(match_operand:P
2 "rs6000_tls_symbol_ref" "")
10397 (match_operand:P
3 "gpc_reg_operand" "b")]
10399 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10400 "addi %
0,%
1,%
2@got@tlsgd@l")
10402 (define_insn "*tls_ld_pcrel<bits>"
10403 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10404 (unspec:P [(const_int
0)]
10406 "HAVE_AS_TLS && TARGET_ELF"
10407 "la %
0,%&@got@tlsld@pcrel"
10408 [(set_attr "prefixed" "yes")])
10410 (define_insn_and_split "*tls_ld<bits>"
10411 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10412 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")]
10414 "HAVE_AS_TLS && TARGET_ELF"
10415 "addi %
0,%
1,%&@got@tlsld"
10416 "&& TARGET_CMODEL != CMODEL_SMALL"
10417 [(set (match_dup
2)
10419 (unspec:P [(match_dup
1)] UNSPEC_TLSLD)))
10421 (lo_sum:P (match_dup
2)
10422 (unspec:P [(match_dup
1)] UNSPEC_TLSLD)))]
10424 operands[
2] = gen_reg_rtx (<MODE>mode);
10426 [(set (attr "length")
10427 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10431 (define_insn "*tls_ld_high<bits>"
10432 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10434 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")]
10436 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10437 "addis %
0,%
1,%&@got@tlsld@ha")
10439 (define_insn "*tls_ld_low<bits>"
10440 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10441 (lo_sum:P (match_operand:P
1 "gpc_reg_operand" "b")
10442 (unspec:P [(match_operand:P
2 "gpc_reg_operand" "b")]
10444 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10445 "addi %
0,%
1,%&@got@tlsld@l")
10447 (define_insn "tls_dtprel_<bits>"
10448 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10449 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10450 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10451 UNSPEC_TLSDTPREL))]
10453 "addi %
0,%
1,%
2@dtprel"
10454 [(set (attr "prefixed")
10455 (if_then_else (match_test "rs6000_tls_size ==
16")
10456 (const_string "no")
10457 (const_string "yes")))])
10459 (define_insn "tls_dtprel_ha_<bits>"
10460 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10461 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10462 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10463 UNSPEC_TLSDTPRELHA))]
10465 "addis %
0,%
1,%
2@dtprel@ha")
10467 (define_insn "tls_dtprel_lo_<bits>"
10468 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10469 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10470 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10471 UNSPEC_TLSDTPRELLO))]
10473 "addi %
0,%
1,%
2@dtprel@l")
10475 (define_insn_and_split "tls_got_dtprel_<bits>"
10476 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10477 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10478 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10479 UNSPEC_TLSGOTDTPREL))]
10481 "<ptrload> %
0,%
2@got@dtprel(%
1)"
10482 "&& TARGET_CMODEL != CMODEL_SMALL"
10483 [(set (match_dup
3)
10485 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGOTDTPREL)))
10487 (lo_sum:P (match_dup
3)
10488 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGOTDTPREL)))]
10490 operands[
3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10492 [(set (attr "length")
10493 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10497 (define_insn "*tls_got_dtprel_high<bits>"
10498 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10500 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10501 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10502 UNSPEC_TLSGOTDTPREL)))]
10503 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10504 "addis %
0,%
1,%
2@got@dtprel@ha")
10506 (define_insn "*tls_got_dtprel_low<bits>"
10507 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10508 (lo_sum:P (match_operand:P
1 "gpc_reg_operand" "b")
10509 (unspec:P [(match_operand:P
3 "gpc_reg_operand" "b")
10510 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10511 UNSPEC_TLSGOTDTPREL)))]
10512 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10513 "<ptrload> %
0,%
2@got@dtprel@l(%
1)")
10515 (define_insn "tls_tprel_<bits>"
10516 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10517 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10518 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10521 "addi %
0,%
1,%
2@tprel"
10522 [(set (attr "prefixed")
10523 (if_then_else (match_test "rs6000_tls_size ==
16")
10524 (const_string "no")
10525 (const_string "yes")))])
10527 (define_insn "tls_tprel_ha_<bits>"
10528 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10529 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10530 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10531 UNSPEC_TLSTPRELHA))]
10533 "addis %
0,%
1,%
2@tprel@ha")
10535 (define_insn "tls_tprel_lo_<bits>"
10536 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10537 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10538 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10539 UNSPEC_TLSTPRELLO))]
10541 "addi %
0,%
1,%
2@tprel@l")
10543 (define_insn "*tls_got_tprel_pcrel_<bits>"
10544 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10545 (unspec:P [(const_int
0)
10546 (match_operand:P
1 "rs6000_tls_symbol_ref" "")]
10547 UNSPEC_TLSGOTTPREL))]
10549 "<ptrload> %
0,%
1@got@tprel@pcrel"
10550 [(set_attr "prefixed" "yes")])
10552 ;; "b" output constraint here and on tls_tls input to support linker tls
10553 ;; optimization. The linker may edit the instructions emitted by a
10554 ;; tls_got_tprel/tls_tls pair to addis,addi.
10555 (define_insn_and_split "tls_got_tprel_<bits>"
10556 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10557 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10558 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10559 UNSPEC_TLSGOTTPREL))]
10561 "<ptrload> %
0,%
2@got@tprel(%
1)"
10562 "&& TARGET_CMODEL != CMODEL_SMALL"
10563 [(set (match_dup
3)
10565 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGOTTPREL)))
10567 (lo_sum:P (match_dup
3)
10568 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGOTTPREL)))]
10570 operands[
3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10572 [(set (attr "length")
10573 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10577 (define_insn "*tls_got_tprel_high<bits>"
10578 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10580 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10581 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10582 UNSPEC_TLSGOTTPREL)))]
10583 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10584 "addis %
0,%
1,%
2@got@tprel@ha")
10586 (define_insn "*tls_got_tprel_low<bits>"
10587 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10588 (lo_sum:P (match_operand:P
1 "gpc_reg_operand" "b")
10589 (unspec:P [(match_operand:P
3 "gpc_reg_operand" "b")
10590 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10591 UNSPEC_TLSGOTTPREL)))]
10592 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10593 "<ptrload> %
0,%
2@got@tprel@l(%
1)")
10595 (define_insn "tls_tls_pcrel_<bits>"
10596 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10597 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10598 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10599 UNSPEC_TLSTLS_PCREL))]
10600 "TARGET_ELF && HAVE_AS_TLS"
10601 "add %
0,%
1,%
2@tls@pcrel")
10603 (define_insn "tls_tls_<bits>"
10604 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10605 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10606 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
10608 "TARGET_ELF && HAVE_AS_TLS"
10609 "add %
0,%
1,%
2@tls")
10611 (define_expand "tls_get_tpointer"
10612 [(set (match_operand:SI
0 "gpc_reg_operand")
10613 (unspec:SI [(const_int
0)] UNSPEC_TLSTLS))]
10614 "TARGET_XCOFF && HAVE_AS_TLS"
10616 emit_insn (gen_tls_get_tpointer_internal ());
10617 emit_move_insn (operands[
0], gen_rtx_REG (SImode,
3));
10621 (define_insn "tls_get_tpointer_internal"
10623 (unspec:SI [(const_int
0)] UNSPEC_TLSTLS))
10624 (clobber (reg:SI LR_REGNO))]
10625 "TARGET_XCOFF && HAVE_AS_TLS"
10626 "bla .__get_tpointer")
10628 (define_expand "tls_get_addr<mode>"
10629 [(set (match_operand:P
0 "gpc_reg_operand")
10630 (unspec:P [(match_operand:P
1 "gpc_reg_operand")
10631 (match_operand:P
2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
10632 "TARGET_XCOFF && HAVE_AS_TLS"
10634 emit_move_insn (gen_rtx_REG (Pmode,
3), operands[
1]);
10635 emit_move_insn (gen_rtx_REG (Pmode,
4), operands[
2]);
10636 emit_insn (gen_tls_get_addr_internal<mode> ());
10637 emit_move_insn (operands[
0], gen_rtx_REG (Pmode,
3));
10641 (define_insn "tls_get_addr_internal<mode>"
10643 (unspec:P [(reg:P
3) (reg:P
4)] UNSPEC_TLSTLS))
10644 (clobber (reg:P
0))
10645 (clobber (reg:P
4))
10646 (clobber (reg:P
5))
10647 (clobber (reg:P
11))
10648 (clobber (reg:CC CR0_REGNO))
10649 (clobber (reg:P LR_REGNO))]
10650 "TARGET_XCOFF && HAVE_AS_TLS"
10651 "bla .__tls_get_addr")
10653 ;; Next come insns related to the calling sequence.
10655 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10656 ;; We move the back-chain and decrement the stack pointer.
10658 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
10659 ;; constant alloca, using that predicate will force the generic code to put
10660 ;; the constant size into a register before calling the expander.
10662 ;; As a result the expander would not have the constant size information
10663 ;; in those cases and would have to generate less efficient code.
10665 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10666 ;; the constant size. The value is forced into a register if necessary.
10668 (define_expand "allocate_stack"
10669 [(set (match_operand
0 "gpc_reg_operand")
10670 (minus (reg
1) (match_operand
1 "reg_or_cint_operand")))
10672 (minus (reg
1) (match_dup
1)))]
10675 rtx chain = gen_reg_rtx (Pmode);
10676 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10678 rtx insn, par, set, mem;
10680 /* By allowing reg_or_cint_operand as the predicate we can get
10681 better code for stack-clash-protection because we do not lose
10682 size information. But the rest of the code expects the operand
10683 to be reg_or_short_operand. If it isn't, then force it into
10685 rtx orig_op1 = operands[
1];
10686 if (!reg_or_short_operand (operands[
1], Pmode))
10687 operands[
1] = force_reg (Pmode, operands[
1]);
10689 emit_move_insn (chain, stack_bot);
10691 /* Check stack bounds if necessary. */
10692 if (crtl->limit_stack)
10695 available = expand_binop (Pmode, sub_optab,
10696 stack_pointer_rtx, stack_limit_rtx,
10697 NULL_RTX,
1, OPTAB_WIDEN);
10698 emit_insn (gen_cond_trap (LTU, available, operands[
1], const0_rtx));
10701 /* Allocate and probe if requested.
10702 This may look similar to the loop we use for prologue allocations,
10703 but it is critically different. For the former we know the loop
10704 will iterate, but do not know that generally here. The former
10705 uses that knowledge to rotate the loop. Combining them would be
10706 possible with some performance cost. */
10707 if (flag_stack_clash_protection)
10709 rtx rounded_size, last_addr, residual;
10710 HOST_WIDE_INT probe_interval;
10711 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10712 &residual, &probe_interval,
10715 /* We do occasionally get in here with constant sizes, we might
10716 as well do a reasonable job when we obviously can. */
10717 if (rounded_size != const0_rtx)
10719 rtx loop_lab, end_loop;
10720 bool rotated = CONST_INT_P (rounded_size);
10721 rtx update = GEN_INT (-probe_interval);
10722 if (probe_interval >
32768)
10723 update = force_reg (Pmode, update);
10725 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10726 last_addr, rotated);
10729 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10733 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
10736 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10737 last_addr, rotated);
10740 /* Now handle residuals. We just have to set operands[
1] correctly
10741 and let the rest of the expander run. */
10742 operands[
1] = residual;
10745 if (!(CONST_INT_P (operands[
1])
10746 && IN_RANGE (INTVAL (operands[
1]), -
32767,
32768)))
10748 operands[
1] = force_reg (Pmode, operands[
1]);
10749 neg_op0 = gen_reg_rtx (Pmode);
10750 emit_insn (gen_neg2 (Pmode, neg_op0, operands[
1]));
10753 neg_op0 = GEN_INT (-INTVAL (operands[
1]));
10755 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10756 : gen_movdi_update_stack))
10757 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10759 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10760 it now and set the alias set/attributes. The above gen_*_update
10761 calls will generate a PARALLEL with the MEM set being the first
10763 par = PATTERN (insn);
10764 gcc_assert (GET_CODE (par) == PARALLEL);
10765 set = XVECEXP (par,
0,
0);
10766 gcc_assert (GET_CODE (set) == SET);
10767 mem = SET_DEST (set);
10768 gcc_assert (MEM_P (mem));
10769 MEM_NOTRAP_P (mem) =
1;
10770 set_mem_alias_set (mem, get_frame_alias_set ());
10772 emit_move_insn (operands[
0], virtual_stack_dynamic_rtx);
10776 ;; These patterns say how to save and restore the stack pointer. We need not
10777 ;; save the stack pointer at function level since we are careful to
10778 ;; preserve the backchain. At block level, we have to restore the backchain
10779 ;; when we restore the stack pointer.
10781 ;; For nonlocal gotos, we must save both the stack pointer and its
10782 ;; backchain and restore both. Note that in the nonlocal case, the
10783 ;; save area is a memory location.
10785 (define_expand "save_stack_function"
10786 [(match_operand
0 "any_operand")
10787 (match_operand
1 "any_operand")]
10791 (define_expand "restore_stack_function"
10792 [(match_operand
0 "any_operand")
10793 (match_operand
1 "any_operand")]
10797 ;; Adjust stack pointer (op0) to a new value (op1).
10798 ;; First copy old stack backchain to new location, and ensure that the
10799 ;; scheduler won't reorder the sp assignment before the backchain write.
10800 (define_expand "restore_stack_block"
10801 [(set (match_dup
2) (match_dup
3))
10802 (set (match_dup
4) (match_dup
2))
10804 (set (match_operand
0 "register_operand")
10805 (match_operand
1 "register_operand"))]
10810 operands[
1] = force_reg (Pmode, operands[
1]);
10811 operands[
2] = gen_reg_rtx (Pmode);
10812 operands[
3] = gen_frame_mem (Pmode, operands[
0]);
10813 operands[
4] = gen_frame_mem (Pmode, operands[
1]);
10814 p = rtvec_alloc (
1);
10815 RTVEC_ELT (p,
0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[
0]),
10817 operands[
5] = gen_rtx_PARALLEL (VOIDmode, p);
10820 (define_expand "save_stack_nonlocal"
10821 [(set (match_dup
3) (match_dup
4))
10822 (set (match_operand
0 "memory_operand") (match_dup
3))
10823 (set (match_dup
2) (match_operand
1 "register_operand"))]
10826 int units_per_word = (TARGET_32BIT) ?
4 :
8;
10828 /* Copy the backchain to the first word, sp to the second. */
10829 operands[
0] = adjust_address_nv (operands[
0], Pmode,
0);
10830 operands[
2] = adjust_address_nv (operands[
0], Pmode, units_per_word);
10831 operands[
3] = gen_reg_rtx (Pmode);
10832 operands[
4] = gen_frame_mem (Pmode, operands[
1]);
10835 (define_expand "restore_stack_nonlocal"
10836 [(set (match_dup
2) (match_operand
1 "memory_operand"))
10837 (set (match_dup
3) (match_dup
4))
10838 (set (match_dup
5) (match_dup
2))
10840 (set (match_operand
0 "register_operand") (match_dup
3))]
10843 int units_per_word = (TARGET_32BIT) ?
4 :
8;
10846 /* Restore the backchain from the first word, sp from the second. */
10847 operands[
2] = gen_reg_rtx (Pmode);
10848 operands[
3] = gen_reg_rtx (Pmode);
10849 operands[
1] = adjust_address_nv (operands[
1], Pmode,
0);
10850 operands[
4] = adjust_address_nv (operands[
1], Pmode, units_per_word);
10851 operands[
5] = gen_frame_mem (Pmode, operands[
3]);
10852 p = rtvec_alloc (
1);
10853 RTVEC_ELT (p,
0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[
0]),
10855 operands[
6] = gen_rtx_PARALLEL (VOIDmode, p);
10858 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10859 ;; to the symbol or label.
10860 (define_insn "*pcrel_local_addr"
10861 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
10862 (match_operand:DI
1 "pcrel_local_address"))]
10865 [(set_attr "prefixed" "yes")])
10867 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10868 ;; program are both defined in the main program, the linker will optimize this
10869 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10870 ;; the dynamic linker and loaded up. Print_operand_address will append a
10871 ;; @got@pcrel to the symbol.
10872 (define_insn "*pcrel_extern_addr"
10873 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
10874 (match_operand:DI
1 "pcrel_external_address"))]
10877 [(set_attr "prefixed" "yes")
10878 (set_attr "type" "load")
10879 (set_attr "loads_external_address" "yes")])
10881 ;; TOC register handling.
10883 ;; Code to initialize the TOC register...
10885 (define_insn "load_toc_aix_si"
10886 [(parallel [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
10887 (unspec:SI [(const_int
0)] UNSPEC_TOC))
10888 (use (reg:SI
2))])]
10889 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10892 extern int need_toc_init;
10894 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
1);
10895 operands[
1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10896 operands[
2] = gen_rtx_REG (Pmode,
2);
10897 return "lwz %
0,%
1(%
2)";
10899 [(set_attr "type" "load")
10900 (set_attr "update" "no")
10901 (set_attr "indexed" "no")])
10903 (define_insn "load_toc_aix_di"
10904 [(parallel [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
10905 (unspec:DI [(const_int
0)] UNSPEC_TOC))
10906 (use (reg:DI
2))])]
10907 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10910 extern int need_toc_init;
10912 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10913 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10915 strcat (buf, "@toc");
10916 operands[
1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10917 operands[
2] = gen_rtx_REG (Pmode,
2);
10918 return "ld %
0,%
1(%
2)";
10920 [(set_attr "type" "load")
10921 (set_attr "update" "no")
10922 (set_attr "indexed" "no")])
10924 (define_insn "load_toc_v4_pic_si"
10925 [(set (reg:SI LR_REGNO)
10926 (unspec:SI [(const_int
0)] UNSPEC_TOC))]
10927 "DEFAULT_ABI == ABI_V4 && flag_pic ==
1 && TARGET_32BIT"
10928 "bl _GLOBAL_OFFSET_TABLE_@local-
4"
10929 [(set_attr "type" "branch")])
10931 (define_expand "load_toc_v4_PIC_1"
10932 [(parallel [(set (reg:SI LR_REGNO)
10933 (match_operand:SI
0 "immediate_operand" "s"))
10934 (use (unspec [(match_dup
0)] UNSPEC_TOC))])]
10935 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10936 && (flag_pic ==
2 || (flag_pic && TARGET_SECURE_PLT))"
10939 (define_insn "load_toc_v4_PIC_1_normal"
10940 [(set (reg:SI LR_REGNO)
10941 (match_operand:SI
0 "immediate_operand" "s"))
10942 (use (unspec [(match_dup
0)] UNSPEC_TOC))]
10943 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10944 && (flag_pic ==
2 || (flag_pic && TARGET_SECURE_PLT))"
10945 "bcl
20,
31,%
0\n%
0:"
10946 [(set_attr "type" "branch")
10947 (set_attr "cannot_copy" "yes")])
10949 (define_insn "load_toc_v4_PIC_1_476"
10950 [(set (reg:SI LR_REGNO)
10951 (match_operand:SI
0 "immediate_operand" "s"))
10952 (use (unspec [(match_dup
0)] UNSPEC_TOC))]
10953 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10954 && (flag_pic ==
2 || (flag_pic && TARGET_SECURE_PLT))"
10957 static char templ[
32];
10959 get_ppc476_thunk_name (name);
10960 sprintf (templ, "bl %s
\n%%
0:", name);
10963 [(set_attr "type" "branch")
10964 (set_attr "cannot_copy" "yes")])
10966 (define_expand "load_toc_v4_PIC_1b"
10967 [(parallel [(set (reg:SI LR_REGNO)
10968 (unspec:SI [(match_operand:SI
0 "immediate_operand" "s")
10969 (label_ref (match_operand
1 ""))]
10972 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic ==
2"
10975 (define_insn "load_toc_v4_PIC_1b_normal"
10976 [(set (reg:SI LR_REGNO)
10977 (unspec:SI [(match_operand:SI
0 "immediate_operand" "s")
10978 (label_ref (match_operand
1 "" ""))]
10981 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic ==
2"
10982 "bcl
20,
31,$+
8\;.long %
0-$"
10983 [(set_attr "type" "branch")
10984 (set_attr "length" "
8")])
10986 (define_insn "load_toc_v4_PIC_1b_476"
10987 [(set (reg:SI LR_REGNO)
10988 (unspec:SI [(match_operand:SI
0 "immediate_operand" "s")
10989 (label_ref (match_operand
1 "" ""))]
10992 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic ==
2"
10995 static char templ[
32];
10997 get_ppc476_thunk_name (name);
10998 sprintf (templ, "bl %s\;b $+
8\;.long %%
0-$", name);
11001 [(set_attr "type" "branch")
11002 (set_attr "length" "
16")])
11004 (define_insn "load_toc_v4_PIC_2"
11005 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
11007 (match_operand:SI
1 "gpc_reg_operand" "b")
11009 (minus:SI (match_operand:SI
2 "immediate_operand" "s")
11010 (match_operand:SI
3 "immediate_operand" "s"))))))]
11011 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic ==
2"
11013 [(set_attr "type" "load")])
11015 (define_insn "load_toc_v4_PIC_3b"
11016 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
11018 (match_operand:SI
1 "gpc_reg_operand" "b")
11021 (minus:SI (match_operand:SI
2 "symbol_ref_operand" "s")
11022 (match_operand:SI
3 "symbol_ref_operand" "s"))))))]
11023 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
11024 "addis %
0,%
1,%
2-%
3@ha")
11026 (define_insn "load_toc_v4_PIC_3c"
11027 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
11029 (match_operand:SI
1 "gpc_reg_operand" "b")
11031 (minus:SI (match_operand:SI
2 "symbol_ref_operand" "s")
11032 (match_operand:SI
3 "symbol_ref_operand" "s")))))]
11033 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
11034 "addi %
0,%
1,%
2-%
3@l")
11036 ;; If the TOC is shared over a translation unit, as happens with all
11037 ;; the kinds of PIC that we support, we need to restore the TOC
11038 ;; pointer only when jumping over units of translation.
11039 ;; On Darwin, we need to reload the picbase.
11041 (define_expand "builtin_setjmp_receiver"
11042 [(use (label_ref (match_operand
0 "")))]
11043 "(DEFAULT_ABI == ABI_V4 && flag_pic ==
1)
11044 || (TARGET_TOC && TARGET_MINIMAL_TOC)
11045 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
11048 if (DEFAULT_ABI == ABI_DARWIN)
11050 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
11051 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
11055 crtl->uses_pic_offset_table =
1;
11056 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
11057 CODE_LABEL_NUMBER (operands[
0]));
11058 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
11060 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
11061 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
11062 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
11063 picrtx, tmplabrtx));
11067 rs6000_emit_load_toc_table (FALSE);
11071 ;; Largetoc support
11072 (define_insn "*largetoc_high"
11073 [(set (match_operand:DI
0 "gpc_reg_operand" "=b*r")
11075 (unspec [(match_operand:DI
1 "" "")
11076 (match_operand:DI
2 "gpc_reg_operand" "b")]
11078 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11079 "addis %
0,%
2,%
1@toc@ha")
11081 (define_insn "*largetoc_high_aix<mode>"
11082 [(set (match_operand:P
0 "gpc_reg_operand" "=b*r")
11084 (unspec [(match_operand:P
1 "" "")
11085 (match_operand:P
2 "gpc_reg_operand" "b")]
11087 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11088 "addis %
0,%
1@u(%
2)")
11090 (define_insn "*largetoc_high_plus"
11091 [(set (match_operand:DI
0 "gpc_reg_operand" "=b*r")
11094 (unspec [(match_operand:DI
1 "" "")
11095 (match_operand:DI
2 "gpc_reg_operand" "b")]
11097 (match_operand:DI
3 "add_cint_operand" "n"))))]
11098 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11099 "addis %
0,%
2,%
1+%
3@toc@ha")
11101 (define_insn "*largetoc_high_plus_aix<mode>"
11102 [(set (match_operand:P
0 "gpc_reg_operand" "=b*r")
11105 (unspec [(match_operand:P
1 "" "")
11106 (match_operand:P
2 "gpc_reg_operand" "b")]
11108 (match_operand:P
3 "add_cint_operand" "n"))))]
11109 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11110 "addis %
0,%
1+%
3@u(%
2)")
11112 (define_insn "*largetoc_low"
11113 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
11114 (lo_sum:DI (match_operand:DI
1 "gpc_reg_operand" "b")
11115 (match_operand:DI
2 "" "")))]
11116 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
11119 (define_insn "*largetoc_low_aix<mode>"
11120 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
11121 (lo_sum:P (match_operand:P
1 "gpc_reg_operand" "b")
11122 (match_operand:P
2 "" "")))]
11123 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
11126 (define_insn_and_split "*tocref<mode>"
11127 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
11128 (match_operand:P
1 "small_toc_ref" "R"))]
11130 && legitimate_constant_pool_address_p (operands[
1], QImode, false)"
11132 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
11133 [(set (match_dup
0) (high:P (match_dup
1)))
11134 (set (match_dup
0) (lo_sum:P (match_dup
0) (match_dup
1)))])
11136 ;; Elf specific ways of loading addresses for non-PIC code.
11137 ;; The output of this could be r0, but we make a very strong
11138 ;; preference for a base register because it will usually
11139 ;; be needed there.
11140 (define_insn "elf_high"
11141 [(set (match_operand:SI
0 "gpc_reg_operand" "=b*r")
11142 (high:SI (match_operand
1 "" "")))]
11143 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
11146 (define_insn "elf_low"
11147 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
11148 (lo_sum:SI (match_operand:SI
1 "gpc_reg_operand" "b")
11149 (match_operand
2 "" "")))]
11150 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
11153 (define_insn "*pltseq_tocsave_<mode>"
11154 [(set (match_operand:P
0 "memory_operand" "=m")
11155 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
11156 (match_operand:P
2 "symbol_ref_operand" "s")
11157 (match_operand:P
3 "" "")]
11160 && DEFAULT_ABI == ABI_ELFv2"
11162 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
11165 (define_insn "*pltseq_plt16_ha_<mode>"
11166 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
11167 (unspec:P [(match_operand:P
1 "" "")
11168 (match_operand:P
2 "symbol_ref_operand" "s")
11169 (match_operand:P
3 "" "")]
11173 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
11176 (define_insn "*pltseq_plt16_lo_<mode>"
11177 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
11178 (unspec_volatile:P [(match_operand:P
1 "gpc_reg_operand" "b")
11179 (match_operand:P
2 "symbol_ref_operand" "s")
11180 (match_operand:P
3 "" "")]
11181 UNSPECV_PLT16_LO))]
11184 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
11186 [(set_attr "type" "load")])
11188 (define_insn "*pltseq_mtctr_<mode>"
11189 [(set (match_operand:P
0 "register_operand" "=c")
11190 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "r")
11191 (match_operand:P
2 "symbol_ref_operand" "s")
11192 (match_operand:P
3 "" "")]
11196 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
11199 (define_insn "*pltseq_plt_pcrel<mode>"
11200 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
11201 (unspec_volatile:P [(match_operand:P
1 "" "")
11202 (match_operand:P
2 "symbol_ref_operand" "s")
11203 (match_operand:P
3 "" "")]
11204 UNSPECV_PLT_PCREL))]
11205 "HAVE_AS_PLTSEQ && TARGET_ELF
11206 && rs6000_pcrel_p ()"
11208 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
11210 [(set_attr "type" "load")
11211 (set_attr "length" "
12")])
11213 ;; Call and call_value insns
11214 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
11215 (define_expand "call"
11216 [(parallel [(call (mem:SI (match_operand
0 "address_operand"))
11217 (match_operand
1 ""))
11218 (use (match_operand
2 ""))
11219 (clobber (reg:SI LR_REGNO))])]
11223 if (MACHOPIC_INDIRECT)
11224 operands[
0] = machopic_indirect_call_target (operands[
0]);
11227 gcc_assert (MEM_P (operands[
0]));
11229 operands[
0] = XEXP (operands[
0],
0);
11231 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11232 rs6000_call_aix (NULL_RTX, operands[
0], operands[
1], operands[
2]);
11233 else if (DEFAULT_ABI == ABI_V4)
11234 rs6000_call_sysv (NULL_RTX, operands[
0], operands[
1], operands[
2]);
11235 else if (DEFAULT_ABI == ABI_DARWIN)
11236 rs6000_call_darwin (NULL_RTX, operands[
0], operands[
1], operands[
2]);
11238 gcc_unreachable ();
11243 (define_expand "call_value"
11244 [(parallel [(set (match_operand
0 "")
11245 (call (mem:SI (match_operand
1 "address_operand"))
11246 (match_operand
2 "")))
11247 (use (match_operand
3 ""))
11248 (clobber (reg:SI LR_REGNO))])]
11252 if (MACHOPIC_INDIRECT)
11253 operands[
1] = machopic_indirect_call_target (operands[
1]);
11256 gcc_assert (MEM_P (operands[
1]));
11258 operands[
1] = XEXP (operands[
1],
0);
11260 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11261 rs6000_call_aix (operands[
0], operands[
1], operands[
2], operands[
3]);
11262 else if (DEFAULT_ABI == ABI_V4)
11263 rs6000_call_sysv (operands[
0], operands[
1], operands[
2], operands[
3]);
11264 else if (DEFAULT_ABI == ABI_DARWIN)
11265 rs6000_call_darwin (operands[
0], operands[
1], operands[
2], operands[
3]);
11267 gcc_unreachable ();
11272 ;; Call to function in current module. No TOC pointer reload needed.
11273 ;; Operand2 is nonzero if we are using the V
.4 calling sequence and
11274 ;; either the function was not prototyped, or it was prototyped as a
11275 ;; variable argument function. It is >
0 if FP registers were passed
11276 ;; and <
0 if they were not.
11278 (define_insn "*call_local<mode>"
11279 [(call (mem:SI (match_operand:P
0 "current_file_function_operand" "s,s"))
11281 (use (match_operand:SI
2 "immediate_operand" "O,n"))
11282 (clobber (reg:P LR_REGNO))]
11283 "(INTVAL (operands[
2]) & CALL_LONG) ==
0"
11285 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
11286 output_asm_insn ("crxor
6,
6,
6", operands);
11288 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
11289 output_asm_insn ("creqv
6,
6,
6", operands);
11291 if (rs6000_pcrel_p ())
11292 return "bl %z0@notoc";
11293 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
11295 [(set_attr "type" "branch")
11296 (set_attr "length" "
4,
8")])
11298 (define_insn "*call_value_local<mode>"
11299 [(set (match_operand
0 "" "")
11300 (call (mem:SI (match_operand:P
1 "current_file_function_operand" "s,s"))
11301 (match_operand
2)))
11302 (use (match_operand:SI
3 "immediate_operand" "O,n"))
11303 (clobber (reg:P LR_REGNO))]
11304 "(INTVAL (operands[
3]) & CALL_LONG) ==
0"
11306 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
11307 output_asm_insn ("crxor
6,
6,
6", operands);
11309 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
11310 output_asm_insn ("creqv
6,
6,
6", operands);
11312 if (rs6000_pcrel_p ())
11313 return "bl %z1@notoc";
11314 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
11316 [(set_attr "type" "branch")
11317 (set_attr "length" "
4,
8")])
11320 ;; A function pointer under System V is just a normal pointer
11321 ;; operands[
0] is the function pointer
11322 ;; operands[
1] is the tls call arg
11323 ;; operands[
2] is the value FUNCTION_ARG returns for the VOID argument
11324 ;; which indicates how to set cr1
11326 (define_insn "*call_indirect_nonlocal_sysv<mode>"
11327 [(call (mem:SI (match_operand:P
0 "indirect_call_operand" "c,*l,X"))
11329 (use (match_operand:SI
2 "immediate_operand" "n,n,n"))
11330 (clobber (reg:P LR_REGNO))]
11331 "DEFAULT_ABI == ABI_V4
11332 || DEFAULT_ABI == ABI_DARWIN"
11334 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
11335 output_asm_insn ("crxor
6,
6,
6", operands);
11337 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
11338 output_asm_insn ("creqv
6,
6,
6", operands);
11340 return rs6000_indirect_call_template (operands,
0);
11342 [(set_attr "type" "jmpreg")
11343 (set (attr "length")
11344 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11345 (match_test "which_alternative !=
1"))
11346 (match_test "(INTVAL (operands[
2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11347 (const_string "
12")
11348 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11349 (match_test "which_alternative !=
1"))
11350 (match_test "(INTVAL (operands[
2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11351 (const_string "
8")]
11352 (const_string "
4")))])
11354 (define_insn "*call_nonlocal_sysv<mode>"
11355 [(call (mem:SI (match_operand:P
0 "symbol_ref_operand" "s,s"))
11357 (use (match_operand:SI
2 "immediate_operand" "O,n"))
11358 (clobber (reg:P LR_REGNO))]
11359 "(DEFAULT_ABI == ABI_DARWIN
11360 || (DEFAULT_ABI == ABI_V4
11361 && (INTVAL (operands[
2]) & CALL_LONG) ==
0))"
11363 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
11364 output_asm_insn ("crxor
6,
6,
6", operands);
11366 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
11367 output_asm_insn ("creqv
6,
6,
6", operands);
11369 return rs6000_call_template (operands,
0);
11371 [(set_attr "type" "branch,branch")
11372 (set_attr "length" "
4,
8")])
11374 (define_insn "*call_nonlocal_sysv_secure<mode>"
11375 [(call (mem:SI (match_operand:P
0 "symbol_ref_operand" "s,s"))
11377 (use (match_operand:SI
2 "immediate_operand" "O,n"))
11378 (use (match_operand:SI
3 "register_operand" "r,r"))
11379 (clobber (reg:P LR_REGNO))]
11380 "(DEFAULT_ABI == ABI_V4
11381 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[
0])
11382 && (INTVAL (operands[
2]) & CALL_LONG) ==
0)"
11384 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
11385 output_asm_insn ("crxor
6,
6,
6", operands);
11387 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
11388 output_asm_insn ("creqv
6,
6,
6", operands);
11390 return rs6000_call_template (operands,
0);
11392 [(set_attr "type" "branch,branch")
11393 (set_attr "length" "
4,
8")])
11395 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11396 [(set (match_operand
0 "" "")
11397 (call (mem:SI (match_operand:P
1 "indirect_call_operand" "c,*l,X"))
11398 (match_operand:P
2 "unspec_tls" "")))
11399 (use (match_operand:SI
3 "immediate_operand" "n,n,n"))
11400 (clobber (reg:P LR_REGNO))]
11401 "DEFAULT_ABI == ABI_V4
11402 || DEFAULT_ABI == ABI_DARWIN"
11404 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
11405 output_asm_insn ("crxor
6,
6,
6", operands);
11407 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
11408 output_asm_insn ("creqv
6,
6,
6", operands);
11410 return rs6000_indirect_call_template (operands,
1);
11412 [(set_attr "type" "jmpreg")
11413 (set (attr "length")
11415 (if_then_else (match_test "IS_V4_FP_ARGS (operands[
3])")
11418 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11419 (match_test "which_alternative !=
1"))
11423 (define_insn "*call_value_nonlocal_sysv<mode>"
11424 [(set (match_operand
0 "" "")
11425 (call (mem:SI (match_operand:P
1 "symbol_ref_operand" "s"))
11426 (match_operand:P
2 "unspec_tls" "")))
11427 (use (match_operand:SI
3 "immediate_operand" "n"))
11428 (clobber (reg:P LR_REGNO))]
11429 "(DEFAULT_ABI == ABI_DARWIN
11430 || (DEFAULT_ABI == ABI_V4
11431 && (INTVAL (operands[
3]) & CALL_LONG) ==
0))"
11433 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
11434 output_asm_insn ("crxor
6,
6,
6", operands);
11436 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
11437 output_asm_insn ("creqv
6,
6,
6", operands);
11439 return rs6000_call_template (operands,
1);
11441 [(set_attr "type" "branch")
11442 (set (attr "length")
11443 (if_then_else (match_test "IS_V4_FP_ARGS (operands[
3])")
11447 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11448 [(set (match_operand
0 "" "")
11449 (call (mem:SI (match_operand:P
1 "symbol_ref_operand" "s"))
11450 (match_operand:P
2 "unspec_tls" "")))
11451 (use (match_operand:SI
3 "immediate_operand" "n"))
11452 (use (match_operand:SI
4 "register_operand" "r"))
11453 (clobber (reg:P LR_REGNO))]
11454 "(DEFAULT_ABI == ABI_V4
11455 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[
1])
11456 && (INTVAL (operands[
3]) & CALL_LONG) ==
0)"
11458 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
11459 output_asm_insn ("crxor
6,
6,
6", operands);
11461 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
11462 output_asm_insn ("creqv
6,
6,
6", operands);
11464 return rs6000_call_template (operands,
1);
11466 [(set_attr "type" "branch")
11467 (set (attr "length")
11468 (if_then_else (match_test "IS_V4_FP_ARGS (operands[
3])")
11472 ;; Call to AIX abi function which may be in another module.
11473 ;; Restore the TOC pointer (r2) after the call.
11475 (define_insn "*call_nonlocal_aix<mode>"
11476 [(call (mem:SI (match_operand:P
0 "symbol_ref_operand" "s"))
11478 (use (match_operand:SI
2 "immediate_operand" "n"))
11479 (clobber (reg:P LR_REGNO))]
11480 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11481 && (INTVAL (operands[
2]) & CALL_LONG) ==
0"
11483 return rs6000_call_template (operands,
0);
11485 [(set_attr "type" "branch")
11486 (set (attr "length")
11487 (if_then_else (match_test "rs6000_pcrel_p ()")
11491 (define_insn "*call_value_nonlocal_aix<mode>"
11492 [(set (match_operand
0 "" "")
11493 (call (mem:SI (match_operand:P
1 "symbol_ref_operand" "s"))
11494 (match_operand:P
2 "unspec_tls" "")))
11495 (use (match_operand:SI
3 "immediate_operand" "n"))
11496 (clobber (reg:P LR_REGNO))]
11497 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11498 && (INTVAL (operands[
3]) & CALL_LONG) ==
0"
11500 return rs6000_call_template (operands,
1);
11502 [(set_attr "type" "branch")
11503 (set (attr "length")
11504 (if_then_else (match_test "rs6000_pcrel_p ()")
11508 ;; Call to indirect functions with the AIX abi using a
3 word descriptor.
11509 ;; Operand0 is the addresss of the function to call
11510 ;; Operand3 is the location in the function descriptor to load r2 from
11511 ;; Operand4 is the offset of the stack location holding the current TOC pointer
11513 (define_insn "*call_indirect_aix<mode>"
11514 [(call (mem:SI (match_operand:P
0 "indirect_call_operand" "c,*l,X"))
11516 (use (match_operand:SI
2 "immediate_operand" "n,n,n"))
11517 (use (match_operand:P
3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
11518 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P
4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
11519 (clobber (reg:P LR_REGNO))]
11520 "DEFAULT_ABI == ABI_AIX"
11522 return rs6000_indirect_call_template (operands,
0);
11524 [(set_attr "type" "jmpreg")
11525 (set (attr "length")
11526 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11527 (match_test "which_alternative !=
1"))
11528 (const_string "
16")
11529 (const_string "
12")))])
11531 (define_insn "*call_value_indirect_aix<mode>"
11532 [(set (match_operand
0 "" "")
11533 (call (mem:SI (match_operand:P
1 "indirect_call_operand" "c,*l,X"))
11534 (match_operand:P
2 "unspec_tls" "")))
11535 (use (match_operand:SI
3 "immediate_operand" "n,n,n"))
11536 (use (match_operand:P
4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
11537 (set (reg:P TOC_REGNUM)
11538 (unspec:P [(match_operand:P
5 "const_int_operand" "n,n,n")]
11540 (clobber (reg:P LR_REGNO))]
11541 "DEFAULT_ABI == ABI_AIX"
11543 return rs6000_indirect_call_template (operands,
1);
11545 [(set_attr "type" "jmpreg")
11546 (set (attr "length")
11547 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11548 (match_test "which_alternative !=
1"))
11549 (const_string "
16")
11550 (const_string "
12")))])
11552 ;; Call to indirect functions with the ELFv2 ABI.
11553 ;; Operand0 is the addresss of the function to call
11554 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11556 (define_insn "*call_indirect_elfv2<mode>"
11557 [(call (mem:SI (match_operand:P
0 "indirect_call_operand" "c,*l,X"))
11559 (use (match_operand:SI
2 "immediate_operand" "n,n,n"))
11560 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P
3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
11561 (clobber (reg:P LR_REGNO))]
11562 "DEFAULT_ABI == ABI_ELFv2"
11564 return rs6000_indirect_call_template (operands,
0);
11566 [(set_attr "type" "jmpreg")
11567 (set (attr "length")
11568 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11569 (match_test "which_alternative !=
1"))
11570 (const_string "
12")
11571 (const_string "
8")))])
11573 (define_insn "*call_indirect_pcrel<mode>"
11574 [(call (mem:SI (match_operand:P
0 "indirect_call_operand" "c,*l,X"))
11576 (use (match_operand:SI
2 "immediate_operand" "n,n,n"))
11577 (clobber (reg:P LR_REGNO))]
11578 "rs6000_pcrel_p ()"
11580 return rs6000_indirect_call_template (operands,
0);
11582 [(set_attr "type" "jmpreg")
11583 (set (attr "length")
11584 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11585 (match_test "which_alternative !=
1"))
11587 (const_string "
4")))])
11589 (define_insn "*call_value_indirect_elfv2<mode>"
11590 [(set (match_operand
0 "" "")
11591 (call (mem:SI (match_operand:P
1 "indirect_call_operand" "c,*l,X"))
11592 (match_operand:P
2 "unspec_tls" "")))
11593 (use (match_operand:SI
3 "immediate_operand" "n,n,n"))
11594 (set (reg:P TOC_REGNUM)
11595 (unspec:P [(match_operand:P
4 "const_int_operand" "n,n,n")]
11597 (clobber (reg:P LR_REGNO))]
11598 "DEFAULT_ABI == ABI_ELFv2"
11600 return rs6000_indirect_call_template (operands,
1);
11602 [(set_attr "type" "jmpreg")
11603 (set (attr "length")
11604 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11605 (match_test "which_alternative !=
1"))
11606 (const_string "
12")
11607 (const_string "
8")))])
11609 (define_insn "*call_value_indirect_pcrel<mode>"
11610 [(set (match_operand
0 "" "")
11611 (call (mem:SI (match_operand:P
1 "indirect_call_operand" "c,*l,X"))
11612 (match_operand:P
2 "unspec_tls" "")))
11613 (use (match_operand:SI
3 "immediate_operand" "n,n,n"))
11614 (clobber (reg:P LR_REGNO))]
11615 "rs6000_pcrel_p ()"
11617 return rs6000_indirect_call_template (operands,
1);
11619 [(set_attr "type" "jmpreg")
11620 (set (attr "length")
11621 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
11622 (match_test "which_alternative !=
1"))
11624 (const_string "
4")))])
11626 ;; Call subroutine returning any type.
11627 (define_expand "untyped_call"
11628 [(parallel [(call (match_operand
0 "")
11630 (match_operand
1 "")
11631 (match_operand
2 "")])]
11636 emit_call_insn (gen_call (operands[
0], const0_rtx, const0_rtx));
11638 for (int i =
0; i < XVECLEN (operands[
2],
0); i++)
11639 emit_clobber (SET_SRC (XVECEXP (operands[
2],
0, i)));
11640 emit_insn (gen_blockage ());
11642 for (i =
0; i < XVECLEN (operands[
2],
0); i++)
11644 rtx set = XVECEXP (operands[
2],
0, i);
11645 emit_move_insn (SET_DEST (set), SET_SRC (set));
11648 /* The optimizer does not know that the call sets the function value
11649 registers we stored in the result block. We avoid problems by
11650 claiming that all hard registers are used and clobbered at this
11652 emit_insn (gen_blockage ());
11657 ;; sibling call patterns
11658 (define_expand "sibcall"
11659 [(parallel [(call (mem:SI (match_operand
0 "address_operand"))
11660 (match_operand
1 ""))
11661 (use (match_operand
2 ""))
11666 if (MACHOPIC_INDIRECT)
11667 operands[
0] = machopic_indirect_call_target (operands[
0]);
11670 gcc_assert (MEM_P (operands[
0]));
11671 gcc_assert (CONST_INT_P (operands[
1]));
11673 operands[
0] = XEXP (operands[
0],
0);
11675 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11676 rs6000_sibcall_aix (NULL_RTX, operands[
0], operands[
1], operands[
2]);
11677 else if (DEFAULT_ABI == ABI_V4)
11678 rs6000_sibcall_sysv (NULL_RTX, operands[
0], operands[
1], operands[
2]);
11679 else if (DEFAULT_ABI == ABI_DARWIN)
11680 rs6000_sibcall_darwin (NULL_RTX, operands[
0], operands[
1], operands[
2]);
11682 gcc_unreachable ();
11687 (define_expand "sibcall_value"
11688 [(parallel [(set (match_operand
0 "register_operand")
11689 (call (mem:SI (match_operand
1 "address_operand"))
11690 (match_operand
2 "")))
11691 (use (match_operand
3 ""))
11696 if (MACHOPIC_INDIRECT)
11697 operands[
1] = machopic_indirect_call_target (operands[
1]);
11700 gcc_assert (MEM_P (operands[
1]));
11701 gcc_assert (CONST_INT_P (operands[
2]));
11703 operands[
1] = XEXP (operands[
1],
0);
11705 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11706 rs6000_sibcall_aix (operands[
0], operands[
1], operands[
2], operands[
3]);
11707 else if (DEFAULT_ABI == ABI_V4)
11708 rs6000_sibcall_sysv (operands[
0], operands[
1], operands[
2], operands[
3]);
11709 else if (DEFAULT_ABI == ABI_DARWIN)
11710 rs6000_sibcall_darwin (operands[
0], operands[
1], operands[
2], operands[
3]);
11712 gcc_unreachable ();
11717 (define_insn "*sibcall_local<mode>"
11718 [(call (mem:SI (match_operand:P
0 "current_file_function_operand" "s,s"))
11720 (use (match_operand:SI
2 "immediate_operand" "O,n"))
11722 "(INTVAL (operands[
2]) & CALL_LONG) ==
0"
11724 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
11725 output_asm_insn ("crxor
6,
6,
6", operands);
11727 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
11728 output_asm_insn ("creqv
6,
6,
6", operands);
11730 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11732 [(set_attr "type" "branch")
11733 (set_attr "length" "
4,
8")])
11735 (define_insn "*sibcall_value_local<mode>"
11736 [(set (match_operand
0 "" "")
11737 (call (mem:SI (match_operand:P
1 "current_file_function_operand" "s,s"))
11738 (match_operand
2)))
11739 (use (match_operand:SI
3 "immediate_operand" "O,n"))
11741 "(INTVAL (operands[
3]) & CALL_LONG) ==
0"
11743 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
11744 output_asm_insn ("crxor
6,
6,
6", operands);
11746 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
11747 output_asm_insn ("creqv
6,
6,
6", operands);
11749 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11751 [(set_attr "type" "branch")
11752 (set_attr "length" "
4,
8")])
11754 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11755 [(call (mem:SI (match_operand:P
0 "indirect_call_operand" "c,*l,X"))
11757 (use (match_operand:SI
2 "immediate_operand" "n,n,n"))
11759 "DEFAULT_ABI == ABI_V4
11760 || DEFAULT_ABI == ABI_DARWIN"
11762 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
11763 output_asm_insn ("crxor
6,
6,
6", operands);
11765 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
11766 output_asm_insn ("creqv
6,
6,
6", operands);
11768 return rs6000_indirect_sibcall_template (operands,
0);
11770 [(set_attr "type" "jmpreg")
11771 (set (attr "length")
11772 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11773 (match_test "which_alternative !=
1"))
11774 (match_test "(INTVAL (operands[
2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11775 (const_string "
12")
11776 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11777 (match_test "which_alternative !=
1"))
11778 (match_test "(INTVAL (operands[
2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11779 (const_string "
8")]
11780 (const_string "
4")))])
11782 (define_insn "*sibcall_nonlocal_sysv<mode>"
11783 [(call (mem:SI (match_operand:P
0 "symbol_ref_operand" "s,s"))
11785 (use (match_operand
2 "immediate_operand" "O,n"))
11787 "(DEFAULT_ABI == ABI_DARWIN
11788 || DEFAULT_ABI == ABI_V4)
11789 && (INTVAL (operands[
2]) & CALL_LONG) ==
0"
11791 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
11792 output_asm_insn ("crxor
6,
6,
6", operands);
11794 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
11795 output_asm_insn ("creqv
6,
6,
6", operands);
11797 return rs6000_sibcall_template (operands,
0);
11799 [(set_attr "type" "branch")
11800 (set_attr "length" "
4,
8")])
11802 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11803 [(set (match_operand
0 "" "")
11804 (call (mem:SI (match_operand:P
1 "indirect_call_operand" "c,*l,X"))
11805 (match_operand
2)))
11806 (use (match_operand:SI
3 "immediate_operand" "n,n,n"))
11808 "DEFAULT_ABI == ABI_V4
11809 || DEFAULT_ABI == ABI_DARWIN"
11811 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
11812 output_asm_insn ("crxor
6,
6,
6", operands);
11814 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
11815 output_asm_insn ("creqv
6,
6,
6", operands);
11817 return rs6000_indirect_sibcall_template (operands,
1);
11819 [(set_attr "type" "jmpreg")
11820 (set (attr "length")
11821 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11822 (match_test "which_alternative !=
1"))
11823 (match_test "(INTVAL (operands[
3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11824 (const_string "
12")
11825 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11826 (match_test "which_alternative !=
1"))
11827 (match_test "(INTVAL (operands[
3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11828 (const_string "
8")]
11829 (const_string "
4")))])
11831 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11832 [(set (match_operand
0 "" "")
11833 (call (mem:SI (match_operand:P
1 "symbol_ref_operand" "s,s"))
11834 (match_operand
2)))
11835 (use (match_operand:SI
3 "immediate_operand" "O,n"))
11837 "(DEFAULT_ABI == ABI_DARWIN
11838 || DEFAULT_ABI == ABI_V4)
11839 && (INTVAL (operands[
3]) & CALL_LONG) ==
0"
11841 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
11842 output_asm_insn ("crxor
6,
6,
6", operands);
11844 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
11845 output_asm_insn ("creqv
6,
6,
6", operands);
11847 return rs6000_sibcall_template (operands,
1);
11849 [(set_attr "type" "branch")
11850 (set_attr "length" "
4,
8")])
11852 ;; AIX ABI sibling call patterns.
11854 (define_insn "*sibcall_aix<mode>"
11855 [(call (mem:SI (match_operand:P
0 "call_operand" "s,c"))
11858 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11860 if (which_alternative ==
0)
11861 return rs6000_sibcall_template (operands,
0);
11865 [(set_attr "type" "branch")])
11867 (define_insn "*sibcall_value_aix<mode>"
11868 [(set (match_operand
0 "" "")
11869 (call (mem:SI (match_operand:P
1 "call_operand" "s,c"))
11870 (match_operand
2)))
11872 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11874 if (which_alternative ==
0)
11875 return rs6000_sibcall_template (operands,
1);
11879 [(set_attr "type" "branch")])
11881 (define_expand "sibcall_epilogue"
11882 [(use (const_int
0))]
11885 if (!TARGET_SCHED_PROLOG)
11886 emit_insn (gen_blockage ());
11887 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11891 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11892 ;; all of memory. This blocks insns from being moved across this point.
11894 (define_insn "blockage"
11895 [(unspec_volatile [(const_int
0)] UNSPECV_BLOCK)]
11898 [(set_attr "length" "
0")])
11900 (define_expand "probe_stack_address"
11901 [(use (match_operand
0 "address_operand"))]
11904 operands[
0] = gen_rtx_MEM (Pmode, operands[
0]);
11905 MEM_VOLATILE_P (operands[
0]) =
1;
11908 emit_insn (gen_probe_stack_di (operands[
0]));
11910 emit_insn (gen_probe_stack_si (operands[
0]));
11914 (define_insn "probe_stack_<mode>"
11915 [(set (match_operand:P
0 "memory_operand" "=m")
11916 (unspec:P [(const_int
0)] UNSPEC_PROBE_STACK))]
11919 operands[
1] = gen_rtx_REG (Pmode,
0);
11920 return "st<wd>%U0%X0 %
1,%
0";
11922 [(set_attr "type" "store")
11923 (set (attr "update")
11924 (if_then_else (match_operand
0 "update_address_mem")
11925 (const_string "yes")
11926 (const_string "no")))
11927 (set (attr "indexed")
11928 (if_then_else (match_operand
0 "indexed_address_mem")
11929 (const_string "yes")
11930 (const_string "no")))])
11932 (define_insn "probe_stack_range<P:mode>"
11933 [(set (match_operand:P
0 "register_operand" "=&r")
11934 (unspec_volatile:P [(match_operand:P
1 "register_operand" "
0")
11935 (match_operand:P
2 "register_operand" "r")
11936 (match_operand:P
3 "register_operand" "r")]
11937 UNSPECV_PROBE_STACK_RANGE))]
11939 "* return output_probe_stack_range (operands[
0], operands[
2], operands[
3]);"
11940 [(set_attr "type" "three")])
11942 ;; Compare insns are next. Note that the RS/
6000 has two types of compares,
11943 ;; signed & unsigned, and one type of branch.
11945 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11946 ;; insns, and branches.
11948 (define_expand "cbranch<mode>
4"
11949 [(use (match_operator
0 "comparison_operator"
11950 [(match_operand:GPR
1 "gpc_reg_operand")
11951 (match_operand:GPR
2 "reg_or_short_operand")]))
11952 (use (match_operand
3))]
11955 /* Take care of the possibility that operands[
2] might be negative but
11956 this might be a logical operation. That insn doesn't exist. */
11957 if (CONST_INT_P (operands[
2])
11958 && INTVAL (operands[
2]) <
0)
11960 operands[
2] = force_reg (<MODE>mode, operands[
2]);
11961 operands[
0] = gen_rtx_fmt_ee (GET_CODE (operands[
0]),
11962 GET_MODE (operands[
0]),
11963 operands[
1], operands[
2]);
11966 rs6000_emit_cbranch (<MODE>mode, operands);
11970 (define_expand "cbranch<mode>
4"
11971 [(use (match_operator
0 "comparison_operator"
11972 [(match_operand:FP
1 "gpc_reg_operand")
11973 (match_operand:FP
2 "gpc_reg_operand")]))
11974 (use (match_operand
3))]
11977 rs6000_emit_cbranch (<MODE>mode, operands);
11981 (define_expand "cbranchcc4"
11983 (if_then_else (match_operator
0 "branch_comparison_operator"
11984 [(match_operand
1 "cc_reg_operand")
11985 (match_operand
2 "zero_constant")])
11986 (label_ref (match_operand
3))
11991 (define_expand "cstore<mode>
4_signed"
11992 [(use (match_operator
1 "signed_comparison_operator"
11993 [(match_operand:P
2 "gpc_reg_operand")
11994 (match_operand:P
3 "gpc_reg_operand")]))
11995 (clobber (match_operand:P
0 "gpc_reg_operand"))]
11998 enum rtx_code cond_code = GET_CODE (operands[
1]);
12000 rtx op0 = operands[
0];
12001 rtx op1 = operands[
2];
12002 rtx op2 = operands[
3];
12004 if (cond_code == GE || cond_code == LT)
12006 cond_code = swap_condition (cond_code);
12007 std::swap (op1, op2);
12010 rtx tmp1 = gen_reg_rtx (<MODE>mode);
12011 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12012 rtx tmp3 = gen_reg_rtx (<MODE>mode);
12014 int sh = GET_MODE_BITSIZE (<MODE>mode) -
1;
12015 emit_insn (gen_lshr<mode>
3 (tmp1, op1, GEN_INT (sh)));
12016 emit_insn (gen_ashr<mode>
3 (tmp2, op2, GEN_INT (sh)));
12018 emit_insn (gen_subf<mode>
3_carry (tmp3, op1, op2));
12020 if (cond_code == LE)
12021 emit_insn (gen_add<mode>
3_carry_in (op0, tmp1, tmp2));
12024 rtx tmp4 = gen_reg_rtx (<MODE>mode);
12025 emit_insn (gen_add<mode>
3_carry_in (tmp4, tmp1, tmp2));
12026 emit_insn (gen_xor<mode>
3 (op0, tmp4, const1_rtx));
12032 (define_expand "cstore<mode>
4_unsigned"
12033 [(use (match_operator
1 "unsigned_comparison_operator"
12034 [(match_operand:P
2 "gpc_reg_operand")
12035 (match_operand:P
3 "reg_or_short_operand")]))
12036 (clobber (match_operand:P
0 "gpc_reg_operand"))]
12039 enum rtx_code cond_code = GET_CODE (operands[
1]);
12041 rtx op0 = operands[
0];
12042 rtx op1 = operands[
2];
12043 rtx op2 = operands[
3];
12045 if (cond_code == GEU || cond_code == LTU)
12047 cond_code = swap_condition (cond_code);
12048 std::swap (op1, op2);
12051 if (!gpc_reg_operand (op1, <MODE>mode))
12052 op1 = force_reg (<MODE>mode, op1);
12053 if (!reg_or_short_operand (op2, <MODE>mode))
12054 op2 = force_reg (<MODE>mode, op2);
12056 rtx tmp = gen_reg_rtx (<MODE>mode);
12057 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12059 emit_insn (gen_subf<mode>
3_carry (tmp, op1, op2));
12060 emit_insn (gen_subf<mode>
3_carry_in_xx (tmp2));
12062 if (cond_code == LEU)
12063 emit_insn (gen_add<mode>
3 (op0, tmp2, const1_rtx));
12065 emit_insn (gen_neg<mode>
2 (op0, tmp2));
12070 (define_expand "cstore_si_as_di"
12071 [(use (match_operator
1 "unsigned_comparison_operator"
12072 [(match_operand:SI
2 "gpc_reg_operand")
12073 (match_operand:SI
3 "reg_or_short_operand")]))
12074 (clobber (match_operand:SI
0 "gpc_reg_operand"))]
12077 int uns_flag = unsigned_comparison_operator (operands[
1], VOIDmode) ?
1 :
0;
12078 enum rtx_code cond_code = signed_condition (GET_CODE (operands[
1]));
12080 operands[
2] = force_reg (SImode, operands[
2]);
12081 operands[
3] = force_reg (SImode, operands[
3]);
12082 rtx op1 = gen_reg_rtx (DImode);
12083 rtx op2 = gen_reg_rtx (DImode);
12084 convert_move (op1, operands[
2], uns_flag);
12085 convert_move (op2, operands[
3], uns_flag);
12087 if (cond_code == GT || cond_code == LE)
12089 cond_code = swap_condition (cond_code);
12090 std::swap (op1, op2);
12093 rtx tmp = gen_reg_rtx (DImode);
12094 rtx tmp2 = gen_reg_rtx (DImode);
12095 emit_insn (gen_subdi3 (tmp, op1, op2));
12096 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (
63)));
12102 gcc_unreachable ();
12107 tmp3 = gen_reg_rtx (DImode);
12108 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
12112 convert_move (operands[
0], tmp3,
1);
12117 (define_expand "cstore<mode>
4_signed_imm"
12118 [(use (match_operator
1 "signed_comparison_operator"
12119 [(match_operand:GPR
2 "gpc_reg_operand")
12120 (match_operand:GPR
3 "immediate_operand")]))
12121 (clobber (match_operand:GPR
0 "gpc_reg_operand"))]
12124 bool invert = false;
12126 enum rtx_code cond_code = GET_CODE (operands[
1]);
12128 rtx op0 = operands[
0];
12129 rtx op1 = operands[
2];
12130 HOST_WIDE_INT val = INTVAL (operands[
3]);
12132 if (cond_code == GE || cond_code == GT)
12134 cond_code = reverse_condition (cond_code);
12138 if (cond_code == LE)
12141 rtx tmp = gen_reg_rtx (<MODE>mode);
12142 emit_insn (gen_add<mode>
3 (tmp, op1, GEN_INT (-val)));
12143 rtx x = gen_reg_rtx (<MODE>mode);
12145 emit_insn (gen_and<mode>
3 (x, op1, tmp));
12147 emit_insn (gen_ior<mode>
3 (x, op1, tmp));
12151 rtx tmp = gen_reg_rtx (<MODE>mode);
12152 emit_insn (gen_one_cmpl<mode>
2 (tmp, x));
12156 int sh = GET_MODE_BITSIZE (<MODE>mode) -
1;
12157 emit_insn (gen_lshr<mode>
3 (op0, x, GEN_INT (sh)));
12162 (define_expand "cstore<mode>
4_unsigned_imm"
12163 [(use (match_operator
1 "unsigned_comparison_operator"
12164 [(match_operand:GPR
2 "gpc_reg_operand")
12165 (match_operand:GPR
3 "immediate_operand")]))
12166 (clobber (match_operand:GPR
0 "gpc_reg_operand"))]
12169 bool invert = false;
12171 enum rtx_code cond_code = GET_CODE (operands[
1]);
12173 rtx op0 = operands[
0];
12174 rtx op1 = operands[
2];
12175 HOST_WIDE_INT val = INTVAL (operands[
3]);
12177 if (cond_code == GEU || cond_code == GTU)
12179 cond_code = reverse_condition (cond_code);
12183 if (cond_code == LEU)
12186 rtx tmp = gen_reg_rtx (<MODE>mode);
12187 rtx tmp2 = gen_reg_rtx (<MODE>mode);
12188 emit_insn (gen_add<mode>
3 (tmp, op1, GEN_INT (-val)));
12189 emit_insn (gen_one_cmpl<mode>
2 (tmp2, op1));
12190 rtx x = gen_reg_rtx (<MODE>mode);
12192 emit_insn (gen_ior<mode>
3 (x, tmp, tmp2));
12194 emit_insn (gen_and<mode>
3 (x, tmp, tmp2));
12198 rtx tmp = gen_reg_rtx (<MODE>mode);
12199 emit_insn (gen_one_cmpl<mode>
2 (tmp, x));
12203 int sh = GET_MODE_BITSIZE (<MODE>mode) -
1;
12204 emit_insn (gen_lshr<mode>
3 (op0, x, GEN_INT (sh)));
12209 (define_expand "cstore<mode>
4"
12210 [(use (match_operator
1 "comparison_operator"
12211 [(match_operand:GPR
2 "gpc_reg_operand")
12212 (match_operand:GPR
3 "reg_or_short_operand")]))
12213 (clobber (match_operand:GPR
0 "gpc_reg_operand"))]
12216 /* Everything is best done with setbc[r] if available. */
12217 if (TARGET_POWER10 && TARGET_ISEL)
12219 rs6000_emit_int_cmove (operands[
0], operands[
1], const1_rtx, const0_rtx);
12223 /* Expanding EQ and NE directly to some machine instructions does not help
12224 but does hurt combine. So don't. */
12225 if (GET_CODE (operands[
1]) == EQ)
12226 emit_insn (gen_eq<mode>
3 (operands[
0], operands[
2], operands[
3]));
12227 else if (<MODE>mode == Pmode
12228 && GET_CODE (operands[
1]) == NE)
12229 emit_insn (gen_ne<mode>
3 (operands[
0], operands[
2], operands[
3]));
12230 else if (GET_CODE (operands[
1]) == NE)
12232 rtx tmp = gen_reg_rtx (<MODE>mode);
12233 emit_insn (gen_eq<mode>
3 (tmp, operands[
2], operands[
3]));
12234 emit_insn (gen_xor<mode>
3 (operands[
0], tmp, const1_rtx));
12237 /* If ISEL is fast, expand to it. */
12238 else if (TARGET_ISEL)
12239 rs6000_emit_int_cmove (operands[
0], operands[
1], const1_rtx, const0_rtx);
12241 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
12242 etc. combinations magically work out just right. */
12243 else if (<MODE>mode == Pmode
12244 && unsigned_comparison_operator (operands[
1], VOIDmode))
12245 emit_insn (gen_cstore<mode>
4_unsigned (operands[
0], operands[
1],
12246 operands[
2], operands[
3]));
12248 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
12249 else if (<MODE>mode == SImode && Pmode == DImode)
12250 emit_insn (gen_cstore_si_as_di (operands[
0], operands[
1],
12251 operands[
2], operands[
3]));
12253 /* For signed comparisons against a constant, we can do some simple
12255 else if (signed_comparison_operator (operands[
1], VOIDmode)
12256 && CONST_INT_P (operands[
3]))
12257 emit_insn (gen_cstore<mode>
4_signed_imm (operands[
0], operands[
1],
12258 operands[
2], operands[
3]));
12260 /* And similarly for unsigned comparisons. */
12261 else if (unsigned_comparison_operator (operands[
1], VOIDmode)
12262 && CONST_INT_P (operands[
3]))
12263 emit_insn (gen_cstore<mode>
4_unsigned_imm (operands[
0], operands[
1],
12264 operands[
2], operands[
3]));
12266 /* We also do not want to use mfcr for signed comparisons. */
12267 else if (<MODE>mode == Pmode
12268 && signed_comparison_operator (operands[
1], VOIDmode))
12269 emit_insn (gen_cstore<mode>
4_signed (operands[
0], operands[
1],
12270 operands[
2], operands[
3]));
12272 /* Everything else, use the mfcr brute force. */
12274 rs6000_emit_sCOND (<MODE>mode, operands);
12279 (define_expand "cstore<mode>
4"
12280 [(use (match_operator
1 "comparison_operator"
12281 [(match_operand:FP
2 "gpc_reg_operand")
12282 (match_operand:FP
3 "gpc_reg_operand")]))
12283 (clobber (match_operand:SI
0 "gpc_reg_operand"))]
12286 rs6000_emit_sCOND (<MODE>mode, operands);
12291 (define_expand "stack_protect_set"
12292 [(match_operand
0 "memory_operand")
12293 (match_operand
1 "memory_operand")]
12296 if (rs6000_stack_protector_guard == SSP_TLS)
12298 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
12299 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
12300 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
12301 operands[
1] = gen_rtx_MEM (Pmode, addr);
12305 emit_insn (gen_stack_protect_setdi (operands[
0], operands[
1]));
12307 emit_insn (gen_stack_protect_setsi (operands[
0], operands[
1]));
12312 (define_insn "stack_protect_setsi"
12313 [(set (match_operand:SI
0 "memory_operand" "=m")
12314 (unspec:SI [(match_operand:SI
1 "memory_operand" "m")] UNSPEC_SP_SET))
12315 (set (match_scratch:SI
2 "=&r") (const_int
0))]
12317 "lwz%U1%X1 %
2,%
1\;stw%U0%X0 %
2,%
0\;li %
2,
0"
12318 [(set_attr "type" "three")
12319 (set_attr "length" "
12")])
12321 ;; We can't use the prefixed attribute here because there are two memory
12322 ;; instructions. We can't split the insn due to the fact that this operation
12323 ;; needs to be done in one piece.
12324 (define_insn "stack_protect_setdi"
12325 [(set (match_operand:DI
0 "memory_operand" "=Y")
12326 (unspec:DI [(match_operand:DI
1 "memory_operand" "Y")] UNSPEC_SP_SET))
12327 (set (match_scratch:DI
2 "=&r") (const_int
0))]
12330 if (prefixed_memory (operands[
1], DImode))
12331 output_asm_insn ("pld %
2,%
1", operands);
12333 output_asm_insn ("ld%U1%X1 %
2,%
1", operands);
12335 if (prefixed_memory (operands[
0], DImode))
12336 output_asm_insn ("pstd %
2,%
0", operands);
12338 output_asm_insn ("std%U0%X0 %
2,%
0", operands);
12342 [(set_attr "type" "three")
12344 ;; Back to back prefixed memory instructions take
20 bytes (
8 bytes for each
12345 ;; prefixed instruction +
4 bytes for the possible NOP). Add in
4 bytes for
12346 ;; the LI
0 at the end.
12347 (set_attr "prefixed" "no")
12348 (set_attr "num_insns" "
3")
12349 (set (attr "length")
12350 (cond [(and (match_operand
0 "prefixed_memory")
12351 (match_operand
1 "prefixed_memory"))
12354 (ior (match_operand
0 "prefixed_memory")
12355 (match_operand
1 "prefixed_memory"))
12360 (define_expand "stack_protect_test"
12361 [(match_operand
0 "memory_operand")
12362 (match_operand
1 "memory_operand")
12363 (match_operand
2 "")]
12366 rtx guard = operands[
1];
12368 if (rs6000_stack_protector_guard == SSP_TLS)
12370 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
12371 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
12372 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
12373 guard = gen_rtx_MEM (Pmode, addr);
12376 operands[
1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (
1, guard), UNSPEC_SP_TEST);
12377 rtx test = gen_rtx_EQ (VOIDmode, operands[
0], operands[
1]);
12378 rtx jump = gen_cbranchsi4 (test, operands[
0], operands[
1], operands[
2]);
12379 emit_jump_insn (jump);
12384 (define_insn "stack_protect_testsi"
12385 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=x,?y")
12386 (unspec:CCEQ [(match_operand:SI
1 "memory_operand" "m,m")
12387 (match_operand:SI
2 "memory_operand" "m,m")]
12389 (set (match_scratch:SI
4 "=r,r") (const_int
0))
12390 (clobber (match_scratch:SI
3 "=&r,&r"))]
12393 lwz%U1%X1 %
3,%
1\;lwz%U2%X2 %
4,%
2\;xor. %
3,%
3,%
4\;li %
4,
0
12394 lwz%U1%X1 %
3,%
1\;lwz%U2%X2 %
4,%
2\;cmplw %
0,%
3,%
4\;li %
3,
0\;li %
4,
0"
12395 [(set_attr "length" "
16,
20")])
12397 ;; We can't use the prefixed attribute here because there are two memory
12398 ;; instructions. We can't split the insn due to the fact that this operation
12399 ;; needs to be done in one piece.
12400 (define_insn "stack_protect_testdi"
12401 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=x,?y")
12402 (unspec:CCEQ [(match_operand:DI
1 "memory_operand" "Y,Y")
12403 (match_operand:DI
2 "memory_operand" "Y,Y")]
12405 (set (match_scratch:DI
4 "=r,r") (const_int
0))
12406 (clobber (match_scratch:DI
3 "=&r,&r"))]
12409 if (prefixed_memory (operands[
1], DImode))
12410 output_asm_insn ("pld %
3,%
1", operands);
12412 output_asm_insn ("ld%U1%X1 %
3,%
1", operands);
12414 if (prefixed_memory (operands[
2], DImode))
12415 output_asm_insn ("pld %
4,%
2", operands);
12417 output_asm_insn ("ld%U2%X2 %
4,%
2", operands);
12419 if (which_alternative ==
0)
12420 output_asm_insn ("xor. %
3,%
3,%
4", operands);
12422 output_asm_insn ("cmpld %
0,%
3,%
4\;li %
3,
0", operands);
12426 ;; Back to back prefixed memory instructions take
20 bytes (
8 bytes for each
12427 ;; prefixed instruction +
4 bytes for the possible NOP). Add in either
4 or
12428 ;;
8 bytes to do the test.
12429 [(set_attr "prefixed" "no")
12430 (set_attr "num_insns" "
4,
5")
12431 (set (attr "length")
12432 (cond [(and (match_operand
1 "prefixed_memory")
12433 (match_operand
2 "prefixed_memory"))
12434 (if_then_else (eq_attr "alternative" "
0")
12438 (ior (match_operand
1 "prefixed_memory")
12439 (match_operand
2 "prefixed_memory"))
12440 (if_then_else (eq_attr "alternative" "
0")
12444 (if_then_else (eq_attr "alternative" "
0")
12446 (const_int
20))))])
12449 ;; Here are the actual compare insns.
12450 (define_insn "*cmp<mode>_signed"
12451 [(set (match_operand:CC
0 "cc_reg_operand" "=y")
12452 (compare:CC (match_operand:GPR
1 "gpc_reg_operand" "r")
12453 (match_operand:GPR
2 "reg_or_short_operand" "rI")))]
12455 "cmp<wd>%I2 %
0,%
1,%
2"
12456 [(set_attr "type" "cmp")])
12458 (define_insn "*cmp<mode>_unsigned"
12459 [(set (match_operand:CCUNS
0 "cc_reg_operand" "=y")
12460 (compare:CCUNS (match_operand:GPR
1 "gpc_reg_operand" "r")
12461 (match_operand:GPR
2 "reg_or_u_short_operand" "rK")))]
12463 "cmpl<wd>%I2 %
0,%
1,%
2"
12464 [(set_attr "type" "cmp")])
12466 ;; If we are comparing a register for equality with a large constant,
12467 ;; we can do this with an XOR followed by a compare. But this is profitable
12468 ;; only if the large constant is only used for the comparison (and in this
12469 ;; case we already have a register to reuse as scratch).
12471 ;; For
64-bit registers, we could only do so if the constant's bit
15 is clear:
12472 ;; otherwise we'd need to XOR with FFFFFFFF????
0000 which is not available.
12475 [(set (match_operand:SI
0 "register_operand")
12476 (match_operand:SI
1 "logical_const_operand"))
12477 (set (match_dup
0) (match_operator:SI
3 "boolean_or_operator"
12479 (match_operand:SI
2 "logical_const_operand")]))
12480 (set (match_operand:CC
4 "cc_reg_operand")
12481 (compare:CC (match_operand:SI
5 "gpc_reg_operand")
12484 (if_then_else (match_operator
6 "equality_operator"
12485 [(match_dup
4) (const_int
0)])
12486 (match_operand
7 "")
12487 (match_operand
8 "")))]
12488 "peep2_reg_dead_p (
3, operands[
0])
12489 && peep2_reg_dead_p (
4, operands[
4])
12490 && REGNO (operands[
0]) != REGNO (operands[
5])"
12491 [(set (match_dup
0) (xor:SI (match_dup
5) (match_dup
9)))
12492 (set (match_dup
4) (compare:CC (match_dup
0) (match_dup
10)))
12493 (set (pc) (if_then_else (match_dup
6) (match_dup
7) (match_dup
8)))]
12496 /* Get the constant we are comparing against, and see what it looks like
12497 when sign-extended from
16 to
32 bits. Then see what constant we could
12498 XOR with SEXTC to get the sign-extended value. */
12499 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[
3]),
12501 operands[
1], operands[
2]);
12502 HOST_WIDE_INT c = INTVAL (cnst);
12503 HOST_WIDE_INT sextc = sext_hwi (c,
16);
12504 HOST_WIDE_INT xorv = c ^ sextc;
12506 operands[
9] = GEN_INT (xorv);
12507 operands[
10] = GEN_INT (sextc);
12510 ;; Only need to compare second words if first words equal
12511 (define_insn "*cmp<mode>_internal1"
12512 [(set (match_operand:CCFP
0 "cc_reg_operand" "=y")
12513 (compare:CCFP (match_operand:IBM128
1 "gpc_reg_operand" "d")
12514 (match_operand:IBM128
2 "gpc_reg_operand" "d")))]
12515 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12516 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
12517 "fcmpu %
0,%
1,%
2\;bne %
0,$+
8\;fcmpu %
0,%L1,%L2"
12518 [(set_attr "type" "fpcompare")
12519 (set_attr "length" "
12")])
12521 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
12522 [(set (match_operand:CCFP
0 "cc_reg_operand" "=y")
12523 (compare:CCFP (match_operand:IBM128
1 "gpc_reg_operand" "d")
12524 (match_operand:IBM128
2 "gpc_reg_operand" "d")))
12525 (clobber (match_scratch:DF
3 "=d"))
12526 (clobber (match_scratch:DF
4 "=d"))
12527 (clobber (match_scratch:DF
5 "=d"))
12528 (clobber (match_scratch:DF
6 "=d"))
12529 (clobber (match_scratch:DF
7 "=d"))
12530 (clobber (match_scratch:DF
8 "=d"))
12531 (clobber (match_scratch:DF
9 "=d"))
12532 (clobber (match_scratch:DF
10 "=d"))
12533 (clobber (match_scratch:GPR
11 "=b"))]
12534 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
12535 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
12537 "&& reload_completed"
12538 [(set (match_dup
3) (match_dup
14))
12539 (set (match_dup
4) (match_dup
15))
12540 (set (match_dup
9) (abs:DF (match_dup
5)))
12541 (set (match_dup
0) (compare:CCFP (match_dup
9) (match_dup
3)))
12542 (set (pc) (if_then_else (ne (match_dup
0) (const_int
0))
12543 (label_ref (match_dup
12))
12545 (set (match_dup
0) (compare:CCFP (match_dup
5) (match_dup
7)))
12546 (set (pc) (label_ref (match_dup
13)))
12548 (set (match_dup
10) (minus:DF (match_dup
5) (match_dup
7)))
12549 (set (match_dup
9) (minus:DF (match_dup
6) (match_dup
8)))
12550 (set (match_dup
9) (plus:DF (match_dup
10) (match_dup
9)))
12551 (set (match_dup
0) (compare:CCFP (match_dup
9) (match_dup
4)))
12554 REAL_VALUE_TYPE rv;
12555 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) :
0;
12556 const int hi_word = LONG_DOUBLE_LARGE_FIRST ?
0 : GET_MODE_SIZE (DFmode);
12558 operands[
5] = simplify_gen_subreg (DFmode, operands[
1],
12559 <IBM128:MODE>mode, hi_word);
12560 operands[
6] = simplify_gen_subreg (DFmode, operands[
1],
12561 <IBM128:MODE>mode, lo_word);
12562 operands[
7] = simplify_gen_subreg (DFmode, operands[
2],
12563 <IBM128:MODE>mode, hi_word);
12564 operands[
8] = simplify_gen_subreg (DFmode, operands[
2],
12565 <IBM128:MODE>mode, lo_word);
12566 operands[
12] = gen_label_rtx ();
12567 operands[
13] = gen_label_rtx ();
12569 operands[
14] = force_const_mem (DFmode,
12570 const_double_from_real_value (rv, DFmode));
12571 operands[
15] = force_const_mem (DFmode,
12572 const_double_from_real_value (dconst0,
12577 tocref = create_TOC_reference (XEXP (operands[
14],
0), operands[
11]);
12578 operands[
14] = gen_const_mem (DFmode, tocref);
12579 tocref = create_TOC_reference (XEXP (operands[
15],
0), operands[
11]);
12580 operands[
15] = gen_const_mem (DFmode, tocref);
12581 set_mem_alias_set (operands[
14], get_TOC_alias_set ());
12582 set_mem_alias_set (operands[
15], get_TOC_alias_set ());
12586 ;; Now we have the scc insns. We can do some combinations because of the
12587 ;; way the machine works.
12589 ;; Note that this is probably faster if we can put an insn between the
12590 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12591 ;; cases the insns below which don't use an intermediate CR field will
12592 ;; be used instead.
12593 (define_insn "set<mode>_cc"
12594 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
12595 (match_operator:GPR
1 "scc_comparison_operator"
12596 [(match_operand
2 "cc_reg_operand" "y")
12599 "mfcr %
0%Q2\;rlwinm %
0,%
0,%J1,
1"
12600 [(set (attr "type")
12601 (cond [(match_test "TARGET_MFCRF")
12602 (const_string "mfcrf")
12604 (const_string "mfcr")))
12605 (set_attr "length" "
8")])
12608 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
12609 (define_code_attr UNS [(eq "CC")
12611 (lt "CC") (ltu "CCUNS")
12612 (gt "CC") (gtu "CCUNS")
12613 (le "CC") (leu "CCUNS")
12614 (ge "CC") (geu "CCUNS")])
12615 (define_code_attr UNSu_ [(eq "")
12620 (ge "") (geu "u_")])
12621 (define_code_attr UNSIK [(eq "I")
12626 (ge "I") (geu "K")])
12628 (define_insn_and_split "<code><GPR:mode><GPR2:mode>
2_isel"
12629 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
12630 (cmp:GPR (match_operand:GPR2
1 "gpc_reg_operand" "r")
12631 (match_operand:GPR2
2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
12632 (clobber (match_scratch:GPR
3 "=r"))
12633 (clobber (match_scratch:GPR
4 "=r"))
12634 (clobber (match_scratch:<UNS>
5 "=y"))]
12635 "!TARGET_POWER10 && TARGET_ISEL
12636 && !(<CODE> == EQ && operands[
2] == const0_rtx)
12637 && !(<CODE> == NE && operands[
2] == const0_rtx
12638 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
12643 rtx_code code = <CODE>;
12644 if (CONST_INT_P (operands[
2]) && code != EQ && code != NE)
12646 HOST_WIDE_INT val = INTVAL (operands[
2]);
12647 if (code == LT && val != -
0x8000)
12652 if (code == GT && val !=
0x7fff)
12657 if (code == LTU && val !=
0)
12662 if (code == GTU && val !=
0xffff)
12667 operands[
2] = GEN_INT (val);
12670 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
12671 operands[
3] = const0_rtx;
12674 if (GET_CODE (operands[
3]) == SCRATCH)
12675 operands[
3] = gen_reg_rtx (<GPR:MODE>mode);
12676 emit_move_insn (operands[
3], const0_rtx);
12679 if (GET_CODE (operands[
4]) == SCRATCH)
12680 operands[
4] = gen_reg_rtx (<GPR:MODE>mode);
12681 emit_move_insn (operands[
4], const1_rtx);
12683 if (GET_CODE (operands[
5]) == SCRATCH)
12684 operands[
5] = gen_reg_rtx (<UNS>mode);
12686 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[
1], operands[
2]);
12687 emit_insn (gen_rtx_SET (operands[
5], c1));
12689 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[
5], const0_rtx);
12690 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[
4], operands[
3]);
12691 emit_move_insn (operands[
0], x);
12695 [(set (attr "cost")
12696 (if_then_else (match_test "(CONST_INT_P (operands[
2]) && <CODE> != EQ)
12698 || <CODE> == LE || <CODE> == GE
12699 || <CODE> == LEU || <CODE> == GEU")
12701 (const_string "
10")))])
12703 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12706 (define_expand "eq<mode>
3"
12708 (set (match_operand:GPR
0 "gpc_reg_operand" "=r")
12709 (eq:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
12710 (match_operand:GPR
2 "scc_eq_operand" "<scc_eq_op2>")))
12711 (clobber (match_scratch:GPR
3 "=r"))
12712 (clobber (match_scratch:GPR
4 "=r"))])]
12715 if (TARGET_POWER10)
12717 rtx cc = gen_reg_rtx (CCmode);
12718 rtx compare = gen_rtx_COMPARE (CCmode, operands[
1], operands[
2]);
12719 emit_insn (gen_rtx_SET (cc, compare));
12720 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
12721 emit_insn (gen_setbc_cc_<mode> (operands[
0], eq, cc));
12725 if (TARGET_ISEL && operands[
2] != const0_rtx)
12727 emit_insn (gen_eq<mode><mode>
2_isel (operands[
0], operands[
1],
12733 (define_insn_and_split "*eq<mode>
3"
12734 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
12735 (eq:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
12736 (match_operand:GPR
2 "scc_eq_operand" "<scc_eq_op2>")))
12737 (clobber (match_scratch:GPR
3 "=r"))
12738 (clobber (match_scratch:GPR
4 "=r"))]
12739 "!TARGET_POWER10 && !(TARGET_ISEL && operands[
2] != const0_rtx)"
12742 [(set (match_dup
4)
12743 (clz:GPR (match_dup
3)))
12745 (lshiftrt:GPR (match_dup
4)
12748 operands[
3] = rs6000_emit_eqne (<MODE>mode,
12749 operands[
1], operands[
2], operands[
3]);
12751 if (GET_CODE (operands[
4]) == SCRATCH)
12752 operands[
4] = gen_reg_rtx (<MODE>mode);
12754 operands[
5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12756 [(set (attr "length")
12757 (if_then_else (match_test "operands[
2] == const0_rtx")
12759 (const_string "
12")))])
12761 (define_expand "ne<mode>
3"
12763 (set (match_operand:GPR
0 "gpc_reg_operand" "=r")
12764 (ne:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
12765 (match_operand:GPR
2 "scc_eq_operand" "<scc_eq_op2>")))
12766 (clobber (match_scratch:GPR
3 "=r"))
12767 (clobber (match_scratch:GPR
4 "=r"))
12768 (clobber (reg:GPR CA_REGNO))])]
12771 if (TARGET_POWER10)
12773 rtx cc = gen_reg_rtx (CCmode);
12774 rtx compare = gen_rtx_COMPARE (CCmode, operands[
1], operands[
2]);
12775 emit_insn (gen_rtx_SET (cc, compare));
12776 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
12777 emit_insn (gen_setbc_cc_<mode> (operands[
0], ne, cc));
12781 if (<MODE>mode != Pmode)
12783 rtx x = gen_reg_rtx (<MODE>mode);
12784 emit_insn (gen_eq<mode>
3 (x, operands[
1], operands[
2]));
12785 emit_insn (gen_xor<mode>
3 (operands[
0], x, const1_rtx));
12789 if (TARGET_ISEL && operands[
2] != const0_rtx)
12791 emit_insn (gen_ne<mode><mode>
2_isel (operands[
0], operands[
1],
12797 (define_insn_and_split "*ne<mode>
3"
12798 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12799 (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))]
12804 "!TARGET_POWER10 && !(TARGET_ISEL && operands[
2] != const0_rtx)"
12807 [(parallel [(set (match_dup
4)
12808 (plus:P (match_dup
3)
12810 (set (reg:P CA_REGNO)
12811 (ne:P (match_dup
3)
12813 (parallel [(set (match_dup
0)
12814 (plus:P (plus:P (not:P (match_dup
4))
12817 (clobber (reg:P CA_REGNO))])]
12819 operands[
3] = rs6000_emit_eqne (<MODE>mode,
12820 operands[
1], operands[
2], operands[
3]);
12822 if (GET_CODE (operands[
4]) == SCRATCH)
12823 operands[
4] = gen_reg_rtx (<MODE>mode);
12825 [(set (attr "length")
12826 (if_then_else (match_test "operands[
2] == const0_rtx")
12828 (const_string "
12")))])
12830 (define_insn_and_split "*neg_eq_<mode>"
12831 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12832 (neg:P (eq:P (match_operand:P
1 "gpc_reg_operand" "r")
12833 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))))
12834 (clobber (match_scratch:P
3 "=r"))
12835 (clobber (match_scratch:P
4 "=r"))
12836 (clobber (reg:P CA_REGNO))]
12840 [(parallel [(set (match_dup
4)
12841 (plus:P (match_dup
3)
12843 (set (reg:P CA_REGNO)
12844 (ne:P (match_dup
3)
12846 (parallel [(set (match_dup
0)
12847 (plus:P (reg:P CA_REGNO)
12849 (clobber (reg:P CA_REGNO))])]
12851 operands[
3] = rs6000_emit_eqne (<MODE>mode,
12852 operands[
1], operands[
2], operands[
3]);
12854 if (GET_CODE (operands[
4]) == SCRATCH)
12855 operands[
4] = gen_reg_rtx (<MODE>mode);
12857 [(set (attr "length")
12858 (if_then_else (match_test "operands[
2] == const0_rtx")
12860 (const_string "
12")))])
12862 (define_insn_and_split "*neg_ne_<mode>"
12863 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12864 (neg:P (ne:P (match_operand:P
1 "gpc_reg_operand" "r")
12865 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))))
12866 (clobber (match_scratch:P
3 "=r"))
12867 (clobber (match_scratch:P
4 "=r"))
12868 (clobber (reg:P CA_REGNO))]
12872 [(parallel [(set (match_dup
4)
12873 (neg:P (match_dup
3)))
12874 (set (reg:P CA_REGNO)
12875 (eq:P (match_dup
3)
12877 (parallel [(set (match_dup
0)
12878 (plus:P (reg:P CA_REGNO)
12880 (clobber (reg:P CA_REGNO))])]
12882 operands[
3] = rs6000_emit_eqne (<MODE>mode,
12883 operands[
1], operands[
2], operands[
3]);
12885 if (GET_CODE (operands[
4]) == SCRATCH)
12886 operands[
4] = 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 "*plus_eq_<mode>"
12894 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12895 (plus:P (eq:P (match_operand:P
1 "gpc_reg_operand" "r")
12896 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))
12897 (match_operand:P
3 "gpc_reg_operand" "r")))
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 (neg:P (match_dup
4)))
12906 (set (reg:P CA_REGNO)
12907 (eq:P (match_dup
4)
12909 (parallel [(set (match_dup
0)
12910 (plus:P (match_dup
3)
12912 (clobber (reg:P CA_REGNO))])]
12914 operands[
4] = rs6000_emit_eqne (<MODE>mode,
12915 operands[
1], operands[
2], operands[
4]);
12917 if (GET_CODE (operands[
5]) == SCRATCH)
12918 operands[
5] = gen_reg_rtx (<MODE>mode);
12920 [(set (attr "length")
12921 (if_then_else (match_test "operands[
2] == const0_rtx")
12923 (const_string "
12")))])
12925 (define_insn_and_split "*plus_ne_<mode>"
12926 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12927 (plus:P (ne:P (match_operand:P
1 "gpc_reg_operand" "r")
12928 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))
12929 (match_operand:P
3 "gpc_reg_operand" "r")))
12930 (clobber (match_scratch:P
4 "=r"))
12931 (clobber (match_scratch:P
5 "=r"))
12932 (clobber (reg:P CA_REGNO))]
12936 [(parallel [(set (match_dup
5)
12937 (plus:P (match_dup
4)
12939 (set (reg:P CA_REGNO)
12940 (ne:P (match_dup
4)
12942 (parallel [(set (match_dup
0)
12943 (plus:P (match_dup
3)
12945 (clobber (reg:P CA_REGNO))])]
12947 operands[
4] = rs6000_emit_eqne (<MODE>mode,
12948 operands[
1], operands[
2], operands[
4]);
12950 if (GET_CODE (operands[
5]) == SCRATCH)
12951 operands[
5] = gen_reg_rtx (<MODE>mode);
12953 [(set (attr "length")
12954 (if_then_else (match_test "operands[
2] == const0_rtx")
12956 (const_string "
12")))])
12958 (define_insn_and_split "*minus_eq_<mode>"
12959 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12960 (minus:P (match_operand:P
3 "gpc_reg_operand" "r")
12961 (eq:P (match_operand:P
1 "gpc_reg_operand" "r")
12962 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))))
12963 (clobber (match_scratch:P
4 "=r"))
12964 (clobber (match_scratch:P
5 "=r"))
12965 (clobber (reg:P CA_REGNO))]
12969 [(parallel [(set (match_dup
5)
12970 (plus:P (match_dup
4)
12972 (set (reg:P CA_REGNO)
12973 (ne:P (match_dup
4)
12975 (parallel [(set (match_dup
0)
12976 (plus:P (plus:P (match_dup
3)
12979 (clobber (reg:P CA_REGNO))])]
12981 operands[
4] = rs6000_emit_eqne (<MODE>mode,
12982 operands[
1], operands[
2], operands[
4]);
12984 if (GET_CODE (operands[
5]) == SCRATCH)
12985 operands[
5] = gen_reg_rtx (<MODE>mode);
12987 [(set (attr "length")
12988 (if_then_else (match_test "operands[
2] == const0_rtx")
12990 (const_string "
12")))])
12992 (define_insn_and_split "*minus_ne_<mode>"
12993 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12994 (minus:P (match_operand:P
3 "gpc_reg_operand" "r")
12995 (ne:P (match_operand:P
1 "gpc_reg_operand" "r")
12996 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))))
12997 (clobber (match_scratch:P
4 "=r"))
12998 (clobber (match_scratch:P
5 "=r"))
12999 (clobber (reg:P CA_REGNO))]
13003 [(parallel [(set (match_dup
5)
13004 (neg:P (match_dup
4)))
13005 (set (reg:P CA_REGNO)
13006 (eq:P (match_dup
4)
13008 (parallel [(set (match_dup
0)
13009 (plus:P (plus:P (match_dup
3)
13012 (clobber (reg:P CA_REGNO))])]
13014 operands[
4] = rs6000_emit_eqne (<MODE>mode,
13015 operands[
1], operands[
2], operands[
4]);
13017 if (GET_CODE (operands[
5]) == SCRATCH)
13018 operands[
5] = gen_reg_rtx (<MODE>mode);
13020 [(set (attr "length")
13021 (if_then_else (match_test "operands[
2] == const0_rtx")
13023 (const_string "
12")))])
13025 (define_insn_and_split "*eqsi3_ext<mode>"
13026 [(set (match_operand:EXTSI
0 "gpc_reg_operand" "=r")
13027 (eq:EXTSI (match_operand:SI
1 "gpc_reg_operand" "r")
13028 (match_operand:SI
2 "scc_eq_operand" "rKLI")))
13029 (clobber (match_scratch:SI
3 "=r"))
13030 (clobber (match_scratch:SI
4 "=r"))]
13034 [(set (match_dup
4)
13035 (clz:SI (match_dup
3)))
13038 (lshiftrt:SI (match_dup
4)
13041 operands[
3] = rs6000_emit_eqne (SImode,
13042 operands[
1], operands[
2], operands[
3]);
13044 if (GET_CODE (operands[
4]) == SCRATCH)
13045 operands[
4] = gen_reg_rtx (SImode);
13047 [(set (attr "length")
13048 (if_then_else (match_test "operands[
2] == const0_rtx")
13050 (const_string "
12")))])
13052 (define_insn_and_split "*nesi3_ext<mode>"
13053 [(set (match_operand:EXTSI
0 "gpc_reg_operand" "=r")
13054 (ne:EXTSI (match_operand:SI
1 "gpc_reg_operand" "r")
13055 (match_operand:SI
2 "scc_eq_operand" "rKLI")))
13056 (clobber (match_scratch:SI
3 "=r"))
13057 (clobber (match_scratch:SI
4 "=r"))
13058 (clobber (match_scratch:EXTSI
5 "=r"))]
13062 [(set (match_dup
4)
13063 (clz:SI (match_dup
3)))
13066 (lshiftrt:SI (match_dup
4)
13069 (xor:EXTSI (match_dup
5)
13072 operands[
3] = rs6000_emit_eqne (SImode,
13073 operands[
1], operands[
2], operands[
3]);
13075 if (GET_CODE (operands[
4]) == SCRATCH)
13076 operands[
4] = gen_reg_rtx (SImode);
13077 if (GET_CODE (operands[
5]) == SCRATCH)
13078 operands[
5] = gen_reg_rtx (<MODE>mode);
13080 [(set (attr "length")
13081 (if_then_else (match_test "operands[
2] == const0_rtx")
13082 (const_string "
12")
13083 (const_string "
16")))])
13086 (define_code_iterator fp_rev [ordered ne unle unge])
13087 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
13089 (define_insn_and_split "*<code><mode>_cc"
13090 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
13091 (fp_rev:GPR (match_operand:CCFP
1 "cc_reg_operand" "y")
13093 "!flag_finite_math_only"
13098 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
13099 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[
1], const0_rtx);
13100 rtx tmp = gen_reg_rtx (<MODE>mode);
13101 emit_move_insn (tmp, eq);
13102 emit_insn (gen_xor<mode>
3 (operands[
0], tmp, const1_rtx));
13105 [(set_attr "length" "
12")])
13107 (define_insn_and_split "*<code><mode>_cc"
13108 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
13109 (fp_two:GPR (match_operand:CCFP
1 "cc_reg_operand" "y")
13111 "!flag_finite_math_only"
13116 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[
1]);
13118 emit_move_insn (operands[
0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
13121 [(set_attr "length" "
12")])
13123 ;; Conditional branches.
13124 ;; These either are a single bc insn, or a bc around a b.
13126 (define_insn "*cbranch"
13128 (if_then_else (match_operator
1 "branch_comparison_operator"
13129 [(match_operand
2 "cc_reg_operand" "y")
13131 (label_ref (match_operand
0))
13135 return output_cbranch (operands[
1], "%l0",
0, insn);
13137 [(set_attr "type" "branch")
13138 (set (attr "length")
13139 (if_then_else (and (ge (minus (match_dup
0) (pc))
13140 (const_int -
32768))
13141 (lt (minus (match_dup
0) (pc))
13142 (const_int
32764)))
13146 (define_insn_and_split "*cbranch_2insn"
13148 (if_then_else (match_operator
1 "extra_insn_branch_comparison_operator"
13149 [(match_operand
2 "cc_reg_operand" "y")
13151 (label_ref (match_operand
0))
13153 "!flag_finite_math_only"
13158 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[
1]), SImode, operands[
2]);
13160 rtx note = find_reg_note (curr_insn, REG_BR_PROB,
0);
13162 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[
0]);
13163 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
13164 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
13165 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
13169 profile_probability prob
13170 = profile_probability::from_reg_br_prob_note (XINT (note,
0));
13172 add_reg_br_prob_note (get_last_insn (), prob);
13177 [(set_attr "type" "branch")
13178 (set (attr "length")
13179 (if_then_else (and (ge (minus (match_dup
0) (pc))
13180 (const_int -
32764))
13181 (lt (minus (match_dup
0) (pc))
13182 (const_int
32760)))
13186 ;; Conditional return.
13187 (define_insn "*creturn"
13189 (if_then_else (match_operator
0 "branch_comparison_operator"
13190 [(match_operand
1 "cc_reg_operand" "y")
13196 return output_cbranch (operands[
0], NULL,
0, insn);
13198 [(set_attr "type" "jmpreg")])
13200 ;; Logic on condition register values.
13202 ; This pattern matches things like
13203 ; (set (reg:CCEQ
68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP
68) (const_int
0))
13204 ; (eq:SI (reg:CCFP
68) (const_int
0)))
13206 ; which are generated by the branch logic.
13207 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
13209 (define_insn "@cceq_ior_compare_<mode>"
13210 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=y,?y")
13211 (compare:CCEQ (match_operator:GPR
1 "boolean_operator"
13212 [(match_operator:GPR
2
13213 "branch_positive_comparison_operator"
13215 "cc_reg_operand" "y,y")
13217 (match_operator:GPR
4
13218 "branch_positive_comparison_operator"
13220 "cc_reg_operand" "
0,y")
13224 "cr%q1 %E0,%j2,%j4"
13225 [(set_attr "type" "cr_logical")
13226 (set_attr "cr_logical_3op" "no,yes")])
13228 ; Why is the constant -
1 here, but
1 in the previous pattern?
13229 ; Because ~
1 has all but the low bit set.
13230 (define_insn "cceq_ior_compare_complement"
13231 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=y,?y")
13232 (compare:CCEQ (match_operator:SI
1 "boolean_operator"
13233 [(not:SI (match_operator:SI
2
13234 "branch_positive_comparison_operator"
13236 "cc_reg_operand" "y,y")
13238 (match_operator:SI
4
13239 "branch_positive_comparison_operator"
13241 "cc_reg_operand" "
0,y")
13245 "cr%q1 %E0,%j2,%j4"
13246 [(set_attr "type" "cr_logical")
13247 (set_attr "cr_logical_3op" "no,yes")])
13249 (define_insn "@cceq_rev_compare_<mode>"
13250 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=y,?y")
13251 (compare:CCEQ (match_operator:GPR
1
13252 "branch_positive_comparison_operator"
13254 "cc_reg_operand" "
0,y")
13259 [(set_attr "type" "cr_logical")
13260 (set_attr "cr_logical_3op" "no,yes")])
13262 ;; If we are comparing the result of two comparisons, this can be done
13263 ;; using creqv or crxor.
13265 (define_insn_and_split ""
13266 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=y")
13267 (compare:CCEQ (match_operator
1 "branch_comparison_operator"
13268 [(match_operand
2 "cc_reg_operand" "y")
13270 (match_operator
3 "branch_comparison_operator"
13271 [(match_operand
4 "cc_reg_operand" "y")
13276 [(set (match_dup
0) (compare:CCEQ (xor:SI (match_dup
1) (match_dup
3))
13279 int positive_1, positive_2;
13281 positive_1 = branch_positive_comparison_operator (operands[
1],
13282 GET_MODE (operands[
1]));
13283 positive_2 = branch_positive_comparison_operator (operands[
3],
13284 GET_MODE (operands[
3]));
13287 operands[
1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[
2]),
13288 GET_CODE (operands[
1])),
13290 operands[
2], const0_rtx);
13291 else if (GET_MODE (operands[
1]) != SImode)
13292 operands[
1] = gen_rtx_fmt_ee (GET_CODE (operands[
1]), SImode,
13293 operands[
2], const0_rtx);
13296 operands[
3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[
4]),
13297 GET_CODE (operands[
3])),
13299 operands[
4], const0_rtx);
13300 else if (GET_MODE (operands[
3]) != SImode)
13301 operands[
3] = gen_rtx_fmt_ee (GET_CODE (operands[
3]), SImode,
13302 operands[
4], const0_rtx);
13304 if (positive_1 == positive_2)
13306 operands[
1] = gen_rtx_NOT (SImode, operands[
1]);
13307 operands[
5] = constm1_rtx;
13311 operands[
5] = const1_rtx;
13315 ;; Unconditional branch and return.
13317 (define_insn "jump"
13319 (label_ref (match_operand
0)))]
13322 [(set_attr "type" "branch")])
13324 (define_insn "<return_str>return"
13328 [(set_attr "type" "jmpreg")])
13330 (define_expand "indirect_jump"
13331 [(set (pc) (match_operand
0 "register_operand"))]
13334 if (!rs6000_speculate_indirect_jumps) {
13335 rtx ccreg = gen_reg_rtx (CCmode);
13336 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[
0], ccreg));
13341 (define_insn "*indirect_jump<mode>"
13343 (match_operand:P
0 "register_operand" "c,*l"))]
13344 "rs6000_speculate_indirect_jumps"
13346 [(set_attr "type" "jmpreg")])
13348 (define_insn "@indirect_jump<mode>_nospec"
13349 [(set (pc) (match_operand:P
0 "register_operand" "c,*l"))
13350 (clobber (match_operand:CC
1 "cc_reg_operand" "=y,y"))]
13351 "!rs6000_speculate_indirect_jumps"
13352 "crset %E1\;beq%T0- %
1\;b $"
13353 [(set_attr "type" "jmpreg")
13354 (set_attr "length" "
12")])
13356 ;; Table jump for switch statements:
13357 (define_expand "tablejump"
13358 [(use (match_operand
0))
13359 (use (label_ref (match_operand
1)))]
13362 if (rs6000_speculate_indirect_jumps)
13364 if (rs6000_relative_jumptables)
13365 emit_jump_insn (gen_tablejump_normal (Pmode, operands[
0], operands[
1]));
13367 emit_jump_insn (gen_tablejump_absolute (Pmode, operands[
0],
13372 rtx ccreg = gen_reg_rtx (CCmode);
13374 if (rs6000_relative_jumptables)
13375 jump = gen_tablejump_nospec (Pmode, operands[
0], operands[
1], ccreg);
13377 jump = gen_tablejump_absolute_nospec (Pmode, operands[
0], operands[
1],
13379 emit_jump_insn (jump);
13384 (define_expand "@tablejump<mode>_normal"
13385 [(use (match_operand:SI
0))
13386 (use (match_operand:P
1))]
13387 "rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
13389 rtx off = force_reg (SImode, operands[
0]);
13390 if (<MODE>mode != SImode)
13392 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
13393 off = gen_reg_rtx (Pmode);
13394 emit_move_insn (off, src);
13397 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[
1]));
13398 rtx addr = gen_reg_rtx (Pmode);
13400 emit_insn (gen_add<mode>
3 (addr, off, lab));
13401 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[
1]));
13405 (define_expand "@tablejump<mode>_absolute"
13406 [(use (match_operand:P
0))
13407 (use (match_operand:P
1))]
13408 "rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
13410 rtx addr = gen_reg_rtx (Pmode);
13411 emit_move_insn (addr, operands[
0]);
13413 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[
1]));
13417 (define_expand "@tablejump<mode>_nospec"
13418 [(use (match_operand:SI
0))
13419 (use (match_operand:P
1))
13420 (use (match_operand:CC
2))]
13421 "!rs6000_speculate_indirect_jumps && rs6000_relative_jumptables"
13423 rtx off = force_reg (SImode, operands[
0]);
13424 if (<MODE>mode != SImode)
13426 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off);
13427 off = gen_reg_rtx (Pmode);
13428 emit_move_insn (off, src);
13431 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[
1]));
13432 rtx addr = gen_reg_rtx (Pmode);
13434 emit_insn (gen_add<mode>
3 (addr, off, lab));
13435 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[
1],
13440 (define_expand "@tablejump<mode>_absolute_nospec"
13441 [(use (match_operand:P
0))
13442 (use (match_operand:P
1))
13443 (use (match_operand:CC
2))]
13444 "!rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables"
13446 rtx addr = gen_reg_rtx (Pmode);
13447 emit_move_insn (addr, operands[
0]);
13449 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[
1],
13454 (define_insn "@tablejump<mode>_insn_normal"
13456 (match_operand:P
0 "register_operand" "c,*l"))
13457 (use (label_ref (match_operand
1)))]
13458 "rs6000_speculate_indirect_jumps"
13460 [(set_attr "type" "jmpreg")])
13462 (define_insn "@tablejump<mode>_insn_nospec"
13464 (match_operand:P
0 "register_operand" "c,*l"))
13465 (use (label_ref (match_operand
1)))
13466 (clobber (match_operand:CC
2 "cc_reg_operand" "=y,y"))]
13467 "!rs6000_speculate_indirect_jumps"
13468 "crset %E2\;beq%T0- %
2\;b $"
13469 [(set_attr "type" "jmpreg")
13470 (set_attr "length" "
12")])
13473 [(unspec [(const_int
0)] UNSPEC_NOP)]
13477 (define_insn "group_ending_nop"
13478 [(unspec [(const_int
0)] UNSPEC_GRP_END_NOP)]
13481 operands[
0] = gen_rtx_REG (Pmode,
13482 rs6000_tune == PROCESSOR_POWER6 ?
1 :
2);
13483 return "ori %
0,%
0,
0";
13486 (define_insn "speculation_barrier"
13487 [(unspec_volatile:BLK [(const_int
0)] UNSPECV_SPEC_BARRIER)]
13490 operands[
0] = gen_rtx_REG (Pmode,
31);
13491 return "ori %
0,%
0,
0";
13494 ;; Define the subtract-one-and-jump insns, starting with the template
13495 ;; so loop.c knows what to generate.
13497 (define_expand "doloop_end"
13498 [(use (match_operand
0)) ; loop pseudo
13499 (use (match_operand
1))] ; label
13502 if (GET_MODE (operands[
0]) != Pmode)
13505 emit_jump_insn (gen_ctr (Pmode, operands[
0], operands[
1]));
13509 (define_expand "@ctr<mode>"
13510 [(parallel [(set (pc)
13511 (if_then_else (ne (match_operand:P
0 "register_operand")
13513 (label_ref (match_operand
1))
13516 (plus:P (match_dup
0)
13518 (clobber (match_scratch:CC
2))
13519 (clobber (match_scratch:P
3))])]
13523 ;; We need to be able to do this for any operand, including MEM, or we
13524 ;; will cause reload to blow up since we don't allow output reloads on
13526 ;; For the length attribute to be calculated correctly, the
13527 ;; label MUST be operand
0.
13528 ;; rs6000_legitimate_combined_insn prevents combine creating any of
13529 ;; the ctr<mode> insns.
13531 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
13532 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
13534 (define_insn "<bd>_<mode>"
13536 (if_then_else (eqne (match_operand:P
1 "register_operand" "c,*b,*b,*b")
13538 (label_ref (match_operand
0))
13540 (set (match_operand:P
2 "nonimmediate_operand" "=
1,*r,m,*d*wa*c*l")
13541 (plus:P (match_dup
1)
13543 (clobber (match_scratch:CC
3 "=X,&x,&x,&x"))
13544 (clobber (match_scratch:P
4 "=X,X,&r,r"))]
13547 if (which_alternative !=
0)
13549 else if (get_attr_length (insn) ==
4)
13552 return "<bd_neg> $+
8\;b %l0";
13554 [(set_attr "type" "branch")
13555 (set_attr_alternative "length"
13556 [(if_then_else (and (ge (minus (match_dup
0) (pc))
13557 (const_int -
32768))
13558 (lt (minus (match_dup
0) (pc))
13559 (const_int
32764)))
13562 (const_string "
16")
13563 (const_string "
20")
13564 (const_string "
20")])])
13566 ;; Now the splitter if we could not allocate the CTR register
13569 (if_then_else (match_operator
2 "comparison_operator"
13570 [(match_operand:P
1 "gpc_reg_operand")
13573 (match_operand
6)))
13574 (set (match_operand:P
0 "nonimmediate_operand")
13575 (plus:P (match_dup
1)
13577 (clobber (match_scratch:CC
3))
13578 (clobber (match_scratch:P
4))]
13581 (if_then_else (match_dup
7)
13585 operands[
7] = gen_rtx_fmt_ee (GET_CODE (operands[
2]), VOIDmode, operands[
3],
13587 emit_insn (gen_rtx_SET (operands[
3],
13588 gen_rtx_COMPARE (CCmode, operands[
1], const1_rtx)));
13589 if (int_reg_operand (operands[
0], <MODE>mode))
13590 emit_insn (gen_add<mode>
3 (operands[
0], operands[
1], constm1_rtx));
13593 emit_insn (gen_add<mode>
3 (operands[
4], operands[
1], constm1_rtx));
13594 emit_move_insn (operands[
0], operands[
4]);
13596 /* No DONE so branch comes from the pattern. */
13599 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
13600 ;; Note that in the case of long branches we have to decompose this into
13601 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
13602 ;; and the CR bit, which means there is no way to conveniently invert the
13603 ;; comparison as is done with plain bdnz/bdz.
13605 (define_insn "<bd>tf_<mode>"
13609 (eqne (match_operand:P
1 "register_operand" "c,*b,*b,*b")
13611 (match_operator
3 "branch_comparison_operator"
13612 [(match_operand
4 "cc_reg_operand" "y,y,y,y")
13614 (label_ref (match_operand
0))
13616 (set (match_operand:P
2 "nonimmediate_operand" "=
1,*r,m,*d*wa*c*l")
13617 (plus:P (match_dup
1)
13619 (clobber (match_scratch:P
5 "=X,X,&r,r"))
13620 (clobber (match_scratch:CC
6 "=X,&y,&y,&y"))
13621 (clobber (match_scratch:CCEQ
7 "=X,&y,&y,&y"))]
13624 if (which_alternative !=
0)
13626 else if (get_attr_length (insn) ==
4)
13628 if (branch_positive_comparison_operator (operands[
3],
13629 GET_MODE (operands[
3])))
13630 return "<bd>t %j3,%l0";
13632 return "<bd>f %j3,%l0";
13636 static char seq[
96];
13637 char *bcs = output_cbranch (operands[
3], ".Lshort%=",
1, insn);
13638 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
13642 [(set_attr "type" "branch")
13643 (set_attr_alternative "length"
13644 [(if_then_else (and (ge (minus (match_dup
0) (pc))
13645 (const_int -
32768))
13646 (lt (minus (match_dup
0) (pc))
13647 (const_int
32764)))
13650 (const_string "
16")
13651 (const_string "
20")
13652 (const_string "
20")])])
13654 ;; Now the splitter if we could not allocate the CTR register
13659 (match_operator
1 "comparison_operator"
13660 [(match_operand:P
0 "gpc_reg_operand")
13662 (match_operator
3 "branch_comparison_operator"
13663 [(match_operand
2 "cc_reg_operand")
13666 (match_operand
5)))
13667 (set (match_operand:P
6 "nonimmediate_operand")
13668 (plus:P (match_dup
0)
13670 (clobber (match_scratch:P
7))
13671 (clobber (match_scratch:CC
8))
13672 (clobber (match_scratch:CCEQ
9))]
13676 rtx ctr = operands[
0];
13677 rtx ctrcmp = operands[
1];
13678 rtx ccin = operands[
2];
13679 rtx cccmp = operands[
3];
13680 rtx dst1 = operands[
4];
13681 rtx dst2 = operands[
5];
13682 rtx ctrout = operands[
6];
13683 rtx ctrtmp = operands[
7];
13684 enum rtx_code cmpcode = GET_CODE (ctrcmp);
13685 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
13687 cmpcode = reverse_condition (cmpcode);
13688 /* Generate crand/crandc here. */
13689 emit_insn (gen_rtx_SET (operands[
8],
13690 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
13691 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[
8], const0_rtx);
13693 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
13695 emit_insn (gen_cceq_ior_compare (SImode, operands[
9], andexpr, ctrcmpcc,
13696 operands[
8], cccmp, ccin));
13698 emit_insn (gen_cceq_ior_compare_complement (operands[
9], andexpr, ctrcmpcc,
13699 operands[
8], cccmp, ccin));
13700 if (int_reg_operand (ctrout, <MODE>mode))
13701 emit_insn (gen_add<mode>
3 (ctrout, ctr, constm1_rtx));
13704 emit_insn (gen_add<mode>
3 (ctrtmp, ctr, constm1_rtx));
13705 emit_move_insn (ctrout, ctrtmp);
13707 rtx cmp = gen_rtx_EQ (CCEQmode, operands[
9], const0_rtx);
13708 emit_jump_insn (gen_rtx_SET (pc_rtx,
13709 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
13715 (define_insn "trap"
13716 [(trap_if (const_int
1) (const_int
0))]
13719 [(set_attr "type" "trap")])
13721 (define_expand "ctrap<mode>
4"
13722 [(trap_if (match_operator
0 "ordered_comparison_operator"
13723 [(match_operand:GPR
1 "register_operand")
13724 (match_operand:GPR
2 "reg_or_short_operand")])
13725 (match_operand
3 "zero_constant" ""))]
13730 [(trap_if (match_operator
0 "ordered_comparison_operator"
13731 [(match_operand:GPR
1 "register_operand" "r")
13732 (match_operand:GPR
2 "reg_or_short_operand" "rI")])
13735 "t<wd>%V0%I2 %
1,%
2"
13736 [(set_attr "type" "trap")])
13738 ;; Insns related to generating the function prologue and epilogue.
13740 (define_expand "prologue"
13741 [(use (const_int
0))]
13744 rs6000_emit_prologue ();
13745 if (!TARGET_SCHED_PROLOG)
13746 emit_insn (gen_blockage ());
13750 (define_insn "*movesi_from_cr_one"
13751 [(match_parallel
0 "mfcr_operation"
13752 [(set (match_operand:SI
1 "gpc_reg_operand" "=r")
13753 (unspec:SI [(match_operand:CC
2 "cc_reg_operand" "y")
13754 (match_operand
3 "immediate_operand" "n")]
13755 UNSPEC_MOVESI_FROM_CR))])]
13760 for (i =
0; i < XVECLEN (operands[
0],
0); i++)
13762 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[
0],
0, i)),
0,
1));
13763 operands[
4] = GEN_INT (mask);
13764 output_asm_insn ("mfcr %
1,%
4", operands);
13768 [(set_attr "type" "mfcrf")])
13770 ;; Don't include the volatile CRs since their values are not used wrt CR save
13771 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13772 ;; prologue past an insn (early exit test) that defines a register used in the
13774 (define_insn "prologue_movesi_from_cr"
13775 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
13776 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13777 (reg:CC CR4_REGNO)]
13778 UNSPEC_MOVESI_FROM_CR))]
13781 [(set_attr "type" "mfcr")])
13783 (define_insn "*crsave"
13784 [(match_parallel
0 "crsave_operation"
13785 [(set (match_operand:SI
1 "memory_operand" "=m")
13786 (match_operand:SI
2 "gpc_reg_operand" "r"))])]
13789 [(set_attr "type" "store")])
13791 (define_insn "*stmw"
13792 [(match_parallel
0 "stmw_operation"
13793 [(set (match_operand:SI
1 "memory_operand" "=m")
13794 (match_operand:SI
2 "gpc_reg_operand" "r"))])]
13797 [(set_attr "type" "store")
13798 (set_attr "update" "yes")
13799 (set_attr "indexed" "yes")])
13801 ; The following comment applies to:
13805 ; return_and_restore_gpregs*
13806 ; return_and_restore_fpregs*
13807 ; return_and_restore_fpregs_aix*
13809 ; The out-of-line save / restore functions expects one input argument.
13810 ; Since those are not standard call_insn's, we must avoid using
13811 ; MATCH_OPERAND for that argument. That way the register rename
13812 ; optimization will not try to rename this register.
13813 ; Each pattern is repeated for each possible register number used in
13814 ; various ABIs (r11, r1, and for some functions r12)
13816 (define_insn "*save_gpregs_<mode>_r11"
13817 [(match_parallel
0 "any_parallel_operand"
13818 [(clobber (reg:P LR_REGNO))
13819 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13821 (set (match_operand:P
2 "memory_operand" "=m")
13822 (match_operand:P
3 "gpc_reg_operand" "r"))])]
13825 [(set_attr "type" "branch")])
13827 (define_insn "*save_gpregs_<mode>_r12"
13828 [(match_parallel
0 "any_parallel_operand"
13829 [(clobber (reg:P LR_REGNO))
13830 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13832 (set (match_operand:P
2 "memory_operand" "=m")
13833 (match_operand:P
3 "gpc_reg_operand" "r"))])]
13836 [(set_attr "type" "branch")])
13838 (define_insn "*save_gpregs_<mode>_r1"
13839 [(match_parallel
0 "any_parallel_operand"
13840 [(clobber (reg:P LR_REGNO))
13841 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13843 (set (match_operand:P
2 "memory_operand" "=m")
13844 (match_operand:P
3 "gpc_reg_operand" "r"))])]
13847 [(set_attr "type" "branch")])
13849 (define_insn "*save_fpregs_<mode>_r11"
13850 [(match_parallel
0 "any_parallel_operand"
13851 [(clobber (reg:P LR_REGNO))
13852 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13854 (set (match_operand:DF
2 "memory_operand" "=m")
13855 (match_operand:DF
3 "gpc_reg_operand" "d"))])]
13858 [(set_attr "type" "branch")])
13860 (define_insn "*save_fpregs_<mode>_r12"
13861 [(match_parallel
0 "any_parallel_operand"
13862 [(clobber (reg:P LR_REGNO))
13863 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13865 (set (match_operand:DF
2 "memory_operand" "=m")
13866 (match_operand:DF
3 "gpc_reg_operand" "d"))])]
13869 [(set_attr "type" "branch")])
13871 (define_insn "*save_fpregs_<mode>_r1"
13872 [(match_parallel
0 "any_parallel_operand"
13873 [(clobber (reg:P LR_REGNO))
13874 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13876 (set (match_operand:DF
2 "memory_operand" "=m")
13877 (match_operand:DF
3 "gpc_reg_operand" "d"))])]
13880 [(set_attr "type" "branch")])
13882 ; This is to explain that changes to the stack pointer should
13883 ; not be moved over loads from or stores to stack memory.
13884 (define_insn "stack_tie"
13885 [(match_parallel
0 "tie_operand"
13886 [(set (mem:BLK (reg
1)) (const_int
0))])]
13889 [(set_attr "length" "
0")])
13891 ; Some
32-bit ABIs do not have a red zone, so the stack deallocation has to
13892 ; stay behind all restores from the stack, it cannot be reordered to before
13893 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13894 (define_insn "stack_restore_tie"
13895 [(set (match_operand:SI
0 "gpc_reg_operand" "=r,r")
13896 (plus:SI (match_operand:SI
1 "gpc_reg_operand" "r,r")
13897 (match_operand:SI
2 "reg_or_cint_operand" "O,rI")))
13898 (set (mem:BLK (scratch)) (const_int
0))]
13903 [(set_attr "type" "*,add")])
13905 (define_expand "epilogue"
13906 [(use (const_int
0))]
13909 if (!TARGET_SCHED_PROLOG)
13910 emit_insn (gen_blockage ());
13911 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13915 ; On some processors, doing the mtcrf one CC register at a time is
13916 ; faster (like on the
604e). On others, doing them all at once is
13917 ; faster; for instance, on the
601 and
750.
13919 (define_expand "movsi_to_cr_one"
13920 [(set (match_operand:CC
0 "cc_reg_operand")
13921 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand")
13922 (match_dup
2)] UNSPEC_MOVESI_TO_CR))]
13924 "operands[
2] = GEN_INT (
1 << (
7 - (REGNO (operands[
0]) - CR0_REGNO)));")
13926 (define_insn "*movsi_to_cr"
13927 [(match_parallel
0 "mtcrf_operation"
13928 [(set (match_operand:CC
1 "cc_reg_operand" "=y")
13929 (unspec:CC [(match_operand:SI
2 "gpc_reg_operand" "r")
13930 (match_operand
3 "immediate_operand" "n")]
13931 UNSPEC_MOVESI_TO_CR))])]
13936 for (i =
0; i < XVECLEN (operands[
0],
0); i++)
13937 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[
0],
0, i)),
0,
1));
13938 operands[
4] = GEN_INT (mask);
13939 return "mtcrf %
4,%
2";
13941 [(set_attr "type" "mtcr")])
13943 (define_insn "*mtcrfsi"
13944 [(set (match_operand:CC
0 "cc_reg_operand" "=y")
13945 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
13946 (match_operand
2 "immediate_operand" "n")]
13947 UNSPEC_MOVESI_TO_CR))]
13948 "REG_P (operands[
0])
13949 && CR_REGNO_P (REGNO (operands[
0]))
13950 && CONST_INT_P (operands[
2])
13951 && INTVAL (operands[
2]) ==
1 << (
7 - (REGNO (operands[
0]) - CR0_REGNO))"
13953 [(set_attr "type" "mtcr")])
13955 ; The load-multiple instructions have similar properties.
13956 ; Note that "load_multiple" is a name known to the machine-independent
13957 ; code that actually corresponds to the PowerPC load-string.
13959 (define_insn "*lmw"
13960 [(match_parallel
0 "lmw_operation"
13961 [(set (match_operand:SI
1 "gpc_reg_operand" "=r")
13962 (match_operand:SI
2 "memory_operand" "m"))])]
13965 [(set_attr "type" "load")
13966 (set_attr "update" "yes")
13967 (set_attr "indexed" "yes")
13968 (set_attr "cell_micro" "always")])
13970 ; FIXME: "any_parallel_operand" is a bit flexible...
13972 ; The following comment applies to:
13976 ; return_and_restore_gpregs*
13977 ; return_and_restore_fpregs*
13978 ; return_and_restore_fpregs_aix*
13980 ; The out-of-line save / restore functions expects one input argument.
13981 ; Since those are not standard call_insn's, we must avoid using
13982 ; MATCH_OPERAND for that argument. That way the register rename
13983 ; optimization will not try to rename this register.
13984 ; Each pattern is repeated for each possible register number used in
13985 ; various ABIs (r11, r1, and for some functions r12)
13987 (define_insn "*restore_gpregs_<mode>_r11"
13988 [(match_parallel
0 "any_parallel_operand"
13989 [(clobber (reg:P LR_REGNO))
13990 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13992 (set (match_operand:P
2 "gpc_reg_operand" "=r")
13993 (match_operand:P
3 "memory_operand" "m"))])]
13996 [(set_attr "type" "branch")])
13998 (define_insn "*restore_gpregs_<mode>_r12"
13999 [(match_parallel
0 "any_parallel_operand"
14000 [(clobber (reg:P LR_REGNO))
14001 (use (match_operand:P
1 "symbol_ref_operand" "s"))
14003 (set (match_operand:P
2 "gpc_reg_operand" "=r")
14004 (match_operand:P
3 "memory_operand" "m"))])]
14007 [(set_attr "type" "branch")])
14009 (define_insn "*restore_gpregs_<mode>_r1"
14010 [(match_parallel
0 "any_parallel_operand"
14011 [(clobber (reg:P LR_REGNO))
14012 (use (match_operand:P
1 "symbol_ref_operand" "s"))
14014 (set (match_operand:P
2 "gpc_reg_operand" "=r")
14015 (match_operand:P
3 "memory_operand" "m"))])]
14018 [(set_attr "type" "branch")])
14020 (define_insn "*return_and_restore_gpregs_<mode>_r11"
14021 [(match_parallel
0 "any_parallel_operand"
14023 (clobber (reg:P LR_REGNO))
14024 (use (match_operand:P
1 "symbol_ref_operand" "s"))
14026 (set (match_operand:P
2 "gpc_reg_operand" "=r")
14027 (match_operand:P
3 "memory_operand" "m"))])]
14030 [(set_attr "type" "branch")])
14032 (define_insn "*return_and_restore_gpregs_<mode>_r12"
14033 [(match_parallel
0 "any_parallel_operand"
14035 (clobber (reg:P LR_REGNO))
14036 (use (match_operand:P
1 "symbol_ref_operand" "s"))
14038 (set (match_operand:P
2 "gpc_reg_operand" "=r")
14039 (match_operand:P
3 "memory_operand" "m"))])]
14042 [(set_attr "type" "branch")])
14044 (define_insn "*return_and_restore_gpregs_<mode>_r1"
14045 [(match_parallel
0 "any_parallel_operand"
14047 (clobber (reg:P LR_REGNO))
14048 (use (match_operand:P
1 "symbol_ref_operand" "s"))
14050 (set (match_operand:P
2 "gpc_reg_operand" "=r")
14051 (match_operand:P
3 "memory_operand" "m"))])]
14054 [(set_attr "type" "branch")])
14056 (define_insn "*return_and_restore_fpregs_<mode>_r11"
14057 [(match_parallel
0 "any_parallel_operand"
14059 (clobber (reg:P LR_REGNO))
14060 (use (match_operand:P
1 "symbol_ref_operand" "s"))
14062 (set (match_operand:DF
2 "gpc_reg_operand" "=d")
14063 (match_operand:DF
3 "memory_operand" "m"))])]
14066 [(set_attr "type" "branch")])
14068 (define_insn "*return_and_restore_fpregs_<mode>_r12"
14069 [(match_parallel
0 "any_parallel_operand"
14071 (clobber (reg:P LR_REGNO))
14072 (use (match_operand:P
1 "symbol_ref_operand" "s"))
14074 (set (match_operand:DF
2 "gpc_reg_operand" "=d")
14075 (match_operand:DF
3 "memory_operand" "m"))])]
14078 [(set_attr "type" "branch")])
14080 (define_insn "*return_and_restore_fpregs_<mode>_r1"
14081 [(match_parallel
0 "any_parallel_operand"
14083 (clobber (reg:P LR_REGNO))
14084 (use (match_operand:P
1 "symbol_ref_operand" "s"))
14086 (set (match_operand:DF
2 "gpc_reg_operand" "=d")
14087 (match_operand:DF
3 "memory_operand" "m"))])]
14090 [(set_attr "type" "branch")])
14092 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
14093 [(match_parallel
0 "any_parallel_operand"
14095 (use (match_operand:P
1 "symbol_ref_operand" "s"))
14097 (set (match_operand:DF
2 "gpc_reg_operand" "=d")
14098 (match_operand:DF
3 "memory_operand" "m"))])]
14101 [(set_attr "type" "branch")])
14103 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
14104 [(match_parallel
0 "any_parallel_operand"
14106 (use (match_operand:P
1 "symbol_ref_operand" "s"))
14108 (set (match_operand:DF
2 "gpc_reg_operand" "=d")
14109 (match_operand:DF
3 "memory_operand" "m"))])]
14112 [(set_attr "type" "branch")])
14114 ; This is used in compiling the unwind routines.
14115 (define_expand "eh_return"
14116 [(use (match_operand
0 "general_operand"))]
14119 emit_insn (gen_eh_set_lr (Pmode, operands[
0]));
14123 ; We can't expand this before we know where the link register is stored.
14124 (define_insn_and_split "@eh_set_lr_<mode>"
14125 [(unspec_volatile [(match_operand:P
0 "register_operand" "r")] UNSPECV_EH_RR)
14126 (clobber (match_scratch:P
1 "=&b"))]
14132 rs6000_emit_eh_reg_restore (operands[
0], operands[
1]);
14136 (define_insn "prefetch"
14137 [(prefetch (match_operand
0 "indexed_or_indirect_address" "a")
14138 (match_operand:SI
1 "const_int_operand" "n")
14139 (match_operand:SI
2 "const_int_operand" "n"))]
14144 /* dcbtstt, dcbtt and TH=
0b10000 support starts with ISA
2.06 (Power7).
14145 AIX does not support the dcbtstt and dcbtt extended mnemonics.
14146 The AIX assembler does not support the three operand form of dcbt
14147 and dcbtst on Power
7 (-mpwr7). */
14148 int inst_select = INTVAL (operands[
2]) || !TARGET_DIRECT_MOVE;
14150 if (REG_P (operands[
0]))
14152 if (INTVAL (operands[
1]) ==
0)
14153 return inst_select ? "dcbt
0,%
0" : "dcbt
0,%
0,
16";
14155 return inst_select ? "dcbtst
0,%
0" : "dcbtst
0,%
0,
16";
14159 if (INTVAL (operands[
1]) ==
0)
14160 return inst_select ? "dcbt %a0" : "dcbt %a0,
16";
14162 return inst_select ? "dcbtst %a0" : "dcbtst %a0,
16";
14165 [(set_attr "type" "load")])
14167 ;; Handle -fsplit-stack.
14169 (define_expand "split_stack_prologue"
14173 rs6000_expand_split_stack_prologue ();
14177 (define_expand "load_split_stack_limit"
14178 [(set (match_operand
0)
14179 (unspec [(const_int
0)] UNSPEC_STACK_CHECK))]
14182 emit_insn (gen_rtx_SET (operands[
0],
14183 gen_rtx_UNSPEC (Pmode,
14184 gen_rtvec (
1, const0_rtx),
14185 UNSPEC_STACK_CHECK)));
14189 (define_insn "load_split_stack_limit_di"
14190 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
14191 (unspec:DI [(const_int
0)] UNSPEC_STACK_CHECK))]
14193 "ld %
0,-
0x7040(
13)"
14194 [(set_attr "type" "load")
14195 (set_attr "update" "no")
14196 (set_attr "indexed" "no")])
14198 (define_insn "load_split_stack_limit_si"
14199 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
14200 (unspec:SI [(const_int
0)] UNSPEC_STACK_CHECK))]
14202 "lwz %
0,-
0x7020(
2)"
14203 [(set_attr "type" "load")
14204 (set_attr "update" "no")
14205 (set_attr "indexed" "no")])
14207 ;; A return instruction which the middle-end doesn't see.
14208 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
14209 ;; after the call to __morestack.
14210 (define_insn "split_stack_return"
14211 [(unspec_volatile [(reg:SI
0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
14214 [(set_attr "type" "jmpreg")])
14216 ;; If there are operand
0 bytes available on the stack, jump to
14218 (define_expand "split_stack_space_check"
14219 [(set (match_dup
2)
14220 (unspec [(const_int
0)] UNSPEC_STACK_CHECK))
14222 (minus (reg STACK_POINTER_REGNUM)
14223 (match_operand
0)))
14224 (set (match_dup
4) (compare:CCUNS (match_dup
3) (match_dup
2)))
14225 (set (pc) (if_then_else
14226 (geu (match_dup
4) (const_int
0))
14227 (label_ref (match_operand
1))
14231 rs6000_split_stack_space_check (operands[
0], operands[
1]);
14235 (define_insn "bpermd_<mode>"
14236 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
14237 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "r")
14238 (match_operand:P
2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
14241 [(set_attr "type" "popcnt")])
14244 ;; Builtin fma support. Handle
14245 ;; Note that the conditions for expansion are in the FMA_F iterator.
14247 (define_expand "fma<mode>
4"
14248 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
14250 (match_operand:FMA_F
1 "gpc_reg_operand")
14251 (match_operand:FMA_F
2 "gpc_reg_operand")
14252 (match_operand:FMA_F
3 "gpc_reg_operand")))]
14256 (define_insn "*fma<mode>
4_fpr"
14257 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=d,wa,wa")
14259 (match_operand:SFDF
1 "gpc_reg_operand" "%d,wa,wa")
14260 (match_operand:SFDF
2 "gpc_reg_operand" "d,wa,
0")
14261 (match_operand:SFDF
3 "gpc_reg_operand" "d,
0,wa")))]
14262 "TARGET_HARD_FLOAT"
14264 fmadd<s> %
0,%
1,%
2,%
3
14265 xsmadda<sd>p %x0,%x1,%x2
14266 xsmaddm<sd>p %x0,%x1,%x3"
14267 [(set_attr "type" "fp")
14268 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14270 ; Altivec only has fma and nfms.
14271 (define_expand "fms<mode>
4"
14272 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
14274 (match_operand:FMA_F
1 "gpc_reg_operand")
14275 (match_operand:FMA_F
2 "gpc_reg_operand")
14276 (neg:FMA_F (match_operand:FMA_F
3 "gpc_reg_operand"))))]
14277 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14280 (define_insn "*fms<mode>
4_fpr"
14281 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=d,wa,wa")
14283 (match_operand:SFDF
1 "gpc_reg_operand" "d,wa,wa")
14284 (match_operand:SFDF
2 "gpc_reg_operand" "d,wa,
0")
14285 (neg:SFDF (match_operand:SFDF
3 "gpc_reg_operand" "d,
0,wa"))))]
14286 "TARGET_HARD_FLOAT"
14288 fmsub<s> %
0,%
1,%
2,%
3
14289 xsmsuba<sd>p %x0,%x1,%x2
14290 xsmsubm<sd>p %x0,%x1,%x3"
14291 [(set_attr "type" "fp")
14292 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14294 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
14295 (define_expand "fnma<mode>
4"
14296 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
14299 (match_operand:FMA_F
1 "gpc_reg_operand")
14300 (match_operand:FMA_F
2 "gpc_reg_operand")
14301 (neg:FMA_F (match_operand:FMA_F
3 "gpc_reg_operand")))))]
14302 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
14305 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
14306 (define_expand "fnms<mode>
4"
14307 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
14310 (match_operand:FMA_F
1 "gpc_reg_operand")
14311 (match_operand:FMA_F
2 "gpc_reg_operand")
14312 (match_operand:FMA_F
3 "gpc_reg_operand"))))]
14313 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14316 ; Not an official optab name, but used from builtins.
14317 (define_expand "nfma<mode>
4"
14318 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
14321 (match_operand:FMA_F
1 "gpc_reg_operand")
14322 (match_operand:FMA_F
2 "gpc_reg_operand")
14323 (match_operand:FMA_F
3 "gpc_reg_operand"))))]
14324 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
14327 (define_insn "*nfma<mode>
4_fpr"
14328 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=d,wa,wa")
14331 (match_operand:SFDF
1 "gpc_reg_operand" "d,wa,wa")
14332 (match_operand:SFDF
2 "gpc_reg_operand" "d,wa,
0")
14333 (match_operand:SFDF
3 "gpc_reg_operand" "d,
0,wa"))))]
14334 "TARGET_HARD_FLOAT"
14336 fnmadd<s> %
0,%
1,%
2,%
3
14337 xsnmadda<sd>p %x0,%x1,%x2
14338 xsnmaddm<sd>p %x0,%x1,%x3"
14339 [(set_attr "type" "fp")
14340 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14342 ; Not an official optab name, but used from builtins.
14343 (define_expand "nfms<mode>
4"
14344 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
14347 (match_operand:FMA_F
1 "gpc_reg_operand")
14348 (match_operand:FMA_F
2 "gpc_reg_operand")
14349 (neg:FMA_F (match_operand:FMA_F
3 "gpc_reg_operand")))))]
14353 (define_insn "*nfmssf4_fpr"
14354 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=d,wa,wa")
14357 (match_operand:SFDF
1 "gpc_reg_operand" "d,wa,wa")
14358 (match_operand:SFDF
2 "gpc_reg_operand" "d,wa,
0")
14360 (match_operand:SFDF
3 "gpc_reg_operand" "d,
0,wa")))))]
14361 "TARGET_HARD_FLOAT"
14363 fnmsub<s> %
0,%
1,%
2,%
3
14364 xsnmsuba<sd>p %x0,%x1,%x2
14365 xsnmsubm<sd>p %x0,%x1,%x3"
14366 [(set_attr "type" "fp")
14367 (set_attr "isa" "*,<Fisa>,<Fisa>")])
14369 (define_expand "rs6000_get_timebase"
14370 [(use (match_operand:DI
0 "gpc_reg_operand"))]
14373 if (TARGET_POWERPC64)
14374 emit_insn (gen_rs6000_mftb_di (operands[
0]));
14376 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[
0]));
14380 (define_insn "rs6000_get_timebase_ppc32"
14381 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
14382 (unspec_volatile:DI [(const_int
0)] UNSPECV_MFTB))
14383 (clobber (match_scratch:SI
1 "=r"))
14384 (clobber (match_scratch:CC
2 "=y"))]
14385 "!TARGET_POWERPC64"
14387 if (WORDS_BIG_ENDIAN)
14390 return "mfspr %
0,
269\;"
14398 return "mftbu %
0\;"
14407 return "mfspr %L0,
269\;"
14415 return "mftbu %L0\;"
14422 [(set_attr "length" "
20")])
14424 (define_insn "rs6000_mftb_<mode>"
14425 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
14426 (unspec_volatile:GPR [(const_int
0)] UNSPECV_MFTB))]
14430 return "mfspr %
0,
268";
14436 ;; The ISA
3.0 mffsl instruction is a lower latency instruction
14437 ;; for reading bits [
29:
31], [
45:
51] and [
56:
63] of the FPSCR.
14438 (define_insn "rs6000_mffsl_hw"
14439 [(set (match_operand:DF
0 "gpc_reg_operand" "=d")
14440 (unspec_volatile:DF [(const_int
0)] UNSPECV_MFFSL))]
14441 "TARGET_HARD_FLOAT"
14444 (define_expand "rs6000_mffsl"
14445 [(set (match_operand:DF
0 "gpc_reg_operand")
14446 (unspec_volatile:DF [(const_int
0)] UNSPECV_MFFSL))]
14447 "TARGET_HARD_FLOAT"
14449 /* If the low latency mffsl instruction (ISA
3.0) is available use it,
14450 otherwise fall back to the older mffs instruction to emulate the mffsl
14453 if (!TARGET_P9_MISC)
14455 rtx tmp1 = gen_reg_rtx (DFmode);
14457 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
14458 instruction using the mffs instruction and masking the result. */
14459 emit_insn (gen_rs6000_mffs (tmp1));
14461 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode,
0);
14462 rtx tmp2 = gen_reg_rtx (DImode);
14463 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (
0x70007f0ffLL)));
14465 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode,
0);
14466 emit_move_insn (operands[
0], tmp2df);
14470 emit_insn (gen_rs6000_mffsl_hw (operands[
0]));
14474 (define_insn "rs6000_mffs"
14475 [(set (match_operand:DF
0 "gpc_reg_operand" "=d")
14476 (unspec_volatile:DF [(const_int
0)] UNSPECV_MFFS))]
14477 "TARGET_HARD_FLOAT"
14480 (define_insn "rs6000_mtfsf"
14481 [(unspec_volatile [(match_operand:SI
0 "const_int_operand" "i")
14482 (match_operand:DF
1 "gpc_reg_operand" "d")]
14484 "TARGET_HARD_FLOAT"
14487 (define_insn "rs6000_mtfsf_hi"
14488 [(unspec_volatile [(match_operand:SI
0 "const_int_operand" "n")
14489 (match_operand:DF
1 "gpc_reg_operand" "d")]
14491 "TARGET_HARD_FLOAT"
14495 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
14496 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
14497 ;; register that is being loaded. The fused ops must be physically adjacent.
14499 ;; On Power8 GPR loads, we try to use the register that is being load. The
14500 ;; peephole2 then gathers any other fused possibilities that it can find after
14501 ;; register allocation. If power9 fusion is selected, we also fuse floating
14502 ;; point loads/stores.
14504 ;; Find cases where the addis that feeds into a load instruction is either used
14505 ;; once or is the same as the target register, and replace it with the fusion
14509 [(set (match_operand:P
0 "base_reg_operand")
14510 (match_operand:P
1 "fusion_gpr_addis"))
14511 (set (match_operand:INT1
2 "base_reg_operand")
14512 (match_operand:INT1
3 "fusion_gpr_mem_load"))]
14514 && fusion_gpr_load_p (operands[
0], operands[
1], operands[
2],
14518 expand_fusion_gpr_load (operands);
14522 ;; Fusion insn, created by the define_peephole2 above (and eventually by
14525 (define_insn "*fusion_gpr_load_<mode>"
14526 [(set (match_operand:INT1
0 "base_reg_operand" "=b")
14527 (unspec:INT1 [(match_operand:INT1
1 "fusion_addis_mem_combo_load" "wF")]
14528 UNSPEC_FUSION_GPR))]
14531 return emit_fusion_gpr_load (operands[
0], operands[
1]);
14533 [(set_attr "type" "load")
14534 (set_attr "length" "
8")])
14537 ;; Optimize cases where we want to do a D-form load (register+offset) on
14538 ;; ISA
2.06/
2.07 to an Altivec register, and the register allocator
14543 ;; and we change this to:
14548 [(match_scratch:P
0 "b")
14549 (set (match_operand:ALTIVEC_DFORM
1 "fpr_reg_operand")
14550 (match_operand:ALTIVEC_DFORM
2 "simple_offsettable_mem_operand"))
14551 (set (match_operand:ALTIVEC_DFORM
3 "altivec_register_operand")
14553 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (
2, operands[
1])"
14554 [(set (match_dup
0)
14559 rtx tmp_reg = operands[
0];
14560 rtx mem = operands[
2];
14561 rtx addr = XEXP (mem,
0);
14562 rtx add_op0, add_op1, new_addr;
14564 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14565 add_op0 = XEXP (addr,
0);
14566 add_op1 = XEXP (addr,
1);
14567 gcc_assert (REG_P (add_op0));
14568 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14570 operands[
4] = add_op1;
14571 operands[
5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
14574 ;; Optimize cases were want to do a D-form store on ISA
2.06/
2.07 from an
14575 ;; Altivec register, and the register allocator has generated:
14579 ;; and we change this to:
14584 [(match_scratch:P
0 "b")
14585 (set (match_operand:ALTIVEC_DFORM
1 "fpr_reg_operand")
14586 (match_operand:ALTIVEC_DFORM
2 "altivec_register_operand"))
14587 (set (match_operand:ALTIVEC_DFORM
3 "simple_offsettable_mem_operand")
14589 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (
2, operands[
1])"
14590 [(set (match_dup
0)
14595 rtx tmp_reg = operands[
0];
14596 rtx mem = operands[
3];
14597 rtx addr = XEXP (mem,
0);
14598 rtx add_op0, add_op1, new_addr;
14600 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14601 add_op0 = XEXP (addr,
0);
14602 add_op1 = XEXP (addr,
1);
14603 gcc_assert (REG_P (add_op0));
14604 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14606 operands[
4] = add_op1;
14607 operands[
5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
14611 ;; Miscellaneous ISA
2.06 (power7) instructions
14612 (define_insn "addg6s"
14613 [(set (match_operand:SI
0 "register_operand" "=r")
14614 (unspec:SI [(match_operand:SI
1 "register_operand" "r")
14615 (match_operand:SI
2 "register_operand" "r")]
14619 [(set_attr "type" "integer")])
14621 (define_insn "cdtbcd"
14622 [(set (match_operand:SI
0 "register_operand" "=r")
14623 (unspec:SI [(match_operand:SI
1 "register_operand" "r")]
14627 [(set_attr "type" "integer")])
14629 (define_insn "cbcdtd"
14630 [(set (match_operand:SI
0 "register_operand" "=r")
14631 (unspec:SI [(match_operand:SI
1 "register_operand" "r")]
14635 [(set_attr "type" "integer")])
14637 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14640 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14641 (UNSPEC_DIVEU "eu")])
14643 (define_insn "div<div_extend>_<mode>"
14644 [(set (match_operand:GPR
0 "register_operand" "=r")
14645 (unspec:GPR [(match_operand:GPR
1 "register_operand" "r")
14646 (match_operand:GPR
2 "register_operand" "r")]
14647 UNSPEC_DIV_EXTEND))]
14649 "div<wd><div_extend> %
0,%
1,%
2"
14650 [(set_attr "type" "div")
14651 (set_attr "size" "<bits>")])
14654 ;; Pack/unpack
128-bit floating point types that take
2 scalar registers
14656 ; Type of the
64-bit part when packing/unpacking
128-bit floating point types
14657 (define_mode_attr FP128_64 [(TF "DF")
14662 (define_expand "unpack<mode>"
14663 [(set (match_operand:<FP128_64>
0 "nonimmediate_operand")
14665 [(match_operand:FMOVE128
1 "register_operand")
14666 (match_operand:QI
2 "const_0_to_1_operand")]
14667 UNSPEC_UNPACK_128BIT))]
14668 "FLOAT128_2REG_P (<MODE>mode)"
14671 (define_insn_and_split "unpack<mode>_dm"
14672 [(set (match_operand:<FP128_64>
0 "nonimmediate_operand" "=d,m,d,r,m")
14674 [(match_operand:FMOVE128
1 "register_operand" "d,d,r,d,r")
14675 (match_operand:QI
2 "const_0_to_1_operand" "i,i,i,i,i")]
14676 UNSPEC_UNPACK_128BIT))]
14677 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14679 "&& reload_completed"
14680 [(set (match_dup
0) (match_dup
3))]
14682 unsigned fp_regno = REGNO (operands[
1]) + UINTVAL (operands[
2]);
14684 if (REG_P (operands[
0]) && REGNO (operands[
0]) == fp_regno)
14686 emit_note (NOTE_INSN_DELETED);
14690 operands[
3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14692 [(set_attr "type" "fp,fpstore,mtvsr,mfvsr,store")])
14694 (define_insn_and_split "unpack<mode>_nodm"
14695 [(set (match_operand:<FP128_64>
0 "nonimmediate_operand" "=d,m,m")
14697 [(match_operand:FMOVE128
1 "register_operand" "d,d,r")
14698 (match_operand:QI
2 "const_0_to_1_operand" "i,i,i")]
14699 UNSPEC_UNPACK_128BIT))]
14700 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14702 "&& reload_completed"
14703 [(set (match_dup
0) (match_dup
3))]
14705 unsigned fp_regno = REGNO (operands[
1]) + UINTVAL (operands[
2]);
14707 if (REG_P (operands[
0]) && REGNO (operands[
0]) == fp_regno)
14709 emit_note (NOTE_INSN_DELETED);
14713 operands[
3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14715 [(set_attr "type" "fp,fpstore,store")])
14717 (define_expand "pack<mode>"
14718 [(use (match_operand:FMOVE128
0 "register_operand"))
14719 (use (match_operand:<FP128_64>
1 "register_operand"))
14720 (use (match_operand:<FP128_64>
2 "register_operand"))]
14721 "FLOAT128_2REG_P (<MODE>mode)"
14723 if (TARGET_HARD_FLOAT)
14724 emit_insn (gen_pack<mode>_hard (operands[
0], operands[
1], operands[
2]));
14726 emit_insn (gen_pack<mode>_soft (operands[
0], operands[
1], operands[
2]));
14730 (define_insn_and_split "pack<mode>_hard"
14731 [(set (match_operand:FMOVE128
0 "register_operand" "=&d")
14733 [(match_operand:<FP128_64>
1 "register_operand" "d")
14734 (match_operand:<FP128_64>
2 "register_operand" "d")]
14735 UNSPEC_PACK_128BIT))]
14736 "FLOAT128_2REG_P (<MODE>mode) && TARGET_HARD_FLOAT"
14738 "&& reload_completed"
14739 [(set (match_dup
3) (match_dup
1))
14740 (set (match_dup
4) (match_dup
2))]
14742 unsigned dest_hi = REGNO (operands[
0]);
14743 unsigned dest_lo = dest_hi +
1;
14745 gcc_assert (!IN_RANGE (REGNO (operands[
1]), dest_hi, dest_lo));
14746 gcc_assert (!IN_RANGE (REGNO (operands[
2]), dest_hi, dest_lo));
14748 operands[
3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14749 operands[
4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14751 [(set_attr "type" "fp")
14752 (set_attr "length" "
8")])
14754 (define_insn_and_split "pack<mode>_soft"
14755 [(set (match_operand:FMOVE128
0 "register_operand" "=&r")
14757 [(match_operand:<FP128_64>
1 "register_operand" "r")
14758 (match_operand:<FP128_64>
2 "register_operand" "r")]
14759 UNSPEC_PACK_128BIT))]
14760 "FLOAT128_2REG_P (<MODE>mode) && TARGET_SOFT_FLOAT"
14762 "&& reload_completed"
14763 [(set (match_dup
3) (match_dup
1))
14764 (set (match_dup
4) (match_dup
2))]
14766 unsigned dest_hi = REGNO (operands[
0]);
14767 unsigned dest_lo = dest_hi + (TARGET_POWERPC64 ?
1 :
2);
14769 gcc_assert (!IN_RANGE (REGNO (operands[
1]), dest_hi, dest_lo));
14770 gcc_assert (!IN_RANGE (REGNO (operands[
2]), dest_hi, dest_lo));
14772 operands[
3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14773 operands[
4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14775 [(set_attr "type" "integer")
14776 (set (attr "length")
14778 (match_test "TARGET_POWERPC64")
14780 (const_string "
16")))])
14782 (define_insn "unpack<mode>"
14783 [(set (match_operand:DI
0 "register_operand" "=wa,wa")
14784 (unspec:DI [(match_operand:FMOVE128_VSX
1 "register_operand" "
0,wa")
14785 (match_operand:QI
2 "const_0_to_1_operand" "O,i")]
14786 UNSPEC_UNPACK_128BIT))]
14787 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14789 if (REGNO (operands[
0]) == REGNO (operands[
1]) && INTVAL (operands[
2]) ==
0)
14790 return ASM_COMMENT_START " xxpermdi to same register";
14792 operands[
3] = GEN_INT (INTVAL (operands[
2]) ==
0 ?
0 :
3);
14793 return "xxpermdi %x0,%x1,%x1,%
3";
14795 [(set_attr "type" "vecperm")])
14797 (define_insn "pack<mode>"
14798 [(set (match_operand:FMOVE128_VSX
0 "register_operand" "=wa")
14799 (unspec:FMOVE128_VSX
14800 [(match_operand:DI
1 "register_operand" "wa")
14801 (match_operand:DI
2 "register_operand" "wa")]
14802 UNSPEC_PACK_128BIT))]
14804 "xxpermdi %x0,%x1,%x2,
0"
14805 [(set_attr "type" "vecperm")])
14809 ;; ISA
2.08 IEEE
128-bit floating point support.
14811 (define_insn "add<mode>
3"
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")))]
14816 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14818 [(set_attr "type" "vecfloat")
14819 (set_attr "size" "
128")])
14821 (define_insn "sub<mode>
3"
14822 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14824 (match_operand:IEEE128
1 "altivec_register_operand" "v")
14825 (match_operand:IEEE128
2 "altivec_register_operand" "v")))]
14826 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14828 [(set_attr "type" "vecfloat")
14829 (set_attr "size" "
128")])
14831 (define_insn "mul<mode>
3"
14832 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14834 (match_operand:IEEE128
1 "altivec_register_operand" "v")
14835 (match_operand:IEEE128
2 "altivec_register_operand" "v")))]
14836 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14838 [(set_attr "type" "qmul")
14839 (set_attr "size" "
128")])
14841 (define_insn "div<mode>
3"
14842 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14844 (match_operand:IEEE128
1 "altivec_register_operand" "v")
14845 (match_operand:IEEE128
2 "altivec_register_operand" "v")))]
14846 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14848 [(set_attr "type" "vecdiv")
14849 (set_attr "size" "
128")])
14851 (define_insn "sqrt<mode>
2"
14852 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14854 (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
14855 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14857 [(set_attr "type" "vecdiv")
14858 (set_attr "size" "
128")])
14860 (define_expand "copysign<mode>
3"
14861 [(use (match_operand:IEEE128
0 "altivec_register_operand"))
14862 (use (match_operand:IEEE128
1 "altivec_register_operand"))
14863 (use (match_operand:IEEE128
2 "altivec_register_operand"))]
14864 "FLOAT128_IEEE_P (<MODE>mode)"
14866 if (TARGET_FLOAT128_HW)
14867 emit_insn (gen_copysign<mode>
3_hard (operands[
0], operands[
1],
14870 emit_insn (gen_copysign<mode>
3_soft (operands[
0], operands[
1],
14875 (define_insn "copysign<mode>
3_hard"
14876 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14878 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
14879 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
14881 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14882 "xscpsgnqp %
0,%
2,%
1"
14883 [(set_attr "type" "vecmove")
14884 (set_attr "size" "
128")])
14886 (define_insn "copysign<mode>
3_soft"
14887 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14889 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
14890 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
14892 (clobber (match_scratch:IEEE128
3 "=&v"))]
14893 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14894 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,
1"
14895 [(set_attr "type" "veccomplex")
14896 (set_attr "length" "
8")])
14898 (define_insn "@neg<mode>
2_hw"
14899 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14901 (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
14902 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14904 [(set_attr "type" "vecmove")
14905 (set_attr "size" "
128")])
14908 (define_insn "@abs<mode>
2_hw"
14909 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14911 (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
14912 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14914 [(set_attr "type" "vecmove")
14915 (set_attr "size" "
128")])
14918 (define_insn "*nabs<mode>
2_hw"
14919 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14922 (match_operand:IEEE128
1 "altivec_register_operand" "v"))))]
14923 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14925 [(set_attr "type" "vecmove")
14926 (set_attr "size" "
128")])
14928 ;; Initially don't worry about doing fusion
14929 (define_insn "fma<mode>
4_hw"
14930 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14932 (match_operand:IEEE128
1 "altivec_register_operand" "%v")
14933 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14934 (match_operand:IEEE128
3 "altivec_register_operand" "
0")))]
14935 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14936 "xsmaddqp %
0,%
1,%
2"
14937 [(set_attr "type" "qmul")
14938 (set_attr "size" "
128")])
14940 (define_insn "*fms<mode>
4_hw"
14941 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14943 (match_operand:IEEE128
1 "altivec_register_operand" "%v")
14944 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14946 (match_operand:IEEE128
3 "altivec_register_operand" "
0"))))]
14947 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14948 "xsmsubqp %
0,%
1,%
2"
14949 [(set_attr "type" "qmul")
14950 (set_attr "size" "
128")])
14952 (define_insn "*nfma<mode>
4_hw"
14953 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14956 (match_operand:IEEE128
1 "altivec_register_operand" "%v")
14957 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14958 (match_operand:IEEE128
3 "altivec_register_operand" "
0"))))]
14959 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14960 "xsnmaddqp %
0,%
1,%
2"
14961 [(set_attr "type" "qmul")
14962 (set_attr "size" "
128")])
14964 (define_insn "*nfms<mode>
4_hw"
14965 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14968 (match_operand:IEEE128
1 "altivec_register_operand" "%v")
14969 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14971 (match_operand:IEEE128
3 "altivec_register_operand" "
0")))))]
14972 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14973 "xsnmsubqp %
0,%
1,%
2"
14974 [(set_attr "type" "qmul")
14975 (set_attr "size" "
128")])
14977 (define_insn "extend<SFDF:mode><IEEE128:mode>
2_hw"
14978 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14979 (float_extend:IEEE128
14980 (match_operand:SFDF
1 "altivec_register_operand" "v")))]
14981 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14983 [(set_attr "type" "vecfloat")
14984 (set_attr "size" "
128")])
14986 ;; Conversion between KFmode and TFmode if TFmode is ieee
128-bit floating
14987 ;; point is a simple copy.
14988 (define_insn_and_split "extendkftf2"
14989 [(set (match_operand:TF
0 "vsx_register_operand" "=wa,?wa")
14990 (float_extend:TF (match_operand:KF
1 "vsx_register_operand" "
0,wa")))]
14991 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14995 "&& reload_completed && REGNO (operands[
0]) == REGNO (operands[
1])"
14998 emit_note (NOTE_INSN_DELETED);
15001 [(set_attr "type" "*,veclogical")
15002 (set_attr "length" "
0,
4")])
15004 (define_insn_and_split "trunctfkf2"
15005 [(set (match_operand:KF
0 "vsx_register_operand" "=wa,?wa")
15006 (float_extend:KF (match_operand:TF
1 "vsx_register_operand" "
0,wa")))]
15007 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
15011 "&& reload_completed && REGNO (operands[
0]) == REGNO (operands[
1])"
15014 emit_note (NOTE_INSN_DELETED);
15017 [(set_attr "type" "*,veclogical")
15018 (set_attr "length" "
0,
4")])
15020 (define_insn "trunc<mode>df2_hw"
15021 [(set (match_operand:DF
0 "altivec_register_operand" "=v")
15023 (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
15024 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15026 [(set_attr "type" "vecfloat")
15027 (set_attr "size" "
128")])
15029 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
15030 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
15032 (define_insn_and_split "trunc<mode>sf2_hw"
15033 [(set (match_operand:SF
0 "vsx_register_operand" "=wa")
15035 (match_operand:IEEE128
1 "altivec_register_operand" "v")))
15036 (clobber (match_scratch:DF
2 "=v"))]
15037 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15040 [(set (match_dup
2)
15041 (unspec:DF [(match_dup
1)]
15042 UNSPEC_TRUNC_ROUND_TO_ODD))
15044 (float_truncate:SF (match_dup
2)))]
15046 if (GET_CODE (operands[
2]) == SCRATCH)
15047 operands[
2] = gen_reg_rtx (DFmode);
15049 [(set_attr "type" "vecfloat")
15050 (set_attr "length" "
8")
15051 (set_attr "isa" "p8v")])
15053 ;; Conversion between IEEE
128-bit and integer types
15055 ;; The fix function for DImode and SImode was declared earlier as a
15056 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
15057 ;; have IEEE
128-bit hardware support. QImode and HImode are not provided
15058 ;; unless we have the IEEE
128-bit hardware.
15060 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
15061 ;; to provide a GPR target that used direct move and a conversion in the GPR
15062 ;; which works around QImode/HImode not being allowed in vector registers in
15063 ;; ISA
2.07 (power8).
15064 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>
2_hw"
15065 [(set (match_operand:SDI
0 "altivec_register_operand" "=v")
15066 (any_fix:SDI (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
15067 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15068 "xscvqp<su><wd>z %
0,%
1"
15069 [(set_attr "type" "vecfloat")
15070 (set_attr "size" "
128")])
15072 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>
2"
15073 [(set (match_operand:QHI
0 "altivec_register_operand" "=v")
15075 (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
15076 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15077 "xscvqp<su>wz %
0,%
1"
15078 [(set_attr "type" "vecfloat")
15079 (set_attr "size" "
128")])
15081 ;; Combiner patterns to prevent moving the result of converting an IEEE
128-bit
15082 ;; floating point value to
8/
16/
32-bit integer to GPR in order to save it.
15083 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>
2_mem"
15084 [(set (match_operand:QHSI
0 "memory_operand" "=Z")
15086 (match_operand:IEEE128
1 "altivec_register_operand" "v")))
15087 (clobber (match_scratch:QHSI
2 "=v"))]
15088 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15090 "&& reload_completed"
15091 [(set (match_dup
2)
15092 (any_fix:QHSI (match_dup
1)))
15096 (define_insn "float_<mode>di2_hw"
15097 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15098 (float:IEEE128 (match_operand:DI
1 "altivec_register_operand" "v")))]
15099 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15101 [(set_attr "type" "vecfloat")
15102 (set_attr "size" "
128")])
15104 (define_insn_and_split "float_<mode>si2_hw"
15105 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15106 (float:IEEE128 (match_operand:SI
1 "nonimmediate_operand" "vrZ")))
15107 (clobber (match_scratch:DI
2 "=v"))]
15108 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15111 [(set (match_dup
2)
15112 (sign_extend:DI (match_dup
1)))
15114 (float:IEEE128 (match_dup
2)))]
15116 if (GET_CODE (operands[
2]) == SCRATCH)
15117 operands[
2] = gen_reg_rtx (DImode);
15119 if (MEM_P (operands[
1]))
15120 operands[
1] = rs6000_force_indexed_or_indirect_mem (operands[
1]);
15123 (define_insn_and_split "float<QHI:mode><IEEE128:mode>
2"
15124 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v,v,v")
15125 (float:IEEE128 (match_operand:QHI
1 "nonimmediate_operand" "v,r,Z")))
15126 (clobber (match_scratch:DI
2 "=X,r,X"))]
15127 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15129 "&& reload_completed"
15132 rtx dest = operands[
0];
15133 rtx src = operands[
1];
15134 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
15136 if (altivec_register_operand (src, <QHI:MODE>mode))
15137 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
15138 else if (int_reg_operand (src, <QHI:MODE>mode))
15140 rtx ext_di = operands[
2];
15141 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
15142 emit_move_insn (dest_di, ext_di);
15144 else if (MEM_P (src))
15146 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
15147 emit_move_insn (dest_qhi, src);
15148 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
15151 gcc_unreachable ();
15153 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
15156 [(set_attr "length" "
8,
12,
12")
15157 (set_attr "type" "vecfloat")
15158 (set_attr "size" "
128")])
15160 (define_insn "floatuns_<mode>di2_hw"
15161 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15162 (unsigned_float:IEEE128
15163 (match_operand:DI
1 "altivec_register_operand" "v")))]
15164 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15166 [(set_attr "type" "vecfloat")
15167 (set_attr "size" "
128")])
15169 (define_insn_and_split "floatuns_<mode>si2_hw"
15170 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15171 (unsigned_float:IEEE128
15172 (match_operand:SI
1 "nonimmediate_operand" "vrZ")))
15173 (clobber (match_scratch:DI
2 "=v"))]
15174 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15177 [(set (match_dup
2)
15178 (zero_extend:DI (match_dup
1)))
15180 (float:IEEE128 (match_dup
2)))]
15182 if (GET_CODE (operands[
2]) == SCRATCH)
15183 operands[
2] = gen_reg_rtx (DImode);
15185 if (MEM_P (operands[
1]))
15186 operands[
1] = rs6000_force_indexed_or_indirect_mem (operands[
1]);
15189 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>
2"
15190 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v,v,v")
15191 (unsigned_float:IEEE128
15192 (match_operand:QHI
1 "nonimmediate_operand" "v,r,Z")))
15193 (clobber (match_scratch:DI
2 "=X,r,X"))]
15194 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
15196 "&& reload_completed"
15199 rtx dest = operands[
0];
15200 rtx src = operands[
1];
15201 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
15203 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
15204 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
15205 else if (int_reg_operand (src, <QHI:MODE>mode))
15207 rtx ext_di = operands[
2];
15208 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
15209 emit_move_insn (dest_di, ext_di);
15212 gcc_unreachable ();
15214 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
15217 [(set_attr "length" "
8,
12,
8")
15218 (set_attr "type" "vecfloat")
15219 (set_attr "size" "
128")])
15221 ;; IEEE
128-bit round to integer built-in functions
15222 (define_insn "floor<mode>
2"
15223 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15225 [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
15227 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15229 [(set_attr "type" "vecfloat")
15230 (set_attr "size" "
128")])
15232 (define_insn "ceil<mode>
2"
15233 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15235 [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
15237 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15239 [(set_attr "type" "vecfloat")
15240 (set_attr "size" "
128")])
15242 (define_insn "btrunc<mode>
2"
15243 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15245 [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
15247 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15249 [(set_attr "type" "vecfloat")
15250 (set_attr "size" "
128")])
15252 (define_insn "round<mode>
2"
15253 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15255 [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
15257 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15259 [(set_attr "type" "vecfloat")
15260 (set_attr "size" "
128")])
15262 ;; IEEE
128-bit instructions with round to odd semantics
15263 (define_insn "add<mode>
3_odd"
15264 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15266 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
15267 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
15268 UNSPEC_ADD_ROUND_TO_ODD))]
15269 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15270 "xsaddqpo %
0,%
1,%
2"
15271 [(set_attr "type" "vecfloat")
15272 (set_attr "size" "
128")])
15274 (define_insn "sub<mode>
3_odd"
15275 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15277 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
15278 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
15279 UNSPEC_SUB_ROUND_TO_ODD))]
15280 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15281 "xssubqpo %
0,%
1,%
2"
15282 [(set_attr "type" "vecfloat")
15283 (set_attr "size" "
128")])
15285 (define_insn "mul<mode>
3_odd"
15286 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15288 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
15289 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
15290 UNSPEC_MUL_ROUND_TO_ODD))]
15291 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15292 "xsmulqpo %
0,%
1,%
2"
15293 [(set_attr "type" "qmul")
15294 (set_attr "size" "
128")])
15296 (define_insn "div<mode>
3_odd"
15297 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15299 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
15300 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
15301 UNSPEC_DIV_ROUND_TO_ODD))]
15302 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15303 "xsdivqpo %
0,%
1,%
2"
15304 [(set_attr "type" "vecdiv")
15305 (set_attr "size" "
128")])
15307 (define_insn "sqrt<mode>
2_odd"
15308 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15310 [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
15311 UNSPEC_SQRT_ROUND_TO_ODD))]
15312 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15314 [(set_attr "type" "vecdiv")
15315 (set_attr "size" "
128")])
15317 (define_insn "fma<mode>
4_odd"
15318 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15320 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
15321 (match_operand:IEEE128
2 "altivec_register_operand" "v")
15322 (match_operand:IEEE128
3 "altivec_register_operand" "
0")]
15323 UNSPEC_FMA_ROUND_TO_ODD))]
15324 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15325 "xsmaddqpo %
0,%
1,%
2"
15326 [(set_attr "type" "qmul")
15327 (set_attr "size" "
128")])
15329 (define_insn "*fms<mode>
4_odd"
15330 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15332 [(match_operand:IEEE128
1 "altivec_register_operand" "%v")
15333 (match_operand:IEEE128
2 "altivec_register_operand" "v")
15335 (match_operand:IEEE128
3 "altivec_register_operand" "
0"))]
15336 UNSPEC_FMA_ROUND_TO_ODD))]
15337 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15338 "xsmsubqpo %
0,%
1,%
2"
15339 [(set_attr "type" "qmul")
15340 (set_attr "size" "
128")])
15342 (define_insn "*nfma<mode>
4_odd"
15343 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15346 [(match_operand:IEEE128
1 "altivec_register_operand" "%v")
15347 (match_operand:IEEE128
2 "altivec_register_operand" "v")
15348 (match_operand:IEEE128
3 "altivec_register_operand" "
0")]
15349 UNSPEC_FMA_ROUND_TO_ODD)))]
15350 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15351 "xsnmaddqpo %
0,%
1,%
2"
15352 [(set_attr "type" "qmul")
15353 (set_attr "size" "
128")])
15355 (define_insn "*nfms<mode>
4_odd"
15356 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
15359 [(match_operand:IEEE128
1 "altivec_register_operand" "%v")
15360 (match_operand:IEEE128
2 "altivec_register_operand" "v")
15362 (match_operand:IEEE128
3 "altivec_register_operand" "
0"))]
15363 UNSPEC_FMA_ROUND_TO_ODD)))]
15364 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15365 "xsnmsubqpo %
0,%
1,%
2"
15366 [(set_attr "type" "qmul")
15367 (set_attr "size" "
128")])
15369 (define_insn "trunc<mode>df2_odd"
15370 [(set (match_operand:DF
0 "vsx_register_operand" "=v")
15371 (unspec:DF [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
15372 UNSPEC_TRUNC_ROUND_TO_ODD))]
15373 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15375 [(set_attr "type" "vecfloat")
15376 (set_attr "size" "
128")])
15378 ;; IEEE
128-bit comparisons
15379 (define_insn "*cmp<mode>_hw"
15380 [(set (match_operand:CCFP
0 "cc_reg_operand" "=y")
15381 (compare:CCFP (match_operand:IEEE128
1 "altivec_register_operand" "v")
15382 (match_operand:IEEE128
2 "altivec_register_operand" "v")))]
15383 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
15384 "xscmpuqp %
0,%
1,%
2"
15385 [(set_attr "type" "veccmp")
15386 (set_attr "size" "
128")])
15388 ;; Miscellaneous ISA
3.0 (power9) instructions
15390 (define_expand "darn_32_<mode>"
15391 [(use (match_operand:GPR
0 "register_operand"))]
15394 emit_insn (gen_darn (<MODE>mode, operands[
0], const0_rtx));
15398 (define_expand "darn_64_<mode>"
15399 [(use (match_operand:GPR
0 "register_operand"))]
15402 emit_insn (gen_darn (<MODE>mode, operands[
0], const1_rtx));
15406 (define_expand "darn_raw_<mode>"
15407 [(use (match_operand:GPR
0 "register_operand"))]
15410 emit_insn (gen_darn (<MODE>mode, operands[
0], const2_rtx));
15414 (define_insn "@darn<mode>"
15415 [(set (match_operand:GPR
0 "register_operand" "=r")
15416 (unspec_volatile:GPR [(match_operand
1 "const_int_operand" "n")]
15420 [(set_attr "type" "integer")])
15422 ;; Test byte within range.
15424 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
15425 ;; represents a byte whose value is ignored in this context and
15426 ;; vv, the least significant byte, holds the byte value that is to
15427 ;; be tested for membership within the range specified by operand
2.
15428 ;; The bytes of operand
2 are organized as xx:xx:hi:lo.
15430 ;; Return in target register operand
0 a value of
1 if lo <= vv and
15431 ;; vv <= hi. Otherwise, set register operand
0 to
0.
15433 ;; Though the instructions to which this expansion maps operate on
15434 ;;
64-bit registers, the current implementation only operates on
15435 ;; SI-mode operands as the high-order bits provide no information
15436 ;; that is not already available in the low-order bits. To avoid the
15437 ;; costs of data widening operations, future enhancements might allow
15438 ;; DI mode for operand
0 and/or might allow operand
1 to be QI mode.
15439 (define_expand "cmprb"
15440 [(set (match_dup
3)
15441 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
15442 (match_operand:SI
2 "gpc_reg_operand" "r")]
15444 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
15445 (if_then_else:SI (lt (match_dup
3)
15448 (if_then_else (gt (match_dup
3)
15454 operands[
3] = gen_reg_rtx (CCmode);
15457 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
15458 ;; represents a byte whose value is ignored in this context and
15459 ;; vv, the least significant byte, holds the byte value that is to
15460 ;; be tested for membership within the range specified by operand
2.
15461 ;; The bytes of operand
2 are organized as xx:xx:hi:lo.
15463 ;; Set bit
1 (the GT bit,
0x4) of CR register operand
0 to
1 if
15464 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to
0. The other
15465 ;;
3 bits of the target CR register are all set to
0.
15466 (define_insn "*cmprb_internal"
15467 [(set (match_operand:CC
0 "cc_reg_operand" "=y")
15468 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
15469 (match_operand:SI
2 "gpc_reg_operand" "r")]
15473 [(set_attr "type" "logical")])
15475 ;; Set operand
0 register to -
1 if the LT bit (
0x8) of condition
15476 ;; register operand
1 is on. Otherwise, set operand
0 register to
1
15477 ;; if the GT bit (
0x4) of condition register operand
1 is on.
15478 ;; Otherwise, set operand
0 to
0. Note that the result stored into
15479 ;; register operand
0 is non-zero iff either the LT or GT bits are on
15480 ;; within condition register operand
1.
15481 (define_insn "setb_signed"
15482 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
15483 (if_then_else:SI (lt (match_operand:CC
1 "cc_reg_operand" "y")
15486 (if_then_else (gt (match_dup
1)
15492 [(set_attr "type" "logical")])
15494 (define_insn "setb_unsigned"
15495 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
15496 (if_then_else:SI (ltu (match_operand:CCUNS
1 "cc_reg_operand" "y")
15499 (if_then_else (gtu (match_dup
1)
15505 [(set_attr "type" "logical")])
15507 ;; Test byte within two ranges.
15509 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
15510 ;; represents a byte whose value is ignored in this context and
15511 ;; vv, the least significant byte, holds the byte value that is to
15512 ;; be tested for membership within the range specified by operand
2.
15513 ;; The bytes of operand
2 are organized as hi_1:lo_1:hi_2:lo_2.
15515 ;; Return in target register operand
0 a value of
1 if (lo_1 <= vv and
15516 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
15519 ;; Though the instructions to which this expansion maps operate on
15520 ;;
64-bit registers, the current implementation only operates on
15521 ;; SI-mode operands as the high-order bits provide no information
15522 ;; that is not already available in the low-order bits. To avoid the
15523 ;; costs of data widening operations, future enhancements might allow
15524 ;; DI mode for operand
0 and/or might allow operand
1 to be QI mode.
15525 (define_expand "cmprb2"
15526 [(set (match_dup
3)
15527 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
15528 (match_operand:SI
2 "gpc_reg_operand" "r")]
15530 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
15531 (if_then_else:SI (lt (match_dup
3)
15534 (if_then_else (gt (match_dup
3)
15540 operands[
3] = gen_reg_rtx (CCmode);
15543 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
15544 ;; represents a byte whose value is ignored in this context and
15545 ;; vv, the least significant byte, holds the byte value that is to
15546 ;; be tested for membership within the ranges specified by operand
2.
15547 ;; The bytes of operand
2 are organized as hi_1:lo_1:hi_2:lo_2.
15549 ;; Set bit
1 (the GT bit,
0x4) of CR register operand
0 to
1 if
15550 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
15551 ;; Otherwise, set the GT bit to
0. The other
3 bits of the target
15552 ;; CR register are all set to
0.
15553 (define_insn "*cmprb2_internal"
15554 [(set (match_operand:CC
0 "cc_reg_operand" "=y")
15555 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
15556 (match_operand:SI
2 "gpc_reg_operand" "r")]
15560 [(set_attr "type" "logical")])
15562 ;; Test byte membership within set of
8 bytes.
15564 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
15565 ;; represents a byte whose value is ignored in this context and
15566 ;; vv, the least significant byte, holds the byte value that is to
15567 ;; be tested for membership within the set specified by operand
2.
15568 ;; The bytes of operand
2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
15570 ;; Return in target register operand
0 a value of
1 if vv equals one
15571 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
15572 ;; register operand
0 to
0. Note that the
8 byte values held within
15573 ;; operand
2 need not be unique.
15575 ;; Though the instructions to which this expansion maps operate on
15576 ;;
64-bit registers, the current implementation requires that operands
15577 ;;
0 and
1 have mode SI as the high-order bits provide no information
15578 ;; that is not already available in the low-order bits. To avoid the
15579 ;; costs of data widening operations, future enhancements might allow
15580 ;; DI mode for operand
0 and/or might allow operand
1 to be QI mode.
15581 (define_expand "cmpeqb"
15582 [(set (match_dup
3)
15583 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
15584 (match_operand:DI
2 "gpc_reg_operand" "r")]
15586 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
15587 (if_then_else:SI (lt (match_dup
3)
15590 (if_then_else (gt (match_dup
3)
15594 "TARGET_P9_MISC && TARGET_64BIT"
15596 operands[
3] = gen_reg_rtx (CCmode);
15599 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
15600 ;; represents a byte whose value is ignored in this context and
15601 ;; vv, the least significant byte, holds the byte value that is to
15602 ;; be tested for membership within the set specified by operand
2.
15603 ;; The bytes of operand
2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
15605 ;; Set bit
1 (the GT bit,
0x4) of CR register operand
0 to
1 if vv
15606 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
15607 ;; set the GT bit to zero. The other
3 bits of the target CR register
15608 ;; are all set to
0.
15609 (define_insn "*cmpeqb_internal"
15610 [(set (match_operand:CC
0 "cc_reg_operand" "=y")
15611 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
15612 (match_operand:DI
2 "gpc_reg_operand" "r")]
15614 "TARGET_P9_MISC && TARGET_64BIT"
15616 [(set_attr "type" "logical")])
15619 ;; ROP mitigation instructions.
15621 (define_insn "hashst"
15622 [(set (match_operand:DI
0 "simple_offsettable_mem_operand" "=m")
15623 (unspec_volatile:DI [(match_operand:DI
1 "int_reg_operand" "r")]
15625 "TARGET_POWER10 && rs6000_rop_protect"
15627 static char templ[
32];
15628 const char *p = rs6000_privileged ? "p" : "";
15629 sprintf (templ, "hashst%s %%
1,%%
0", p);
15632 [(set_attr "type" "store")])
15634 (define_insn "hashchk"
15635 [(unspec_volatile [(match_operand:DI
0 "int_reg_operand" "r")
15636 (match_operand:DI
1 "simple_offsettable_mem_operand" "m")]
15638 "TARGET_POWER10 && rs6000_rop_protect"
15640 static char templ[
32];
15641 const char *p = rs6000_privileged ? "p" : "";
15642 sprintf (templ, "hashchk%s %%
0,%%
1", p);
15645 [(set_attr "type" "load")])
15648 (include "sync.md")
15649 (include "vector.md")
15651 (include "altivec.md")
15654 (include "crypto.md")
15656 (include "fusion.md")
15657 (include "pcrel-opt.md")