1 ;; Machine description for IBM RISC System
6000 (POWER) for GNU C compiler
2 ;; Copyright (C)
1990-
2020 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version
3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (STACK_POINTER_REGNUM
1)
31 (STATIC_CHAIN_REGNUM
11)
32 (HARD_FRAME_POINTER_REGNUM
31)
36 (FIRST_ALTIVEC_REGNO
64)
37 (LAST_ALTIVEC_REGNO
95)
41 (ARG_POINTER_REGNUM
99)
53 (FRAME_POINTER_REGNUM
110)
60 (define_c_enum "unspec"
61 [UNSPEC_PROBE_STACK ; probe stack memory reference
62 UNSPEC_TOCPTR ; address of a word pointing to the TOC
63 UNSPEC_TOC ; address of the TOC (more-or-less)
64 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
72 UNSPEC_LD_MPIC ; load_macho_picbase
73 UNSPEC_RELD_MPIC ; re-load_macho_picbase
74 UNSPEC_MPIC_CORRECT ; macho_correct_pic
91 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
109 UNSPEC_MACHOPIC_OFFSET
123 UNSPEC_P8V_RELOAD_FROM_GPR
126 UNSPEC_P8V_RELOAD_FROM_VSX
140 UNSPEC_ADD_ROUND_TO_ODD
141 UNSPEC_SUB_ROUND_TO_ODD
142 UNSPEC_MUL_ROUND_TO_ODD
143 UNSPEC_DIV_ROUND_TO_ODD
144 UNSPEC_FMA_ROUND_TO_ODD
145 UNSPEC_SQRT_ROUND_TO_ODD
146 UNSPEC_TRUNC_ROUND_TO_ODD
160 ;; UNSPEC_VOLATILE usage
163 (define_c_enum "unspecv"
165 UNSPECV_LL ; load-locked
166 UNSPECV_SC ; store-conditional
167 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
168 UNSPECV_EH_RR ; eh_reg_restore
169 UNSPECV_ISYNC ; isync instruction
170 UNSPECV_MFTB ; move from time base
171 UNSPECV_DARN ; darn
1 (deliver a random number)
172 UNSPECV_DARN_32 ; darn
2
173 UNSPECV_DARN_RAW ; darn
0
174 UNSPECV_NLGR ; non-local goto receiver
175 UNSPECV_MFFS ; Move from FPSCR
176 UNSPECV_MFFSL ; Move from FPSCR light instruction version
177 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
178 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
179 UNSPECV_MTFSF ; Move to FPSCR Fields
8 to
15
180 UNSPECV_MTFSF_HI ; Move to FPSCR Fields
0 to
7
181 UNSPECV_MTFSB0 ; Set FPSCR Field bit to
0
182 UNSPECV_MTFSB1 ; Set FPSCR Field bit to
1
183 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
184 UNSPECV_SPEC_BARRIER ; Speculation barrier
189 ; The three different kinds of epilogue.
190 (define_enum "epilogue_type" [normal sibcall eh_return])
192 ;; Define an insn type attribute. This is used in function unit delay
196 add,logical,shift,insert,
198 exts,cntlz,popcnt,isel,
199 load,store,fpload,fpstore,vecload,vecstore,
201 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
202 cr_logical,mfcr,mfcrf,mtcr,
203 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
204 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
205 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
206 veclogical,veccmpfx,vecexts,vecmove,
207 htm,htmsimple,dfp,mma"
208 (const_string "integer"))
210 ;; What data size does this instruction work on?
211 ;; This is used for insert, mul and others as necessary.
212 (define_attr "size" "
8,
16,
32,
64,
128" (const_string "
32"))
214 ;; What is the insn_cost for this insn? The target hook can still override
215 ;; this. For optimizing for size the "length" attribute is used instead.
216 (define_attr "cost" "" (const_int
0))
218 ;; Is this instruction record form ("dot", signed compare to
0, writing CR0)?
219 ;; This is used for add, logical, shift, exts, mul.
220 (define_attr "dot" "no,yes" (const_string "no"))
222 ;; Does this instruction sign-extend its result?
223 ;; This is used for load insns.
224 (define_attr "sign_extend" "no,yes" (const_string "no"))
226 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
227 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
229 ;; Does this instruction use indexed (that is, reg+reg) addressing?
230 ;; This is used for load and store insns. If operand
0 or
1 is a MEM
231 ;; it is automatically set based on that. If a load or store instruction
232 ;; has fewer than two operands it needs to set this attribute manually
233 ;; or the compiler will crash.
234 (define_attr "indexed" "no,yes"
235 (if_then_else (ior (match_operand
0 "indexed_address_mem")
236 (match_operand
1 "indexed_address_mem"))
238 (const_string "no")))
240 ;; Does this instruction use update addressing?
241 ;; This is used for load and store insns. See the comments for "indexed".
242 (define_attr "update" "no,yes"
243 (if_then_else (ior (match_operand
0 "update_address_mem")
244 (match_operand
1 "update_address_mem"))
246 (const_string "no")))
248 ;; Is this instruction using operands[
2] as shift amount, and can that be a
250 ;; This is used for shift insns.
251 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
253 ;; Is this instruction using a shift amount from a register?
254 ;; This is used for shift insns.
255 (define_attr "var_shift" "no,yes"
256 (if_then_else (and (eq_attr "type" "shift")
257 (eq_attr "maybe_var_shift" "yes"))
258 (if_then_else (match_operand
2 "gpc_reg_operand")
261 (const_string "no")))
263 ;; Is copying of this instruction disallowed?
264 (define_attr "cannot_copy" "no,yes" (const_string "no"))
267 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
268 ;; before the instruction. A prefixed instruction has a prefix instruction
269 ;; word that extends the immediate value of the instructions from
12-
16 bits to
270 ;;
34 bits. The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
271 ;; insns. The default "length" attribute will also be adjusted by default to
273 (define_attr "prefixed" "no,yes"
274 (cond [(ior (match_test "!TARGET_PREFIXED")
275 (match_test "!NONJUMP_INSN_P (insn)"))
278 (eq_attr "type" "load,fpload,vecload")
279 (if_then_else (match_test "prefixed_load_p (insn)")
283 (eq_attr "type" "store,fpstore,vecstore")
284 (if_then_else (match_test "prefixed_store_p (insn)")
288 (eq_attr "type" "integer,add")
289 (if_then_else (match_test "prefixed_paddi_p (insn)")
291 (const_string "no"))]
293 (const_string "no")))
295 ;; Return the number of real hardware instructions in a combined insn. If it
296 ;; is
0, just use the length /
4.
297 (define_attr "num_insns" "" (const_int
0))
299 ;; If an insn is prefixed, return the maximum number of prefixed instructions
300 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
302 (define_attr "max_prefixed_insns" "" (const_int
1))
304 ;; Length of the instruction (in bytes). This length does not consider the
305 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
306 ;; the length if there are prefixed instructions.
308 ;; While it might be tempting to use num_insns to calculate the length, it can
309 ;; be problematical unless all insn lengths are adjusted to use num_insns
310 ;; (i.e. if num_insns is
0, it will get the length, which in turn will get
311 ;; num_insns and recurse).
312 (define_attr "length" "" (const_int
4))
314 ;; Processor type -- this attribute must exactly match the processor_type
315 ;; enumeration in rs6000-opts.h.
317 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
318 ppc750,ppc7400,ppc7450,
319 ppc403,ppc405,ppc440,ppc476,
320 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
321 power4,power5,power6,power7,power8,power9,power10,
322 rs64a,mpccore,cell,ppca2,titan"
323 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
325 ;; The ISA we implement.
326 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9,p9v,p9kf,p9tf,p10"
327 (const_string "any"))
329 ;; Is this alternative enabled for the current CPU/ISA/etc.?
330 (define_attr "enabled" ""
332 [(eq_attr "isa" "any")
335 (and (eq_attr "isa" "p5")
336 (match_test "TARGET_POPCNTB"))
339 (and (eq_attr "isa" "p6")
340 (match_test "TARGET_CMPB"))
343 (and (eq_attr "isa" "p7")
344 (match_test "TARGET_POPCNTD"))
347 (and (eq_attr "isa" "p7v")
348 (match_test "TARGET_VSX"))
351 (and (eq_attr "isa" "p8v")
352 (match_test "TARGET_P8_VECTOR"))
355 (and (eq_attr "isa" "p9")
356 (match_test "TARGET_MODULO"))
359 (and (eq_attr "isa" "p9v")
360 (match_test "TARGET_P9_VECTOR"))
363 (and (eq_attr "isa" "p9kf")
364 (match_test "TARGET_FLOAT128_TYPE"))
367 (and (eq_attr "isa" "p9tf")
368 (match_test "FLOAT128_VECTOR_P (TFmode)"))
371 (and (eq_attr "isa" "p10")
372 (match_test "TARGET_POWER10"))
376 ;; If this instruction is microcoded on the CELL processor
377 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
378 (define_attr "cell_micro" "not,conditional,always"
379 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
380 (eq_attr "dot" "yes"))
381 (and (eq_attr "type" "load")
382 (eq_attr "sign_extend" "yes"))
383 (and (eq_attr "type" "shift")
384 (eq_attr "var_shift" "yes")))
385 (const_string "always")
386 (const_string "not")))
388 (automata_option "ndfa")
401 (include "e300c2c3.md")
402 (include "e500mc.md")
403 (include "e500mc64.md")
406 (include "power4.md")
407 (include "power5.md")
408 (include "power6.md")
409 (include "power7.md")
410 (include "power8.md")
411 (include "power9.md")
412 (include "power10.md")
417 (include "predicates.md")
418 (include "constraints.md")
423 ; This mode iterator allows :GPR to be used to indicate the allowable size
424 ; of whole values in GPRs.
425 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
427 ; And again, for patterns that need two (potentially) different integer modes.
428 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
430 ; Any supported integer mode.
431 (define_mode_iterator INT [QI HI SI DI TI PTI])
433 ; Any supported integer mode that fits in one register.
434 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
436 ; Integer modes supported in VSX registers with ISA
3.0 instructions
437 (define_mode_iterator INT_ISA3 [QI HI SI DI])
439 ; Everything we can extend QImode to.
440 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
442 ; Everything we can extend HImode to.
443 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
445 ; Everything we can extend SImode to.
446 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
448 ; QImode or HImode for small integer moves and small atomic ops
449 (define_mode_iterator QHI [QI HI])
451 ; QImode, HImode, SImode for fused ops only for GPR loads
452 (define_mode_iterator QHSI [QI HI SI])
454 ; HImode or SImode for sign extended fusion ops
455 (define_mode_iterator HSI [HI SI])
457 ; SImode or DImode, even if DImode doesn't fit in GPRs.
458 (define_mode_iterator SDI [SI DI])
460 ; The size of a pointer. Also, the size of the value that a record-condition
461 ; (one with a '.') will compare; and the size used for arithmetic carries.
462 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
464 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
465 ; PTImode is GPR only)
466 (define_mode_iterator TI2 [TI PTI])
468 ; Any hardware-supported floating-point mode
469 (define_mode_iterator FP [
470 (SF "TARGET_HARD_FLOAT")
471 (DF "TARGET_HARD_FLOAT")
472 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
473 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
474 (KF "TARGET_FLOAT128_TYPE")
478 ; Any fma capable floating-point mode.
479 (define_mode_iterator FMA_F [
480 (SF "TARGET_HARD_FLOAT")
481 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
482 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
483 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
484 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
485 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
488 ; Floating point move iterators to combine binary and decimal moves
489 (define_mode_iterator FMOVE32 [SF SD])
490 (define_mode_iterator FMOVE64 [DF DD])
491 (define_mode_iterator FMOVE64X [DI DF DD])
492 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
493 (IF "FLOAT128_IBM_P (IFmode)")
494 (TD "TARGET_HARD_FLOAT")])
496 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
497 (IF "FLOAT128_2REG_P (IFmode)")
498 (TD "TARGET_HARD_FLOAT")])
500 ; Iterators for
128 bit types for direct move
501 (define_mode_iterator FMOVE128_GPR [TI
509 (KF "FLOAT128_VECTOR_P (KFmode)")
510 (TF "FLOAT128_VECTOR_P (TFmode)")])
512 ; Iterator for
128-bit VSX types for pack/unpack
513 (define_mode_iterator FMOVE128_VSX [V1TI KF])
515 ; Iterators for converting to/from TFmode
516 (define_mode_iterator IFKF [IF KF])
518 ; Constraints for moving IF/KFmode.
519 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
521 ; Whether a floating point move is ok, don't allow SD without hardware FP
522 (define_mode_attr fmove_ok [(SF "")
524 (SD "TARGET_HARD_FLOAT")
527 ; Convert REAL_VALUE to the appropriate bits
528 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
529 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
530 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
531 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
533 ; Whether
0.0 has an all-zero bit pattern
534 (define_mode_attr zero_fp [(SF "j")
543 ; Definitions for
64-bit VSX
544 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
546 ; Definitions for
64-bit direct move
547 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
549 ; Definitions for
64-bit use of altivec registers
550 (define_mode_attr f64_av [(DF "v") (DD "wn")])
552 ; Definitions for
64-bit access to ISA
3.0 (power9) vector
553 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
555 ; These modes do not fit in integer registers in
32-bit mode.
556 (define_mode_iterator DIFD [DI DF DD])
558 ; Iterator for reciprocal estimate instructions
559 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
562 (define_mode_iterator SFDF [SF DF])
564 ; And again, for when we need two FP modes in a pattern.
565 (define_mode_iterator SFDF2 [SF DF])
567 ; A generic s/d attribute, for sp/dp for example.
568 (define_mode_attr sd [(SF "s") (DF "d")
569 (V4SF "s") (V2DF "d")])
571 ; "s" or nothing, for fmuls/fmul for example.
572 (define_mode_attr s [(SF "s") (DF "")])
574 ; Iterator for
128-bit floating point that uses the IBM double-double format
575 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
576 (TF "FLOAT128_IBM_P (TFmode)")])
578 ; Iterator for
128-bit floating point that uses IEEE
128-bit float
579 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
580 (TF "FLOAT128_IEEE_P (TFmode)")])
582 ; Iterator for
128-bit floating point
583 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
584 (IF "TARGET_FLOAT128_TYPE")
585 (TF "TARGET_LONG_DOUBLE_128")])
587 ; Iterator for signbit on
64-bit machines with direct move
588 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
589 (TF "FLOAT128_VECTOR_P (TFmode)")])
591 ; Iterator for ISA
3.0 supported floating point types
592 (define_mode_iterator FP_ISA3 [SF DF])
594 ; SF/DF constraint for arithmetic on traditional floating point registers
595 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
597 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
598 ; ISA
2.06 (power7). This includes instructions that normally target DF mode,
599 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
601 (define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")])
603 ; Which isa is needed for those float instructions?
604 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
607 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
609 ; Conditional returns.
610 (define_code_iterator any_return [return simple_return])
611 (define_code_attr return_pred [(return "direct_return ()")
612 (simple_return "
1")])
613 (define_code_attr return_str [(return "") (simple_return "simple_")])
616 (define_code_iterator iorxor [ior xor])
617 (define_code_iterator and_ior_xor [and ior xor])
619 ; Signed/unsigned variants of ops.
620 (define_code_iterator any_extend [sign_extend zero_extend])
621 (define_code_iterator any_fix [fix unsigned_fix])
622 (define_code_iterator any_float [float unsigned_float])
624 (define_code_attr u [(sign_extend "")
629 (define_code_attr su [(sign_extend "s")
634 (unsigned_float "u")])
636 (define_code_attr az [(sign_extend "a")
641 (unsigned_float "z")])
643 (define_code_attr uns [(fix "")
646 (unsigned_float "uns")])
648 ; Various instructions that come in SI and DI forms.
649 ; A generic w/d attribute, for things like cmpw/cmpd.
650 (define_mode_attr wd [(QI "b")
661 ; For double extract from different origin types
662 (define_mode_attr du_or_d [(QI "du")
671 ;; How many bits in this mode?
672 (define_mode_attr bits [(QI "
8") (HI "
16") (SI "
32") (DI "
64")
673 (SF "
32") (DF "
64")])
676 (define_mode_attr dbits [(QI "
56") (HI "
48") (SI "
32")])
678 ;; Bitmask for shift instructions
679 (define_mode_attr hH [(SI "h") (DI "H")])
681 ;; A mode twice the size of the given mode
682 (define_mode_attr dmode [(SI "di") (DI "ti")])
683 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
685 ;; Suffix for reload patterns
686 (define_mode_attr ptrsize [(SI "
32bit")
689 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
690 (DI "TARGET_64BIT")])
692 (define_mode_attr mptrsize [(SI "si")
695 (define_mode_attr ptrload [(SI "lwz")
698 (define_mode_attr ptrm [(SI "m")
701 (define_mode_attr rreg [(SF "f")
708 (define_mode_attr rreg2 [(SF "f")
711 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
712 (DF "TARGET_FCFID")])
714 ;; Mode iterator for logical operations on
128-bit types
715 (define_mode_iterator BOOL_128 [TI
717 (V16QI "TARGET_ALTIVEC")
718 (V8HI "TARGET_ALTIVEC")
719 (V4SI "TARGET_ALTIVEC")
720 (V4SF "TARGET_ALTIVEC")
721 (V2DI "TARGET_ALTIVEC")
722 (V2DF "TARGET_ALTIVEC")
723 (V1TI "TARGET_ALTIVEC")])
725 ;; For the GPRs we use
3 constraints for register outputs, two that are the
726 ;; same as the output register, and a third where the output register is an
727 ;; early clobber, so we don't have to deal with register overlaps. For the
728 ;; vector types, we prefer to use the vector registers. For TI mode, allow
731 ;; Mode attribute for boolean operation register constraints for output
732 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
734 (V16QI "wa,v,&?r,?r,?r")
735 (V8HI "wa,v,&?r,?r,?r")
736 (V4SI "wa,v,&?r,?r,?r")
737 (V4SF "wa,v,&?r,?r,?r")
738 (V2DI "wa,v,&?r,?r,?r")
739 (V2DF "wa,v,&?r,?r,?r")
740 (V1TI "wa,v,&?r,?r,?r")])
742 ;; Mode attribute for boolean operation register constraints for operand1
743 (define_mode_attr BOOL_REGS_OP1 [(TI "r,
0,r,wa,v")
751 (V1TI "wa,v,r,
0,r")])
753 ;; Mode attribute for boolean operation register constraints for operand2
754 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,
0,wa,v")
762 (V1TI "wa,v,r,r,
0")])
764 ;; Mode attribute for boolean operation register constraints for operand1
765 ;; for one_cmpl. To simplify things, we repeat the constraint where
0
766 ;; is used for operand1 or operand2
767 (define_mode_attr BOOL_REGS_UNARY [(TI "r,
0,
0,wa,v")
775 (V1TI "wa,v,r,
0,
0")])
777 ;; Reload iterator for creating the function to allocate a base register to
778 ;; supplement addressing modes.
779 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
780 SF SD SI DF DD DI TI PTI KF IF TF
783 ;; Iterate over smin, smax
784 (define_code_iterator fp_minmax [smin smax])
786 (define_code_attr minmax [(smin "min")
789 (define_code_attr SMINMAX [(smin "SMIN")
792 ;; Iterator to optimize the following cases:
793 ;; D-form load to FPR register & move to Altivec register
794 ;; Move Altivec register to FPR register and store
795 (define_mode_iterator ALTIVEC_DFORM [DF
796 (SF "TARGET_P8_VECTOR")
797 (DI "TARGET_POWERPC64")])
799 (include "darwin.md")
801 ;; Start with fixed-point load and store insns. Here we put only the more
802 ;; complex forms. Basic data transfer is done later.
804 (define_insn "zero_extendqi<mode>
2"
805 [(set (match_operand:EXTQI
0 "gpc_reg_operand" "=r,r,^wa,^v")
806 (zero_extend:EXTQI (match_operand:QI
1 "reg_or_mem_operand" "m,r,Z,v")))]
813 [(set_attr "type" "load,shift,fpload,vecperm")
814 (set_attr "isa" "*,*,p9v,p9v")])
816 (define_insn_and_split "*zero_extendqi<mode>
2_dot"
817 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
818 (compare:CC (zero_extend:EXTQI (match_operand:QI
1 "gpc_reg_operand" "r,r"))
820 (clobber (match_scratch:EXTQI
0 "=r,r"))]
825 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
827 (zero_extend:EXTQI (match_dup
1)))
829 (compare:CC (match_dup
0)
832 [(set_attr "type" "logical")
833 (set_attr "dot" "yes")
834 (set_attr "length" "
4,
8")])
836 (define_insn_and_split "*zero_extendqi<mode>
2_dot2"
837 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
838 (compare:CC (zero_extend:EXTQI (match_operand:QI
1 "gpc_reg_operand" "r,r"))
840 (set (match_operand:EXTQI
0 "gpc_reg_operand" "=r,r")
841 (zero_extend:EXTQI (match_dup
1)))]
846 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
848 (zero_extend:EXTQI (match_dup
1)))
850 (compare:CC (match_dup
0)
853 [(set_attr "type" "logical")
854 (set_attr "dot" "yes")
855 (set_attr "length" "
4,
8")])
858 (define_insn "zero_extendhi<mode>
2"
859 [(set (match_operand:EXTHI
0 "gpc_reg_operand" "=r,r,^wa,^v")
860 (zero_extend:EXTHI (match_operand:HI
1 "reg_or_mem_operand" "m,r,Z,v")))]
864 rlwinm %
0,%
1,
0,
0xffff
867 [(set_attr "type" "load,shift,fpload,vecperm")
868 (set_attr "isa" "*,*,p9v,p9v")])
870 (define_insn_and_split "*zero_extendhi<mode>
2_dot"
871 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
872 (compare:CC (zero_extend:EXTHI (match_operand:HI
1 "gpc_reg_operand" "r,r"))
874 (clobber (match_scratch:EXTHI
0 "=r,r"))]
879 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
881 (zero_extend:EXTHI (match_dup
1)))
883 (compare:CC (match_dup
0)
886 [(set_attr "type" "logical")
887 (set_attr "dot" "yes")
888 (set_attr "length" "
4,
8")])
890 (define_insn_and_split "*zero_extendhi<mode>
2_dot2"
891 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
892 (compare:CC (zero_extend:EXTHI (match_operand:HI
1 "gpc_reg_operand" "r,r"))
894 (set (match_operand:EXTHI
0 "gpc_reg_operand" "=r,r")
895 (zero_extend:EXTHI (match_dup
1)))]
900 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
902 (zero_extend:EXTHI (match_dup
1)))
904 (compare:CC (match_dup
0)
907 [(set_attr "type" "logical")
908 (set_attr "dot" "yes")
909 (set_attr "length" "
4,
8")])
912 (define_insn "zero_extendsi<mode>
2"
913 [(set (match_operand:EXTSI
0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
914 (zero_extend:EXTSI (match_operand:SI
1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
923 xxextractuw %x0,%x1,
4"
924 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
925 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
927 (define_insn_and_split "*zero_extendsi<mode>
2_dot"
928 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
929 (compare:CC (zero_extend:EXTSI (match_operand:SI
1 "gpc_reg_operand" "r,r"))
931 (clobber (match_scratch:EXTSI
0 "=r,r"))]
936 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
938 (zero_extend:DI (match_dup
1)))
940 (compare:CC (match_dup
0)
943 [(set_attr "type" "shift")
944 (set_attr "dot" "yes")
945 (set_attr "length" "
4,
8")])
947 (define_insn_and_split "*zero_extendsi<mode>
2_dot2"
948 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
949 (compare:CC (zero_extend:EXTSI (match_operand:SI
1 "gpc_reg_operand" "r,r"))
951 (set (match_operand:EXTSI
0 "gpc_reg_operand" "=r,r")
952 (zero_extend:EXTSI (match_dup
1)))]
957 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
959 (zero_extend:EXTSI (match_dup
1)))
961 (compare:CC (match_dup
0)
964 [(set_attr "type" "shift")
965 (set_attr "dot" "yes")
966 (set_attr "length" "
4,
8")])
969 (define_insn "extendqi<mode>
2"
970 [(set (match_operand:EXTQI
0 "gpc_reg_operand" "=r,?*v")
971 (sign_extend:EXTQI (match_operand:QI
1 "gpc_reg_operand" "r,?*v")))]
976 [(set_attr "type" "exts,vecperm")
977 (set_attr "isa" "*,p9v")])
979 (define_insn_and_split "*extendqi<mode>
2_dot"
980 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
981 (compare:CC (sign_extend:EXTQI (match_operand:QI
1 "gpc_reg_operand" "r,r"))
983 (clobber (match_scratch:EXTQI
0 "=r,r"))]
988 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
990 (sign_extend:EXTQI (match_dup
1)))
992 (compare:CC (match_dup
0)
995 [(set_attr "type" "exts")
996 (set_attr "dot" "yes")
997 (set_attr "length" "
4,
8")])
999 (define_insn_and_split "*extendqi<mode>
2_dot2"
1000 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
1001 (compare:CC (sign_extend:EXTQI (match_operand:QI
1 "gpc_reg_operand" "r,r"))
1003 (set (match_operand:EXTQI
0 "gpc_reg_operand" "=r,r")
1004 (sign_extend:EXTQI (match_dup
1)))]
1009 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
1011 (sign_extend:EXTQI (match_dup
1)))
1013 (compare:CC (match_dup
0)
1016 [(set_attr "type" "exts")
1017 (set_attr "dot" "yes")
1018 (set_attr "length" "
4,
8")])
1021 (define_expand "extendhi<mode>
2"
1022 [(set (match_operand:EXTHI
0 "gpc_reg_operand")
1023 (sign_extend:EXTHI (match_operand:HI
1 "gpc_reg_operand")))]
1027 (define_insn "*extendhi<mode>
2"
1028 [(set (match_operand:EXTHI
0 "gpc_reg_operand" "=r,r,?*v,?*v")
1029 (sign_extend:EXTHI (match_operand:HI
1 "reg_or_mem_operand" "m,r,Z,v")))]
1036 [(set_attr "type" "load,exts,fpload,vecperm")
1037 (set_attr "sign_extend" "yes")
1038 (set_attr "length" "*,*,
8,*")
1039 (set_attr "isa" "*,*,p9v,p9v")])
1042 [(set (match_operand:EXTHI
0 "altivec_register_operand")
1044 (match_operand:HI
1 "indexed_or_indirect_operand")))]
1045 "TARGET_P9_VECTOR && reload_completed"
1049 (sign_extend:EXTHI (match_dup
2)))]
1051 operands[
2] = gen_rtx_REG (HImode, REGNO (operands[
0]));
1054 (define_insn_and_split "*extendhi<mode>
2_dot"
1055 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
1056 (compare:CC (sign_extend:EXTHI (match_operand:HI
1 "gpc_reg_operand" "r,r"))
1058 (clobber (match_scratch:EXTHI
0 "=r,r"))]
1063 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
1065 (sign_extend:EXTHI (match_dup
1)))
1067 (compare:CC (match_dup
0)
1070 [(set_attr "type" "exts")
1071 (set_attr "dot" "yes")
1072 (set_attr "length" "
4,
8")])
1074 (define_insn_and_split "*extendhi<mode>
2_dot2"
1075 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
1076 (compare:CC (sign_extend:EXTHI (match_operand:HI
1 "gpc_reg_operand" "r,r"))
1078 (set (match_operand:EXTHI
0 "gpc_reg_operand" "=r,r")
1079 (sign_extend:EXTHI (match_dup
1)))]
1084 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
1086 (sign_extend:EXTHI (match_dup
1)))
1088 (compare:CC (match_dup
0)
1091 [(set_attr "type" "exts")
1092 (set_attr "dot" "yes")
1093 (set_attr "length" "
4,
8")])
1096 (define_insn "extendsi<mode>
2"
1097 [(set (match_operand:EXTSI
0 "gpc_reg_operand"
1098 "=r, r, d, wa, wa, v, v, wr")
1099 (sign_extend:EXTSI (match_operand:SI
1 "lwa_operand"
1100 "YZ, r, Z, Z, r, v, v, ?wa")))]
1111 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1112 (set_attr "sign_extend" "yes")
1113 (set_attr "length" "*,*,*,*,*,*,
8,
8")
1114 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1117 [(set (match_operand:EXTSI
0 "int_reg_operand")
1118 (sign_extend:EXTSI (match_operand:SI
1 "vsx_register_operand")))]
1119 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1123 (sign_extend:DI (match_dup
2)))]
1125 operands[
2] = gen_rtx_REG (SImode, reg_or_subregno (operands[
0]));
1129 [(set (match_operand:DI
0 "altivec_register_operand")
1130 (sign_extend:DI (match_operand:SI
1 "altivec_register_operand")))]
1131 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1134 rtx dest = operands[
0];
1135 rtx src = operands[
1];
1136 int dest_regno = REGNO (dest);
1137 int src_regno = REGNO (src);
1138 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1139 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1141 if (BYTES_BIG_ENDIAN)
1143 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1144 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1148 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1149 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1154 (define_insn_and_split "*extendsi<mode>
2_dot"
1155 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
1156 (compare:CC (sign_extend:EXTSI (match_operand:SI
1 "gpc_reg_operand" "r,r"))
1158 (clobber (match_scratch:EXTSI
0 "=r,r"))]
1163 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
1165 (sign_extend:EXTSI (match_dup
1)))
1167 (compare:CC (match_dup
0)
1170 [(set_attr "type" "exts")
1171 (set_attr "dot" "yes")
1172 (set_attr "length" "
4,
8")])
1174 (define_insn_and_split "*extendsi<mode>
2_dot2"
1175 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
1176 (compare:CC (sign_extend:EXTSI (match_operand:SI
1 "gpc_reg_operand" "r,r"))
1178 (set (match_operand:EXTSI
0 "gpc_reg_operand" "=r,r")
1179 (sign_extend:EXTSI (match_dup
1)))]
1184 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
1186 (sign_extend:EXTSI (match_dup
1)))
1188 (compare:CC (match_dup
0)
1191 [(set_attr "type" "exts")
1192 (set_attr "dot" "yes")
1193 (set_attr "length" "
4,
8")])
1195 ;; IBM
405,
440,
464 and
476 half-word multiplication operations.
1197 (define_insn "*macchwc"
1198 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1199 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1200 (match_operand:SI
2 "gpc_reg_operand" "r")
1203 (match_operand:HI
1 "gpc_reg_operand" "r")))
1204 (match_operand:SI
4 "gpc_reg_operand" "
0"))
1206 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1207 (plus:SI (mult:SI (ashiftrt:SI
1215 [(set_attr "type" "halfmul")])
1217 (define_insn "*macchw"
1218 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1219 (plus:SI (mult:SI (ashiftrt:SI
1220 (match_operand:SI
2 "gpc_reg_operand" "r")
1223 (match_operand:HI
1 "gpc_reg_operand" "r")))
1224 (match_operand:SI
3 "gpc_reg_operand" "
0")))]
1227 [(set_attr "type" "halfmul")])
1229 (define_insn "*macchwuc"
1230 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1231 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1232 (match_operand:SI
2 "gpc_reg_operand" "r")
1235 (match_operand:HI
1 "gpc_reg_operand" "r")))
1236 (match_operand:SI
4 "gpc_reg_operand" "
0"))
1238 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1239 (plus:SI (mult:SI (lshiftrt:SI
1247 [(set_attr "type" "halfmul")])
1249 (define_insn "*macchwu"
1250 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1251 (plus:SI (mult:SI (lshiftrt:SI
1252 (match_operand:SI
2 "gpc_reg_operand" "r")
1255 (match_operand:HI
1 "gpc_reg_operand" "r")))
1256 (match_operand:SI
3 "gpc_reg_operand" "
0")))]
1259 [(set_attr "type" "halfmul")])
1261 (define_insn "*machhwc"
1262 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1263 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1264 (match_operand:SI
1 "gpc_reg_operand" "%r")
1267 (match_operand:SI
2 "gpc_reg_operand" "r")
1269 (match_operand:SI
4 "gpc_reg_operand" "
0"))
1271 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1272 (plus:SI (mult:SI (ashiftrt:SI
1281 [(set_attr "type" "halfmul")])
1283 (define_insn "*machhw"
1284 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1285 (plus:SI (mult:SI (ashiftrt:SI
1286 (match_operand:SI
1 "gpc_reg_operand" "%r")
1289 (match_operand:SI
2 "gpc_reg_operand" "r")
1291 (match_operand:SI
3 "gpc_reg_operand" "
0")))]
1294 [(set_attr "type" "halfmul")])
1296 (define_insn "*machhwuc"
1297 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1298 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1299 (match_operand:SI
1 "gpc_reg_operand" "%r")
1302 (match_operand:SI
2 "gpc_reg_operand" "r")
1304 (match_operand:SI
4 "gpc_reg_operand" "
0"))
1306 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1307 (plus:SI (mult:SI (lshiftrt:SI
1316 [(set_attr "type" "halfmul")])
1318 (define_insn "*machhwu"
1319 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1320 (plus:SI (mult:SI (lshiftrt:SI
1321 (match_operand:SI
1 "gpc_reg_operand" "%r")
1324 (match_operand:SI
2 "gpc_reg_operand" "r")
1326 (match_operand:SI
3 "gpc_reg_operand" "
0")))]
1329 [(set_attr "type" "halfmul")])
1331 (define_insn "*maclhwc"
1332 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1333 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1334 (match_operand:HI
1 "gpc_reg_operand" "%r"))
1336 (match_operand:HI
2 "gpc_reg_operand" "r")))
1337 (match_operand:SI
4 "gpc_reg_operand" "
0"))
1339 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1340 (plus:SI (mult:SI (sign_extend:SI
1347 [(set_attr "type" "halfmul")])
1349 (define_insn "*maclhw"
1350 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1351 (plus:SI (mult:SI (sign_extend:SI
1352 (match_operand:HI
1 "gpc_reg_operand" "%r"))
1354 (match_operand:HI
2 "gpc_reg_operand" "r")))
1355 (match_operand:SI
3 "gpc_reg_operand" "
0")))]
1358 [(set_attr "type" "halfmul")])
1360 (define_insn "*maclhwuc"
1361 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1362 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1363 (match_operand:HI
1 "gpc_reg_operand" "%r"))
1365 (match_operand:HI
2 "gpc_reg_operand" "r")))
1366 (match_operand:SI
4 "gpc_reg_operand" "
0"))
1368 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1369 (plus:SI (mult:SI (zero_extend:SI
1376 [(set_attr "type" "halfmul")])
1378 (define_insn "*maclhwu"
1379 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1380 (plus:SI (mult:SI (zero_extend:SI
1381 (match_operand:HI
1 "gpc_reg_operand" "%r"))
1383 (match_operand:HI
2 "gpc_reg_operand" "r")))
1384 (match_operand:SI
3 "gpc_reg_operand" "
0")))]
1387 [(set_attr "type" "halfmul")])
1389 (define_insn "*nmacchwc"
1390 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1391 (compare:CC (minus:SI (match_operand:SI
4 "gpc_reg_operand" "
0")
1392 (mult:SI (ashiftrt:SI
1393 (match_operand:SI
2 "gpc_reg_operand" "r")
1396 (match_operand:HI
1 "gpc_reg_operand" "r"))))
1398 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1399 (minus:SI (match_dup
4)
1400 (mult:SI (ashiftrt:SI
1407 [(set_attr "type" "halfmul")])
1409 (define_insn "*nmacchw"
1410 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1411 (minus:SI (match_operand:SI
3 "gpc_reg_operand" "
0")
1412 (mult:SI (ashiftrt:SI
1413 (match_operand:SI
2 "gpc_reg_operand" "r")
1416 (match_operand:HI
1 "gpc_reg_operand" "r")))))]
1419 [(set_attr "type" "halfmul")])
1421 (define_insn "*nmachhwc"
1422 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1423 (compare:CC (minus:SI (match_operand:SI
4 "gpc_reg_operand" "
0")
1424 (mult:SI (ashiftrt:SI
1425 (match_operand:SI
1 "gpc_reg_operand" "%r")
1428 (match_operand:SI
2 "gpc_reg_operand" "r")
1431 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1432 (minus:SI (match_dup
4)
1433 (mult:SI (ashiftrt:SI
1441 [(set_attr "type" "halfmul")])
1443 (define_insn "*nmachhw"
1444 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1445 (minus:SI (match_operand:SI
3 "gpc_reg_operand" "
0")
1446 (mult:SI (ashiftrt:SI
1447 (match_operand:SI
1 "gpc_reg_operand" "%r")
1450 (match_operand:SI
2 "gpc_reg_operand" "r")
1454 [(set_attr "type" "halfmul")])
1456 (define_insn "*nmaclhwc"
1457 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1458 (compare:CC (minus:SI (match_operand:SI
4 "gpc_reg_operand" "
0")
1459 (mult:SI (sign_extend:SI
1460 (match_operand:HI
1 "gpc_reg_operand" "%r"))
1462 (match_operand:HI
2 "gpc_reg_operand" "r"))))
1464 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1465 (minus:SI (match_dup
4)
1466 (mult:SI (sign_extend:SI
1472 [(set_attr "type" "halfmul")])
1474 (define_insn "*nmaclhw"
1475 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1476 (minus:SI (match_operand:SI
3 "gpc_reg_operand" "
0")
1477 (mult:SI (sign_extend:SI
1478 (match_operand:HI
1 "gpc_reg_operand" "%r"))
1480 (match_operand:HI
2 "gpc_reg_operand" "r")))))]
1483 [(set_attr "type" "halfmul")])
1485 (define_insn "*mulchwc"
1486 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1487 (compare:CC (mult:SI (ashiftrt:SI
1488 (match_operand:SI
2 "gpc_reg_operand" "r")
1491 (match_operand:HI
1 "gpc_reg_operand" "r")))
1493 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1494 (mult:SI (ashiftrt:SI
1501 [(set_attr "type" "halfmul")])
1503 (define_insn "*mulchw"
1504 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1505 (mult:SI (ashiftrt:SI
1506 (match_operand:SI
2 "gpc_reg_operand" "r")
1509 (match_operand:HI
1 "gpc_reg_operand" "r"))))]
1512 [(set_attr "type" "halfmul")])
1514 (define_insn "*mulchwuc"
1515 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1516 (compare:CC (mult:SI (lshiftrt:SI
1517 (match_operand:SI
2 "gpc_reg_operand" "r")
1520 (match_operand:HI
1 "gpc_reg_operand" "r")))
1522 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1523 (mult:SI (lshiftrt:SI
1530 [(set_attr "type" "halfmul")])
1532 (define_insn "*mulchwu"
1533 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1534 (mult:SI (lshiftrt:SI
1535 (match_operand:SI
2 "gpc_reg_operand" "r")
1538 (match_operand:HI
1 "gpc_reg_operand" "r"))))]
1541 [(set_attr "type" "halfmul")])
1543 (define_insn "*mulhhwc"
1544 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1545 (compare:CC (mult:SI (ashiftrt:SI
1546 (match_operand:SI
1 "gpc_reg_operand" "%r")
1549 (match_operand:SI
2 "gpc_reg_operand" "r")
1552 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1553 (mult:SI (ashiftrt:SI
1561 [(set_attr "type" "halfmul")])
1563 (define_insn "*mulhhw"
1564 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1565 (mult:SI (ashiftrt:SI
1566 (match_operand:SI
1 "gpc_reg_operand" "%r")
1569 (match_operand:SI
2 "gpc_reg_operand" "r")
1573 [(set_attr "type" "halfmul")])
1575 (define_insn "*mulhhwuc"
1576 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1577 (compare:CC (mult:SI (lshiftrt:SI
1578 (match_operand:SI
1 "gpc_reg_operand" "%r")
1581 (match_operand:SI
2 "gpc_reg_operand" "r")
1584 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1585 (mult:SI (lshiftrt:SI
1593 [(set_attr "type" "halfmul")])
1595 (define_insn "*mulhhwu"
1596 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1597 (mult:SI (lshiftrt:SI
1598 (match_operand:SI
1 "gpc_reg_operand" "%r")
1601 (match_operand:SI
2 "gpc_reg_operand" "r")
1605 [(set_attr "type" "halfmul")])
1607 (define_insn "*mullhwc"
1608 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1609 (compare:CC (mult:SI (sign_extend:SI
1610 (match_operand:HI
1 "gpc_reg_operand" "%r"))
1612 (match_operand:HI
2 "gpc_reg_operand" "r")))
1614 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1615 (mult:SI (sign_extend:SI
1621 [(set_attr "type" "halfmul")])
1623 (define_insn "*mullhw"
1624 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1625 (mult:SI (sign_extend:SI
1626 (match_operand:HI
1 "gpc_reg_operand" "%r"))
1628 (match_operand:HI
2 "gpc_reg_operand" "r"))))]
1631 [(set_attr "type" "halfmul")])
1633 (define_insn "*mullhwuc"
1634 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1635 (compare:CC (mult:SI (zero_extend:SI
1636 (match_operand:HI
1 "gpc_reg_operand" "%r"))
1638 (match_operand:HI
2 "gpc_reg_operand" "r")))
1640 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1641 (mult:SI (zero_extend:SI
1647 [(set_attr "type" "halfmul")])
1649 (define_insn "*mullhwu"
1650 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
1651 (mult:SI (zero_extend:SI
1652 (match_operand:HI
1 "gpc_reg_operand" "%r"))
1654 (match_operand:HI
2 "gpc_reg_operand" "r"))))]
1657 [(set_attr "type" "halfmul")])
1659 ;; IBM
405,
440,
464 and
476 string-search dlmzb instruction support.
1660 (define_insn "dlmzb"
1661 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
1662 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
1663 (match_operand:SI
2 "gpc_reg_operand" "r")]
1665 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
1666 (unspec:SI [(match_dup
1)
1672 (define_expand "strlensi"
1673 [(set (match_operand:SI
0 "gpc_reg_operand")
1674 (unspec:SI [(match_operand:BLK
1 "general_operand")
1675 (match_operand:QI
2 "const_int_operand")
1676 (match_operand
3 "const_int_operand")]
1677 UNSPEC_DLMZB_STRLEN))
1678 (clobber (match_scratch:CC
4))]
1679 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1681 rtx result = operands[
0];
1682 rtx src = operands[
1];
1683 rtx search_char = operands[
2];
1684 rtx align = operands[
3];
1685 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1686 rtx loop_label, end_label, mem, cr0, cond;
1687 if (search_char != const0_rtx
1688 || !CONST_INT_P (align)
1689 || INTVAL (align) <
8)
1691 word1 = gen_reg_rtx (SImode);
1692 word2 = gen_reg_rtx (SImode);
1693 scratch_dlmzb = gen_reg_rtx (SImode);
1694 scratch_string = gen_reg_rtx (Pmode);
1695 loop_label = gen_label_rtx ();
1696 end_label = gen_label_rtx ();
1697 addr = force_reg (Pmode, XEXP (src,
0));
1698 emit_move_insn (scratch_string, addr);
1699 emit_label (loop_label);
1700 mem = change_address (src, SImode, scratch_string);
1701 emit_move_insn (word1, mem);
1702 emit_move_insn (word2, adjust_address (mem, SImode,
4));
1703 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1704 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1705 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1706 emit_jump_insn (gen_rtx_SET (pc_rtx,
1707 gen_rtx_IF_THEN_ELSE (VOIDmode,
1713 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (
8)));
1714 emit_jump_insn (gen_rtx_SET (pc_rtx,
1715 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1717 emit_label (end_label);
1718 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1719 emit_insn (gen_subsi3 (result, scratch_string, addr));
1720 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1724 ;; Fixed-point arithmetic insns.
1726 (define_expand "add<mode>
3"
1727 [(set (match_operand:SDI
0 "gpc_reg_operand")
1728 (plus:SDI (match_operand:SDI
1 "gpc_reg_operand")
1729 (match_operand:SDI
2 "reg_or_add_cint_operand")))]
1732 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1734 rtx lo0 = gen_lowpart (SImode, operands[
0]);
1735 rtx lo1 = gen_lowpart (SImode, operands[
1]);
1736 rtx lo2 = gen_lowpart (SImode, operands[
2]);
1737 rtx hi0 = gen_highpart (SImode, operands[
0]);
1738 rtx hi1 = gen_highpart (SImode, operands[
1]);
1739 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[
2]);
1741 if (!reg_or_short_operand (lo2, SImode))
1742 lo2 = force_reg (SImode, lo2);
1743 if (!adde_operand (hi2, SImode))
1744 hi2 = force_reg (SImode, hi2);
1746 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1747 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1751 if (CONST_INT_P (operands[
2]) && !add_operand (operands[
2], <MODE>mode))
1753 rtx tmp = ((!can_create_pseudo_p ()
1754 || rtx_equal_p (operands[
0], operands[
1]))
1755 ? operands[
0] : gen_reg_rtx (<MODE>mode));
1757 /* Adding a constant to r0 is not a valid insn, so use a different
1758 strategy in that case. */
1759 if (reg_or_subregno (operands[
1]) ==
0 || reg_or_subregno (tmp) ==
0)
1761 if (operands[
0] == operands[
1])
1763 rs6000_emit_move (operands[
0], operands[
2], <MODE>mode);
1764 emit_insn (gen_add<mode>
3 (operands[
0], operands[
1], operands[
0]));
1768 HOST_WIDE_INT val = INTVAL (operands[
2]);
1769 HOST_WIDE_INT low = ((val &
0xffff) ^
0x8000) -
0x8000;
1770 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1772 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1775 /* The ordering here is important for the prolog expander.
1776 When space is allocated from the stack, adding 'low' first may
1777 produce a temporary deallocation (which would be bad). */
1778 emit_insn (gen_add<mode>
3 (tmp, operands[
1], GEN_INT (rest)));
1779 emit_insn (gen_add<mode>
3 (operands[
0], tmp, GEN_INT (low)));
1784 (define_insn "*add<mode>
3"
1785 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r,r,r,r")
1786 (plus:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,b,b,b")
1787 (match_operand:GPR
2 "add_operand" "r,I,L,eI")))]
1794 [(set_attr "type" "add")
1795 (set_attr "isa" "*,*,*,p10")])
1797 (define_insn "*addsi3_high"
1798 [(set (match_operand:SI
0 "gpc_reg_operand" "=b")
1799 (plus:SI (match_operand:SI
1 "gpc_reg_operand" "b")
1800 (high:SI (match_operand
2 "" ""))))]
1801 "TARGET_MACHO && !TARGET_64BIT"
1802 "addis %
0,%
1,ha16(%
2)"
1803 [(set_attr "type" "add")])
1805 (define_insn_and_split "*add<mode>
3_dot"
1806 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
1807 (compare:CC (plus:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
1808 (match_operand:GPR
2 "gpc_reg_operand" "r,r"))
1810 (clobber (match_scratch:GPR
0 "=r,r"))]
1811 "<MODE>mode == Pmode"
1815 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
1817 (plus:GPR (match_dup
1)
1820 (compare:CC (match_dup
0)
1823 [(set_attr "type" "add")
1824 (set_attr "dot" "yes")
1825 (set_attr "length" "
4,
8")])
1827 (define_insn_and_split "*add<mode>
3_dot2"
1828 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
1829 (compare:CC (plus:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
1830 (match_operand:GPR
2 "gpc_reg_operand" "r,r"))
1832 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
1833 (plus:GPR (match_dup
1)
1835 "<MODE>mode == Pmode"
1839 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
1841 (plus:GPR (match_dup
1)
1844 (compare:CC (match_dup
0)
1847 [(set_attr "type" "add")
1848 (set_attr "dot" "yes")
1849 (set_attr "length" "
4,
8")])
1851 (define_insn_and_split "*add<mode>
3_imm_dot"
1852 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
1853 (compare:CC (plus:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,b")
1854 (match_operand:GPR
2 "short_cint_operand" "I,I"))
1856 (clobber (match_scratch:GPR
0 "=r,r"))
1857 (clobber (reg:GPR CA_REGNO))]
1858 "<MODE>mode == Pmode"
1862 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
1864 (plus:GPR (match_dup
1)
1867 (compare:CC (match_dup
0)
1870 [(set_attr "type" "add")
1871 (set_attr "dot" "yes")
1872 (set_attr "length" "
4,
8")])
1874 (define_insn_and_split "*add<mode>
3_imm_dot2"
1875 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
1876 (compare:CC (plus:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,b")
1877 (match_operand:GPR
2 "short_cint_operand" "I,I"))
1879 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
1880 (plus:GPR (match_dup
1)
1882 (clobber (reg:GPR CA_REGNO))]
1883 "<MODE>mode == Pmode"
1887 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
1889 (plus:GPR (match_dup
1)
1892 (compare:CC (match_dup
0)
1895 [(set_attr "type" "add")
1896 (set_attr "dot" "yes")
1897 (set_attr "length" "
4,
8")])
1899 ;; Split an add that we can't do in one insn into two insns, each of which
1900 ;; does one
16-bit part. This is used by combine. Note that the low-order
1901 ;; add should be last in case the result gets used in an address.
1904 [(set (match_operand:GPR
0 "gpc_reg_operand")
1905 (plus:GPR (match_operand:GPR
1 "gpc_reg_operand")
1906 (match_operand:GPR
2 "non_add_cint_operand")))]
1908 [(set (match_dup
0) (plus:GPR (match_dup
1) (match_dup
3)))
1909 (set (match_dup
0) (plus:GPR (match_dup
0) (match_dup
4)))]
1911 HOST_WIDE_INT val = INTVAL (operands[
2]);
1912 HOST_WIDE_INT low = ((val &
0xffff) ^
0x8000) -
0x8000;
1913 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1915 operands[
4] = GEN_INT (low);
1916 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1917 operands[
3] = GEN_INT (rest);
1918 else if (can_create_pseudo_p ())
1920 operands[
3] = gen_reg_rtx (DImode);
1921 emit_move_insn (operands[
3], operands[
2]);
1922 emit_insn (gen_adddi3 (operands[
0], operands[
1], operands[
3]));
1930 (define_insn "add<mode>
3_carry"
1931 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
1932 (plus:P (match_operand:P
1 "gpc_reg_operand" "r")
1933 (match_operand:P
2 "reg_or_short_operand" "rI")))
1934 (set (reg:P CA_REGNO)
1935 (ltu:P (plus:P (match_dup
1)
1940 [(set_attr "type" "add")])
1942 (define_insn "*add<mode>
3_imm_carry_pos"
1943 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
1944 (plus:P (match_operand:P
1 "gpc_reg_operand" "r")
1945 (match_operand:P
2 "short_cint_operand" "n")))
1946 (set (reg:P CA_REGNO)
1947 (geu:P (match_dup
1)
1948 (match_operand:P
3 "const_int_operand" "n")))]
1949 "INTVAL (operands[
2]) >
0
1950 && INTVAL (operands[
2]) + INTVAL (operands[
3]) ==
0"
1952 [(set_attr "type" "add")])
1954 (define_insn "*add<mode>
3_imm_carry_0"
1955 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
1956 (match_operand:P
1 "gpc_reg_operand" "r"))
1957 (set (reg:P CA_REGNO)
1961 [(set_attr "type" "add")])
1963 (define_insn "*add<mode>
3_imm_carry_m1"
1964 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
1965 (plus:P (match_operand:P
1 "gpc_reg_operand" "r")
1967 (set (reg:P CA_REGNO)
1972 [(set_attr "type" "add")])
1974 (define_insn "*add<mode>
3_imm_carry_neg"
1975 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
1976 (plus:P (match_operand:P
1 "gpc_reg_operand" "r")
1977 (match_operand:P
2 "short_cint_operand" "n")))
1978 (set (reg:P CA_REGNO)
1979 (gtu:P (match_dup
1)
1980 (match_operand:P
3 "const_int_operand" "n")))]
1981 "INTVAL (operands[
2]) <
0
1982 && INTVAL (operands[
2]) + INTVAL (operands[
3]) == -
1"
1984 [(set_attr "type" "add")])
1987 (define_expand "add<mode>
3_carry_in"
1989 (set (match_operand:GPR
0 "gpc_reg_operand")
1990 (plus:GPR (plus:GPR (match_operand:GPR
1 "gpc_reg_operand")
1991 (match_operand:GPR
2 "adde_operand"))
1992 (reg:GPR CA_REGNO)))
1993 (clobber (reg:GPR CA_REGNO))])]
1996 if (operands[
2] == const0_rtx)
1998 emit_insn (gen_add<mode>
3_carry_in_0 (operands[
0], operands[
1]));
2001 if (operands[
2] == constm1_rtx)
2003 emit_insn (gen_add<mode>
3_carry_in_m1 (operands[
0], operands[
1]));
2008 (define_insn "*add<mode>
3_carry_in_internal"
2009 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2010 (plus:GPR (plus:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
2011 (match_operand:GPR
2 "gpc_reg_operand" "r"))
2012 (reg:GPR CA_REGNO)))
2013 (clobber (reg:GPR CA_REGNO))]
2016 [(set_attr "type" "add")])
2018 (define_insn "*add<mode>
3_carry_in_internal2"
2019 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2020 (plus:GPR (plus:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
2022 (match_operand:GPR
2 "gpc_reg_operand" "r")))
2023 (clobber (reg:GPR CA_REGNO))]
2026 [(set_attr "type" "add")])
2028 (define_insn "add<mode>
3_carry_in_0"
2029 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2030 (plus:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
2031 (reg:GPR CA_REGNO)))
2032 (clobber (reg:GPR CA_REGNO))]
2035 [(set_attr "type" "add")])
2037 (define_insn "add<mode>
3_carry_in_m1"
2038 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2039 (plus:GPR (plus:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
2042 (clobber (reg:GPR CA_REGNO))]
2045 [(set_attr "type" "add")])
2048 (define_expand "one_cmpl<mode>
2"
2049 [(set (match_operand:SDI
0 "gpc_reg_operand")
2050 (not:SDI (match_operand:SDI
1 "gpc_reg_operand")))]
2053 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2055 rs6000_split_logical (operands, NOT, false, false, false);
2060 (define_insn "*one_cmpl<mode>
2"
2061 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2062 (not:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")))]
2066 (define_insn_and_split "*one_cmpl<mode>
2_dot"
2067 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
2068 (compare:CC (not:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r"))
2070 (clobber (match_scratch:GPR
0 "=r,r"))]
2071 "<MODE>mode == Pmode"
2075 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
2077 (not:GPR (match_dup
1)))
2079 (compare:CC (match_dup
0)
2082 [(set_attr "type" "logical")
2083 (set_attr "dot" "yes")
2084 (set_attr "length" "
4,
8")])
2086 (define_insn_and_split "*one_cmpl<mode>
2_dot2"
2087 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
2088 (compare:CC (not:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r"))
2090 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
2091 (not:GPR (match_dup
1)))]
2092 "<MODE>mode == Pmode"
2096 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
2098 (not:GPR (match_dup
1)))
2100 (compare:CC (match_dup
0)
2103 [(set_attr "type" "logical")
2104 (set_attr "dot" "yes")
2105 (set_attr "length" "
4,
8")])
2108 (define_expand "sub<mode>
3"
2109 [(set (match_operand:SDI
0 "gpc_reg_operand")
2110 (minus:SDI (match_operand:SDI
1 "reg_or_short_operand")
2111 (match_operand:SDI
2 "gpc_reg_operand")))]
2114 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2116 rtx lo0 = gen_lowpart (SImode, operands[
0]);
2117 rtx lo1 = gen_lowpart (SImode, operands[
1]);
2118 rtx lo2 = gen_lowpart (SImode, operands[
2]);
2119 rtx hi0 = gen_highpart (SImode, operands[
0]);
2120 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[
1]);
2121 rtx hi2 = gen_highpart (SImode, operands[
2]);
2123 if (!reg_or_short_operand (lo1, SImode))
2124 lo1 = force_reg (SImode, lo1);
2125 if (!adde_operand (hi1, SImode))
2126 hi1 = force_reg (SImode, hi1);
2128 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2129 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2133 if (short_cint_operand (operands[
1], <MODE>mode))
2135 emit_insn (gen_subf<mode>
3_imm (operands[
0], operands[
2], operands[
1]));
2140 (define_insn "*subf<mode>
3"
2141 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2142 (minus:GPR (match_operand:GPR
2 "gpc_reg_operand" "r")
2143 (match_operand:GPR
1 "gpc_reg_operand" "r")))]
2146 [(set_attr "type" "add")])
2148 (define_insn_and_split "*subf<mode>
3_dot"
2149 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
2150 (compare:CC (minus:GPR (match_operand:GPR
2 "gpc_reg_operand" "r,r")
2151 (match_operand:GPR
1 "gpc_reg_operand" "r,r"))
2153 (clobber (match_scratch:GPR
0 "=r,r"))]
2154 "<MODE>mode == Pmode"
2158 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
2160 (minus:GPR (match_dup
2)
2163 (compare:CC (match_dup
0)
2166 [(set_attr "type" "add")
2167 (set_attr "dot" "yes")
2168 (set_attr "length" "
4,
8")])
2170 (define_insn_and_split "*subf<mode>
3_dot2"
2171 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
2172 (compare:CC (minus:GPR (match_operand:GPR
2 "gpc_reg_operand" "r,r")
2173 (match_operand:GPR
1 "gpc_reg_operand" "r,r"))
2175 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
2176 (minus:GPR (match_dup
2)
2178 "<MODE>mode == Pmode"
2182 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
2184 (minus:GPR (match_dup
2)
2187 (compare:CC (match_dup
0)
2190 [(set_attr "type" "add")
2191 (set_attr "dot" "yes")
2192 (set_attr "length" "
4,
8")])
2194 (define_insn "subf<mode>
3_imm"
2195 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2196 (minus:GPR (match_operand:GPR
2 "short_cint_operand" "I")
2197 (match_operand:GPR
1 "gpc_reg_operand" "r")))
2198 (clobber (reg:GPR CA_REGNO))]
2201 [(set_attr "type" "add")])
2203 (define_insn_and_split "subf<mode>
3_carry_dot2"
2204 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
2205 (compare:CC (minus:P (match_operand:P
2 "gpc_reg_operand" "r,r")
2206 (match_operand:P
1 "gpc_reg_operand" "r,r"))
2208 (set (match_operand:P
0 "gpc_reg_operand" "=r,r")
2209 (minus:P (match_dup
2)
2211 (set (reg:P CA_REGNO)
2212 (leu:P (match_dup
1)
2214 "<MODE>mode == Pmode"
2218 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
2219 [(parallel [(set (match_dup
0)
2220 (minus:P (match_dup
2)
2222 (set (reg:P CA_REGNO)
2223 (leu:P (match_dup
1)
2226 (compare:CC (match_dup
0)
2229 [(set_attr "type" "add")
2230 (set_attr "dot" "yes")
2231 (set_attr "length" "
4,
8")])
2233 (define_insn "subf<mode>
3_carry"
2234 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
2235 (minus:P (match_operand:P
2 "reg_or_short_operand" "rI")
2236 (match_operand:P
1 "gpc_reg_operand" "r")))
2237 (set (reg:P CA_REGNO)
2238 (leu:P (match_dup
1)
2242 [(set_attr "type" "add")])
2244 (define_insn "*subf<mode>
3_imm_carry_0"
2245 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
2246 (neg:P (match_operand:P
1 "gpc_reg_operand" "r")))
2247 (set (reg:P CA_REGNO)
2252 [(set_attr "type" "add")])
2254 (define_insn "*subf<mode>
3_imm_carry_m1"
2255 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
2256 (not:P (match_operand:P
1 "gpc_reg_operand" "r")))
2257 (set (reg:P CA_REGNO)
2261 [(set_attr "type" "add")])
2264 (define_expand "subf<mode>
3_carry_in"
2266 (set (match_operand:GPR
0 "gpc_reg_operand")
2267 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR
1 "gpc_reg_operand"))
2269 (match_operand:GPR
2 "adde_operand")))
2270 (clobber (reg:GPR CA_REGNO))])]
2273 if (operands[
2] == const0_rtx)
2275 emit_insn (gen_subf<mode>
3_carry_in_0 (operands[
0], operands[
1]));
2278 if (operands[
2] == constm1_rtx)
2280 emit_insn (gen_subf<mode>
3_carry_in_m1 (operands[
0], operands[
1]));
2285 (define_insn "*subf<mode>
3_carry_in_internal"
2286 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2287 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR
1 "gpc_reg_operand" "r"))
2289 (match_operand:GPR
2 "gpc_reg_operand" "r")))
2290 (clobber (reg:GPR CA_REGNO))]
2293 [(set_attr "type" "add")])
2295 (define_insn "subf<mode>
3_carry_in_0"
2296 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2297 (plus:GPR (not:GPR (match_operand:GPR
1 "gpc_reg_operand" "r"))
2298 (reg:GPR CA_REGNO)))
2299 (clobber (reg:GPR CA_REGNO))]
2302 [(set_attr "type" "add")])
2304 (define_insn "subf<mode>
3_carry_in_m1"
2305 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2306 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2307 (match_operand:GPR
1 "gpc_reg_operand" "r"))
2309 (clobber (reg:GPR CA_REGNO))]
2312 [(set_attr "type" "add")])
2314 (define_insn "subf<mode>
3_carry_in_xx"
2315 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2316 (plus:GPR (reg:GPR CA_REGNO)
2318 (clobber (reg:GPR CA_REGNO))]
2321 [(set_attr "type" "add")])
2324 (define_insn "@neg<mode>
2"
2325 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2326 (neg:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")))]
2329 [(set_attr "type" "add")])
2331 (define_insn_and_split "*neg<mode>
2_dot"
2332 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
2333 (compare:CC (neg:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r"))
2335 (clobber (match_scratch:GPR
0 "=r,r"))]
2336 "<MODE>mode == Pmode"
2340 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
2342 (neg:GPR (match_dup
1)))
2344 (compare:CC (match_dup
0)
2347 [(set_attr "type" "add")
2348 (set_attr "dot" "yes")
2349 (set_attr "length" "
4,
8")])
2351 (define_insn_and_split "*neg<mode>
2_dot2"
2352 [(set (match_operand:CC
2 "cc_reg_operand" "=x,?y")
2353 (compare:CC (neg:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r"))
2355 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
2356 (neg:GPR (match_dup
1)))]
2357 "<MODE>mode == Pmode"
2361 "&& reload_completed && cc_reg_not_cr0_operand (operands[
2], CCmode)"
2363 (neg:GPR (match_dup
1)))
2365 (compare:CC (match_dup
0)
2368 [(set_attr "type" "add")
2369 (set_attr "dot" "yes")
2370 (set_attr "length" "
4,
8")])
2373 (define_insn "clz<mode>
2"
2374 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2375 (clz:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")))]
2378 [(set_attr "type" "cntlz")])
2380 (define_expand "ctz<mode>
2"
2381 [(set (match_operand:GPR
0 "gpc_reg_operand")
2382 (ctz:GPR (match_operand:GPR
1 "gpc_reg_operand")))]
2387 emit_insn (gen_ctz<mode>
2_hw (operands[
0], operands[
1]));
2391 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2392 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2393 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2397 emit_insn (gen_add<mode>
3 (tmp1, operands[
1], constm1_rtx));
2398 emit_insn (gen_one_cmpl<mode>
2 (tmp2, operands[
1]));
2399 emit_insn (gen_and<mode>
3 (tmp3, tmp1, tmp2));
2400 emit_insn (gen_popcntd<mode>
2 (operands[
0], tmp3));
2404 emit_insn (gen_neg<mode>
2 (tmp1, operands[
1]));
2405 emit_insn (gen_and<mode>
3 (tmp2, operands[
1], tmp1));
2406 emit_insn (gen_clz<mode>
2 (tmp3, tmp2));
2407 emit_insn (gen_sub<mode>
3 (operands[
0], GEN_INT (<bits> -
1), tmp3));
2413 (define_insn "ctz<mode>
2_hw"
2414 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2415 (ctz:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")))]
2418 [(set_attr "type" "cntlz")])
2420 (define_expand "ffs<mode>
2"
2421 [(set (match_operand:GPR
0 "gpc_reg_operand")
2422 (ffs:GPR (match_operand:GPR
1 "gpc_reg_operand")))]
2425 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2426 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2427 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2428 emit_insn (gen_neg<mode>
2 (tmp1, operands[
1]));
2429 emit_insn (gen_and<mode>
3 (tmp2, operands[
1], tmp1));
2430 emit_insn (gen_clz<mode>
2 (tmp3, tmp2));
2431 emit_insn (gen_sub<mode>
3 (operands[
0], GEN_INT (<bits>), tmp3));
2436 (define_expand "popcount<mode>
2"
2437 [(set (match_operand:GPR
0 "gpc_reg_operand")
2438 (popcount:GPR (match_operand:GPR
1 "gpc_reg_operand")))]
2439 "TARGET_POPCNTB || TARGET_POPCNTD"
2441 rs6000_emit_popcount (operands[
0], operands[
1]);
2445 (define_insn "popcntb<mode>
2"
2446 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2447 (unspec:GPR [(match_operand:GPR
1 "gpc_reg_operand" "r")]
2451 [(set_attr "type" "popcnt")])
2453 (define_insn "popcntd<mode>
2"
2454 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2455 (popcount:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")))]
2458 [(set_attr "type" "popcnt")])
2461 (define_expand "parity<mode>
2"
2462 [(set (match_operand:GPR
0 "gpc_reg_operand")
2463 (parity:GPR (match_operand:GPR
1 "gpc_reg_operand")))]
2466 rs6000_emit_parity (operands[
0], operands[
1]);
2470 (define_insn "parity<mode>
2_cmpb"
2471 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2472 (unspec:GPR [(match_operand:GPR
1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2473 "TARGET_CMPB && TARGET_POPCNTB"
2475 [(set_attr "type" "popcnt")])
2477 (define_insn "cfuged"
2478 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
2479 (unspec:DI [(match_operand:DI
1 "gpc_reg_operand" "r")
2480 (match_operand:DI
2 "gpc_reg_operand" "r")]
2482 "TARGET_POWER10 && TARGET_64BIT"
2484 [(set_attr "type" "integer")])
2486 (define_insn "cntlzdm"
2487 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
2488 (unspec:DI [(match_operand:DI
1 "gpc_reg_operand" "r")
2489 (match_operand:DI
2 "gpc_reg_operand" "r")]
2491 "TARGET_POWER10 && TARGET_POWERPC64"
2493 [(set_attr "type" "integer")])
2495 (define_insn "cnttzdm"
2496 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
2497 (unspec:DI [(match_operand:DI
1 "gpc_reg_operand" "r")
2498 (match_operand:DI
2 "gpc_reg_operand" "r")]
2500 "TARGET_POWER10 && TARGET_POWERPC64"
2502 [(set_attr "type" "integer")])
2504 (define_insn "pdepd"
2505 [(set (match_operand:DI
0 "register_operand" "=r")
2506 (unspec:DI [(match_operand:DI
1 "gpc_reg_operand" "r")
2507 (match_operand:DI
2 "gpc_reg_operand" "r")]
2509 "TARGET_POWER10 && TARGET_POWERPC64"
2511 [(set_attr "type" "integer")])
2513 (define_insn "pextd"
2514 [(set (match_operand:DI
0 "register_operand" "=r")
2515 (unspec:DI [(match_operand:DI
1 "gpc_reg_operand" "r")
2516 (match_operand:DI
2 "gpc_reg_operand" "r")]
2518 "TARGET_POWER10 && TARGET_POWERPC64"
2520 [(set_attr "type" "integer")])
2522 (define_insn "cmpb<mode>
3"
2523 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
2524 (unspec:GPR [(match_operand:GPR
1 "gpc_reg_operand" "r")
2525 (match_operand:GPR
2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2528 [(set_attr "type" "cmp")])
2530 ;; Since the hardware zeros the upper part of the register, save generating the
2531 ;; AND immediate if we are converting to unsigned
2532 (define_insn "*bswap<mode>
2_extenddi"
2533 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
2535 (bswap:HSI (match_operand:HSI
1 "memory_operand" "Z"))))]
2538 [(set_attr "type" "load")])
2540 (define_insn "*bswaphi2_extendsi"
2541 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
2543 (bswap:HI (match_operand:HI
1 "memory_operand" "Z"))))]
2546 [(set_attr "type" "load")])
2548 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2549 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2550 ;; load with byte swap, which can be slower than doing it in the registers. It
2551 ;; also prevents certain failures with the RELOAD register allocator.
2553 (define_expand "bswap<mode>
2"
2554 [(use (match_operand:HSI
0 "reg_or_mem_operand"))
2555 (use (match_operand:HSI
1 "reg_or_mem_operand"))]
2558 rtx dest = operands[
0];
2559 rtx src = operands[
1];
2561 if (!REG_P (dest) && !REG_P (src))
2562 src = force_reg (<MODE>mode, src);
2566 src = rs6000_force_indexed_or_indirect_mem (src);
2567 emit_insn (gen_bswap<mode>
2_load (dest, src));
2569 else if (MEM_P (dest))
2571 dest = rs6000_force_indexed_or_indirect_mem (dest);
2572 emit_insn (gen_bswap<mode>
2_store (dest, src));
2575 emit_insn (gen_bswap<mode>
2_reg (dest, src));
2579 (define_insn "bswap<mode>
2_load"
2580 [(set (match_operand:HSI
0 "gpc_reg_operand" "=r")
2581 (bswap:HSI (match_operand:HSI
1 "memory_operand" "Z")))]
2584 [(set_attr "type" "load")])
2586 (define_insn "bswap<mode>
2_store"
2587 [(set (match_operand:HSI
0 "memory_operand" "=Z")
2588 (bswap:HSI (match_operand:HSI
1 "gpc_reg_operand" "r")))]
2591 [(set_attr "type" "store")])
2593 (define_insn_and_split "bswaphi2_reg"
2594 [(set (match_operand:HI
0 "gpc_reg_operand" "=r,&r,wa")
2596 (match_operand:HI
1 "gpc_reg_operand" "r,r,wa")))
2597 (clobber (match_scratch:SI
2 "=X,&r,X"))]
2603 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[
0], HImode)"
2605 (and:SI (lshiftrt:SI (match_dup
4)
2609 (and:SI (ashift:SI (match_dup
4)
2611 (const_int
65280))) ;;
0xff00
2613 (ior:SI (match_dup
3)
2616 operands[
3] = simplify_gen_subreg (SImode, operands[
0], HImode,
0);
2617 operands[
4] = simplify_gen_subreg (SImode, operands[
1], HImode,
0);
2619 [(set_attr "length" "*,
12,*")
2620 (set_attr "type" "shift,*,vecperm")
2621 (set_attr "isa" "p10,*,p9v")])
2623 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2624 ;; zero_extract insns do not change for -mlittle.
2625 (define_insn_and_split "bswapsi2_reg"
2626 [(set (match_operand:SI
0 "gpc_reg_operand" "=r,&r,wa")
2628 (match_operand:SI
1 "gpc_reg_operand" "r,r,wa")))]
2634 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[
0], SImode)"
2635 [(set (match_dup
0) ; DABC
2636 (rotate:SI (match_dup
1)
2638 (set (match_dup
0) ; DCBC
2639 (ior:SI (and:SI (ashift:SI (match_dup
1)
2641 (const_int
16711680))
2642 (and:SI (match_dup
0)
2643 (const_int -
16711681))))
2644 (set (match_dup
0) ; DCBA
2645 (ior:SI (and:SI (lshiftrt:SI (match_dup
1)
2648 (and:SI (match_dup
0)
2649 (const_int -
256))))]
2651 [(set_attr "length" "
4,
12,
4")
2652 (set_attr "type" "shift,*,vecperm")
2653 (set_attr "isa" "p10,*,p9v")])
2655 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2656 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2659 (define_expand "bswapdi2"
2660 [(parallel [(set (match_operand:DI
0 "reg_or_mem_operand")
2662 (match_operand:DI
1 "reg_or_mem_operand")))
2663 (clobber (match_scratch:DI
2))
2664 (clobber (match_scratch:DI
3))])]
2667 rtx dest = operands[
0];
2668 rtx src = operands[
1];
2670 if (!REG_P (dest) && !REG_P (src))
2671 operands[
1] = src = force_reg (DImode, src);
2673 if (TARGET_POWERPC64 && TARGET_LDBRX)
2677 src = rs6000_force_indexed_or_indirect_mem (src);
2678 emit_insn (gen_bswapdi2_load (dest, src));
2680 else if (MEM_P (dest))
2682 dest = rs6000_force_indexed_or_indirect_mem (dest);
2683 emit_insn (gen_bswapdi2_store (dest, src));
2685 else if (TARGET_P9_VECTOR)
2686 emit_insn (gen_bswapdi2_brd (dest, src));
2688 emit_insn (gen_bswapdi2_reg (dest, src));
2692 if (!TARGET_POWERPC64)
2694 /*
32-bit mode needs fewer scratch registers, but
32-bit addressing mode
2695 that uses
64-bit registers needs the same scratch registers as
64-bit
2697 emit_insn (gen_bswapdi2_32bit (dest, src));
2702 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2703 (define_insn "bswapdi2_load"
2704 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
2705 (bswap:DI (match_operand:DI
1 "memory_operand" "Z")))]
2706 "TARGET_POWERPC64 && TARGET_LDBRX"
2708 [(set_attr "type" "load")])
2710 (define_insn "bswapdi2_store"
2711 [(set (match_operand:DI
0 "memory_operand" "=Z")
2712 (bswap:DI (match_operand:DI
1 "gpc_reg_operand" "r")))]
2713 "TARGET_POWERPC64 && TARGET_LDBRX"
2715 [(set_attr "type" "store")])
2717 (define_insn "bswapdi2_brd"
2718 [(set (match_operand:DI
0 "gpc_reg_operand" "=r,wa")
2719 (bswap:DI (match_operand:DI
1 "gpc_reg_operand" "r,wa")))]
2724 [(set_attr "type" "shift,vecperm")
2725 (set_attr "isa" "p10,p9v")])
2727 (define_insn "bswapdi2_reg"
2728 [(set (match_operand:DI
0 "gpc_reg_operand" "=&r")
2729 (bswap:DI (match_operand:DI
1 "gpc_reg_operand" "r")))
2730 (clobber (match_scratch:DI
2 "=&r"))
2731 (clobber (match_scratch:DI
3 "=&r"))]
2732 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2734 [(set_attr "length" "
36")])
2736 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2737 (define_insn "*bswapdi2_64bit"
2738 [(set (match_operand:DI
0 "reg_or_mem_operand" "=r,Z,&r")
2739 (bswap:DI (match_operand:DI
1 "reg_or_mem_operand" "Z,r,r")))
2740 (clobber (match_scratch:DI
2 "=&b,&b,&r"))
2741 (clobber (match_scratch:DI
3 "=&r,&r,&r"))]
2742 "TARGET_POWERPC64 && !TARGET_LDBRX
2743 && (REG_P (operands[
0]) || REG_P (operands[
1]))
2744 && !(MEM_P (operands[
0]) && MEM_VOLATILE_P (operands[
0]))
2745 && !(MEM_P (operands[
1]) && MEM_VOLATILE_P (operands[
1]))"
2747 [(set_attr "length" "
16,
12,
36")])
2750 [(set (match_operand:DI
0 "gpc_reg_operand")
2751 (bswap:DI (match_operand:DI
1 "indexed_or_indirect_operand")))
2752 (clobber (match_operand:DI
2 "gpc_reg_operand"))
2753 (clobber (match_operand:DI
3 "gpc_reg_operand"))]
2754 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2757 rtx dest = operands[
0];
2758 rtx src = operands[
1];
2759 rtx op2 = operands[
2];
2760 rtx op3 = operands[
3];
2761 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2762 BYTES_BIG_ENDIAN ?
4 :
0);
2763 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2764 BYTES_BIG_ENDIAN ?
4 :
0);
2770 addr1 = XEXP (src,
0);
2771 if (GET_CODE (addr1) == PLUS)
2773 emit_insn (gen_add3_insn (op2, XEXP (addr1,
0), GEN_INT (
4)));
2774 if (TARGET_AVOID_XFORM)
2776 emit_insn (gen_add3_insn (op2, XEXP (addr1,
1), op2));
2780 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1,
1));
2782 else if (TARGET_AVOID_XFORM)
2784 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (
4)));
2789 emit_move_insn (op2, GEN_INT (
4));
2790 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2793 word1 = change_address (src, SImode, addr1);
2794 word2 = change_address (src, SImode, addr2);
2796 if (BYTES_BIG_ENDIAN)
2798 emit_insn (gen_bswapsi2 (op3_32, word2));
2799 emit_insn (gen_bswapsi2 (dest_32, word1));
2803 emit_insn (gen_bswapsi2 (op3_32, word1));
2804 emit_insn (gen_bswapsi2 (dest_32, word2));
2807 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (
32)));
2808 emit_insn (gen_iordi3 (dest, dest, op3));
2813 [(set (match_operand:DI
0 "indexed_or_indirect_operand")
2814 (bswap:DI (match_operand:DI
1 "gpc_reg_operand")))
2815 (clobber (match_operand:DI
2 "gpc_reg_operand"))
2816 (clobber (match_operand:DI
3 "gpc_reg_operand"))]
2817 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2820 rtx dest = operands[
0];
2821 rtx src = operands[
1];
2822 rtx op2 = operands[
2];
2823 rtx op3 = operands[
3];
2824 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2825 BYTES_BIG_ENDIAN ?
4 :
0);
2826 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2827 BYTES_BIG_ENDIAN ?
4 :
0);
2833 addr1 = XEXP (dest,
0);
2834 if (GET_CODE (addr1) == PLUS)
2836 emit_insn (gen_add3_insn (op2, XEXP (addr1,
0), GEN_INT (
4)));
2837 if (TARGET_AVOID_XFORM)
2839 emit_insn (gen_add3_insn (op2, XEXP (addr1,
1), op2));
2843 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1,
1));
2845 else if (TARGET_AVOID_XFORM)
2847 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (
4)));
2852 emit_move_insn (op2, GEN_INT (
4));
2853 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2856 word1 = change_address (dest, SImode, addr1);
2857 word2 = change_address (dest, SImode, addr2);
2859 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (
32)));
2861 if (BYTES_BIG_ENDIAN)
2863 emit_insn (gen_bswapsi2 (word1, src_si));
2864 emit_insn (gen_bswapsi2 (word2, op3_si));
2868 emit_insn (gen_bswapsi2 (word2, src_si));
2869 emit_insn (gen_bswapsi2 (word1, op3_si));
2875 [(set (match_operand:DI
0 "gpc_reg_operand")
2876 (bswap:DI (match_operand:DI
1 "gpc_reg_operand")))
2877 (clobber (match_operand:DI
2 "gpc_reg_operand"))
2878 (clobber (match_operand:DI
3 "gpc_reg_operand"))]
2879 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2882 rtx dest = operands[
0];
2883 rtx src = operands[
1];
2884 rtx op2 = operands[
2];
2885 rtx op3 = operands[
3];
2886 int lo_off = BYTES_BIG_ENDIAN ?
4 :
0;
2887 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2888 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2889 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2890 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2892 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (
32)));
2893 emit_insn (gen_bswapsi2 (dest_si, src_si));
2894 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2895 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (
32)));
2896 emit_insn (gen_iordi3 (dest, dest, op3));
2900 (define_insn "bswapdi2_32bit"
2901 [(set (match_operand:DI
0 "reg_or_mem_operand" "=r,Z,?&r")
2902 (bswap:DI (match_operand:DI
1 "reg_or_mem_operand" "Z,r,r")))
2903 (clobber (match_scratch:SI
2 "=&b,&b,X"))]
2904 "!TARGET_POWERPC64 && (REG_P (operands[
0]) || REG_P (operands[
1]))"
2906 [(set_attr "length" "
16,
12,
36")])
2909 [(set (match_operand:DI
0 "gpc_reg_operand")
2910 (bswap:DI (match_operand:DI
1 "indexed_or_indirect_operand")))
2911 (clobber (match_operand:SI
2 "gpc_reg_operand"))]
2912 "!TARGET_POWERPC64 && reload_completed"
2915 rtx dest = operands[
0];
2916 rtx src = operands[
1];
2917 rtx op2 = operands[
2];
2918 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode,
0);
2919 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode,
4);
2925 addr1 = XEXP (src,
0);
2926 if (GET_CODE (addr1) == PLUS)
2928 emit_insn (gen_add3_insn (op2, XEXP (addr1,
0), GEN_INT (
4)));
2929 if (TARGET_AVOID_XFORM
2930 || REGNO (XEXP (addr1,
1)) == REGNO (dest2))
2932 emit_insn (gen_add3_insn (op2, XEXP (addr1,
1), op2));
2936 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1,
1));
2938 else if (TARGET_AVOID_XFORM
2939 || REGNO (addr1) == REGNO (dest2))
2941 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (
4)));
2946 emit_move_insn (op2, GEN_INT (
4));
2947 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2950 word1 = change_address (src, SImode, addr1);
2951 word2 = change_address (src, SImode, addr2);
2953 emit_insn (gen_bswapsi2 (dest2, word1));
2954 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2955 thus allowing us to omit an early clobber on the output. */
2956 emit_insn (gen_bswapsi2 (dest1, word2));
2961 [(set (match_operand:DI
0 "indexed_or_indirect_operand")
2962 (bswap:DI (match_operand:DI
1 "gpc_reg_operand")))
2963 (clobber (match_operand:SI
2 "gpc_reg_operand"))]
2964 "!TARGET_POWERPC64 && reload_completed"
2967 rtx dest = operands[
0];
2968 rtx src = operands[
1];
2969 rtx op2 = operands[
2];
2970 rtx src1 = simplify_gen_subreg (SImode, src, DImode,
0);
2971 rtx src2 = simplify_gen_subreg (SImode, src, DImode,
4);
2977 addr1 = XEXP (dest,
0);
2978 if (GET_CODE (addr1) == PLUS)
2980 emit_insn (gen_add3_insn (op2, XEXP (addr1,
0), GEN_INT (
4)));
2981 if (TARGET_AVOID_XFORM)
2983 emit_insn (gen_add3_insn (op2, XEXP (addr1,
1), op2));
2987 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1,
1));
2989 else if (TARGET_AVOID_XFORM)
2991 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (
4)));
2996 emit_move_insn (op2, GEN_INT (
4));
2997 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
3000 word1 = change_address (dest, SImode, addr1);
3001 word2 = change_address (dest, SImode, addr2);
3003 emit_insn (gen_bswapsi2 (word2, src1));
3004 emit_insn (gen_bswapsi2 (word1, src2));
3009 [(set (match_operand:DI
0 "gpc_reg_operand")
3010 (bswap:DI (match_operand:DI
1 "gpc_reg_operand")))
3011 (clobber (match_operand:SI
2 ""))]
3012 "!TARGET_POWERPC64 && reload_completed"
3015 rtx dest = operands[
0];
3016 rtx src = operands[
1];
3017 rtx src1 = simplify_gen_subreg (SImode, src, DImode,
0);
3018 rtx src2 = simplify_gen_subreg (SImode, src, DImode,
4);
3019 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode,
0);
3020 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode,
4);
3022 emit_insn (gen_bswapsi2 (dest1, src2));
3023 emit_insn (gen_bswapsi2 (dest2, src1));
3028 (define_insn "mul<mode>
3"
3029 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3030 (mult:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,r")
3031 (match_operand:GPR
2 "reg_or_short_operand" "r,I")))]
3036 [(set_attr "type" "mul")
3038 (cond [(match_operand:GPR
2 "s8bit_cint_operand")
3040 (match_operand:GPR
2 "short_cint_operand")
3041 (const_string "
16")]
3042 (const_string "<bits>")))])
3044 (define_insn_and_split "*mul<mode>
3_dot"
3045 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
3046 (compare:CC (mult:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
3047 (match_operand:GPR
2 "gpc_reg_operand" "r,r"))
3049 (clobber (match_scratch:GPR
0 "=r,r"))]
3050 "<MODE>mode == Pmode"
3054 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
3056 (mult:GPR (match_dup
1)
3059 (compare:CC (match_dup
0)
3062 [(set_attr "type" "mul")
3063 (set_attr "size" "<bits>")
3064 (set_attr "dot" "yes")
3065 (set_attr "length" "
4,
8")])
3067 (define_insn_and_split "*mul<mode>
3_dot2"
3068 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
3069 (compare:CC (mult:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
3070 (match_operand:GPR
2 "gpc_reg_operand" "r,r"))
3072 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3073 (mult:GPR (match_dup
1)
3075 "<MODE>mode == Pmode"
3079 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
3081 (mult:GPR (match_dup
1)
3084 (compare:CC (match_dup
0)
3087 [(set_attr "type" "mul")
3088 (set_attr "size" "<bits>")
3089 (set_attr "dot" "yes")
3090 (set_attr "length" "
4,
8")])
3093 (define_expand "<su>mul<mode>
3_highpart"
3094 [(set (match_operand:GPR
0 "gpc_reg_operand")
3096 (mult:<DMODE> (any_extend:<DMODE>
3097 (match_operand:GPR
1 "gpc_reg_operand"))
3099 (match_operand:GPR
2 "gpc_reg_operand")))
3103 if (<MODE>mode == SImode && TARGET_POWERPC64)
3105 emit_insn (gen_<su>mulsi3_highpart_64 (operands[
0], operands[
1],
3110 if (!WORDS_BIG_ENDIAN)
3112 emit_insn (gen_<su>mul<mode>
3_highpart_le (operands[
0], operands[
1],
3118 (define_insn "*<su>mul<mode>
3_highpart"
3119 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3121 (mult:<DMODE> (any_extend:<DMODE>
3122 (match_operand:GPR
1 "gpc_reg_operand" "r"))
3124 (match_operand:GPR
2 "gpc_reg_operand" "r")))
3126 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3127 "mulh<wd><u> %
0,%
1,%
2"
3128 [(set_attr "type" "mul")
3129 (set_attr "size" "<bits>")])
3131 (define_insn "<su>mulsi3_highpart_le"
3132 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
3134 (mult:DI (any_extend:DI
3135 (match_operand:SI
1 "gpc_reg_operand" "r"))
3137 (match_operand:SI
2 "gpc_reg_operand" "r")))
3139 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3141 [(set_attr "type" "mul")])
3143 (define_insn "<su>muldi3_highpart_le"
3144 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
3146 (mult:TI (any_extend:TI
3147 (match_operand:DI
1 "gpc_reg_operand" "r"))
3149 (match_operand:DI
2 "gpc_reg_operand" "r")))
3151 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3153 [(set_attr "type" "mul")
3154 (set_attr "size" "
64")])
3156 (define_insn "<su>mulsi3_highpart_64"
3157 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
3160 (mult:DI (any_extend:DI
3161 (match_operand:SI
1 "gpc_reg_operand" "r"))
3163 (match_operand:SI
2 "gpc_reg_operand" "r")))
3167 [(set_attr "type" "mul")])
3169 (define_expand "<u>mul<mode><dmode>
3"
3170 [(set (match_operand:<DMODE>
0 "gpc_reg_operand")
3171 (mult:<DMODE> (any_extend:<DMODE>
3172 (match_operand:GPR
1 "gpc_reg_operand"))
3174 (match_operand:GPR
2 "gpc_reg_operand"))))]
3175 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3177 rtx l = gen_reg_rtx (<MODE>mode);
3178 rtx h = gen_reg_rtx (<MODE>mode);
3179 emit_insn (gen_mul<mode>
3 (l, operands[
1], operands[
2]));
3180 emit_insn (gen_<su>mul<mode>
3_highpart (h, operands[
1], operands[
2]));
3181 emit_move_insn (gen_lowpart (<MODE>mode, operands[
0]), l);
3182 emit_move_insn (gen_highpart (<MODE>mode, operands[
0]), h);
3186 (define_insn "*maddld<mode>
4"
3187 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3188 (plus:GPR (mult:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
3189 (match_operand:GPR
2 "gpc_reg_operand" "r"))
3190 (match_operand:GPR
3 "gpc_reg_operand" "r")))]
3192 "maddld %
0,%
1,%
2,%
3"
3193 [(set_attr "type" "mul")])
3195 (define_insn "udiv<mode>
3"
3196 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3197 (udiv:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
3198 (match_operand:GPR
2 "gpc_reg_operand" "r")))]
3201 [(set_attr "type" "div")
3202 (set_attr "size" "<bits>")])
3205 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3206 ;; modulus. If it isn't a power of two, force operands into register and do
3208 (define_expand "div<mode>
3"
3209 [(set (match_operand:GPR
0 "gpc_reg_operand")
3210 (div:GPR (match_operand:GPR
1 "gpc_reg_operand")
3211 (match_operand:GPR
2 "reg_or_cint_operand")))]
3214 if (CONST_INT_P (operands[
2])
3215 && INTVAL (operands[
2]) >
0
3216 && exact_log2 (INTVAL (operands[
2])) >=
0)
3218 emit_insn (gen_div<mode>
3_sra (operands[
0], operands[
1], operands[
2]));
3222 operands[
2] = force_reg (<MODE>mode, operands[
2]);
3225 (define_insn "*div<mode>
3"
3226 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3227 (div:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
3228 (match_operand:GPR
2 "gpc_reg_operand" "r")))]
3231 [(set_attr "type" "div")
3232 (set_attr "size" "<bits>")])
3234 (define_insn "div<mode>
3_sra"
3235 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3236 (div:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
3237 (match_operand:GPR
2 "exact_log2_cint_operand" "N")))
3238 (clobber (reg:GPR CA_REGNO))]
3240 "sra<wd>i %
0,%
1,%p2\;addze %
0,%
0"
3241 [(set_attr "type" "two")
3242 (set_attr "length" "
8")])
3244 (define_insn_and_split "*div<mode>
3_sra_dot"
3245 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
3246 (compare:CC (div:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
3247 (match_operand:GPR
2 "exact_log2_cint_operand" "N,N"))
3249 (clobber (match_scratch:GPR
0 "=r,r"))
3250 (clobber (reg:GPR CA_REGNO))]
3251 "<MODE>mode == Pmode"
3253 sra<wd>i %
0,%
1,%p2\;addze. %
0,%
0
3255 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
3256 [(parallel [(set (match_dup
0)
3257 (div:GPR (match_dup
1)
3259 (clobber (reg:GPR CA_REGNO))])
3261 (compare:CC (match_dup
0)
3264 [(set_attr "type" "two")
3265 (set_attr "length" "
8,
12")
3266 (set_attr "cell_micro" "not")])
3268 (define_insn_and_split "*div<mode>
3_sra_dot2"
3269 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
3270 (compare:CC (div:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
3271 (match_operand:GPR
2 "exact_log2_cint_operand" "N,N"))
3273 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3274 (div:GPR (match_dup
1)
3276 (clobber (reg:GPR CA_REGNO))]
3277 "<MODE>mode == Pmode"
3279 sra<wd>i %
0,%
1,%p2\;addze. %
0,%
0
3281 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
3282 [(parallel [(set (match_dup
0)
3283 (div:GPR (match_dup
1)
3285 (clobber (reg:GPR CA_REGNO))])
3287 (compare:CC (match_dup
0)
3290 [(set_attr "type" "two")
3291 (set_attr "length" "
8,
12")
3292 (set_attr "cell_micro" "not")])
3294 (define_expand "mod<mode>
3"
3295 [(set (match_operand:GPR
0 "gpc_reg_operand")
3296 (mod:GPR (match_operand:GPR
1 "gpc_reg_operand")
3297 (match_operand:GPR
2 "reg_or_cint_operand")))]
3304 if (!CONST_INT_P (operands[
2])
3305 || INTVAL (operands[
2]) <=
0
3306 || (i = exact_log2 (INTVAL (operands[
2]))) <
0)
3311 operands[
2] = force_reg (<MODE>mode, operands[
2]);
3315 temp1 = gen_reg_rtx (<MODE>mode);
3316 temp2 = gen_reg_rtx (<MODE>mode);
3318 emit_insn (gen_div<mode>
3 (temp1, operands[
1], operands[
2]));
3319 emit_insn (gen_ashl<mode>
3 (temp2, temp1, GEN_INT (i)));
3320 emit_insn (gen_sub<mode>
3 (operands[
0], operands[
1], temp2));
3325 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3326 ;; mod, prefer putting the result of mod into a different register
3327 (define_insn "*mod<mode>
3"
3328 [(set (match_operand:GPR
0 "gpc_reg_operand" "=&r")
3329 (mod:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
3330 (match_operand:GPR
2 "gpc_reg_operand" "r")))]
3333 [(set_attr "type" "div")
3334 (set_attr "size" "<bits>")])
3337 (define_insn "umod<mode>
3"
3338 [(set (match_operand:GPR
0 "gpc_reg_operand" "=&r")
3339 (umod:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
3340 (match_operand:GPR
2 "gpc_reg_operand" "r")))]
3343 [(set_attr "type" "div")
3344 (set_attr "size" "<bits>")])
3346 ;; On machines with modulo support, do a combined div/mod the old fashioned
3347 ;; method, since the multiply/subtract is faster than doing the mod instruction
3351 [(set (match_operand:GPR
0 "gpc_reg_operand")
3352 (div:GPR (match_operand:GPR
1 "gpc_reg_operand")
3353 (match_operand:GPR
2 "gpc_reg_operand")))
3354 (set (match_operand:GPR
3 "gpc_reg_operand")
3355 (mod:GPR (match_dup
1)
3358 && ! reg_mentioned_p (operands[
0], operands[
1])
3359 && ! reg_mentioned_p (operands[
0], operands[
2])
3360 && ! reg_mentioned_p (operands[
3], operands[
1])
3361 && ! reg_mentioned_p (operands[
3], operands[
2])"
3363 (div:GPR (match_dup
1)
3366 (mult:GPR (match_dup
0)
3369 (minus:GPR (match_dup
1)
3373 [(set (match_operand:GPR
0 "gpc_reg_operand")
3374 (udiv:GPR (match_operand:GPR
1 "gpc_reg_operand")
3375 (match_operand:GPR
2 "gpc_reg_operand")))
3376 (set (match_operand:GPR
3 "gpc_reg_operand")
3377 (umod:GPR (match_dup
1)
3380 && ! reg_mentioned_p (operands[
0], operands[
1])
3381 && ! reg_mentioned_p (operands[
0], operands[
2])
3382 && ! reg_mentioned_p (operands[
3], operands[
1])
3383 && ! reg_mentioned_p (operands[
3], operands[
2])"
3385 (udiv:GPR (match_dup
1)
3388 (mult:GPR (match_dup
0)
3391 (minus:GPR (match_dup
1)
3395 ;; Logical instructions
3396 ;; The logical instructions are mostly combined by using match_operator,
3397 ;; but the plain AND insns are somewhat different because there is no
3398 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3399 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3401 (define_expand "and<mode>
3"
3402 [(set (match_operand:SDI
0 "gpc_reg_operand")
3403 (and:SDI (match_operand:SDI
1 "gpc_reg_operand")
3404 (match_operand:SDI
2 "reg_or_cint_operand")))]
3407 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3409 rs6000_split_logical (operands, AND, false, false, false);
3413 if (CONST_INT_P (operands[
2]))
3415 if (rs6000_is_valid_and_mask (operands[
2], <MODE>mode))
3417 emit_insn (gen_and<mode>
3_mask (operands[
0], operands[
1], operands[
2]));
3421 if (logical_const_operand (operands[
2], <MODE>mode))
3423 emit_insn (gen_and<mode>
3_imm (operands[
0], operands[
1], operands[
2]));
3427 if (rs6000_is_valid_2insn_and (operands[
2], <MODE>mode))
3429 rs6000_emit_2insn_and (<MODE>mode, operands, true,
0);
3433 operands[
2] = force_reg (<MODE>mode, operands[
2]);
3438 (define_insn "and<mode>
3_imm"
3439 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3440 (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r")
3441 (match_operand:GPR
2 "logical_const_operand" "n")))
3442 (clobber (match_scratch:CC
3 "=x"))]
3443 "!rs6000_is_valid_and_mask (operands[
2], <MODE>mode)"
3444 "andi%e2. %
0,%
1,%u2"
3445 [(set_attr "type" "logical")
3446 (set_attr "dot" "yes")])
3448 (define_insn_and_split "*and<mode>
3_imm_dot"
3449 [(set (match_operand:CC
3 "cc_reg_operand" "=x,??y")
3450 (compare:CC (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,r")
3451 (match_operand:GPR
2 "logical_const_operand" "n,n"))
3453 (clobber (match_scratch:GPR
0 "=r,r"))
3454 (clobber (match_scratch:CC
4 "=X,x"))]
3455 "(<MODE>mode == Pmode || UINTVAL (operands[
2]) <=
0x7fffffff)
3456 && !rs6000_is_valid_and_mask (operands[
2], <MODE>mode)"
3460 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
3461 [(parallel [(set (match_dup
0)
3462 (and:GPR (match_dup
1)
3464 (clobber (match_dup
4))])
3466 (compare:CC (match_dup
0)
3469 [(set_attr "type" "logical")
3470 (set_attr "dot" "yes")
3471 (set_attr "length" "
4,
8")])
3473 (define_insn_and_split "*and<mode>
3_imm_dot2"
3474 [(set (match_operand:CC
3 "cc_reg_operand" "=x,??y")
3475 (compare:CC (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,r")
3476 (match_operand:GPR
2 "logical_const_operand" "n,n"))
3478 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3479 (and:GPR (match_dup
1)
3481 (clobber (match_scratch:CC
4 "=X,x"))]
3482 "(<MODE>mode == Pmode || UINTVAL (operands[
2]) <=
0x7fffffff)
3483 && !rs6000_is_valid_and_mask (operands[
2], <MODE>mode)"
3487 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
3488 [(parallel [(set (match_dup
0)
3489 (and:GPR (match_dup
1)
3491 (clobber (match_dup
4))])
3493 (compare:CC (match_dup
0)
3496 [(set_attr "type" "logical")
3497 (set_attr "dot" "yes")
3498 (set_attr "length" "
4,
8")])
3500 (define_insn_and_split "*and<mode>
3_imm_mask_dot"
3501 [(set (match_operand:CC
3 "cc_reg_operand" "=x,??y")
3502 (compare:CC (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,r")
3503 (match_operand:GPR
2 "logical_const_operand" "n,n"))
3505 (clobber (match_scratch:GPR
0 "=r,r"))]
3506 "(<MODE>mode == Pmode || UINTVAL (operands[
2]) <=
0x7fffffff)
3507 && rs6000_is_valid_and_mask (operands[
2], <MODE>mode)"
3511 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
3513 (and:GPR (match_dup
1)
3516 (compare:CC (match_dup
0)
3519 [(set_attr "type" "logical")
3520 (set_attr "dot" "yes")
3521 (set_attr "length" "
4,
8")])
3523 (define_insn_and_split "*and<mode>
3_imm_mask_dot2"
3524 [(set (match_operand:CC
3 "cc_reg_operand" "=x,??y")
3525 (compare:CC (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,r")
3526 (match_operand:GPR
2 "logical_const_operand" "n,n"))
3528 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3529 (and:GPR (match_dup
1)
3531 "(<MODE>mode == Pmode || UINTVAL (operands[
2]) <=
0x7fffffff)
3532 && rs6000_is_valid_and_mask (operands[
2], <MODE>mode)"
3536 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
3538 (and:GPR (match_dup
1)
3541 (compare:CC (match_dup
0)
3544 [(set_attr "type" "logical")
3545 (set_attr "dot" "yes")
3546 (set_attr "length" "
4,
8")])
3548 (define_insn "*and<mode>
3_imm_dot_shifted"
3549 [(set (match_operand:CC
3 "cc_reg_operand" "=x")
3552 (lshiftrt:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r")
3553 (match_operand:SI
4 "const_int_operand" "n"))
3554 (match_operand:GPR
2 "const_int_operand" "n"))
3556 (clobber (match_scratch:GPR
0 "=r"))]
3557 "logical_const_operand (GEN_INT (UINTVAL (operands[
2])
3558 << INTVAL (operands[
4])),
3560 && (<MODE>mode == Pmode
3561 || (UINTVAL (operands[
2]) << INTVAL (operands[
4])) <=
0x7fffffff)"
3563 operands[
2] = GEN_INT (UINTVAL (operands[
2]) << INTVAL (operands[
4]));
3564 return "andi%e2. %
0,%
1,%u2";
3566 [(set_attr "type" "logical")
3567 (set_attr "dot" "yes")])
3570 (define_insn "and<mode>
3_mask"
3571 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3572 (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r")
3573 (match_operand:GPR
2 "const_int_operand" "n")))]
3574 "rs6000_is_valid_and_mask (operands[
2], <MODE>mode)"
3576 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3578 [(set_attr "type" "shift")])
3580 (define_insn_and_split "*and<mode>
3_mask_dot"
3581 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
3582 (compare:CC (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,r")
3583 (match_operand:GPR
2 "const_int_operand" "n,n"))
3585 (clobber (match_scratch:GPR
0 "=r,r"))]
3586 "(<MODE>mode == Pmode || UINTVAL (operands[
2]) <=
0x7fffffff)
3587 && !logical_const_operand (operands[
2], <MODE>mode)
3588 && rs6000_is_valid_and_mask (operands[
2], <MODE>mode)"
3590 if (which_alternative ==
0)
3591 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3595 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
3597 (and:GPR (match_dup
1)
3600 (compare:CC (match_dup
0)
3603 [(set_attr "type" "shift")
3604 (set_attr "dot" "yes")
3605 (set_attr "length" "
4,
8")])
3607 (define_insn_and_split "*and<mode>
3_mask_dot2"
3608 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
3609 (compare:CC (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,r")
3610 (match_operand:GPR
2 "const_int_operand" "n,n"))
3612 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3613 (and:GPR (match_dup
1)
3615 "(<MODE>mode == Pmode || UINTVAL (operands[
2]) <=
0x7fffffff)
3616 && !logical_const_operand (operands[
2], <MODE>mode)
3617 && rs6000_is_valid_and_mask (operands[
2], <MODE>mode)"
3619 if (which_alternative ==
0)
3620 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3624 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
3626 (and:GPR (match_dup
1)
3629 (compare:CC (match_dup
0)
3632 [(set_attr "type" "shift")
3633 (set_attr "dot" "yes")
3634 (set_attr "length" "
4,
8")])
3637 (define_insn_and_split "*and<mode>
3_2insn"
3638 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3639 (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r")
3640 (match_operand:GPR
2 "const_int_operand" "n")))]
3641 "rs6000_is_valid_2insn_and (operands[
2], <MODE>mode)
3642 && !(rs6000_is_valid_and_mask (operands[
2], <MODE>mode)
3643 || logical_const_operand (operands[
2], <MODE>mode))"
3648 rs6000_emit_2insn_and (<MODE>mode, operands, false,
0);
3651 [(set_attr "type" "shift")
3652 (set_attr "length" "
8")])
3654 (define_insn_and_split "*and<mode>
3_2insn_dot"
3655 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
3656 (compare:CC (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,r")
3657 (match_operand:GPR
2 "const_int_operand" "n,n"))
3659 (clobber (match_scratch:GPR
0 "=r,r"))]
3660 "(<MODE>mode == Pmode || UINTVAL (operands[
2]) <=
0x7fffffff)
3661 && rs6000_is_valid_2insn_and (operands[
2], <MODE>mode)
3662 && !(rs6000_is_valid_and_mask (operands[
2], <MODE>mode)
3663 || logical_const_operand (operands[
2], <MODE>mode))"
3665 "&& reload_completed"
3668 rs6000_emit_2insn_and (<MODE>mode, operands, false,
1);
3671 [(set_attr "type" "shift")
3672 (set_attr "dot" "yes")
3673 (set_attr "length" "
8,
12")])
3675 (define_insn_and_split "*and<mode>
3_2insn_dot2"
3676 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
3677 (compare:CC (and:GPR (match_operand:GPR
1 "gpc_reg_operand" "%r,r")
3678 (match_operand:GPR
2 "const_int_operand" "n,n"))
3680 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3681 (and:GPR (match_dup
1)
3683 "(<MODE>mode == Pmode || UINTVAL (operands[
2]) <=
0x7fffffff)
3684 && rs6000_is_valid_2insn_and (operands[
2], <MODE>mode)
3685 && !(rs6000_is_valid_and_mask (operands[
2], <MODE>mode)
3686 || logical_const_operand (operands[
2], <MODE>mode))"
3688 "&& reload_completed"
3691 rs6000_emit_2insn_and (<MODE>mode, operands, false,
2);
3694 [(set_attr "type" "shift")
3695 (set_attr "dot" "yes")
3696 (set_attr "length" "
8,
12")])
3699 (define_expand "<code><mode>
3"
3700 [(set (match_operand:SDI
0 "gpc_reg_operand")
3701 (iorxor:SDI (match_operand:SDI
1 "gpc_reg_operand")
3702 (match_operand:SDI
2 "reg_or_cint_operand")))]
3705 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3707 rs6000_split_logical (operands, <CODE>, false, false, false);
3711 if (non_logical_cint_operand (operands[
2], <MODE>mode))
3713 rtx tmp = ((!can_create_pseudo_p ()
3714 || rtx_equal_p (operands[
0], operands[
1]))
3715 ? operands[
0] : gen_reg_rtx (<MODE>mode));
3717 HOST_WIDE_INT value = INTVAL (operands[
2]);
3718 HOST_WIDE_INT lo = value &
0xffff;
3719 HOST_WIDE_INT hi = value - lo;
3721 emit_insn (gen_<code><mode>
3 (tmp, operands[
1], GEN_INT (hi)));
3722 emit_insn (gen_<code><mode>
3 (operands[
0], tmp, GEN_INT (lo)));
3726 if (!reg_or_logical_cint_operand (operands[
2], <MODE>mode))
3727 operands[
2] = force_reg (<MODE>mode, operands[
2]);
3731 [(set (match_operand:GPR
0 "gpc_reg_operand")
3732 (iorxor:GPR (match_operand:GPR
1 "gpc_reg_operand")
3733 (match_operand:GPR
2 "non_logical_cint_operand")))]
3736 (iorxor:GPR (match_dup
1)
3739 (iorxor:GPR (match_dup
3)
3742 operands[
3] = ((!can_create_pseudo_p ()
3743 || rtx_equal_p (operands[
0], operands[
1]))
3744 ? operands[
0] : gen_reg_rtx (<MODE>mode));
3746 HOST_WIDE_INT value = INTVAL (operands[
2]);
3747 HOST_WIDE_INT lo = value &
0xffff;
3748 HOST_WIDE_INT hi = value - lo;
3750 operands[
4] = GEN_INT (hi);
3751 operands[
5] = GEN_INT (lo);
3754 (define_insn "*bool<mode>
3_imm"
3755 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3756 (match_operator:GPR
3 "boolean_or_operator"
3757 [(match_operand:GPR
1 "gpc_reg_operand" "%r")
3758 (match_operand:GPR
2 "logical_const_operand" "n")]))]
3761 [(set_attr "type" "logical")])
3763 (define_insn "*bool<mode>
3"
3764 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3765 (match_operator:GPR
3 "boolean_operator"
3766 [(match_operand:GPR
1 "gpc_reg_operand" "r")
3767 (match_operand:GPR
2 "gpc_reg_operand" "r")]))]
3770 [(set_attr "type" "logical")])
3772 (define_insn_and_split "*bool<mode>
3_dot"
3773 [(set (match_operand:CC
4 "cc_reg_operand" "=x,?y")
3774 (compare:CC (match_operator:GPR
3 "boolean_operator"
3775 [(match_operand:GPR
1 "gpc_reg_operand" "r,r")
3776 (match_operand:GPR
2 "gpc_reg_operand" "r,r")])
3778 (clobber (match_scratch:GPR
0 "=r,r"))]
3779 "<MODE>mode == Pmode"
3783 "&& reload_completed && cc_reg_not_cr0_operand (operands[
4], CCmode)"
3787 (compare:CC (match_dup
0)
3790 [(set_attr "type" "logical")
3791 (set_attr "dot" "yes")
3792 (set_attr "length" "
4,
8")])
3794 (define_insn_and_split "*bool<mode>
3_dot2"
3795 [(set (match_operand:CC
4 "cc_reg_operand" "=x,?y")
3796 (compare:CC (match_operator:GPR
3 "boolean_operator"
3797 [(match_operand:GPR
1 "gpc_reg_operand" "r,r")
3798 (match_operand:GPR
2 "gpc_reg_operand" "r,r")])
3800 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3802 "<MODE>mode == Pmode"
3806 "&& reload_completed && cc_reg_not_cr0_operand (operands[
4], CCmode)"
3810 (compare:CC (match_dup
0)
3813 [(set_attr "type" "logical")
3814 (set_attr "dot" "yes")
3815 (set_attr "length" "
4,
8")])
3818 (define_insn "*boolc<mode>
3"
3819 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3820 (match_operator:GPR
3 "boolean_operator"
3821 [(not:GPR (match_operand:GPR
2 "gpc_reg_operand" "r"))
3822 (match_operand:GPR
1 "gpc_reg_operand" "r")]))]
3825 [(set_attr "type" "logical")])
3827 (define_insn_and_split "*boolc<mode>
3_dot"
3828 [(set (match_operand:CC
4 "cc_reg_operand" "=x,?y")
3829 (compare:CC (match_operator:GPR
3 "boolean_operator"
3830 [(not:GPR (match_operand:GPR
2 "gpc_reg_operand" "r,r"))
3831 (match_operand:GPR
1 "gpc_reg_operand" "r,r")])
3833 (clobber (match_scratch:GPR
0 "=r,r"))]
3834 "<MODE>mode == Pmode"
3838 "&& reload_completed && cc_reg_not_cr0_operand (operands[
4], CCmode)"
3842 (compare:CC (match_dup
0)
3845 [(set_attr "type" "logical")
3846 (set_attr "dot" "yes")
3847 (set_attr "length" "
4,
8")])
3849 (define_insn_and_split "*boolc<mode>
3_dot2"
3850 [(set (match_operand:CC
4 "cc_reg_operand" "=x,?y")
3851 (compare:CC (match_operator:GPR
3 "boolean_operator"
3852 [(not:GPR (match_operand:GPR
2 "gpc_reg_operand" "r,r"))
3853 (match_operand:GPR
1 "gpc_reg_operand" "r,r")])
3855 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3857 "<MODE>mode == Pmode"
3861 "&& reload_completed && cc_reg_not_cr0_operand (operands[
4], CCmode)"
3865 (compare:CC (match_dup
0)
3868 [(set_attr "type" "logical")
3869 (set_attr "dot" "yes")
3870 (set_attr "length" "
4,
8")])
3873 (define_insn "*boolcc<mode>
3"
3874 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3875 (match_operator:GPR
3 "boolean_operator"
3876 [(not:GPR (match_operand:GPR
1 "gpc_reg_operand" "r"))
3877 (not:GPR (match_operand:GPR
2 "gpc_reg_operand" "r"))]))]
3880 [(set_attr "type" "logical")])
3882 (define_insn_and_split "*boolcc<mode>
3_dot"
3883 [(set (match_operand:CC
4 "cc_reg_operand" "=x,?y")
3884 (compare:CC (match_operator:GPR
3 "boolean_operator"
3885 [(not:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r"))
3886 (not:GPR (match_operand:GPR
2 "gpc_reg_operand" "r,r"))])
3888 (clobber (match_scratch:GPR
0 "=r,r"))]
3889 "<MODE>mode == Pmode"
3893 "&& reload_completed && cc_reg_not_cr0_operand (operands[
4], CCmode)"
3897 (compare:CC (match_dup
0)
3900 [(set_attr "type" "logical")
3901 (set_attr "dot" "yes")
3902 (set_attr "length" "
4,
8")])
3904 (define_insn_and_split "*boolcc<mode>
3_dot2"
3905 [(set (match_operand:CC
4 "cc_reg_operand" "=x,?y")
3906 (compare:CC (match_operator:GPR
3 "boolean_operator"
3907 [(not:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r"))
3908 (not:GPR (match_operand:GPR
2 "gpc_reg_operand" "r,r"))])
3910 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3912 "<MODE>mode == Pmode"
3916 "&& reload_completed && cc_reg_not_cr0_operand (operands[
4], CCmode)"
3920 (compare:CC (match_dup
0)
3923 [(set_attr "type" "logical")
3924 (set_attr "dot" "yes")
3925 (set_attr "length" "
4,
8")])
3928 ;; TODO: Should have dots of this as well.
3929 (define_insn "*eqv<mode>
3"
3930 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3931 (not:GPR (xor:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
3932 (match_operand:GPR
2 "gpc_reg_operand" "r"))))]
3935 [(set_attr "type" "logical")])
3937 ;; Rotate-and-mask and insert.
3939 (define_insn "*rotl<mode>
3_mask"
3940 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
3941 (and:GPR (match_operator:GPR
4 "rotate_mask_operator"
3942 [(match_operand:GPR
1 "gpc_reg_operand" "r")
3943 (match_operand:SI
2 "reg_or_cint_operand" "rn")])
3944 (match_operand:GPR
3 "const_int_operand" "n")))]
3945 "rs6000_is_valid_shift_mask (operands[
3], operands[
4], <MODE>mode)"
3947 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3949 [(set_attr "type" "shift")
3950 (set_attr "maybe_var_shift" "yes")])
3952 (define_insn_and_split "*rotl<mode>
3_mask_dot"
3953 [(set (match_operand:CC
5 "cc_reg_operand" "=x,?y")
3955 (and:GPR (match_operator:GPR
4 "rotate_mask_operator"
3956 [(match_operand:GPR
1 "gpc_reg_operand" "r,r")
3957 (match_operand:SI
2 "reg_or_cint_operand" "rn,rn")])
3958 (match_operand:GPR
3 "const_int_operand" "n,n"))
3960 (clobber (match_scratch:GPR
0 "=r,r"))]
3961 "(<MODE>mode == Pmode || UINTVAL (operands[
3]) <=
0x7fffffff)
3962 && rs6000_is_valid_shift_mask (operands[
3], operands[
4], <MODE>mode)"
3964 if (which_alternative ==
0)
3965 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3969 "&& reload_completed && cc_reg_not_cr0_operand (operands[
5], CCmode)"
3971 (and:GPR (match_dup
4)
3974 (compare:CC (match_dup
0)
3977 [(set_attr "type" "shift")
3978 (set_attr "maybe_var_shift" "yes")
3979 (set_attr "dot" "yes")
3980 (set_attr "length" "
4,
8")])
3982 (define_insn_and_split "*rotl<mode>
3_mask_dot2"
3983 [(set (match_operand:CC
5 "cc_reg_operand" "=x,?y")
3985 (and:GPR (match_operator:GPR
4 "rotate_mask_operator"
3986 [(match_operand:GPR
1 "gpc_reg_operand" "r,r")
3987 (match_operand:SI
2 "reg_or_cint_operand" "rn,rn")])
3988 (match_operand:GPR
3 "const_int_operand" "n,n"))
3990 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
3991 (and:GPR (match_dup
4)
3993 "(<MODE>mode == Pmode || UINTVAL (operands[
3]) <=
0x7fffffff)
3994 && rs6000_is_valid_shift_mask (operands[
3], operands[
4], <MODE>mode)"
3996 if (which_alternative ==
0)
3997 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
4001 "&& reload_completed && cc_reg_not_cr0_operand (operands[
5], CCmode)"
4003 (and:GPR (match_dup
4)
4006 (compare:CC (match_dup
0)
4009 [(set_attr "type" "shift")
4010 (set_attr "maybe_var_shift" "yes")
4011 (set_attr "dot" "yes")
4012 (set_attr "length" "
4,
8")])
4014 ; Special case for less-than-
0. We can do it with just one machine
4015 ; instruction, but the generic optimizers do not realise it is cheap.
4016 (define_insn "*lt0_<mode>di"
4017 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4018 (lt:GPR (match_operand:DI
1 "gpc_reg_operand" "r")
4022 [(set_attr "type" "shift")])
4024 (define_insn "*lt0_<mode>si"
4025 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4026 (lt:GPR (match_operand:SI
1 "gpc_reg_operand" "r")
4029 "rlwinm %
0,%
1,
1,
31,
31"
4030 [(set_attr "type" "shift")])
4034 ; Two forms for insert (the two arms of the IOR are not canonicalized,
4035 ; both are an AND so are the same precedence).
4036 (define_insn "*rotl<mode>
3_insert"
4037 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4038 (ior:GPR (and:GPR (match_operator:GPR
4 "rotate_mask_operator"
4039 [(match_operand:GPR
1 "gpc_reg_operand" "r")
4040 (match_operand:SI
2 "const_int_operand" "n")])
4041 (match_operand:GPR
3 "const_int_operand" "n"))
4042 (and:GPR (match_operand:GPR
5 "gpc_reg_operand" "
0")
4043 (match_operand:GPR
6 "const_int_operand" "n"))))]
4044 "rs6000_is_valid_insert_mask (operands[
3], operands[
4], <MODE>mode)
4045 && UINTVAL (operands[
3]) + UINTVAL (operands[
6]) +
1 ==
0"
4047 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4049 [(set_attr "type" "insert")])
4050 ; FIXME: this needs an attr "size", so that the scheduler can see the
4051 ; difference between rlwimi and rldimi. We also might want dot forms,
4052 ; but not for rlwimi on POWER4 and similar processors.
4054 (define_insn "*rotl<mode>
3_insert_2"
4055 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4056 (ior:GPR (and:GPR (match_operand:GPR
5 "gpc_reg_operand" "
0")
4057 (match_operand:GPR
6 "const_int_operand" "n"))
4058 (and:GPR (match_operator:GPR
4 "rotate_mask_operator"
4059 [(match_operand:GPR
1 "gpc_reg_operand" "r")
4060 (match_operand:SI
2 "const_int_operand" "n")])
4061 (match_operand:GPR
3 "const_int_operand" "n"))))]
4062 "rs6000_is_valid_insert_mask (operands[
3], operands[
4], <MODE>mode)
4063 && UINTVAL (operands[
3]) + UINTVAL (operands[
6]) +
1 ==
0"
4065 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4067 [(set_attr "type" "insert")])
4069 ; There are also some forms without one of the ANDs.
4070 (define_insn "*rotl<mode>
3_insert_3"
4071 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4072 (ior:GPR (and:GPR (match_operand:GPR
3 "gpc_reg_operand" "
0")
4073 (match_operand:GPR
4 "const_int_operand" "n"))
4074 (ashift:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
4075 (match_operand:SI
2 "const_int_operand" "n"))))]
4076 "INTVAL (operands[
2]) == exact_log2 (UINTVAL (operands[
4]) +
1)"
4078 if (<MODE>mode == SImode)
4079 return "rlwimi %
0,%
1,%h2,
0,
31-%h2";
4081 return "rldimi %
0,%
1,%H2,
0";
4083 [(set_attr "type" "insert")])
4085 (define_insn "*rotl<mode>
3_insert_4"
4086 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4087 (ior:GPR (and:GPR (match_operand:GPR
3 "gpc_reg_operand" "
0")
4088 (match_operand:GPR
4 "const_int_operand" "n"))
4089 (lshiftrt:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
4090 (match_operand:SI
2 "const_int_operand" "n"))))]
4091 "<MODE>mode == SImode &&
4092 GET_MODE_PRECISION (<MODE>mode)
4093 == INTVAL (operands[
2]) + exact_log2 (-UINTVAL (operands[
4]))"
4095 operands[
2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4096 - INTVAL (operands[
2]));
4097 if (<MODE>mode == SImode)
4098 return "rlwimi %
0,%
1,%h2,
32-%h2,
31";
4100 return "rldimi %
0,%
1,%H2,
64-%H2";
4102 [(set_attr "type" "insert")])
4104 (define_insn "*rotlsi3_insert_5"
4105 [(set (match_operand:SI
0 "gpc_reg_operand" "=r,r")
4106 (ior:SI (and:SI (match_operand:SI
1 "gpc_reg_operand" "
0,r")
4107 (match_operand:SI
2 "const_int_operand" "n,n"))
4108 (and:SI (match_operand:SI
3 "gpc_reg_operand" "r,
0")
4109 (match_operand:SI
4 "const_int_operand" "n,n"))))]
4110 "rs6000_is_valid_mask (operands[
2], NULL, NULL, SImode)
4111 && UINTVAL (operands[
2]) !=
0 && UINTVAL (operands[
4]) !=
0
4112 && UINTVAL (operands[
2]) + UINTVAL (operands[
4]) +
1 ==
0"
4116 [(set_attr "type" "insert")])
4118 (define_insn "*rotldi3_insert_6"
4119 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
4120 (ior:DI (and:DI (match_operand:DI
1 "gpc_reg_operand" "
0")
4121 (match_operand:DI
2 "const_int_operand" "n"))
4122 (and:DI (match_operand:DI
3 "gpc_reg_operand" "r")
4123 (match_operand:DI
4 "const_int_operand" "n"))))]
4124 "exact_log2 (-UINTVAL (operands[
2])) >
0
4125 && UINTVAL (operands[
2]) + UINTVAL (operands[
4]) +
1 ==
0"
4127 operands[
5] = GEN_INT (
64 - exact_log2 (-UINTVAL (operands[
2])));
4128 return "rldimi %
0,%
3,
0,%
5";
4130 [(set_attr "type" "insert")
4131 (set_attr "size" "
64")])
4133 (define_insn "*rotldi3_insert_7"
4134 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
4135 (ior:DI (and:DI (match_operand:DI
3 "gpc_reg_operand" "r")
4136 (match_operand:DI
4 "const_int_operand" "n"))
4137 (and:DI (match_operand:DI
1 "gpc_reg_operand" "
0")
4138 (match_operand:DI
2 "const_int_operand" "n"))))]
4139 "exact_log2 (-UINTVAL (operands[
2])) >
0
4140 && UINTVAL (operands[
2]) + UINTVAL (operands[
4]) +
1 ==
0"
4142 operands[
5] = GEN_INT (
64 - exact_log2 (-UINTVAL (operands[
2])));
4143 return "rldimi %
0,%
3,
0,%
5";
4145 [(set_attr "type" "insert")
4146 (set_attr "size" "
64")])
4149 ; This handles the important case of multiple-precision shifts. There is
4150 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4152 [(set (match_operand:GPR
0 "gpc_reg_operand")
4153 (ior:GPR (ashift:GPR (match_operand:GPR
1 "gpc_reg_operand")
4154 (match_operand:SI
3 "const_int_operand"))
4155 (lshiftrt:GPR (match_operand:GPR
2 "gpc_reg_operand")
4156 (match_operand:SI
4 "const_int_operand"))))]
4157 "can_create_pseudo_p ()
4158 && INTVAL (operands[
3]) + INTVAL (operands[
4])
4159 >= GET_MODE_PRECISION (<MODE>mode)"
4161 (lshiftrt:GPR (match_dup
2)
4164 (ior:GPR (and:GPR (match_dup
5)
4166 (ashift:GPR (match_dup
1)
4169 unsigned HOST_WIDE_INT mask =
1;
4170 mask = (mask << INTVAL (operands[
3])) -
1;
4171 operands[
5] = gen_reg_rtx (<MODE>mode);
4172 operands[
6] = GEN_INT (mask);
4176 [(set (match_operand:GPR
0 "gpc_reg_operand")
4177 (ior:GPR (lshiftrt:GPR (match_operand:GPR
2 "gpc_reg_operand")
4178 (match_operand:SI
4 "const_int_operand"))
4179 (ashift:GPR (match_operand:GPR
1 "gpc_reg_operand")
4180 (match_operand:SI
3 "const_int_operand"))))]
4181 "can_create_pseudo_p ()
4182 && INTVAL (operands[
3]) + INTVAL (operands[
4])
4183 >= GET_MODE_PRECISION (<MODE>mode)"
4185 (lshiftrt:GPR (match_dup
2)
4188 (ior:GPR (and:GPR (match_dup
5)
4190 (ashift:GPR (match_dup
1)
4193 unsigned HOST_WIDE_INT mask =
1;
4194 mask = (mask << INTVAL (operands[
3])) -
1;
4195 operands[
5] = gen_reg_rtx (<MODE>mode);
4196 operands[
6] = GEN_INT (mask);
4200 ; Another important case is setting some bits to
1; we can do that with
4201 ; an insert instruction, in many cases.
4202 (define_insn_and_split "*ior<mode>_mask"
4203 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4204 (ior:GPR (match_operand:GPR
1 "gpc_reg_operand" "
0")
4205 (match_operand:GPR
2 "const_int_operand" "n")))
4206 (clobber (match_scratch:GPR
3 "=r"))]
4207 "!logical_const_operand (operands[
2], <MODE>mode)
4208 && rs6000_is_valid_mask (operands[
2], NULL, NULL, <MODE>mode)"
4214 (ior:GPR (and:GPR (rotate:GPR (match_dup
3)
4217 (and:GPR (match_dup
1)
4221 rs6000_is_valid_mask (operands[
2], &nb, &ne, <MODE>mode);
4222 if (GET_CODE (operands[
3]) == SCRATCH)
4223 operands[
3] = gen_reg_rtx (<MODE>mode);
4224 operands[
4] = GEN_INT (ne);
4225 operands[
5] = GEN_INT (~UINTVAL (operands[
2]));
4227 [(set_attr "type" "two")
4228 (set_attr "length" "
8")])
4231 ; Yet another case is an rldimi with the second value coming from memory.
4232 ; The zero_extend that should become part of the rldimi is merged into the
4233 ; load from memory instead. Split things properly again.
4235 [(set (match_operand:DI
0 "gpc_reg_operand")
4236 (ior:DI (ashift:DI (match_operand:DI
1 "gpc_reg_operand")
4237 (match_operand:SI
2 "const_int_operand"))
4238 (zero_extend:DI (match_operand:QHSI
3 "memory_operand"))))]
4239 "INTVAL (operands[
2]) == <bits>"
4241 (zero_extend:DI (match_dup
3)))
4243 (ior:DI (and:DI (match_dup
4)
4245 (ashift:DI (match_dup
1)
4248 operands[
4] = gen_reg_rtx (DImode);
4249 operands[
5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) -
1);
4252 ; rldimi with UNSPEC_SI_FROM_SF.
4253 (define_insn_and_split "*rotldi3_insert_sf"
4254 [(set (match_operand:DI
0 "gpc_reg_operand")
4256 (ashift:DI (match_operand:DI
1 "gpc_reg_operand")
4257 (match_operand:SI
2 "const_int_operand"))
4260 [(match_operand:SF
3 "memory_operand")]
4261 UNSPEC_SI_FROM_SF))))
4262 (clobber (match_scratch:V4SF
4))]
4263 "TARGET_POWERPC64 && INTVAL (operands[
2]) == <bits>"
4266 [(parallel [(set (match_dup
5)
4267 (zero_extend:DI (unspec:QHSI [(match_dup
3)] UNSPEC_SI_FROM_SF)))
4268 (clobber (match_dup
4))])
4271 (and:DI (match_dup
5) (match_dup
6))
4272 (ashift:DI (match_dup
1) (match_dup
2))))]
4274 operands[
5] = gen_reg_rtx (DImode);
4275 operands[
6] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) -
1);
4280 [(set (match_operand:SI
0 "gpc_reg_operand")
4281 (ior:SI (ashift:SI (match_operand:SI
1 "gpc_reg_operand")
4282 (match_operand:SI
2 "const_int_operand"))
4283 (zero_extend:SI (match_operand:QHI
3 "memory_operand"))))]
4284 "INTVAL (operands[
2]) == <bits>"
4286 (zero_extend:SI (match_dup
3)))
4288 (ior:SI (and:SI (match_dup
4)
4290 (ashift:SI (match_dup
1)
4293 operands[
4] = gen_reg_rtx (SImode);
4294 operands[
5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) -
1);
4298 ;; Now the simple shifts.
4300 (define_insn "rotl<mode>
3"
4301 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4302 (rotate:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
4303 (match_operand:SI
2 "reg_or_cint_operand" "rn")))]
4305 "rotl<wd>%I2 %
0,%
1,%<hH>
2"
4306 [(set_attr "type" "shift")
4307 (set_attr "maybe_var_shift" "yes")])
4309 (define_insn "*rotlsi3_64"
4310 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
4312 (rotate:SI (match_operand:SI
1 "gpc_reg_operand" "r")
4313 (match_operand:SI
2 "reg_or_cint_operand" "rn"))))]
4315 "rotlw%I2 %
0,%
1,%h2"
4316 [(set_attr "type" "shift")
4317 (set_attr "maybe_var_shift" "yes")])
4319 (define_insn_and_split "*rotl<mode>
3_dot"
4320 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
4321 (compare:CC (rotate:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
4322 (match_operand:SI
2 "reg_or_cint_operand" "rn,rn"))
4324 (clobber (match_scratch:GPR
0 "=r,r"))]
4325 "<MODE>mode == Pmode"
4327 rotl<wd>%I2. %
0,%
1,%<hH>
2
4329 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
4331 (rotate:GPR (match_dup
1)
4334 (compare:CC (match_dup
0)
4337 [(set_attr "type" "shift")
4338 (set_attr "maybe_var_shift" "yes")
4339 (set_attr "dot" "yes")
4340 (set_attr "length" "
4,
8")])
4342 (define_insn_and_split "*rotl<mode>
3_dot2"
4343 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
4344 (compare:CC (rotate:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
4345 (match_operand:SI
2 "reg_or_cint_operand" "rn,rn"))
4347 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
4348 (rotate:GPR (match_dup
1)
4350 "<MODE>mode == Pmode"
4352 rotl<wd>%I2. %
0,%
1,%<hH>
2
4354 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
4356 (rotate:GPR (match_dup
1)
4359 (compare:CC (match_dup
0)
4362 [(set_attr "type" "shift")
4363 (set_attr "maybe_var_shift" "yes")
4364 (set_attr "dot" "yes")
4365 (set_attr "length" "
4,
8")])
4368 (define_insn "ashl<mode>
3"
4369 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4370 (ashift:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
4371 (match_operand:SI
2 "reg_or_cint_operand" "rn")))]
4373 "sl<wd>%I2 %
0,%
1,%<hH>
2"
4374 [(set_attr "type" "shift")
4375 (set_attr "maybe_var_shift" "yes")])
4377 (define_insn "*ashlsi3_64"
4378 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
4380 (ashift:SI (match_operand:SI
1 "gpc_reg_operand" "r")
4381 (match_operand:SI
2 "reg_or_cint_operand" "rn"))))]
4384 [(set_attr "type" "shift")
4385 (set_attr "maybe_var_shift" "yes")])
4387 (define_insn_and_split "*ashl<mode>
3_dot"
4388 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
4389 (compare:CC (ashift:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
4390 (match_operand:SI
2 "reg_or_cint_operand" "rn,rn"))
4392 (clobber (match_scratch:GPR
0 "=r,r"))]
4393 "<MODE>mode == Pmode"
4395 sl<wd>%I2. %
0,%
1,%<hH>
2
4397 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
4399 (ashift:GPR (match_dup
1)
4402 (compare:CC (match_dup
0)
4405 [(set_attr "type" "shift")
4406 (set_attr "maybe_var_shift" "yes")
4407 (set_attr "dot" "yes")
4408 (set_attr "length" "
4,
8")])
4410 (define_insn_and_split "*ashl<mode>
3_dot2"
4411 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
4412 (compare:CC (ashift:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
4413 (match_operand:SI
2 "reg_or_cint_operand" "rn,rn"))
4415 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
4416 (ashift:GPR (match_dup
1)
4418 "<MODE>mode == Pmode"
4420 sl<wd>%I2. %
0,%
1,%<hH>
2
4422 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
4424 (ashift:GPR (match_dup
1)
4427 (compare:CC (match_dup
0)
4430 [(set_attr "type" "shift")
4431 (set_attr "maybe_var_shift" "yes")
4432 (set_attr "dot" "yes")
4433 (set_attr "length" "
4,
8")])
4435 ;; Pretend we have a memory form of extswsli until register allocation is done
4436 ;; so that we use LWZ to load the value from memory, instead of LWA.
4437 (define_insn_and_split "ashdi3_extswsli"
4438 [(set (match_operand:DI
0 "gpc_reg_operand" "=r,r")
4440 (sign_extend:DI (match_operand:SI
1 "reg_or_mem_operand" "r,m"))
4441 (match_operand:DI
2 "u6bit_cint_operand" "n,n")))]
4446 "&& reload_completed && MEM_P (operands[
1])"
4450 (ashift:DI (sign_extend:DI (match_dup
3))
4453 operands[
3] = gen_lowpart (SImode, operands[
0]);
4455 [(set_attr "type" "shift")
4456 (set_attr "maybe_var_shift" "no")])
4459 (define_insn_and_split "ashdi3_extswsli_dot"
4460 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y,?x,??y")
4463 (sign_extend:DI (match_operand:SI
1 "reg_or_mem_operand" "r,r,m,m"))
4464 (match_operand:DI
2 "u6bit_cint_operand" "n,n,n,n"))
4466 (clobber (match_scratch:DI
0 "=r,r,r,r"))]
4473 "&& reload_completed
4474 && (cc_reg_not_cr0_operand (operands[
3], CCmode)
4475 || memory_operand (operands[
1], SImode))"
4478 rtx dest = operands[
0];
4479 rtx src = operands[
1];
4480 rtx shift = operands[
2];
4481 rtx cr = operands[
3];
4488 src2 = gen_lowpart (SImode, dest);
4489 emit_move_insn (src2, src);
4492 if (REGNO (cr) == CR0_REGNO)
4494 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4498 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4499 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4502 [(set_attr "type" "shift")
4503 (set_attr "maybe_var_shift" "no")
4504 (set_attr "dot" "yes")
4505 (set_attr "length" "
4,
8,
8,
12")])
4507 (define_insn_and_split "ashdi3_extswsli_dot2"
4508 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y,?x,??y")
4511 (sign_extend:DI (match_operand:SI
1 "reg_or_mem_operand" "r,r,m,m"))
4512 (match_operand:DI
2 "u6bit_cint_operand" "n,n,n,n"))
4514 (set (match_operand:DI
0 "gpc_reg_operand" "=r,r,r,r")
4515 (ashift:DI (sign_extend:DI (match_dup
1))
4523 "&& reload_completed
4524 && (cc_reg_not_cr0_operand (operands[
3], CCmode)
4525 || memory_operand (operands[
1], SImode))"
4528 rtx dest = operands[
0];
4529 rtx src = operands[
1];
4530 rtx shift = operands[
2];
4531 rtx cr = operands[
3];
4538 src2 = gen_lowpart (SImode, dest);
4539 emit_move_insn (src2, src);
4542 if (REGNO (cr) == CR0_REGNO)
4544 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4548 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4549 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4552 [(set_attr "type" "shift")
4553 (set_attr "maybe_var_shift" "no")
4554 (set_attr "dot" "yes")
4555 (set_attr "length" "
4,
8,
8,
12")])
4557 (define_insn "lshr<mode>
3"
4558 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4559 (lshiftrt:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
4560 (match_operand:SI
2 "reg_or_cint_operand" "rn")))]
4562 "sr<wd>%I2 %
0,%
1,%<hH>
2"
4563 [(set_attr "type" "shift")
4564 (set_attr "maybe_var_shift" "yes")])
4566 (define_insn "*lshrsi3_64"
4567 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
4569 (lshiftrt:SI (match_operand:SI
1 "gpc_reg_operand" "r")
4570 (match_operand:SI
2 "reg_or_cint_operand" "rn"))))]
4573 [(set_attr "type" "shift")
4574 (set_attr "maybe_var_shift" "yes")])
4576 (define_insn_and_split "*lshr<mode>
3_dot"
4577 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
4578 (compare:CC (lshiftrt:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
4579 (match_operand:SI
2 "reg_or_cint_operand" "rn,rn"))
4581 (clobber (match_scratch:GPR
0 "=r,r"))]
4582 "<MODE>mode == Pmode"
4584 sr<wd>%I2. %
0,%
1,%<hH>
2
4586 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
4588 (lshiftrt:GPR (match_dup
1)
4591 (compare:CC (match_dup
0)
4594 [(set_attr "type" "shift")
4595 (set_attr "maybe_var_shift" "yes")
4596 (set_attr "dot" "yes")
4597 (set_attr "length" "
4,
8")])
4599 (define_insn_and_split "*lshr<mode>
3_dot2"
4600 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
4601 (compare:CC (lshiftrt:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
4602 (match_operand:SI
2 "reg_or_cint_operand" "rn,rn"))
4604 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
4605 (lshiftrt:GPR (match_dup
1)
4607 "<MODE>mode == Pmode"
4609 sr<wd>%I2. %
0,%
1,%<hH>
2
4611 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
4613 (lshiftrt:GPR (match_dup
1)
4616 (compare:CC (match_dup
0)
4619 [(set_attr "type" "shift")
4620 (set_attr "maybe_var_shift" "yes")
4621 (set_attr "dot" "yes")
4622 (set_attr "length" "
4,
8")])
4625 (define_insn "ashr<mode>
3"
4626 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
4627 (ashiftrt:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
4628 (match_operand:SI
2 "reg_or_cint_operand" "rn")))
4629 (clobber (reg:GPR CA_REGNO))]
4631 "sra<wd>%I2 %
0,%
1,%<hH>
2"
4632 [(set_attr "type" "shift")
4633 (set_attr "maybe_var_shift" "yes")])
4635 (define_insn "*ashrsi3_64"
4636 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
4638 (ashiftrt:SI (match_operand:SI
1 "gpc_reg_operand" "r")
4639 (match_operand:SI
2 "reg_or_cint_operand" "rn"))))
4640 (clobber (reg:SI CA_REGNO))]
4643 [(set_attr "type" "shift")
4644 (set_attr "maybe_var_shift" "yes")])
4646 (define_insn_and_split "*ashr<mode>
3_dot"
4647 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
4648 (compare:CC (ashiftrt:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
4649 (match_operand:SI
2 "reg_or_cint_operand" "rn,rn"))
4651 (clobber (match_scratch:GPR
0 "=r,r"))
4652 (clobber (reg:GPR CA_REGNO))]
4653 "<MODE>mode == Pmode"
4655 sra<wd>%I2. %
0,%
1,%<hH>
2
4657 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
4658 [(parallel [(set (match_dup
0)
4659 (ashiftrt:GPR (match_dup
1)
4661 (clobber (reg:GPR CA_REGNO))])
4663 (compare:CC (match_dup
0)
4666 [(set_attr "type" "shift")
4667 (set_attr "maybe_var_shift" "yes")
4668 (set_attr "dot" "yes")
4669 (set_attr "length" "
4,
8")])
4671 (define_insn_and_split "*ashr<mode>
3_dot2"
4672 [(set (match_operand:CC
3 "cc_reg_operand" "=x,?y")
4673 (compare:CC (ashiftrt:GPR (match_operand:GPR
1 "gpc_reg_operand" "r,r")
4674 (match_operand:SI
2 "reg_or_cint_operand" "rn,rn"))
4676 (set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
4677 (ashiftrt:GPR (match_dup
1)
4679 (clobber (reg:GPR CA_REGNO))]
4680 "<MODE>mode == Pmode"
4682 sra<wd>%I2. %
0,%
1,%<hH>
2
4684 "&& reload_completed && cc_reg_not_cr0_operand (operands[
3], CCmode)"
4685 [(parallel [(set (match_dup
0)
4686 (ashiftrt:GPR (match_dup
1)
4688 (clobber (reg:GPR CA_REGNO))])
4690 (compare:CC (match_dup
0)
4693 [(set_attr "type" "shift")
4694 (set_attr "maybe_var_shift" "yes")
4695 (set_attr "dot" "yes")
4696 (set_attr "length" "
4,
8")])
4698 ;; Builtins to replace a division to generate FRE reciprocal estimate
4699 ;; instructions and the necessary fixup instructions
4700 (define_expand "recip<mode>
3"
4701 [(match_operand:RECIPF
0 "gpc_reg_operand")
4702 (match_operand:RECIPF
1 "gpc_reg_operand")
4703 (match_operand:RECIPF
2 "gpc_reg_operand")]
4704 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4706 rs6000_emit_swdiv (operands[
0], operands[
1], operands[
2], false);
4710 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4711 ;; hardware division. This is only done before register allocation and with
4712 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4713 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4714 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4716 [(set (match_operand:RECIPF
0 "gpc_reg_operand")
4717 (div:RECIPF (match_operand
1 "gpc_reg_operand")
4718 (match_operand
2 "gpc_reg_operand")))]
4719 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4720 && can_create_pseudo_p () && flag_finite_math_only
4721 && !flag_trapping_math && flag_reciprocal_math"
4724 rs6000_emit_swdiv (operands[
0], operands[
1], operands[
2], true);
4728 ;; Builtins to replace
1/sqrt(x) with instructions using RSQRTE and the
4729 ;; appropriate fixup.
4730 (define_expand "rsqrt<mode>
2"
4731 [(match_operand:RECIPF
0 "gpc_reg_operand")
4732 (match_operand:RECIPF
1 "gpc_reg_operand")]
4733 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4735 rs6000_emit_swsqrt (operands[
0], operands[
1],
1);
4739 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4740 ;; modes here, and also add in conditional vsx/power8-vector support to access
4741 ;; values in the traditional Altivec registers if the appropriate
4742 ;; -mupper-regs-{df,sf} option is enabled.
4744 (define_expand "abs<mode>
2"
4745 [(set (match_operand:SFDF
0 "gpc_reg_operand")
4746 (abs:SFDF (match_operand:SFDF
1 "gpc_reg_operand")))]
4750 (define_insn "*abs<mode>
2_fpr"
4751 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,<Fv>")
4752 (abs:SFDF (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4757 [(set_attr "type" "fpsimple")])
4759 (define_insn "*nabs<mode>
2_fpr"
4760 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,<Fv>")
4763 (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4768 [(set_attr "type" "fpsimple")])
4770 (define_expand "neg<mode>
2"
4771 [(set (match_operand:SFDF
0 "gpc_reg_operand")
4772 (neg:SFDF (match_operand:SFDF
1 "gpc_reg_operand")))]
4776 (define_insn "*neg<mode>
2_fpr"
4777 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,<Fv>")
4778 (neg:SFDF (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4783 [(set_attr "type" "fpsimple")])
4785 (define_expand "add<mode>
3"
4786 [(set (match_operand:SFDF
0 "gpc_reg_operand")
4787 (plus:SFDF (match_operand:SFDF
1 "gpc_reg_operand")
4788 (match_operand:SFDF
2 "gpc_reg_operand")))]
4792 (define_insn "*add<mode>
3_fpr"
4793 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa")
4794 (plus:SFDF (match_operand:SFDF
1 "gpc_reg_operand" "%<Ff>,wa")
4795 (match_operand:SFDF
2 "gpc_reg_operand" "<Ff>,wa")))]
4799 xsadd<sd>p %x0,%x1,%x2"
4800 [(set_attr "type" "fp")
4801 (set_attr "isa" "*,<Fisa>")])
4803 (define_expand "sub<mode>
3"
4804 [(set (match_operand:SFDF
0 "gpc_reg_operand")
4805 (minus:SFDF (match_operand:SFDF
1 "gpc_reg_operand")
4806 (match_operand:SFDF
2 "gpc_reg_operand")))]
4810 (define_insn "*sub<mode>
3_fpr"
4811 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa")
4812 (minus:SFDF (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,wa")
4813 (match_operand:SFDF
2 "gpc_reg_operand" "<Ff>,wa")))]
4817 xssub<sd>p %x0,%x1,%x2"
4818 [(set_attr "type" "fp")
4819 (set_attr "isa" "*,<Fisa>")])
4821 (define_expand "mul<mode>
3"
4822 [(set (match_operand:SFDF
0 "gpc_reg_operand")
4823 (mult:SFDF (match_operand:SFDF
1 "gpc_reg_operand")
4824 (match_operand:SFDF
2 "gpc_reg_operand")))]
4828 (define_insn "*mul<mode>
3_fpr"
4829 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa")
4830 (mult:SFDF (match_operand:SFDF
1 "gpc_reg_operand" "%<Ff>,wa")
4831 (match_operand:SFDF
2 "gpc_reg_operand" "<Ff>,wa")))]
4835 xsmul<sd>p %x0,%x1,%x2"
4836 [(set_attr "type" "dmul")
4837 (set_attr "isa" "*,<Fisa>")])
4839 (define_expand "div<mode>
3"
4840 [(set (match_operand:SFDF
0 "gpc_reg_operand")
4841 (div:SFDF (match_operand:SFDF
1 "gpc_reg_operand")
4842 (match_operand:SFDF
2 "gpc_reg_operand")))]
4845 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4846 && can_create_pseudo_p () && flag_finite_math_only
4847 && !flag_trapping_math && flag_reciprocal_math)
4849 rs6000_emit_swdiv (operands[
0], operands[
1], operands[
2], true);
4854 (define_insn "*div<mode>
3_fpr"
4855 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa")
4856 (div:SFDF (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,wa")
4857 (match_operand:SFDF
2 "gpc_reg_operand" "<Ff>,wa")))]
4861 xsdiv<sd>p %x0,%x1,%x2"
4862 [(set_attr "type" "<sd>div")
4863 (set_attr "isa" "*,<Fisa>")])
4865 (define_insn "*sqrt<mode>
2_internal"
4866 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa")
4867 (sqrt:SFDF (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,wa")))]
4868 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4871 xssqrt<sd>p %x0,%x1"
4872 [(set_attr "type" "<sd>sqrt")
4873 (set_attr "isa" "*,<Fisa>")])
4875 (define_expand "sqrt<mode>
2"
4876 [(set (match_operand:SFDF
0 "gpc_reg_operand")
4877 (sqrt:SFDF (match_operand:SFDF
1 "gpc_reg_operand")))]
4878 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4880 if (<MODE>mode == SFmode
4881 && TARGET_RECIP_PRECISION
4882 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4883 && !optimize_function_for_size_p (cfun)
4884 && flag_finite_math_only && !flag_trapping_math
4885 && flag_unsafe_math_optimizations)
4887 rs6000_emit_swsqrt (operands[
0], operands[
1],
0);
4892 ;; Floating point reciprocal approximation
4893 (define_insn "fre<sd>"
4894 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa")
4895 (unspec:SFDF [(match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,wa")]
4901 [(set_attr "type" "fp")
4902 (set_attr "isa" "*,<Fisa>")])
4904 (define_insn "*rsqrt<mode>
2"
4905 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa")
4906 (unspec:SFDF [(match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,wa")]
4908 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4911 xsrsqrte<sd>p %x0,%x1"
4912 [(set_attr "type" "fp")
4913 (set_attr "isa" "*,<Fisa>")])
4915 ;; Floating point comparisons
4916 (define_insn "*cmp<mode>_fpr"
4917 [(set (match_operand:CCFP
0 "cc_reg_operand" "=y,y")
4918 (compare:CCFP (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,wa")
4919 (match_operand:SFDF
2 "gpc_reg_operand" "<Ff>,wa")))]
4923 xscmpudp %
0,%x1,%x2"
4924 [(set_attr "type" "fpcompare")
4925 (set_attr "isa" "*,<Fisa>")])
4927 ;; Floating point conversions
4928 (define_expand "extendsfdf2"
4929 [(set (match_operand:DF
0 "gpc_reg_operand")
4930 (float_extend:DF (match_operand:SF
1 "reg_or_mem_operand")))]
4933 if (HONOR_SNANS (SFmode))
4934 operands[
1] = force_reg (SFmode, operands[
1]);
4937 (define_insn_and_split "*extendsfdf2_fpr"
4938 [(set (match_operand:DF
0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4939 (float_extend:DF (match_operand:SF
1 "reg_or_mem_operand" "
0,f,m,
0,wa,Z,wY")))]
4940 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4946 xscpsgndp %x0,%x1,%x1
4949 "&& reload_completed && REG_P (operands[
1]) && REGNO (operands[
0]) == REGNO (operands[
1])"
4952 emit_note (NOTE_INSN_DELETED);
4955 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4956 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4958 (define_insn "*extendsfdf2_snan"
4959 [(set (match_operand:DF
0 "gpc_reg_operand" "=d,wa")
4960 (float_extend:DF (match_operand:SF
1 "gpc_reg_operand" "f,wa")))]
4961 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4965 [(set_attr "type" "fp")
4966 (set_attr "isa" "*,p8v")])
4968 (define_expand "truncdfsf2"
4969 [(set (match_operand:SF
0 "gpc_reg_operand")
4970 (float_truncate:SF (match_operand:DF
1 "gpc_reg_operand")))]
4974 (define_insn "*truncdfsf2_fpr"
4975 [(set (match_operand:SF
0 "gpc_reg_operand" "=f,wa")
4976 (float_truncate:SF (match_operand:DF
1 "gpc_reg_operand" "d,wa")))]
4981 [(set_attr "type" "fp")
4982 (set_attr "isa" "*,p8v")])
4984 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4985 ;; builtins.c and optabs.c that are not correct for IBM long double
4986 ;; when little-endian.
4987 (define_expand "signbit<mode>
2"
4989 (float_truncate:DF (match_operand:FLOAT128
1 "gpc_reg_operand")))
4991 (subreg:DI (match_dup
2)
0))
4994 (set (match_operand:SI
0 "gpc_reg_operand")
4997 && (!FLOAT128_IEEE_P (<MODE>mode)
4998 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
5000 if (FLOAT128_IEEE_P (<MODE>mode))
5002 rtx dest = operands[
0];
5003 rtx src = operands[
1];
5004 rtx tmp = gen_reg_rtx (DImode);
5005 rtx dest_di = gen_lowpart (DImode, dest);
5007 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
5008 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (
63)));
5011 operands[
2] = gen_reg_rtx (DFmode);
5012 operands[
3] = gen_reg_rtx (DImode);
5013 if (TARGET_POWERPC64)
5015 operands[
4] = gen_reg_rtx (DImode);
5016 operands[
5] = gen_rtx_LSHIFTRT (DImode, operands[
3], GEN_INT (
63));
5017 operands[
6] = gen_rtx_SUBREG (SImode, operands[
4],
5018 WORDS_BIG_ENDIAN ?
4 :
0);
5022 operands[
4] = gen_reg_rtx (SImode);
5023 operands[
5] = gen_rtx_SUBREG (SImode, operands[
3],
5024 WORDS_BIG_ENDIAN ?
0 :
4);
5025 operands[
6] = gen_rtx_LSHIFTRT (SImode, operands[
4], GEN_INT (
31));
5029 ;; Optimize IEEE
128-bit signbit on
64-bit systems with direct move to avoid
5030 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
5031 ;; register allocator would typically move the entire _Float128 item to GPRs (
2
5032 ;; instructions on ISA
3.0,
3-
4 instructions on ISA
2.07).
5034 ;; After register allocation, if the _Float128 had originally been in GPRs, the
5035 ;; split allows the post reload phases to eliminate the move, and do the shift
5036 ;; directly with the register that contains the signbit.
5037 (define_insn_and_split "@signbit<mode>
2_dm"
5038 [(set (match_operand:DI
0 "gpc_reg_operand" "=r,r")
5039 (unspec:DI [(match_operand:SIGNBIT
1 "gpc_reg_operand" "wa,r")]
5041 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5045 "&& reload_completed && int_reg_operand (operands[
1], <MODE>mode)"
5049 operands[
2] = gen_highpart (DImode, operands[
1]);
5051 [(set_attr "type" "mftgpr,*")])
5053 ;; Optimize IEEE
128-bit signbit on to avoid loading the value into a vector
5054 ;; register and then doing a direct move if the value comes from memory. On
5055 ;; little endian, we have to load the
2nd double-word to get the sign bit.
5056 (define_insn_and_split "*signbit<mode>
2_dm_mem"
5057 [(set (match_operand:DI
0 "gpc_reg_operand" "=b")
5058 (unspec:DI [(match_operand:SIGNBIT
1 "memory_operand" "m")]
5060 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5066 rtx dest = operands[
0];
5067 rtx src = operands[
1];
5068 rtx addr = XEXP (src,
0);
5070 if (WORDS_BIG_ENDIAN)
5071 operands[
2] = adjust_address (src, DImode,
0);
5073 else if (REG_P (addr) || SUBREG_P (addr))
5074 operands[
2] = adjust_address (src, DImode,
8);
5076 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr,
0))
5077 && CONST_INT_P (XEXP (addr,
1)) && mem_operand_gpr (src, DImode))
5078 operands[
2] = adjust_address (src, DImode,
8);
5082 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
5083 emit_insn (gen_rtx_SET (tmp, addr));
5084 operands[
2] = change_address (src, DImode,
5085 gen_rtx_PLUS (DImode, tmp, GEN_INT (
8)));
5089 (define_expand "copysign<mode>
3"
5091 (abs:SFDF (match_operand:SFDF
1 "gpc_reg_operand")))
5093 (neg:SFDF (abs:SFDF (match_dup
1))))
5094 (set (match_operand:SFDF
0 "gpc_reg_operand")
5095 (if_then_else:SFDF (ge (match_operand:SFDF
2 "gpc_reg_operand")
5100 && ((TARGET_PPC_GFXOPT
5101 && !HONOR_NANS (<MODE>mode)
5102 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5104 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5106 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5108 emit_insn (gen_copysign<mode>
3_fcpsgn (operands[
0], operands[
1],
5113 operands[
3] = gen_reg_rtx (<MODE>mode);
5114 operands[
4] = gen_reg_rtx (<MODE>mode);
5115 operands[
5] = CONST0_RTX (<MODE>mode);
5118 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5119 ;; compiler from optimizing -
0.0
5120 (define_insn "copysign<mode>
3_fcpsgn"
5121 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,<Fv>")
5122 (unspec:SFDF [(match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>")
5123 (match_operand:SFDF
2 "gpc_reg_operand" "<Ff>,<Fv>")]
5125 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5128 xscpsgndp %x0,%x2,%x1"
5129 [(set_attr "type" "fpsimple")])
5131 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5132 ;; fsel instruction and some auxiliary computations. Then we just have a
5133 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5135 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5136 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5137 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5138 ;; define_splits to make them if made by combine. On VSX machines we have the
5139 ;; min/max instructions.
5141 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5142 ;; to allow either DF/SF to use only traditional registers.
5144 (define_expand "s<minmax><mode>
3"
5145 [(set (match_operand:SFDF
0 "gpc_reg_operand")
5146 (fp_minmax:SFDF (match_operand:SFDF
1 "gpc_reg_operand")
5147 (match_operand:SFDF
2 "gpc_reg_operand")))]
5150 rs6000_emit_minmax (operands[
0], <SMINMAX>, operands[
1], operands[
2]);
5154 (define_insn "*s<minmax><mode>
3_vsx"
5155 [(set (match_operand:SFDF
0 "vsx_register_operand" "=<Fv>")
5156 (fp_minmax:SFDF (match_operand:SFDF
1 "vsx_register_operand" "<Fv>")
5157 (match_operand:SFDF
2 "vsx_register_operand" "<Fv>")))]
5158 "TARGET_VSX && TARGET_HARD_FLOAT"
5160 return (TARGET_P9_MINMAX
5161 ? "xs<minmax>cdp %x0,%x1,%x2"
5162 : "xs<minmax>dp %x0,%x1,%x2");
5164 [(set_attr "type" "fp")])
5166 ;; The conditional move instructions allow us to perform max and min operations
5167 ;; even when we don't have the appropriate max/min instruction using the FSEL
5170 (define_insn_and_split "*s<minmax><mode>
3_fpr"
5171 [(set (match_operand:SFDF
0 "gpc_reg_operand")
5172 (fp_minmax:SFDF (match_operand:SFDF
1 "gpc_reg_operand")
5173 (match_operand:SFDF
2 "gpc_reg_operand")))]
5174 "!TARGET_VSX && TARGET_MINMAX"
5179 rs6000_emit_minmax (operands[
0], <SMINMAX>, operands[
1], operands[
2]);
5183 (define_expand "mov<mode>cc"
5184 [(set (match_operand:GPR
0 "gpc_reg_operand")
5185 (if_then_else:GPR (match_operand
1 "comparison_operator")
5186 (match_operand:GPR
2 "gpc_reg_operand")
5187 (match_operand:GPR
3 "gpc_reg_operand")))]
5190 if (rs6000_emit_cmove (operands[
0], operands[
1], operands[
2], operands[
3]))
5196 ;; We use the BASE_REGS for the isel input operands because, if rA is
5197 ;;
0, the value of
0 is placed in rD upon truth. Similarly for rB
5198 ;; because we may switch the operands and rB may end up being rA.
5200 ;; We need
2 patterns: an unsigned and a signed pattern. We could
5201 ;; leave out the mode in operand
4 and use one pattern, but reload can
5202 ;; change the mode underneath our feet and then gets confused trying
5203 ;; to reload the value.
5204 (define_mode_iterator CCEITHER [CC CCUNS])
5205 (define_mode_attr un [(CC "") (CCUNS "un")])
5206 (define_insn "isel_<un>signed_<GPR:mode>"
5207 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
5209 (match_operator
1 "scc_comparison_operator"
5210 [(match_operand:CCEITHER
4 "cc_reg_operand" "y,y")
5212 (match_operand:GPR
2 "reg_or_zero_operand" "O,b")
5213 (match_operand:GPR
3 "gpc_reg_operand" "r,r")))]
5216 [(set_attr "type" "isel")])
5218 ;; These patterns can be useful for combine; they let combine know that
5219 ;; isel can handle reversed comparisons so long as the operands are
5222 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5223 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r,r")
5225 (match_operator
1 "scc_rev_comparison_operator"
5226 [(match_operand:CCEITHER
4 "cc_reg_operand" "y,y")
5228 (match_operand:GPR
2 "gpc_reg_operand" "r,r")
5229 (match_operand:GPR
3 "reg_or_zero_operand" "O,b")))]
5232 PUT_CODE (operands[
1], reverse_condition (GET_CODE (operands[
1])));
5233 return "isel %
0,%
3,%
2,%j1";
5235 [(set_attr "type" "isel")])
5237 ; Set Boolean Condition (Reverse)
5238 (define_insn "setbc_<un>signed_<GPR:mode>"
5239 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
5240 (match_operator:GPR
1 "scc_comparison_operator"
5241 [(match_operand:CCEITHER
2 "cc_reg_operand" "y")
5245 [(set_attr "type" "isel")])
5247 (define_insn "*setbcr_<un>signed_<GPR:mode>"
5248 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
5249 (match_operator:GPR
1 "scc_rev_comparison_operator"
5250 [(match_operand:CCEITHER
2 "cc_reg_operand" "y")
5254 [(set_attr "type" "isel")])
5256 ; Set Negative Boolean Condition (Reverse)
5257 (define_insn "*setnbc_<un>signed_<GPR:mode>"
5258 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
5259 (neg:GPR (match_operator:GPR
1 "scc_comparison_operator"
5260 [(match_operand:CCEITHER
2 "cc_reg_operand" "y")
5264 [(set_attr "type" "isel")])
5266 (define_insn "*setnbcr_<un>signed_<GPR:mode>"
5267 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
5268 (neg:GPR (match_operator:GPR
1 "scc_rev_comparison_operator"
5269 [(match_operand:CCEITHER
2 "cc_reg_operand" "y")
5273 [(set_attr "type" "isel")])
5275 ;; Floating point conditional move
5276 (define_expand "mov<mode>cc"
5277 [(set (match_operand:SFDF
0 "gpc_reg_operand")
5278 (if_then_else:SFDF (match_operand
1 "comparison_operator")
5279 (match_operand:SFDF
2 "gpc_reg_operand")
5280 (match_operand:SFDF
3 "gpc_reg_operand")))]
5281 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5283 if (rs6000_emit_cmove (operands[
0], operands[
1], operands[
2], operands[
3]))
5289 (define_insn "*fsel<SFDF:mode><SFDF2:mode>
4"
5290 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5292 (ge (match_operand:SFDF2
1 "gpc_reg_operand" "<SFDF2:rreg2>")
5293 (match_operand:SFDF2
4 "zero_fp_constant" "F"))
5294 (match_operand:SFDF
2 "gpc_reg_operand" "<SFDF:rreg2>")
5295 (match_operand:SFDF
3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5296 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5298 [(set_attr "type" "fp")])
5300 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5301 [(set (match_operand:SFDF
0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5303 (match_operator:CCFP
1 "fpmask_comparison_operator"
5304 [(match_operand:SFDF2
2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5305 (match_operand:SFDF2
3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5306 (match_operand:SFDF
4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5307 (match_operand:SFDF
5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5308 (clobber (match_scratch:V2DI
6 "=
0,&wa"))]
5313 (if_then_else:V2DI (match_dup
1)
5317 (if_then_else:SFDF (ne (match_dup
6)
5322 if (GET_CODE (operands[
6]) == SCRATCH)
5323 operands[
6] = gen_reg_rtx (V2DImode);
5325 operands[
7] = CONSTM1_RTX (V2DImode);
5326 operands[
8] = CONST0_RTX (V2DImode);
5328 [(set_attr "length" "
8")
5329 (set_attr "type" "vecperm")])
5331 ;; Handle inverting the fpmask comparisons.
5332 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5333 [(set (match_operand:SFDF
0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5335 (match_operator:CCFP
1 "invert_fpmask_comparison_operator"
5336 [(match_operand:SFDF2
2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5337 (match_operand:SFDF2
3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5338 (match_operand:SFDF
4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5339 (match_operand:SFDF
5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5340 (clobber (match_scratch:V2DI
6 "=
0,&wa"))]
5345 (if_then_else:V2DI (match_dup
9)
5349 (if_then_else:SFDF (ne (match_dup
6)
5354 rtx op1 = operands[
1];
5355 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5357 if (GET_CODE (operands[
6]) == SCRATCH)
5358 operands[
6] = gen_reg_rtx (V2DImode);
5360 operands[
7] = CONSTM1_RTX (V2DImode);
5361 operands[
8] = CONST0_RTX (V2DImode);
5363 operands[
9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[
2], operands[
3]);
5365 [(set_attr "length" "
8")
5366 (set_attr "type" "vecperm")])
5368 (define_insn "*fpmask<mode>"
5369 [(set (match_operand:V2DI
0 "vsx_register_operand" "=wa")
5371 (match_operator:CCFP
1 "fpmask_comparison_operator"
5372 [(match_operand:SFDF
2 "vsx_register_operand" "<Fv>")
5373 (match_operand:SFDF
3 "vsx_register_operand" "<Fv>")])
5374 (match_operand:V2DI
4 "all_ones_constant" "")
5375 (match_operand:V2DI
5 "zero_constant" "")))]
5377 "xscmp%V1dp %x0,%x2,%x3"
5378 [(set_attr "type" "fpcompare")])
5380 (define_insn "*xxsel<mode>"
5381 [(set (match_operand:SFDF
0 "vsx_register_operand" "=<Fv>")
5382 (if_then_else:SFDF (ne (match_operand:V2DI
1 "vsx_register_operand" "wa")
5383 (match_operand:V2DI
2 "zero_constant" ""))
5384 (match_operand:SFDF
3 "vsx_register_operand" "<Fv>")
5385 (match_operand:SFDF
4 "vsx_register_operand" "<Fv>")))]
5387 "xxsel %x0,%x4,%x3,%x1"
5388 [(set_attr "type" "vecmove")])
5391 ;; Conversions to and from floating-point.
5393 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5394 ; don't want to support putting SImode in FPR registers.
5395 (define_insn "lfiwax"
5396 [(set (match_operand:DI
0 "gpc_reg_operand" "=d,wa,wa,v")
5397 (unspec:DI [(match_operand:SI
1 "reg_or_indexed_operand" "Z,Z,r,v")]
5399 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5405 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5406 (set_attr "isa" "*,p8v,p8v,p9v")])
5408 ; This split must be run before register allocation because it allocates the
5409 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5410 ; it earlier to allow for the combiner to merge insns together where it might
5411 ; not be needed and also in case the insns are deleted as dead code.
5413 (define_insn_and_split "floatsi<mode>
2_lfiwax"
5414 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=d,<Fv>")
5415 (float:SFDF (match_operand:SI
1 "nonimmediate_operand" "r,r")))
5416 (clobber (match_scratch:DI
2 "=d,wa"))]
5417 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5418 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5423 rtx dest = operands[
0];
5424 rtx src = operands[
1];
5427 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5428 tmp = convert_to_mode (DImode, src, false);
5432 if (GET_CODE (tmp) == SCRATCH)
5433 tmp = gen_reg_rtx (DImode);
5436 src = rs6000_force_indexed_or_indirect_mem (src);
5437 emit_insn (gen_lfiwax (tmp, src));
5441 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5442 emit_move_insn (stack, src);
5443 emit_insn (gen_lfiwax (tmp, stack));
5446 emit_insn (gen_floatdi<mode>
2 (dest, tmp));
5449 [(set_attr "length" "
12")
5450 (set_attr "type" "fpload")])
5452 (define_insn_and_split "floatsi<mode>
2_lfiwax_mem"
5453 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=d,<Fv>")
5456 (match_operand:SI
1 "indexed_or_indirect_operand" "Z,Z"))))
5457 (clobber (match_scratch:DI
2 "=d,wa"))]
5458 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5463 operands[
1] = rs6000_force_indexed_or_indirect_mem (operands[
1]);
5464 if (GET_CODE (operands[
2]) == SCRATCH)
5465 operands[
2] = gen_reg_rtx (DImode);
5466 if (TARGET_P8_VECTOR)
5467 emit_insn (gen_extendsidi2 (operands[
2], operands[
1]));
5469 emit_insn (gen_lfiwax (operands[
2], operands[
1]));
5470 emit_insn (gen_floatdi<mode>
2 (operands[
0], operands[
2]));
5473 [(set_attr "length" "
8")
5474 (set_attr "type" "fpload")])
5476 (define_insn "lfiwzx"
5477 [(set (match_operand:DI
0 "gpc_reg_operand" "=d,wa,wa,wa")
5478 (unspec:DI [(match_operand:SI
1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5480 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5485 xxextractuw %x0,%x1,
4"
5486 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5487 (set_attr "isa" "*,p8v,p8v,p9v")])
5489 (define_insn_and_split "floatunssi<mode>
2_lfiwzx"
5490 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=d,<Fv>")
5491 (unsigned_float:SFDF (match_operand:SI
1 "nonimmediate_operand" "r,r")))
5492 (clobber (match_scratch:DI
2 "=d,wa"))]
5493 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5498 rtx dest = operands[
0];
5499 rtx src = operands[
1];
5502 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5503 tmp = convert_to_mode (DImode, src, true);
5507 if (GET_CODE (tmp) == SCRATCH)
5508 tmp = gen_reg_rtx (DImode);
5511 src = rs6000_force_indexed_or_indirect_mem (src);
5512 emit_insn (gen_lfiwzx (tmp, src));
5516 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5517 emit_move_insn (stack, src);
5518 emit_insn (gen_lfiwzx (tmp, stack));
5521 emit_insn (gen_floatdi<mode>
2 (dest, tmp));
5524 [(set_attr "length" "
12")
5525 (set_attr "type" "fpload")])
5527 (define_insn_and_split "floatunssi<mode>
2_lfiwzx_mem"
5528 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=d,<Fv>")
5529 (unsigned_float:SFDF
5531 (match_operand:SI
1 "indexed_or_indirect_operand" "Z,Z"))))
5532 (clobber (match_scratch:DI
2 "=d,wa"))]
5533 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5538 operands[
1] = rs6000_force_indexed_or_indirect_mem (operands[
1]);
5539 if (GET_CODE (operands[
2]) == SCRATCH)
5540 operands[
2] = gen_reg_rtx (DImode);
5541 if (TARGET_P8_VECTOR)
5542 emit_insn (gen_zero_extendsidi2 (operands[
2], operands[
1]));
5544 emit_insn (gen_lfiwzx (operands[
2], operands[
1]));
5545 emit_insn (gen_floatdi<mode>
2 (operands[
0], operands[
2]));
5548 [(set_attr "length" "
8")
5549 (set_attr "type" "fpload")])
5551 ; For each of these conversions, there is a define_expand, a define_insn
5552 ; with a '#' template, and a define_split (with C code). The idea is
5553 ; to allow constant folding with the template of the define_insn,
5554 ; then to have the insns split later (between sched1 and final).
5556 (define_expand "floatsidf2"
5557 [(parallel [(set (match_operand:DF
0 "gpc_reg_operand")
5558 (float:DF (match_operand:SI
1 "nonimmediate_operand")))
5561 (clobber (match_dup
4))
5562 (clobber (match_dup
5))
5563 (clobber (match_dup
6))])]
5566 if (TARGET_LFIWAX && TARGET_FCFID)
5568 emit_insn (gen_floatsidf2_lfiwax (operands[
0], operands[
1]));
5571 else if (TARGET_FCFID)
5573 rtx dreg = operands[
1];
5575 dreg = force_reg (SImode, dreg);
5576 dreg = convert_to_mode (DImode, dreg, false);
5577 emit_insn (gen_floatdidf2 (operands[
0], dreg));
5581 if (!REG_P (operands[
1]))
5582 operands[
1] = force_reg (SImode, operands[
1]);
5583 operands[
2] = force_reg (SImode, GEN_INT (
0x43300000));
5584 operands[
3] = force_reg (DFmode, CONST_DOUBLE_ATOF (
\"4503601774854144\", DFmode));
5585 operands[
4] = rs6000_allocate_stack_temp (DFmode, true, false);
5586 operands[
5] = gen_reg_rtx (DFmode);
5587 operands[
6] = gen_reg_rtx (SImode);
5590 (define_insn_and_split "*floatsidf2_internal"
5591 [(set (match_operand:DF
0 "gpc_reg_operand" "=&d")
5592 (float:DF (match_operand:SI
1 "gpc_reg_operand" "r")))
5593 (use (match_operand:SI
2 "gpc_reg_operand" "r"))
5594 (use (match_operand:DF
3 "gpc_reg_operand" "d"))
5595 (clobber (match_operand:DF
4 "offsettable_mem_operand" "=o"))
5596 (clobber (match_operand:DF
5 "gpc_reg_operand" "=&d"))
5597 (clobber (match_operand:SI
6 "gpc_reg_operand" "=&r"))]
5598 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5603 rtx lowword, highword;
5604 gcc_assert (MEM_P (operands[
4]));
5605 highword = adjust_address (operands[
4], SImode,
0);
5606 lowword = adjust_address (operands[
4], SImode,
4);
5607 if (! WORDS_BIG_ENDIAN)
5608 std::swap (lowword, highword);
5610 emit_insn (gen_xorsi3 (operands[
6], operands[
1],
5611 GEN_INT (~ (HOST_WIDE_INT)
0x7fffffff)));
5612 emit_move_insn (lowword, operands[
6]);
5613 emit_move_insn (highword, operands[
2]);
5614 emit_move_insn (operands[
5], operands[
4]);
5615 emit_insn (gen_subdf3 (operands[
0], operands[
5], operands[
3]));
5618 [(set_attr "length" "
24")
5619 (set_attr "type" "fp")])
5621 ;; If we don't have a direct conversion to single precision, don't enable this
5622 ;; conversion for
32-bit without fast math, because we don't have the insn to
5623 ;; generate the fixup swizzle to avoid double rounding problems.
5624 (define_expand "floatunssisf2"
5625 [(set (match_operand:SF
0 "gpc_reg_operand")
5626 (unsigned_float:SF (match_operand:SI
1 "nonimmediate_operand")))]
5628 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5630 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5632 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5634 emit_insn (gen_floatunssisf2_lfiwzx (operands[
0], operands[
1]));
5639 rtx dreg = operands[
1];
5641 dreg = force_reg (SImode, dreg);
5642 dreg = convert_to_mode (DImode, dreg, true);
5643 emit_insn (gen_floatdisf2 (operands[
0], dreg));
5648 (define_expand "floatunssidf2"
5649 [(parallel [(set (match_operand:DF
0 "gpc_reg_operand")
5650 (unsigned_float:DF (match_operand:SI
1 "nonimmediate_operand")))
5653 (clobber (match_dup
4))
5654 (clobber (match_dup
5))])]
5657 if (TARGET_LFIWZX && TARGET_FCFID)
5659 emit_insn (gen_floatunssidf2_lfiwzx (operands[
0], operands[
1]));
5662 else if (TARGET_FCFID)
5664 rtx dreg = operands[
1];
5666 dreg = force_reg (SImode, dreg);
5667 dreg = convert_to_mode (DImode, dreg, true);
5668 emit_insn (gen_floatdidf2 (operands[
0], dreg));
5672 if (!REG_P (operands[
1]))
5673 operands[
1] = force_reg (SImode, operands[
1]);
5674 operands[
2] = force_reg (SImode, GEN_INT (
0x43300000));
5675 operands[
3] = force_reg (DFmode, CONST_DOUBLE_ATOF (
\"4503599627370496\", DFmode));
5676 operands[
4] = rs6000_allocate_stack_temp (DFmode, true, false);
5677 operands[
5] = gen_reg_rtx (DFmode);
5680 (define_insn_and_split "*floatunssidf2_internal"
5681 [(set (match_operand:DF
0 "gpc_reg_operand" "=&d")
5682 (unsigned_float:DF (match_operand:SI
1 "gpc_reg_operand" "r")))
5683 (use (match_operand:SI
2 "gpc_reg_operand" "r"))
5684 (use (match_operand:DF
3 "gpc_reg_operand" "d"))
5685 (clobber (match_operand:DF
4 "offsettable_mem_operand" "=o"))
5686 (clobber (match_operand:DF
5 "gpc_reg_operand" "=&d"))]
5687 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5688 && !(TARGET_FCFID && TARGET_POWERPC64)"
5693 rtx lowword, highword;
5694 gcc_assert (MEM_P (operands[
4]));
5695 highword = adjust_address (operands[
4], SImode,
0);
5696 lowword = adjust_address (operands[
4], SImode,
4);
5697 if (! WORDS_BIG_ENDIAN)
5698 std::swap (lowword, highword);
5700 emit_move_insn (lowword, operands[
1]);
5701 emit_move_insn (highword, operands[
2]);
5702 emit_move_insn (operands[
5], operands[
4]);
5703 emit_insn (gen_subdf3 (operands[
0], operands[
5], operands[
3]));
5706 [(set_attr "length" "
20")
5707 (set_attr "type" "fp")])
5709 ;; ISA
3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5710 ;; vector registers. These insns favor doing the sign/zero extension in
5711 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5712 ;; extension and then a direct move.
5714 (define_expand "float<QHI:mode><FP_ISA3:mode>
2"
5715 [(parallel [(set (match_operand:FP_ISA3
0 "vsx_register_operand")
5717 (match_operand:QHI
1 "input_operand")))
5718 (clobber (match_scratch:DI
2))
5719 (clobber (match_scratch:DI
3))
5720 (clobber (match_scratch:<QHI:MODE>
4))])]
5721 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5723 if (MEM_P (operands[
1]))
5724 operands[
1] = rs6000_force_indexed_or_indirect_mem (operands[
1]);
5727 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>
2_internal"
5728 [(set (match_operand:FP_ISA3
0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5730 (match_operand:QHI
1 "reg_or_indexed_operand" "v,r,Z")))
5731 (clobber (match_scratch:DI
2 "=v,wa,v"))
5732 (clobber (match_scratch:DI
3 "=X,r,X"))
5733 (clobber (match_scratch:<QHI:MODE>
4 "=X,X,v"))]
5734 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5736 "&& reload_completed"
5739 rtx result = operands[
0];
5740 rtx input = operands[
1];
5741 rtx di = operands[
2];
5745 rtx tmp = operands[
3];
5746 if (altivec_register_operand (input, <QHI:MODE>mode))
5747 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5748 else if (GET_CODE (tmp) == SCRATCH)
5749 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5752 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5753 emit_move_insn (di, tmp);
5758 rtx tmp = operands[
4];
5759 emit_move_insn (tmp, input);
5760 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5763 emit_insn (gen_floatdi<FP_ISA3:mode>
2 (result, di));
5766 [(set_attr "isa" "p9v,*,p9v")])
5768 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>
2"
5769 [(parallel [(set (match_operand:FP_ISA3
0 "vsx_register_operand")
5770 (unsigned_float:FP_ISA3
5771 (match_operand:QHI
1 "input_operand")))
5772 (clobber (match_scratch:DI
2))
5773 (clobber (match_scratch:DI
3))])]
5774 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5776 if (MEM_P (operands[
1]))
5777 operands[
1] = rs6000_force_indexed_or_indirect_mem (operands[
1]);
5780 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>
2_internal"
5781 [(set (match_operand:FP_ISA3
0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5782 (unsigned_float:FP_ISA3
5783 (match_operand:QHI
1 "reg_or_indexed_operand" "v,r,Z")))
5784 (clobber (match_scratch:DI
2 "=v,wa,wa"))
5785 (clobber (match_scratch:DI
3 "=X,r,X"))]
5786 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5788 "&& reload_completed"
5791 rtx result = operands[
0];
5792 rtx input = operands[
1];
5793 rtx di = operands[
2];
5795 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5796 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5799 rtx tmp = operands[
3];
5800 if (GET_CODE (tmp) == SCRATCH)
5801 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5804 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5805 emit_move_insn (di, tmp);
5809 emit_insn (gen_floatdi<FP_ISA3:mode>
2 (result, di));
5812 [(set_attr "isa" "p9v,*,p9v")])
5814 (define_expand "fix_trunc<mode>si2"
5815 [(set (match_operand:SI
0 "gpc_reg_operand")
5816 (fix:SI (match_operand:SFDF
1 "gpc_reg_operand")))]
5819 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5821 rtx src = force_reg (<MODE>mode, operands[
1]);
5824 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[
0], src));
5827 rtx tmp = gen_reg_rtx (DImode);
5828 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5829 emit_insn (gen_fix_trunc<mode>si2_internal (operands[
0], src,
5836 ; Like the convert to float patterns, this insn must be split before
5837 ; register allocation so that it can allocate the memory slot if it
5839 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5840 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
5841 (fix:SI (match_operand:SFDF
1 "gpc_reg_operand" "d")))
5842 (clobber (match_scratch:DI
2 "=d"))]
5843 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5844 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5849 rtx dest = operands[
0];
5850 rtx src = operands[
1];
5851 rtx tmp = operands[
2];
5853 if (GET_CODE (tmp) == SCRATCH)
5854 tmp = gen_reg_rtx (DImode);
5856 emit_insn (gen_fctiwz_<mode> (tmp, src));
5857 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >=
32))
5859 dest = rs6000_force_indexed_or_indirect_mem (dest);
5860 emit_insn (gen_stfiwx (dest, tmp));
5863 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5865 dest = gen_lowpart (DImode, dest);
5866 emit_move_insn (dest, tmp);
5871 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5872 emit_insn (gen_stfiwx (stack, tmp));
5873 emit_move_insn (dest, stack);
5877 [(set_attr "length" "
12")
5878 (set_attr "type" "fp")])
5880 (define_insn_and_split "fix_trunc<mode>si2_internal"
5881 [(set (match_operand:SI
0 "gpc_reg_operand" "=r,?r")
5882 (fix:SI (match_operand:SFDF
1 "gpc_reg_operand" "d,<rreg>")))
5883 (clobber (match_operand:DI
2 "gpc_reg_operand" "=
1,d"))
5884 (clobber (match_operand:DI
3 "offsettable_mem_operand" "=o,o"))]
5886 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5892 gcc_assert (MEM_P (operands[
3]));
5893 lowword = adjust_address (operands[
3], SImode, WORDS_BIG_ENDIAN ?
4 :
0);
5895 emit_insn (gen_fctiwz_<mode> (operands[
2], operands[
1]));
5896 emit_move_insn (operands[
3], operands[
2]);
5897 emit_move_insn (operands[
0], lowword);
5900 [(set_attr "length" "
16")
5901 (set_attr "type" "fp")])
5903 (define_expand "fix_trunc<mode>di2"
5904 [(set (match_operand:DI
0 "gpc_reg_operand")
5905 (fix:DI (match_operand:SFDF
1 "gpc_reg_operand")))]
5906 "TARGET_HARD_FLOAT && TARGET_FCFID"
5909 (define_insn "*fix_trunc<mode>di2_fctidz"
5910 [(set (match_operand:DI
0 "gpc_reg_operand" "=d,wa")
5911 (fix:DI (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5912 "TARGET_HARD_FLOAT && TARGET_FCFID"
5916 [(set_attr "type" "fp")])
5918 ;; If we have ISA
3.0, QI/HImode values can go in both VSX registers and GPR
5919 ;; registers. If we have ISA
2.07, we don't allow QI/HImode values in the
5920 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5921 ;; values can go in VSX registers. Keeping the direct move part through
5922 ;; register allocation prevents the register allocator from doing a direct move
5923 ;; of the SImode value to a GPR, and then a store/load.
5924 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>
2"
5925 [(set (match_operand:<QHI:MODE>
0 "gpc_reg_operand" "=d,wa,r")
5926 (any_fix:QHI (match_operand:SFDF
1 "gpc_reg_operand" "d,wa,wa")))
5927 (clobber (match_scratch:SI
2 "=X,X,wa"))]
5928 "TARGET_DIRECT_MOVE"
5931 xscvdp<su>xws %x0,%x1
5933 "&& reload_completed && int_reg_operand (operands[
0], <QHI:MODE>mode)"
5935 (any_fix:SI (match_dup
1)))
5939 operands[
3] = gen_rtx_REG (SImode, REGNO (operands[
0]));
5941 [(set_attr "type" "fp")
5942 (set_attr "length" "
4,
4,
8")
5943 (set_attr "isa" "p9v,p9v,*")])
5945 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5946 [(set (match_operand:SI
0 "gpc_reg_operand" "=d,wa")
5947 (any_fix:SI (match_operand:SFDF
1 "gpc_reg_operand" "d,wa")))]
5948 "TARGET_DIRECT_MOVE"
5951 xscvdp<su>xws %x0,%x1"
5952 [(set_attr "type" "fp")])
5954 ;; Keep the convert and store together through register allocation to prevent
5955 ;; the register allocator from getting clever and doing a direct move to a GPR
5956 ;; and then store for reg+offset stores.
5957 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>
2_mem"
5958 [(set (match_operand:QHSI
0 "memory_operand" "=Z")
5959 (any_fix:QHSI (match_operand:SFDF
1 "gpc_reg_operand" "wa")))
5960 (clobber (match_scratch:SI
2 "=wa"))]
5961 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5963 "&& reload_completed"
5965 (any_fix:SI (match_dup
1)))
5969 operands[
3] = (<QHSI:MODE>mode == SImode
5971 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[
2])));
5974 (define_expand "fixuns_trunc<mode>si2"
5975 [(set (match_operand:SI
0 "gpc_reg_operand")
5976 (unsigned_fix:SI (match_operand:SFDF
1 "gpc_reg_operand")))]
5977 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5979 if (!TARGET_P8_VECTOR)
5981 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[
0], operands[
1]));
5986 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5987 [(set (match_operand:SI
0 "nonimmediate_operand" "=rm")
5988 (unsigned_fix:SI (match_operand:SFDF
1 "gpc_reg_operand" "d")))
5989 (clobber (match_scratch:DI
2 "=d"))]
5990 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5991 && TARGET_STFIWX && can_create_pseudo_p ()
5992 && !TARGET_P8_VECTOR"
5997 rtx dest = operands[
0];
5998 rtx src = operands[
1];
5999 rtx tmp = operands[
2];
6001 if (GET_CODE (tmp) == SCRATCH)
6002 tmp = gen_reg_rtx (DImode);
6004 emit_insn (gen_fctiwuz_<mode> (tmp, src));
6007 dest = rs6000_force_indexed_or_indirect_mem (dest);
6008 emit_insn (gen_stfiwx (dest, tmp));
6011 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
6013 dest = gen_lowpart (DImode, dest);
6014 emit_move_insn (dest, tmp);
6019 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6020 emit_insn (gen_stfiwx (stack, tmp));
6021 emit_move_insn (dest, stack);
6025 [(set_attr "length" "
12")
6026 (set_attr "type" "fp")])
6028 (define_insn "fixuns_trunc<mode>di2"
6029 [(set (match_operand:DI
0 "gpc_reg_operand" "=d,wa")
6030 (unsigned_fix:DI (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>")))]
6031 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
6035 [(set_attr "type" "fp")])
6037 (define_insn "rs6000_mtfsb0"
6038 [(unspec_volatile [(match_operand:SI
0 "u5bit_cint_operand" "n")]
6042 [(set_attr "type" "fp")])
6044 (define_insn "rs6000_mtfsb1"
6045 [(unspec_volatile [(match_operand:SI
0 "u5bit_cint_operand" "n")]
6049 [(set_attr "type" "fp")])
6051 (define_insn "rs6000_mffscrn"
6052 [(set (match_operand:DF
0 "gpc_reg_operand" "=d")
6053 (unspec_volatile:DF [(match_operand:DF
1 "gpc_reg_operand" "d")]
6057 [(set_attr "type" "fp")])
6059 (define_insn "rs6000_mffscdrn"
6060 [(set (match_operand:DF
0 "gpc_reg_operand" "=d")
6061 (unspec_volatile:DF [(const_int
0)] UNSPECV_MFFSCDRN))
6062 (use (match_operand:DF
1 "gpc_reg_operand" "d"))]
6065 [(set_attr "type" "fp")])
6067 (define_expand "rs6000_set_fpscr_rn"
6068 [(match_operand:DI
0 "reg_or_cint_operand")]
6071 rtx tmp_df = gen_reg_rtx (DFmode);
6073 /* The floating point rounding control bits are FPSCR[
62:
63]. Put the
6074 new rounding mode bits from operands[
0][
62:
63] into FPSCR[
62:
63]. */
6077 rtx src_df = force_reg (DImode, operands[
0]);
6078 src_df = simplify_gen_subreg (DFmode, src_df, DImode,
0);
6079 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
6083 if (CONST_INT_P (operands[
0]))
6085 if ((INTVAL (operands[
0]) &
0x1) ==
0x1)
6086 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (
31)));
6088 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (
31)));
6090 if ((INTVAL (operands[
0]) &
0x2) ==
0x2)
6091 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (
30)));
6093 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (
30)));
6097 rtx tmp_rn = gen_reg_rtx (DImode);
6098 rtx tmp_di = gen_reg_rtx (DImode);
6100 /* Extract new RN mode from operand. */
6101 emit_insn (gen_anddi3 (tmp_rn, operands[
0], GEN_INT (
0x3)));
6103 /* Insert new RN mode into FSCPR. */
6104 emit_insn (gen_rs6000_mffs (tmp_df));
6105 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode,
0);
6106 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-
4)));
6107 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6109 /* Need to write to field k=
15. The fields are [
0:
15]. Hence with
6110 L=
0, W=
0, FLM_i must be equal to
8,
16 = i +
8*(
1-W). FLM is an
6111 8-bit field[
0:
7]. Need to set the bit that corresponds to the
6112 value of i that you want [
0:
7]. */
6113 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode,
0);
6114 emit_insn (gen_rs6000_mtfsf (GEN_INT (
0x01), tmp_df));
6119 (define_expand "rs6000_set_fpscr_drn"
6120 [(match_operand:DI
0 "gpc_reg_operand")]
6123 rtx tmp_df = gen_reg_rtx (DFmode);
6125 /* The decimal floating point rounding control bits are FPSCR[
29:
31]. Put the
6126 new rounding mode bits from operands[
0][
61:
63] into FPSCR[
29:
31]. */
6129 rtx src_df = gen_reg_rtx (DFmode);
6131 emit_insn (gen_ashldi3 (operands[
0], operands[
0], GEN_INT (
32)));
6132 src_df = simplify_gen_subreg (DFmode, operands[
0], DImode,
0);
6133 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6137 rtx tmp_rn = gen_reg_rtx (DImode);
6138 rtx tmp_di = gen_reg_rtx (DImode);
6140 /* Extract new DRN mode from operand. */
6141 emit_insn (gen_anddi3 (tmp_rn, operands[
0], GEN_INT (
0x7)));
6142 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (
32)));
6144 /* Insert new RN mode into FSCPR. */
6145 emit_insn (gen_rs6000_mffs (tmp_df));
6146 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode,
0);
6147 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (
0xFFFFFFF8FFFFFFFFULL)));
6148 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6150 /* Need to write to field
7. The fields are [
0:
15]. The equation to
6151 select the field is i +
8*(
1-W). Hence with L=
0 and W=
1, need to set
6152 i to
0x1 to get field
7 where i selects the field. */
6153 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode,
0);
6154 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (
0x01), tmp_df));
6159 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6160 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6161 ;; because the first makes it clear that operand
0 is not live
6162 ;; before the instruction.
6163 (define_insn "fctiwz_<mode>"
6164 [(set (match_operand:DI
0 "gpc_reg_operand" "=d,wa")
6166 (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6172 [(set_attr "type" "fp")])
6174 (define_insn "fctiwuz_<mode>"
6175 [(set (match_operand:DI
0 "gpc_reg_operand" "=d,wa")
6176 (unspec:DI [(unsigned_fix:SI
6177 (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6179 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6183 [(set_attr "type" "fp")])
6185 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6186 ;; since the friz instruction does not truncate the value if the floating
6187 ;; point value is < LONG_MIN or > LONG_MAX.
6188 (define_insn "*friz"
6189 [(set (match_operand:DF
0 "gpc_reg_operand" "=d,wa")
6190 (float:DF (fix:DI (match_operand:DF
1 "gpc_reg_operand" "d,wa"))))]
6191 "TARGET_HARD_FLOAT && TARGET_FPRND
6192 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6196 [(set_attr "type" "fp")])
6198 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6199 ;; optimization prevents on ISA
2.06 systems and earlier having to store the
6200 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6201 ;; extend it, store it back on the stack from the GPR, load it back into the
6202 ;; FP/vector unit to do the rounding. If we have direct move (ISA
2.07),
6203 ;; disable using store and load to sign/zero extend the value.
6204 (define_insn_and_split "*round32<mode>
2_fprs"
6205 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=d")
6207 (fix:SI (match_operand:SFDF
1 "gpc_reg_operand" "d"))))
6208 (clobber (match_scratch:DI
2 "=d"))
6209 (clobber (match_scratch:DI
3 "=d"))]
6211 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6212 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6217 rtx dest = operands[
0];
6218 rtx src = operands[
1];
6219 rtx tmp1 = operands[
2];
6220 rtx tmp2 = operands[
3];
6221 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6223 if (GET_CODE (tmp1) == SCRATCH)
6224 tmp1 = gen_reg_rtx (DImode);
6225 if (GET_CODE (tmp2) == SCRATCH)
6226 tmp2 = gen_reg_rtx (DImode);
6228 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6229 emit_insn (gen_stfiwx (stack, tmp1));
6230 emit_insn (gen_lfiwax (tmp2, stack));
6231 emit_insn (gen_floatdi<mode>
2 (dest, tmp2));
6234 [(set_attr "type" "fpload")
6235 (set_attr "length" "
16")])
6237 (define_insn_and_split "*roundu32<mode>
2_fprs"
6238 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=d")
6239 (unsigned_float:SFDF
6240 (unsigned_fix:SI (match_operand:SFDF
1 "gpc_reg_operand" "d"))))
6241 (clobber (match_scratch:DI
2 "=d"))
6242 (clobber (match_scratch:DI
3 "=d"))]
6244 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6245 && can_create_pseudo_p ()"
6250 rtx dest = operands[
0];
6251 rtx src = operands[
1];
6252 rtx tmp1 = operands[
2];
6253 rtx tmp2 = operands[
3];
6254 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6256 if (GET_CODE (tmp1) == SCRATCH)
6257 tmp1 = gen_reg_rtx (DImode);
6258 if (GET_CODE (tmp2) == SCRATCH)
6259 tmp2 = gen_reg_rtx (DImode);
6261 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6262 emit_insn (gen_stfiwx (stack, tmp1));
6263 emit_insn (gen_lfiwzx (tmp2, stack));
6264 emit_insn (gen_floatdi<mode>
2 (dest, tmp2));
6267 [(set_attr "type" "fpload")
6268 (set_attr "length" "
16")])
6270 ;; No VSX equivalent to fctid
6271 (define_insn "lrint<mode>di2"
6272 [(set (match_operand:DI
0 "gpc_reg_operand" "=d")
6273 (unspec:DI [(match_operand:SFDF
1 "gpc_reg_operand" "<rreg2>")]
6275 "TARGET_HARD_FLOAT && TARGET_FPRND"
6277 [(set_attr "type" "fp")])
6279 (define_insn "btrunc<mode>
2"
6280 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,<Fv>")
6281 (unspec:SFDF [(match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>")]
6283 "TARGET_HARD_FLOAT && TARGET_FPRND"
6287 [(set_attr "type" "fp")])
6289 (define_insn "ceil<mode>
2"
6290 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,<Fv>")
6291 (unspec:SFDF [(match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>")]
6293 "TARGET_HARD_FLOAT && TARGET_FPRND"
6297 [(set_attr "type" "fp")])
6299 (define_insn "floor<mode>
2"
6300 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,<Fv>")
6301 (unspec:SFDF [(match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,<Fv>")]
6303 "TARGET_HARD_FLOAT && TARGET_FPRND"
6307 [(set_attr "type" "fp")])
6309 ;; No VSX equivalent to frin
6310 (define_insn "round<mode>
2"
6311 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<rreg2>")
6312 (unspec:SFDF [(match_operand:SFDF
1 "gpc_reg_operand" "<rreg2>")]
6314 "TARGET_HARD_FLOAT && TARGET_FPRND"
6316 [(set_attr "type" "fp")])
6318 (define_insn "*xsrdpi<mode>
2"
6319 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Fv>")
6320 (unspec:SFDF [(match_operand:SFDF
1 "gpc_reg_operand" "<Fv>")]
6322 "TARGET_HARD_FLOAT && TARGET_VSX"
6324 [(set_attr "type" "fp")])
6326 (define_expand "lround<mode>di2"
6328 (unspec:SFDF [(match_operand:SFDF
1 "gpc_reg_operand")]
6330 (set (match_operand:DI
0 "gpc_reg_operand")
6331 (unspec:DI [(match_dup
2)]
6333 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6335 operands[
2] = gen_reg_rtx (<MODE>mode);
6338 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6339 (define_insn "stfiwx"
6340 [(set (match_operand:SI
0 "memory_operand" "=Z,Z")
6341 (unspec:SI [(match_operand:DI
1 "gpc_reg_operand" "d,wa")]
6347 [(set_attr "type" "fpstore")
6348 (set_attr "isa" "*,p8v")])
6350 ;; If we don't have a direct conversion to single precision, don't enable this
6351 ;; conversion for
32-bit without fast math, because we don't have the insn to
6352 ;; generate the fixup swizzle to avoid double rounding problems.
6353 (define_expand "floatsisf2"
6354 [(set (match_operand:SF
0 "gpc_reg_operand")
6355 (float:SF (match_operand:SI
1 "nonimmediate_operand")))]
6357 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6359 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6361 if (TARGET_FCFIDS && TARGET_LFIWAX)
6363 emit_insn (gen_floatsisf2_lfiwax (operands[
0], operands[
1]));
6366 else if (TARGET_FCFID && TARGET_LFIWAX)
6368 rtx dfreg = gen_reg_rtx (DFmode);
6369 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[
1]));
6370 emit_insn (gen_truncdfsf2 (operands[
0], dfreg));
6375 rtx dreg = operands[
1];
6377 dreg = force_reg (SImode, dreg);
6378 dreg = convert_to_mode (DImode, dreg, false);
6379 emit_insn (gen_floatdisf2 (operands[
0], dreg));
6384 (define_insn "floatdidf2"
6385 [(set (match_operand:DF
0 "gpc_reg_operand" "=d,wa")
6386 (float:DF (match_operand:DI
1 "gpc_reg_operand" "d,wa")))]
6387 "TARGET_FCFID && TARGET_HARD_FLOAT"
6391 [(set_attr "type" "fp")])
6393 ; Allow the combiner to merge source memory operands to the conversion so that
6394 ; the optimizer/register allocator doesn't try to load the value too early in a
6395 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6396 ; hit. We will split after reload to avoid the trip through the GPRs
6398 (define_insn_and_split "*floatdidf2_mem"
6399 [(set (match_operand:DF
0 "gpc_reg_operand" "=d,wa")
6400 (float:DF (match_operand:DI
1 "memory_operand" "m,Z")))
6401 (clobber (match_scratch:DI
2 "=d,wa"))]
6402 "TARGET_HARD_FLOAT && TARGET_FCFID"
6404 "&& reload_completed"
6405 [(set (match_dup
2) (match_dup
1))
6406 (set (match_dup
0) (float:DF (match_dup
2)))]
6408 [(set_attr "length" "
8")
6409 (set_attr "type" "fpload")])
6411 (define_expand "floatunsdidf2"
6412 [(set (match_operand:DF
0 "gpc_reg_operand")
6414 (match_operand:DI
1 "gpc_reg_operand")))]
6415 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6418 (define_insn "*floatunsdidf2_fcfidu"
6419 [(set (match_operand:DF
0 "gpc_reg_operand" "=d,wa")
6420 (unsigned_float:DF (match_operand:DI
1 "gpc_reg_operand" "d,wa")))]
6421 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6425 [(set_attr "type" "fp")])
6427 (define_insn_and_split "*floatunsdidf2_mem"
6428 [(set (match_operand:DF
0 "gpc_reg_operand" "=d,wa")
6429 (unsigned_float:DF (match_operand:DI
1 "memory_operand" "m,Z")))
6430 (clobber (match_scratch:DI
2 "=d,wa"))]
6431 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6433 "&& reload_completed"
6434 [(set (match_dup
2) (match_dup
1))
6435 (set (match_dup
0) (unsigned_float:DF (match_dup
2)))]
6437 [(set_attr "length" "
8")
6438 (set_attr "type" "fpload")])
6440 (define_expand "floatdisf2"
6441 [(set (match_operand:SF
0 "gpc_reg_operand")
6442 (float:SF (match_operand:DI
1 "gpc_reg_operand")))]
6443 "TARGET_FCFID && TARGET_HARD_FLOAT
6444 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6448 rtx val = operands[
1];
6449 if (!flag_unsafe_math_optimizations)
6451 rtx label = gen_label_rtx ();
6452 val = gen_reg_rtx (DImode);
6453 emit_insn (gen_floatdisf2_internal2 (val, operands[
1], label));
6456 emit_insn (gen_floatdisf2_internal1 (operands[
0], val));
6461 (define_insn "floatdisf2_fcfids"
6462 [(set (match_operand:SF
0 "gpc_reg_operand" "=f,wa")
6463 (float:SF (match_operand:DI
1 "gpc_reg_operand" "d,wa")))]
6464 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6468 [(set_attr "type" "fp")
6469 (set_attr "isa" "*,p8v")])
6471 (define_insn_and_split "*floatdisf2_mem"
6472 [(set (match_operand:SF
0 "gpc_reg_operand" "=f,wa,wa")
6473 (float:SF (match_operand:DI
1 "memory_operand" "m,m,Z")))
6474 (clobber (match_scratch:DI
2 "=d,d,wa"))]
6475 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6477 "&& reload_completed"
6480 emit_move_insn (operands[
2], operands[
1]);
6481 emit_insn (gen_floatdisf2_fcfids (operands[
0], operands[
2]));
6484 [(set_attr "length" "
8")
6485 (set_attr "isa" "*,p8v,p8v")])
6487 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6488 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6489 ;; from double rounding.
6490 ;; Instead of creating a new cpu type for two FP operations, just use fp
6491 (define_insn_and_split "floatdisf2_internal1"
6492 [(set (match_operand:SF
0 "gpc_reg_operand" "=f")
6493 (float:SF (match_operand:DI
1 "gpc_reg_operand" "d")))
6494 (clobber (match_scratch:DF
2 "=d"))]
6495 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6497 "&& reload_completed"
6499 (float:DF (match_dup
1)))
6501 (float_truncate:SF (match_dup
2)))]
6503 [(set_attr "length" "
8")
6504 (set_attr "type" "fp")])
6506 ;; Twiddles bits to avoid double rounding.
6507 ;; Bits that might be truncated when converting to DFmode are replaced
6508 ;; by a bit that won't be lost at that stage, but is below the SFmode
6509 ;; rounding position.
6510 (define_expand "floatdisf2_internal2"
6511 [(parallel [(set (match_dup
3) (ashiftrt:DI (match_operand:DI
1 "")
6513 (clobber (reg:DI CA_REGNO))])
6514 (set (match_operand:DI
0 "") (and:DI (match_dup
1)
6516 (set (match_dup
3) (plus:DI (match_dup
3)
6518 (set (match_dup
0) (plus:DI (match_dup
0)
6520 (set (match_dup
4) (compare:CCUNS (match_dup
3)
6522 (set (match_dup
0) (ior:DI (match_dup
0)
6524 (set (match_dup
0) (and:DI (match_dup
0)
6526 (set (pc) (if_then_else (geu (match_dup
4) (const_int
0))
6527 (label_ref (match_operand:DI
2 ""))
6529 (set (match_dup
0) (match_dup
1))]
6530 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6532 operands[
3] = gen_reg_rtx (DImode);
6533 operands[
4] = gen_reg_rtx (CCUNSmode);
6536 (define_expand "floatunsdisf2"
6537 [(set (match_operand:SF
0 "gpc_reg_operand")
6538 (unsigned_float:SF (match_operand:DI
1 "gpc_reg_operand")))]
6539 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6542 (define_insn "floatunsdisf2_fcfidus"
6543 [(set (match_operand:SF
0 "gpc_reg_operand" "=f,wa")
6544 (unsigned_float:SF (match_operand:DI
1 "gpc_reg_operand" "d,wa")))]
6545 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6549 [(set_attr "type" "fp")
6550 (set_attr "isa" "*,p8v")])
6552 (define_insn_and_split "*floatunsdisf2_mem"
6553 [(set (match_operand:SF
0 "gpc_reg_operand" "=f,wa,wa")
6554 (unsigned_float:SF (match_operand:DI
1 "memory_operand" "m,m,Z")))
6555 (clobber (match_scratch:DI
2 "=d,d,wa"))]
6556 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6558 "&& reload_completed"
6561 emit_move_insn (operands[
2], operands[
1]);
6562 emit_insn (gen_floatunsdisf2_fcfidus (operands[
0], operands[
2]));
6565 [(set_attr "type" "fpload")
6566 (set_attr "length" "
8")
6567 (set_attr "isa" "*,p8v,p8v")])
6569 ;; Define the TImode operations that can be done in a small number
6570 ;; of instructions. The & constraints are to prevent the register
6571 ;; allocator from allocating registers that overlap with the inputs
6572 ;; (for example, having an input in
7,
8 and an output in
6,
7). We
6573 ;; also allow for the output being the same as one of the inputs.
6575 (define_expand "addti3"
6576 [(set (match_operand:TI
0 "gpc_reg_operand")
6577 (plus:TI (match_operand:TI
1 "gpc_reg_operand")
6578 (match_operand:TI
2 "reg_or_short_operand")))]
6581 rtx lo0 = gen_lowpart (DImode, operands[
0]);
6582 rtx lo1 = gen_lowpart (DImode, operands[
1]);
6583 rtx lo2 = gen_lowpart (DImode, operands[
2]);
6584 rtx hi0 = gen_highpart (DImode, operands[
0]);
6585 rtx hi1 = gen_highpart (DImode, operands[
1]);
6586 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[
2]);
6588 if (!reg_or_short_operand (lo2, DImode))
6589 lo2 = force_reg (DImode, lo2);
6590 if (!adde_operand (hi2, DImode))
6591 hi2 = force_reg (DImode, hi2);
6593 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6594 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6598 (define_expand "subti3"
6599 [(set (match_operand:TI
0 "gpc_reg_operand")
6600 (minus:TI (match_operand:TI
1 "reg_or_short_operand")
6601 (match_operand:TI
2 "gpc_reg_operand")))]
6604 rtx lo0 = gen_lowpart (DImode, operands[
0]);
6605 rtx lo1 = gen_lowpart (DImode, operands[
1]);
6606 rtx lo2 = gen_lowpart (DImode, operands[
2]);
6607 rtx hi0 = gen_highpart (DImode, operands[
0]);
6608 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[
1]);
6609 rtx hi2 = gen_highpart (DImode, operands[
2]);
6611 if (!reg_or_short_operand (lo1, DImode))
6612 lo1 = force_reg (DImode, lo1);
6613 if (!adde_operand (hi1, DImode))
6614 hi1 = force_reg (DImode, hi1);
6616 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6617 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6621 ;;
128-bit logical operations expanders
6623 (define_expand "and<mode>
3"
6624 [(set (match_operand:BOOL_128
0 "vlogical_operand")
6625 (and:BOOL_128 (match_operand:BOOL_128
1 "vlogical_operand")
6626 (match_operand:BOOL_128
2 "vlogical_operand")))]
6630 (define_expand "ior<mode>
3"
6631 [(set (match_operand:BOOL_128
0 "vlogical_operand")
6632 (ior:BOOL_128 (match_operand:BOOL_128
1 "vlogical_operand")
6633 (match_operand:BOOL_128
2 "vlogical_operand")))]
6637 (define_expand "xor<mode>
3"
6638 [(set (match_operand:BOOL_128
0 "vlogical_operand")
6639 (xor:BOOL_128 (match_operand:BOOL_128
1 "vlogical_operand")
6640 (match_operand:BOOL_128
2 "vlogical_operand")))]
6644 (define_expand "nor<mode>
3"
6645 [(set (match_operand:BOOL_128
0 "vlogical_operand")
6647 (not:BOOL_128 (match_operand:BOOL_128
1 "vlogical_operand"))
6648 (not:BOOL_128 (match_operand:BOOL_128
2 "vlogical_operand"))))]
6652 (define_expand "andc<mode>
3"
6653 [(set (match_operand:BOOL_128
0 "vlogical_operand")
6655 (not:BOOL_128 (match_operand:BOOL_128
2 "vlogical_operand"))
6656 (match_operand:BOOL_128
1 "vlogical_operand")))]
6660 ;; Power8 vector logical instructions.
6661 (define_expand "eqv<mode>
3"
6662 [(set (match_operand:BOOL_128
0 "vlogical_operand")
6664 (xor:BOOL_128 (match_operand:BOOL_128
1 "vlogical_operand")
6665 (match_operand:BOOL_128
2 "vlogical_operand"))))]
6666 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6669 ;; Rewrite nand into canonical form
6670 (define_expand "nand<mode>
3"
6671 [(set (match_operand:BOOL_128
0 "vlogical_operand")
6673 (not:BOOL_128 (match_operand:BOOL_128
1 "vlogical_operand"))
6674 (not:BOOL_128 (match_operand:BOOL_128
2 "vlogical_operand"))))]
6675 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6678 ;; The canonical form is to have the negated element first, so we need to
6679 ;; reverse arguments.
6680 (define_expand "orc<mode>
3"
6681 [(set (match_operand:BOOL_128
0 "vlogical_operand")
6683 (not:BOOL_128 (match_operand:BOOL_128
2 "vlogical_operand"))
6684 (match_operand:BOOL_128
1 "vlogical_operand")))]
6685 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6688 ;;
128-bit logical operations insns and split operations
6689 (define_insn_and_split "*and<mode>
3_internal"
6690 [(set (match_operand:BOOL_128
0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6692 (match_operand:BOOL_128
1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6693 (match_operand:BOOL_128
2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6696 if (TARGET_VSX && vsx_register_operand (operands[
0], <MODE>mode))
6697 return "xxland %x0,%x1,%x2";
6699 if (TARGET_ALTIVEC && altivec_register_operand (operands[
0], <MODE>mode))
6700 return "vand %
0,%
1,%
2";
6704 "reload_completed && int_reg_operand (operands[
0], <MODE>mode)"
6707 rs6000_split_logical (operands, AND, false, false, false);
6712 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6713 (const_string "veclogical")
6714 (const_string "integer")))
6715 (set (attr "length")
6717 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6720 (match_test "TARGET_POWERPC64")
6722 (const_string "
16"))))])
6725 (define_insn_and_split "*bool<mode>
3_internal"
6726 [(set (match_operand:BOOL_128
0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6727 (match_operator:BOOL_128
3 "boolean_or_operator"
6728 [(match_operand:BOOL_128
1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6729 (match_operand:BOOL_128
2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6732 if (TARGET_VSX && vsx_register_operand (operands[
0], <MODE>mode))
6733 return "xxl%q3 %x0,%x1,%x2";
6735 if (TARGET_ALTIVEC && altivec_register_operand (operands[
0], <MODE>mode))
6736 return "v%q3 %
0,%
1,%
2";
6740 "reload_completed && int_reg_operand (operands[
0], <MODE>mode)"
6743 rs6000_split_logical (operands, GET_CODE (operands[
3]), false, false, false);
6748 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6749 (const_string "veclogical")
6750 (const_string "integer")))
6751 (set (attr "length")
6753 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6756 (match_test "TARGET_POWERPC64")
6758 (const_string "
16"))))])
6761 (define_insn_and_split "*boolc<mode>
3_internal1"
6762 [(set (match_operand:BOOL_128
0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6763 (match_operator:BOOL_128
3 "boolean_operator"
6765 (match_operand:BOOL_128
2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6766 (match_operand:BOOL_128
1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6767 "TARGET_P8_VECTOR || (GET_CODE (operands[
3]) == AND)"
6769 if (TARGET_VSX && vsx_register_operand (operands[
0], <MODE>mode))
6770 return "xxl%q3 %x0,%x1,%x2";
6772 if (TARGET_ALTIVEC && altivec_register_operand (operands[
0], <MODE>mode))
6773 return "v%q3 %
0,%
1,%
2";
6777 "(TARGET_P8_VECTOR || (GET_CODE (operands[
3]) == AND))
6778 && reload_completed && int_reg_operand (operands[
0], <MODE>mode)"
6781 rs6000_split_logical (operands, GET_CODE (operands[
3]), false, false, true);
6786 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6787 (const_string "veclogical")
6788 (const_string "integer")))
6789 (set (attr "length")
6791 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6794 (match_test "TARGET_POWERPC64")
6796 (const_string "
16"))))])
6798 (define_insn_and_split "*boolc<mode>
3_internal2"
6799 [(set (match_operand:TI2
0 "int_reg_operand" "=&r,r,r")
6800 (match_operator:TI2
3 "boolean_operator"
6802 (match_operand:TI2
2 "int_reg_operand" "r,
0,r"))
6803 (match_operand:TI2
1 "int_reg_operand" "r,r,
0")]))]
6804 "!TARGET_P8_VECTOR && (GET_CODE (operands[
3]) != AND)"
6806 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[
3]) != AND)"
6809 rs6000_split_logical (operands, GET_CODE (operands[
3]), false, false, true);
6812 [(set_attr "type" "integer")
6813 (set (attr "length")
6815 (match_test "TARGET_POWERPC64")
6817 (const_string "
16")))])
6820 (define_insn_and_split "*boolcc<mode>
3_internal1"
6821 [(set (match_operand:BOOL_128
0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6822 (match_operator:BOOL_128
3 "boolean_operator"
6824 (match_operand:BOOL_128
1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6826 (match_operand:BOOL_128
2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6827 "TARGET_P8_VECTOR || (GET_CODE (operands[
3]) == AND)"
6829 if (TARGET_VSX && vsx_register_operand (operands[
0], <MODE>mode))
6830 return "xxl%q3 %x0,%x1,%x2";
6832 if (TARGET_ALTIVEC && altivec_register_operand (operands[
0], <MODE>mode))
6833 return "v%q3 %
0,%
1,%
2";
6837 "(TARGET_P8_VECTOR || (GET_CODE (operands[
3]) == AND))
6838 && reload_completed && int_reg_operand (operands[
0], <MODE>mode)"
6841 rs6000_split_logical (operands, GET_CODE (operands[
3]), false, true, true);
6846 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6847 (const_string "veclogical")
6848 (const_string "integer")))
6849 (set (attr "length")
6851 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6854 (match_test "TARGET_POWERPC64")
6856 (const_string "
16"))))])
6858 (define_insn_and_split "*boolcc<mode>
3_internal2"
6859 [(set (match_operand:TI2
0 "int_reg_operand" "=&r,r,r")
6860 (match_operator:TI2
3 "boolean_operator"
6862 (match_operand:TI2
1 "int_reg_operand" "r,
0,r"))
6864 (match_operand:TI2
2 "int_reg_operand" "r,r,
0"))]))]
6865 "!TARGET_P8_VECTOR && (GET_CODE (operands[
3]) != AND)"
6867 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[
3]) != AND)"
6870 rs6000_split_logical (operands, GET_CODE (operands[
3]), false, true, true);
6873 [(set_attr "type" "integer")
6874 (set (attr "length")
6876 (match_test "TARGET_POWERPC64")
6878 (const_string "
16")))])
6882 (define_insn_and_split "*eqv<mode>
3_internal1"
6883 [(set (match_operand:BOOL_128
0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6886 (match_operand:BOOL_128
1 "vlogical_operand" "<BOOL_REGS_OP1>")
6887 (match_operand:BOOL_128
2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6890 if (vsx_register_operand (operands[
0], <MODE>mode))
6891 return "xxleqv %x0,%x1,%x2";
6895 "TARGET_P8_VECTOR && reload_completed
6896 && int_reg_operand (operands[
0], <MODE>mode)"
6899 rs6000_split_logical (operands, XOR, true, false, false);
6904 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6905 (const_string "veclogical")
6906 (const_string "integer")))
6907 (set (attr "length")
6909 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6912 (match_test "TARGET_POWERPC64")
6914 (const_string "
16"))))])
6916 (define_insn_and_split "*eqv<mode>
3_internal2"
6917 [(set (match_operand:TI2
0 "int_reg_operand" "=&r,r,r")
6920 (match_operand:TI2
1 "int_reg_operand" "r,
0,r")
6921 (match_operand:TI2
2 "int_reg_operand" "r,r,
0"))))]
6924 "reload_completed && !TARGET_P8_VECTOR"
6927 rs6000_split_logical (operands, XOR, true, false, false);
6930 [(set_attr "type" "integer")
6931 (set (attr "length")
6933 (match_test "TARGET_POWERPC64")
6935 (const_string "
16")))])
6937 ;;
128-bit one's complement
6938 (define_insn_and_split "one_cmpl<mode>
2"
6939 [(set (match_operand:BOOL_128
0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6941 (match_operand:BOOL_128
1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6944 if (TARGET_VSX && vsx_register_operand (operands[
0], <MODE>mode))
6945 return "xxlnor %x0,%x1,%x1";
6947 if (TARGET_ALTIVEC && altivec_register_operand (operands[
0], <MODE>mode))
6948 return "vnor %
0,%
1,%
1";
6952 "reload_completed && int_reg_operand (operands[
0], <MODE>mode)"
6955 rs6000_split_logical (operands, NOT, false, false, false);
6960 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6961 (const_string "veclogical")
6962 (const_string "integer")))
6963 (set (attr "length")
6965 (match_test "vsx_register_operand (operands[
0], <MODE>mode)")
6968 (match_test "TARGET_POWERPC64")
6970 (const_string "
16"))))])
6973 ;; Now define ways of moving data around.
6975 ;; Set up a register with a value from the GOT table
6977 (define_expand "movsi_got"
6978 [(set (match_operand:SI
0 "gpc_reg_operand")
6979 (unspec:SI [(match_operand:SI
1 "got_operand")
6980 (match_dup
2)] UNSPEC_MOVSI_GOT))]
6981 "DEFAULT_ABI == ABI_V4 && flag_pic ==
1"
6983 if (GET_CODE (operands[
1]) == CONST)
6985 rtx offset = const0_rtx;
6986 HOST_WIDE_INT value;
6988 operands[
1] = eliminate_constant_term (XEXP (operands[
1],
0), &offset);
6989 value = INTVAL (offset);
6992 rtx tmp = (!can_create_pseudo_p ()
6994 : gen_reg_rtx (Pmode));
6995 emit_insn (gen_movsi_got (tmp, operands[
1]));
6996 emit_insn (gen_addsi3 (operands[
0], tmp, offset));
7001 operands[
2] = rs6000_got_register (operands[
1]);
7004 (define_insn "*movsi_got_internal"
7005 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
7006 (unspec:SI [(match_operand:SI
1 "got_no_const_operand" "")
7007 (match_operand:SI
2 "gpc_reg_operand" "b")]
7009 "DEFAULT_ABI == ABI_V4 && flag_pic ==
1"
7010 "lwz %
0,%a1@got(%
2)"
7011 [(set_attr "type" "load")])
7013 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
7014 ;; didn't get allocated to a hard register.
7016 [(set (match_operand:SI
0 "gpc_reg_operand")
7017 (unspec:SI [(match_operand:SI
1 "got_no_const_operand")
7018 (match_operand:SI
2 "memory_operand")]
7020 "DEFAULT_ABI == ABI_V4
7022 && reload_completed"
7023 [(set (match_dup
0) (match_dup
2))
7024 (set (match_dup
0) (unspec:SI [(match_dup
1)(match_dup
0)]
7029 ;; LWZ LFIWZX LXSIWZX
7030 ;; STW STFIWX STXSIWX
7032 ;; XXLOR XXSPLTIB
0 XXSPLTIB -
1 VSPLTISW
7033 ;; XXLXOR
0 XXLORC -
1 P9 const
7037 (define_insn "*movsi_internal1"
7038 [(set (match_operand:SI
0 "nonimmediate_operand"
7047 (match_operand:SI
1 "input_operand"
7056 "gpc_reg_operand (operands[
0], SImode)
7057 || gpc_reg_operand (operands[
1], SImode)"
7085 load, fpload, fpload,
7086 store, fpstore, fpstore,
7088 veclogical, vecsimple, vecsimple, vecsimple,
7089 veclogical, veclogical, vecsimple,
7111 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
7112 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...)
0))
7114 ;; Because SF values are actually stored as DF values within the vector
7115 ;; registers, we need to convert the value to the vector SF format when
7116 ;; we need to use the bits in a union or similar cases. We only need
7117 ;; to do this transformation when the value is a vector register. Loads,
7118 ;; stores, and transfers within GPRs are assumed to be safe.
7120 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
7121 ;; no alternatives, because the call is created as part of secondary_reload,
7122 ;; and operand #
2's register class is used to allocate the temporary register.
7123 ;; This function is called before reload, and it creates the temporary as
7126 ;; MR LWZ LFIWZX LXSIWZX STW
7127 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
7130 (define_insn_and_split "movsi_from_sf"
7131 [(set (match_operand:SI
0 "nonimmediate_operand"
7132 "=r, r, ?*d, ?*v, m,
7135 (unspec:SI [(match_operand:SF
1 "input_operand"
7140 (clobber (match_scratch:V4SF
2
7144 "TARGET_NO_SF_SUBREG
7145 && (register_operand (operands[
0], SImode)
7146 || register_operand (operands[
1], SFmode))"
7159 "&& reload_completed
7160 && int_reg_operand (operands[
0], SImode)
7161 && vsx_reg_sfsubreg_ok (operands[
1], SFmode)"
7164 rtx op0 = operands[
0];
7165 rtx op1 = operands[
1];
7166 rtx op2 = operands[
2];
7167 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7168 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7170 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7171 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7175 "*, load, fpload, fpload, store,
7176 fpstore, fpstore, fpstore, mftgpr, fp,
7184 *, p9v, p8v, p8v, p8v,
7187 ;; movsi_from_sf with zero extension
7189 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7192 (define_insn_and_split "*movdi_from_sf_zero_ext"
7193 [(set (match_operand:DI
0 "gpc_reg_operand"
7194 "=r, r, ?*d, ?*v, r,
7197 (unspec:SI [(match_operand:SF
1 "input_operand"
7200 UNSPEC_SI_FROM_SF)))
7201 (clobber (match_scratch:V4SF
2
7204 "TARGET_DIRECT_MOVE_64BIT
7205 && (register_operand (operands[
0], DImode)
7206 || register_operand (operands[
1], SImode))"
7215 "&& reload_completed
7216 && register_operand (operands[
0], DImode)
7217 && vsx_reg_sfsubreg_ok (operands[
1], SFmode)"
7220 rtx op0 = operands[
0];
7221 rtx op1 = operands[
1];
7222 rtx op2 = operands[
2];
7223 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7225 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7226 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7230 "*, load, fpload, fpload, two,
7236 "*, *, p8v, p8v, p8v,
7239 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7240 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7241 ;; conversion explicitly since that doesn't work in most cases if the input
7242 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7243 ;; former handles cases where the input will not fit in a SFmode, and the
7244 ;; latter assumes the value has already been rounded.
7245 (define_insn "*movsi_from_df"
7246 [(set (match_operand:SI
0 "gpc_reg_operand" "=wa")
7247 (unspec:SI [(float_truncate:SF
7248 (match_operand:DF
1 "gpc_reg_operand" "wa"))]
7249 UNSPEC_SI_FROM_SF))]
7250 "TARGET_NO_SF_SUBREG"
7252 [(set_attr "type" "fp")])
7254 ;; Split a load of a large constant into the appropriate two-insn
7258 [(set (match_operand:SI
0 "gpc_reg_operand")
7259 (match_operand:SI
1 "const_int_operand"))]
7260 "num_insns_constant (operands[
1], SImode) >
1"
7264 (ior:SI (match_dup
0)
7267 if (rs6000_emit_set_const (operands[
0], operands[
1]))
7273 ;; Split loading -
128.
.127 to use XXSPLITB and VEXTSW2D
7275 [(set (match_operand:DI
0 "altivec_register_operand")
7276 (match_operand:DI
1 "xxspltib_constant_split"))]
7277 "TARGET_P9_VECTOR && reload_completed"
7280 rtx op0 = operands[
0];
7281 rtx op1 = operands[
1];
7282 int r = REGNO (op0);
7283 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7285 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7286 emit_insn (gen_vsx_sign_extend_qi_si (operands[
0], op0_v16qi));
7290 (define_insn "*mov<mode>_internal2"
7291 [(set (match_operand:CC
2 "cc_reg_operand" "=y,x,?y")
7292 (compare:CC (match_operand:P
1 "gpc_reg_operand" "
0,r,r")
7294 (set (match_operand:P
0 "gpc_reg_operand" "=r,r,r") (match_dup
1))]
7300 [(set_attr "type" "cmp,logical,cmp")
7301 (set_attr "dot" "yes")
7302 (set_attr "length" "
4,
4,
8")])
7305 [(set (match_operand:CC
2 "cc_reg_not_cr0_operand")
7306 (compare:CC (match_operand:P
1 "gpc_reg_operand")
7308 (set (match_operand:P
0 "gpc_reg_operand") (match_dup
1))]
7310 [(set (match_dup
0) (match_dup
1))
7312 (compare:CC (match_dup
0)
7316 (define_expand "mov<mode>"
7317 [(set (match_operand:INT
0 "general_operand")
7318 (match_operand:INT
1 "any_operand"))]
7321 rs6000_emit_move (operands[
0], operands[
1], <MODE>mode);
7325 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7326 ;; XXLOR load
0 load -
1 VSPLTI* # MFVSRWZ
7327 ;; MTVSRWZ MF%
1 MT%
1 NOP
7328 (define_insn "*mov<mode>_internal"
7329 [(set (match_operand:QHI
0 "nonimmediate_operand"
7330 "=r, r, wa, m, Z, r,
7331 wa, wa, wa, v, ?v, r,
7333 (match_operand:QHI
1 "input_operand"
7335 wa, O, wM, wB, wS, wa,
7337 "gpc_reg_operand (operands[
0], <MODE>mode)
7338 || gpc_reg_operand (operands[
1], <MODE>mode)"
7357 "*, load, fpload, store, fpstore, *,
7358 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7359 mffgpr, mfjmpr, mtjmpr, *")
7365 "*, *, p9v, *, p9v, *,
7366 p9v, p9v, p9v, p9v, p9v, p9v,
7370 ;; Here is how to move condition codes around. When we store CC data in
7371 ;; an integer register or memory, we store just the high-order
4 bits.
7372 ;; This lets us not shift in the most common case of CR0.
7373 (define_expand "movcc"
7374 [(set (match_operand:CC
0 "nonimmediate_operand")
7375 (match_operand:CC
1 "nonimmediate_operand"))]
7379 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7381 (define_insn "*movcc_<mode>"
7382 [(set (match_operand:CC_any
0 "nonimmediate_operand"
7383 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7384 (match_operand:CC_any
1 "general_operand"
7385 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7386 "register_operand (operands[
0], <MODE>mode)
7387 || register_operand (operands[
1], <MODE>mode)"
7391 rlwinm %
1,%
1,%F0,
0xffffffff\;mtcrf %R0,%
1\;rlwinm %
1,%
1,%f0,
0xffffffff
7394 mfcr %
0%Q1\;rlwinm %
0,%
0,%f1,
0xf0000000
7401 [(set_attr_alternative "type"
7402 [(const_string "cr_logical")
7403 (const_string "mtcr")
7404 (const_string "mtcr")
7405 (const_string "cr_logical")
7406 (if_then_else (match_test "TARGET_MFCRF")
7407 (const_string "mfcrf") (const_string "mfcr"))
7408 (if_then_else (match_test "TARGET_MFCRF")
7409 (const_string "mfcrf") (const_string "mfcr"))
7410 (const_string "integer")
7411 (const_string "integer")
7412 (const_string "mfjmpr")
7413 (const_string "mtjmpr")
7414 (const_string "load")
7415 (const_string "store")])
7416 (set_attr "length" "*,*,
12,*,*,
8,*,*,*,*,*,*")])
7418 ;; For floating-point, we normally deal with the floating-point registers
7419 ;; unless -msoft-float is used. The sole exception is that parameter passing
7420 ;; can produce floating-point values in fixed-point registers. Unless the
7421 ;; value is a simple constant or already in memory, we deal with this by
7422 ;; allocating memory and copying the value explicitly via that memory location.
7424 ;; Move
32-bit binary/decimal floating point
7425 (define_expand "mov<mode>"
7426 [(set (match_operand:FMOVE32
0 "nonimmediate_operand")
7427 (match_operand:FMOVE32
1 "any_operand"))]
7430 rs6000_emit_move (operands[
0], operands[
1], <MODE>mode);
7435 [(set (match_operand:FMOVE32
0 "gpc_reg_operand")
7436 (match_operand:FMOVE32
1 "const_double_operand"))]
7438 && ((REG_P (operands[
0]) && REGNO (operands[
0]) <=
31)
7439 || (SUBREG_P (operands[
0])
7440 && REG_P (SUBREG_REG (operands[
0]))
7441 && REGNO (SUBREG_REG (operands[
0])) <=
31))"
7442 [(set (match_dup
2) (match_dup
3))]
7446 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[
1]), l);
7448 if (! TARGET_POWERPC64)
7449 operands[
2] = operand_subword (operands[
0],
0,
0, <MODE>mode);
7451 operands[
2] = gen_lowpart (SImode, operands[
0]);
7453 operands[
3] = gen_int_mode (l, SImode);
7456 ;; Originally, we tried to keep movsf and movsd common, but the differences
7457 ;; addressing was making it rather difficult to hide with mode attributes. In
7458 ;; particular for SFmode, on ISA
2.07 (power8) systems, having the GPR store
7459 ;; before the VSX stores meant that the register allocator would tend to do a
7460 ;; direct move to the GPR (which involves conversion from scalar to
7461 ;; vector/memory formats) to save values in the traditional Altivec registers,
7462 ;; while SDmode had problems on power6 if the GPR store was not first due to
7463 ;; the power6 not having an integer store operation.
7465 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7466 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7467 ;; MR MT<x> MF<x> NOP
7469 (define_insn "movsf_hardfloat"
7470 [(set (match_operand:SF
0 "nonimmediate_operand"
7471 "=!r, f, v, wa, m, wY,
7472 Z, m, wa, !r, f, wa,
7474 (match_operand:SF
1 "input_operand"
7478 "(register_operand (operands[
0], SFmode)
7479 || register_operand (operands[
1], SFmode))
7480 && TARGET_HARD_FLOAT
7481 && (TARGET_ALLOW_SF_SUBREG
7482 || valid_sf_si_move (operands[
0], operands[
1], SFmode))"
7495 xscpsgndp %x0,%x1,%x1
7501 "load, fpload, fpload, fpload, fpstore, fpstore,
7502 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7503 *, mtjmpr, mfjmpr, *")
7505 "*, *, p9v, p8v, *, p9v,
7509 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7510 ;; FMR MR MT%
0 MF%
1 NOP
7511 (define_insn "movsd_hardfloat"
7512 [(set (match_operand:SD
0 "nonimmediate_operand"
7513 "=!r, d, m, Z, ?d, ?r,
7514 f, !r, *c*l, !r, *h")
7515 (match_operand:SD
1 "input_operand"
7518 "(register_operand (operands[
0], SDmode)
7519 || register_operand (operands[
1], SDmode))
7520 && TARGET_HARD_FLOAT"
7534 "load, fpload, store, fpstore, mffgpr, mftgpr,
7535 fpsimple, *, mtjmpr, mfjmpr, *")
7537 "*, p7, *, *, p8v, p8v,
7540 ;; MR MT%
0 MF%
0 LWZ STW LI
7541 ;; LIS G-const. F/n-const NOP
7542 (define_insn "*mov<mode>_softfloat"
7543 [(set (match_operand:FMOVE32
0 "nonimmediate_operand"
7544 "=r, *c*l, r, r, m, r,
7547 (match_operand:FMOVE32
1 "input_operand"
7551 "(gpc_reg_operand (operands[
0], <MODE>mode)
7552 || gpc_reg_operand (operands[
1], <MODE>mode))
7553 && TARGET_SOFT_FLOAT"
7566 "*, mtjmpr, mfjmpr, load, store, *,
7573 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7574 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...)
0))
7576 ;; Because SF values are actually stored as DF values within the vector
7577 ;; registers, we need to convert the value to the vector SF format when
7578 ;; we need to use the bits in a union or similar cases. We only need
7579 ;; to do this transformation when the value is a vector register. Loads,
7580 ;; stores, and transfers within GPRs are assumed to be safe.
7582 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7583 ;; no alternatives, because the call is created as part of secondary_reload,
7584 ;; and operand #
2's register class is used to allocate the temporary register.
7585 ;; This function is called before reload, and it creates the temporary as
7588 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7589 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7590 (define_insn_and_split "movsf_from_si"
7591 [(set (match_operand:SF
0 "nonimmediate_operand"
7592 "=!r, f, v, wa, m, Z,
7594 (unspec:SF [(match_operand:SI
1 "input_operand"
7598 (clobber (match_scratch:DI
2
7601 "TARGET_NO_SF_SUBREG
7602 && (register_operand (operands[
0], SFmode)
7603 || register_operand (operands[
1], SImode))"
7616 "&& reload_completed
7617 && vsx_reg_sfsubreg_ok (operands[
0], SFmode)
7618 && int_reg_operand_not_pseudo (operands[
1], SImode)"
7621 rtx op0 = operands[
0];
7622 rtx op1 = operands[
1];
7623 rtx op2 = operands[
2];
7624 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7626 /* Move SF value to upper
32-bits for xscvspdpn. */
7627 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (
32)));
7628 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7629 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7636 "load, fpload, fpload, fpload, store, fpstore,
7637 fpstore, vecfloat, mftgpr, *")
7639 "*, *, p9v, p8v, *, *,
7640 p8v, p8v, p8v, *")])
7642 ;; For extracting high part element from DImode register like:
7643 ;; {%
1:SF=unspec[r122:DI>>
0x20#
0]
86;clobber scratch;}
7644 ;; split it before reload with "and mask" to avoid generating shift right
7645 ;;
32 bit then shift left
32 bit.
7646 (define_insn_and_split "movsf_from_si2"
7647 [(set (match_operand:SF
0 "gpc_reg_operand" "=wa")
7651 (match_operand:DI
1 "input_operand" "r")
7655 (clobber (match_scratch:DI
2 "=r"))]
7656 "TARGET_NO_SF_SUBREG"
7661 if (GET_CODE (operands[
2]) == SCRATCH)
7662 operands[
2] = gen_reg_rtx (DImode);
7664 rtx mask = GEN_INT (HOST_WIDE_INT_M1U <<
32);
7665 emit_insn (gen_anddi3 (operands[
2], operands[
1], mask));
7666 emit_insn (gen_p8_mtvsrd_sf (operands[
0], operands[
2]));
7667 emit_insn (gen_vsx_xscvspdpn_directmove (operands[
0], operands[
0]));
7670 [(set_attr "length" "
12")
7671 (set_attr "type" "vecfloat")
7672 (set_attr "isa" "p8v")])
7674 ;; Move
64-bit binary/decimal floating point
7675 (define_expand "mov<mode>"
7676 [(set (match_operand:FMOVE64
0 "nonimmediate_operand")
7677 (match_operand:FMOVE64
1 "any_operand"))]
7680 rs6000_emit_move (operands[
0], operands[
1], <MODE>mode);
7685 [(set (match_operand:FMOVE64
0 "gpc_reg_operand")
7686 (match_operand:FMOVE64
1 "const_int_operand"))]
7687 "! TARGET_POWERPC64 && reload_completed
7688 && ((REG_P (operands[
0]) && REGNO (operands[
0]) <=
31)
7689 || (SUBREG_P (operands[
0])
7690 && REG_P (SUBREG_REG (operands[
0]))
7691 && REGNO (SUBREG_REG (operands[
0])) <=
31))"
7692 [(set (match_dup
2) (match_dup
4))
7693 (set (match_dup
3) (match_dup
1))]
7695 int endian = (WORDS_BIG_ENDIAN ==
0);
7696 HOST_WIDE_INT value = INTVAL (operands[
1]);
7698 operands[
2] = operand_subword (operands[
0], endian,
0, <MODE>mode);
7699 operands[
3] = operand_subword (operands[
0],
1 - endian,
0, <MODE>mode);
7700 operands[
4] = GEN_INT (value >>
32);
7701 operands[
1] = GEN_INT (((value &
0xffffffff) ^
0x80000000) -
0x80000000);
7705 [(set (match_operand:FMOVE64
0 "gpc_reg_operand")
7706 (match_operand:FMOVE64
1 "const_double_operand"))]
7707 "! TARGET_POWERPC64 && reload_completed
7708 && ((REG_P (operands[
0]) && REGNO (operands[
0]) <=
31)
7709 || (SUBREG_P (operands[
0])
7710 && REG_P (SUBREG_REG (operands[
0]))
7711 && REGNO (SUBREG_REG (operands[
0])) <=
31))"
7712 [(set (match_dup
2) (match_dup
4))
7713 (set (match_dup
3) (match_dup
5))]
7715 int endian = (WORDS_BIG_ENDIAN ==
0);
7718 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[
1]), l);
7720 operands[
2] = operand_subword (operands[
0], endian,
0, <MODE>mode);
7721 operands[
3] = operand_subword (operands[
0],
1 - endian,
0, <MODE>mode);
7722 operands[
4] = gen_int_mode (l[endian], SImode);
7723 operands[
5] = gen_int_mode (l[
1 - endian], SImode);
7727 [(set (match_operand:FMOVE64
0 "gpc_reg_operand")
7728 (match_operand:FMOVE64
1 "const_double_operand"))]
7729 "TARGET_POWERPC64 && reload_completed
7730 && ((REG_P (operands[
0]) && REGNO (operands[
0]) <=
31)
7731 || (SUBREG_P (operands[
0])
7732 && REG_P (SUBREG_REG (operands[
0]))
7733 && REGNO (SUBREG_REG (operands[
0])) <=
31))"
7734 [(set (match_dup
2) (match_dup
3))]
7736 int endian = (WORDS_BIG_ENDIAN ==
0);
7740 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[
1]), l);
7742 operands[
2] = gen_lowpart (DImode, operands[
0]);
7743 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7744 val = ((HOST_WIDE_INT)(unsigned long)l[endian] <<
32
7745 | ((HOST_WIDE_INT)(unsigned long)l[
1 - endian]));
7747 operands[
3] = gen_int_mode (val, DImode);
7750 ;; Don't have reload use general registers to load a constant. It is
7751 ;; less efficient than loading the constant into an FP register, since
7752 ;; it will probably be used there.
7754 ;; The move constraints are ordered to prefer floating point registers before
7755 ;; general purpose registers to avoid doing a store and a load to get the value
7756 ;; into a floating point register when it is needed for a floating point
7757 ;; operation. Prefer traditional floating point registers over VSX registers,
7758 ;; since the D-form version of the memory instructions does not need a GPR for
7759 ;; reloading. ISA
3.0 (power9) adds D-form addressing for scalars to Altivec
7762 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7763 ;; except for
0.0 which can be created on VSX with an xor instruction.
7765 ;; STFD LFD FMR LXSD STXSD
7766 ;; LXSD STXSD XXLOR XXLXOR GPR<-
0
7770 (define_insn "*mov<mode>_hardfloat32"
7771 [(set (match_operand:FMOVE64
0 "nonimmediate_operand"
7772 "=m, d, d, <f64_p9>, wY,
7773 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7775 (match_operand:FMOVE64
1 "input_operand"
7776 "d, m, d, wY, <f64_p9>,
7777 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7779 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7780 && (gpc_reg_operand (operands[
0], <MODE>mode)
7781 || gpc_reg_operand (operands[
1], <MODE>mode))"
7797 "fpstore, fpload, fpsimple, fpload, fpstore,
7798 fpload, fpstore, veclogical, veclogical, two,
7800 (set_attr "size" "
64")
7810 ;; STW LWZ MR G-const H-const F-const
7812 (define_insn "*mov<mode>_softfloat32"
7813 [(set (match_operand:FMOVE64
0 "nonimmediate_operand"
7814 "=Y, r, r, r, r, r")
7816 (match_operand:FMOVE64
1 "input_operand"
7817 "r, Y, r, G, H, F"))]
7820 && (gpc_reg_operand (operands[
0], <MODE>mode)
7821 || gpc_reg_operand (operands[
1], <MODE>mode))"
7824 "store, load, two, *, *, *")
7827 "
8,
8,
8,
8,
12,
16")])
7829 ; ld/std require word-aligned displacements -> 'Y' constraint.
7830 ; List Y->r and r->Y before r->r for reload.
7832 ;; STFD LFD FMR LXSD STXSD
7833 ;; LXSDX STXSDX XXLOR XXLXOR LI
0
7834 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7835 ;; NOP MFVSRD MTVSRD
7837 (define_insn "*mov<mode>_hardfloat64"
7838 [(set (match_operand:FMOVE64
0 "nonimmediate_operand"
7839 "=m, d, d, <f64_p9>, wY,
7840 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7841 YZ, r, !r, *c*l, !r,
7843 (match_operand:FMOVE64
1 "input_operand"
7844 "d, m, d, wY, <f64_p9>,
7845 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7848 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7849 && (gpc_reg_operand (operands[
0], <MODE>mode)
7850 || gpc_reg_operand (operands[
1], <MODE>mode))"
7871 "fpstore, fpload, fpsimple, fpload, fpstore,
7872 fpload, fpstore, veclogical, veclogical, integer,
7873 store, load, *, mtjmpr, mfjmpr,
7875 (set_attr "size" "
64")
7882 ;; STD LD MR MT<SPR> MF<SPR> G-const
7883 ;; H-const F-const Special
7885 (define_insn "*mov<mode>_softfloat64"
7886 [(set (match_operand:FMOVE64
0 "nonimmediate_operand"
7887 "=Y, r, r, *c*l, r, r,
7890 (match_operand:FMOVE64
1 "input_operand"
7894 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7895 && (gpc_reg_operand (operands[
0], <MODE>mode)
7896 || gpc_reg_operand (operands[
1], <MODE>mode))"
7908 "store, load, *, mtjmpr, mfjmpr, *,
7915 (define_expand "mov<mode>"
7916 [(set (match_operand:FMOVE128
0 "general_operand")
7917 (match_operand:FMOVE128
1 "any_operand"))]
7920 rs6000_emit_move (operands[
0], operands[
1], <MODE>mode);
7924 ;; It's important to list Y->r and r->Y before r->r because otherwise
7925 ;; reload, given m->r, will try to pick r->r and reload it, which
7926 ;; doesn't make progress.
7928 ;; We can't split little endian direct moves of TDmode, because the words are
7929 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7930 ;; problematical. Don't allow direct move for this case.
7932 ;; FPR load FPR store FPR move FPR zero GPR load
7933 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
7935 (define_insn_and_split "*mov<mode>_64bit_dm"
7936 [(set (match_operand:FMOVE128_FPR
0 "nonimmediate_operand"
7940 (match_operand:FMOVE128_FPR
1 "input_operand"
7941 "d, m, d, <zero_fp>, r,
7942 <zero_fp>, Y, r, d, r"))]
7944 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7945 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7946 && (gpc_reg_operand (operands[
0], <MODE>mode)
7947 || gpc_reg_operand (operands[
1], <MODE>mode))"
7949 "&& reload_completed"
7952 rs6000_split_multireg_move (operands[
0], operands[
1]);
7955 [(set_attr "length" "
8")
7956 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7957 (set_attr "max_prefixed_insns" "
2")
7958 (set_attr "num_insns" "
2")])
7960 (define_insn_and_split "*movtd_64bit_nodm"
7961 [(set (match_operand:TD
0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7962 (match_operand:TD
1 "input_operand" "d,m,d,r,Y,r"))]
7963 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7964 && (gpc_reg_operand (operands[
0], TDmode)
7965 || gpc_reg_operand (operands[
1], TDmode))"
7967 "&& reload_completed"
7970 rs6000_split_multireg_move (operands[
0], operands[
1]);
7973 [(set_attr "length" "
8,
8,
8,
12,
12,
8")
7974 (set_attr "max_prefixed_insns" "
2")
7975 (set_attr "num_insns" "
2,
2,
2,
3,
3,
2")])
7977 (define_insn_and_split "*mov<mode>_32bit"
7978 [(set (match_operand:FMOVE128_FPR
0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7979 (match_operand:FMOVE128_FPR
1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7980 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7981 && (FLOAT128_2REG_P (<MODE>mode)
7982 || int_reg_operand_not_pseudo (operands[
0], <MODE>mode)
7983 || int_reg_operand_not_pseudo (operands[
1], <MODE>mode))
7984 && (gpc_reg_operand (operands[
0], <MODE>mode)
7985 || gpc_reg_operand (operands[
1], <MODE>mode))"
7987 "&& reload_completed"
7990 rs6000_split_multireg_move (operands[
0], operands[
1]);
7993 [(set_attr "length" "
8,
8,
8,
8,
20,
20,
16")])
7995 (define_insn_and_split "*mov<mode>_softfloat"
7996 [(set (match_operand:FMOVE128
0 "nonimmediate_operand" "=Y,r,r,r")
7997 (match_operand:FMOVE128
1 "input_operand" "r,Y,F,r"))]
7999 && (gpc_reg_operand (operands[
0], <MODE>mode)
8000 || gpc_reg_operand (operands[
1], <MODE>mode))"
8002 "&& reload_completed"
8005 rs6000_split_multireg_move (operands[
0], operands[
1]);
8008 [(set_attr_alternative "length"
8009 [(if_then_else (match_test "TARGET_POWERPC64")
8011 (const_string "
16"))
8012 (if_then_else (match_test "TARGET_POWERPC64")
8014 (const_string "
16"))
8015 (if_then_else (match_test "TARGET_POWERPC64")
8017 (const_string "
32"))
8018 (if_then_else (match_test "TARGET_POWERPC64")
8020 (const_string "
16"))])])
8022 (define_expand "@extenddf<mode>
2"
8023 [(set (match_operand:FLOAT128
0 "gpc_reg_operand")
8024 (float_extend:FLOAT128 (match_operand:DF
1 "gpc_reg_operand")))]
8025 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8027 if (FLOAT128_IEEE_P (<MODE>mode))
8028 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8029 else if (TARGET_VSX)
8030 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[
0], operands[
1]));
8033 rtx zero = gen_reg_rtx (DFmode);
8034 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
8036 emit_insn (gen_extenddf2_fprs (<MODE>mode,
8037 operands[
0], operands[
1], zero));
8042 ;; Allow memory operands for the source to be created by the combiner.
8043 (define_insn_and_split "@extenddf<mode>
2_fprs"
8044 [(set (match_operand:IBM128
0 "gpc_reg_operand" "=d,d,&d")
8045 (float_extend:IBM128
8046 (match_operand:DF
1 "nonimmediate_operand" "d,m,d")))
8047 (use (match_operand:DF
2 "nonimmediate_operand" "m,m,d"))]
8048 "!TARGET_VSX && TARGET_HARD_FLOAT
8049 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
8051 "&& reload_completed"
8052 [(set (match_dup
3) (match_dup
1))
8053 (set (match_dup
4) (match_dup
2))]
8055 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) :
0;
8056 const int hi_word = LONG_DOUBLE_LARGE_FIRST ?
0 : GET_MODE_SIZE (DFmode);
8058 operands[
3] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, hi_word);
8059 operands[
4] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, lo_word);
8062 (define_insn_and_split "@extenddf<mode>
2_vsx"
8063 [(set (match_operand:IBM128
0 "gpc_reg_operand" "=d,d")
8064 (float_extend:IBM128
8065 (match_operand:DF
1 "nonimmediate_operand" "wa,m")))]
8066 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
8068 "&& reload_completed"
8069 [(set (match_dup
2) (match_dup
1))
8070 (set (match_dup
3) (match_dup
4))]
8072 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) :
0;
8073 const int hi_word = LONG_DOUBLE_LARGE_FIRST ?
0 : GET_MODE_SIZE (DFmode);
8075 operands[
2] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, hi_word);
8076 operands[
3] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, lo_word);
8077 operands[
4] = CONST0_RTX (DFmode);
8080 (define_expand "extendsf<mode>
2"
8081 [(set (match_operand:FLOAT128
0 "gpc_reg_operand")
8082 (float_extend:FLOAT128 (match_operand:SF
1 "gpc_reg_operand")))]
8083 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8085 if (FLOAT128_IEEE_P (<MODE>mode))
8086 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8089 rtx tmp = gen_reg_rtx (DFmode);
8090 emit_insn (gen_extendsfdf2 (tmp, operands[
1]));
8091 emit_insn (gen_extenddf<mode>
2 (operands[
0], tmp));
8096 (define_expand "trunc<mode>df2"
8097 [(set (match_operand:DF
0 "gpc_reg_operand")
8098 (float_truncate:DF (match_operand:FLOAT128
1 "gpc_reg_operand")))]
8099 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8101 if (FLOAT128_IEEE_P (<MODE>mode))
8103 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8108 (define_insn_and_split "trunc<mode>df2_internal1"
8109 [(set (match_operand:DF
0 "gpc_reg_operand" "=d,?d")
8111 (match_operand:IBM128
1 "gpc_reg_operand" "
0,d")))]
8112 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
8113 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8117 "&& reload_completed && REGNO (operands[
0]) == REGNO (operands[
1])"
8120 emit_note (NOTE_INSN_DELETED);
8123 [(set_attr "type" "fpsimple")])
8125 (define_insn "trunc<mode>df2_internal2"
8126 [(set (match_operand:DF
0 "gpc_reg_operand" "=d")
8127 (float_truncate:DF (match_operand:IBM128
1 "gpc_reg_operand" "d")))]
8128 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8129 && TARGET_LONG_DOUBLE_128"
8131 [(set_attr "type" "fp")])
8133 (define_expand "trunc<mode>sf2"
8134 [(set (match_operand:SF
0 "gpc_reg_operand")
8135 (float_truncate:SF (match_operand:FLOAT128
1 "gpc_reg_operand")))]
8136 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8138 if (FLOAT128_IEEE_P (<MODE>mode))
8139 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8142 rtx tmp = gen_reg_rtx (DFmode);
8143 emit_insn (gen_trunc<mode>df2 (tmp, operands[
1]));
8144 emit_insn (gen_truncdfsf2 (operands[
0], tmp));
8149 (define_expand "floatsi<mode>
2"
8150 [(parallel [(set (match_operand:FLOAT128
0 "gpc_reg_operand")
8151 (float:FLOAT128 (match_operand:SI
1 "gpc_reg_operand")))
8152 (clobber (match_scratch:DI
2))])]
8153 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8155 rtx op0 = operands[
0];
8156 rtx op1 = operands[
1];
8158 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8160 else if (FLOAT128_IEEE_P (<MODE>mode))
8162 rs6000_expand_float128_convert (op0, op1, false);
8167 rtx tmp = gen_reg_rtx (DFmode);
8168 expand_float (tmp, op1, false);
8169 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8174 ; fadd, but rounding towards zero.
8175 ; This is probably not the optimal code sequence.
8176 (define_insn "fix_trunc_helper<mode>"
8177 [(set (match_operand:DF
0 "gpc_reg_operand" "=d")
8178 (unspec:DF [(match_operand:IBM128
1 "gpc_reg_operand" "d")]
8179 UNSPEC_FIX_TRUNC_TF))
8180 (clobber (match_operand:DF
2 "gpc_reg_operand" "=&d"))]
8181 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8182 "mffs %
2\n\tmtfsb
1 31\n\tmtfsb
0 30\n\tfadd %
0,%
1,%L1
\n\tmtfsf
1,%
2"
8183 [(set_attr "type" "fp")
8184 (set_attr "length" "
20")])
8186 (define_expand "fix_trunc<mode>si2"
8187 [(set (match_operand:SI
0 "gpc_reg_operand")
8188 (fix:SI (match_operand:FLOAT128
1 "gpc_reg_operand")))]
8189 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8191 rtx op0 = operands[
0];
8192 rtx op1 = operands[
1];
8194 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8198 if (FLOAT128_IEEE_P (<MODE>mode))
8199 rs6000_expand_float128_convert (op0, op1, false);
8201 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8206 (define_expand "@fix_trunc<mode>si2_fprs"
8207 [(parallel [(set (match_operand:SI
0 "gpc_reg_operand")
8208 (fix:SI (match_operand:IBM128
1 "gpc_reg_operand")))
8209 (clobber (match_dup
2))
8210 (clobber (match_dup
3))
8211 (clobber (match_dup
4))
8212 (clobber (match_dup
5))])]
8213 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8215 operands[
2] = gen_reg_rtx (DFmode);
8216 operands[
3] = gen_reg_rtx (DFmode);
8217 operands[
4] = gen_reg_rtx (DImode);
8218 operands[
5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8221 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8222 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
8223 (fix:SI (match_operand:IBM128
1 "gpc_reg_operand" "d")))
8224 (clobber (match_operand:DF
2 "gpc_reg_operand" "=d"))
8225 (clobber (match_operand:DF
3 "gpc_reg_operand" "=&d"))
8226 (clobber (match_operand:DI
4 "gpc_reg_operand" "=d"))
8227 (clobber (match_operand:DI
5 "offsettable_mem_operand" "=o"))]
8228 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8234 emit_insn (gen_fix_trunc_helper<mode> (operands[
2], operands[
1],
8237 gcc_assert (MEM_P (operands[
5]));
8238 lowword = adjust_address (operands[
5], SImode, WORDS_BIG_ENDIAN ?
4 :
0);
8240 emit_insn (gen_fctiwz_df (operands[
4], operands[
2]));
8241 emit_move_insn (operands[
5], operands[
4]);
8242 emit_move_insn (operands[
0], lowword);
8246 (define_expand "fix_trunc<mode>di2"
8247 [(set (match_operand:DI
0 "gpc_reg_operand")
8248 (fix:DI (match_operand:IEEE128
1 "gpc_reg_operand")))]
8249 "TARGET_FLOAT128_TYPE"
8251 if (!TARGET_FLOAT128_HW)
8253 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8258 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>
2"
8259 [(set (match_operand:SDI
0 "gpc_reg_operand")
8260 (unsigned_fix:SDI (match_operand:IEEE128
1 "gpc_reg_operand")))]
8261 "TARGET_FLOAT128_TYPE"
8263 rs6000_expand_float128_convert (operands[
0], operands[
1], true);
8267 (define_expand "floatdi<mode>
2"
8268 [(set (match_operand:IEEE128
0 "gpc_reg_operand")
8269 (float:IEEE128 (match_operand:DI
1 "gpc_reg_operand")))]
8270 "TARGET_FLOAT128_TYPE"
8272 if (!TARGET_FLOAT128_HW)
8274 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8279 (define_expand "floatunsdi<IEEE128:mode>
2"
8280 [(set (match_operand:IEEE128
0 "gpc_reg_operand")
8281 (unsigned_float:IEEE128 (match_operand:DI
1 "gpc_reg_operand")))]
8282 "TARGET_FLOAT128_TYPE"
8284 if (!TARGET_FLOAT128_HW)
8286 rs6000_expand_float128_convert (operands[
0], operands[
1], true);
8291 (define_expand "floatuns<IEEE128:mode>
2"
8292 [(set (match_operand:IEEE128
0 "gpc_reg_operand")
8293 (unsigned_float:IEEE128 (match_operand:SI
1 "gpc_reg_operand")))]
8294 "TARGET_FLOAT128_TYPE"
8296 rtx op0 = operands[
0];
8297 rtx op1 = operands[
1];
8299 if (TARGET_FLOAT128_HW)
8300 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8302 rs6000_expand_float128_convert (op0, op1, true);
8306 (define_expand "neg<mode>
2"
8307 [(set (match_operand:FLOAT128
0 "gpc_reg_operand")
8308 (neg:FLOAT128 (match_operand:FLOAT128
1 "gpc_reg_operand")))]
8309 "FLOAT128_IEEE_P (<MODE>mode)
8310 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8312 if (FLOAT128_IEEE_P (<MODE>mode))
8314 if (TARGET_FLOAT128_HW)
8315 emit_insn (gen_neg2_hw (<MODE>mode, operands[
0], operands[
1]));
8316 else if (TARGET_FLOAT128_TYPE)
8317 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8318 operands[
0], operands[
1]));
8321 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8322 rtx target = emit_library_call_value (libfunc, operands[
0], LCT_CONST,
8324 operands[
1], <MODE>mode);
8326 if (target && !rtx_equal_p (target, operands[
0]))
8327 emit_move_insn (operands[
0], target);
8333 (define_insn "neg<mode>
2_internal"
8334 [(set (match_operand:IBM128
0 "gpc_reg_operand" "=d")
8335 (neg:IBM128 (match_operand:IBM128
1 "gpc_reg_operand" "d")))]
8336 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8338 if (REGNO (operands[
0]) == REGNO (operands[
1]) +
1)
8339 return "fneg %L0,%L1\;fneg %
0,%
1";
8341 return "fneg %
0,%
1\;fneg %L0,%L1";
8343 [(set_attr "type" "fpsimple")
8344 (set_attr "length" "
8")])
8346 (define_expand "abs<mode>
2"
8347 [(set (match_operand:FLOAT128
0 "gpc_reg_operand")
8348 (abs:FLOAT128 (match_operand:FLOAT128
1 "gpc_reg_operand")))]
8349 "FLOAT128_IEEE_P (<MODE>mode)
8350 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8354 if (FLOAT128_IEEE_P (<MODE>mode))
8356 if (TARGET_FLOAT128_HW)
8358 emit_insn (gen_abs2_hw (<MODE>mode, operands[
0], operands[
1]));
8361 else if (TARGET_FLOAT128_TYPE)
8363 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8364 operands[
0], operands[
1]));
8371 label = gen_label_rtx ();
8372 emit_insn (gen_abs2_internal (<MODE>mode, operands[
0], operands[
1], label));
8377 (define_expand "@abs<mode>
2_internal"
8378 [(set (match_operand:IBM128
0 "gpc_reg_operand")
8379 (match_operand:IBM128
1 "gpc_reg_operand"))
8380 (set (match_dup
3) (match_dup
5))
8381 (set (match_dup
5) (abs:DF (match_dup
5)))
8382 (set (match_dup
4) (compare:CCFP (match_dup
3) (match_dup
5)))
8383 (set (pc) (if_then_else (eq (match_dup
4) (const_int
0))
8384 (label_ref (match_operand
2 ""))
8386 (set (match_dup
6) (neg:DF (match_dup
6)))]
8387 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8389 const int hi_word = LONG_DOUBLE_LARGE_FIRST ?
0 : GET_MODE_SIZE (DFmode);
8390 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) :
0;
8391 operands[
3] = gen_reg_rtx (DFmode);
8392 operands[
4] = gen_reg_rtx (CCFPmode);
8393 operands[
5] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, hi_word);
8394 operands[
6] = simplify_gen_subreg (DFmode, operands[
0], <MODE>mode, lo_word);
8398 ;; Generate IEEE
128-bit -
0.0 (
0x80000000000000000000000000000000) in a vector
8401 (define_expand "ieee_128bit_negative_zero"
8402 [(set (match_operand:V16QI
0 "register_operand") (match_dup
1))]
8403 "TARGET_FLOAT128_TYPE"
8405 rtvec v = rtvec_alloc (
16);
8408 for (i =
0; i <
16; i++)
8409 RTVEC_ELT (v, i) = const0_rtx;
8411 high = (BYTES_BIG_ENDIAN) ?
0 :
15;
8412 RTVEC_ELT (v, high) = gen_int_mode (
0x80, QImode);
8414 rs6000_expand_vector_init (operands[
0], gen_rtx_PARALLEL (V16QImode, v));
8418 ;; IEEE
128-bit negate
8420 ;; We have
2 insns here for negate and absolute value. The first uses
8421 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8422 ;; insns, and second insn after the first split pass loads up the bit to
8423 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8424 ;; neg/abs to create the constant just once.
8426 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>
2"
8427 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
8428 (neg:IEEE128 (match_operand:IEEE128
1 "register_operand" "wa")))
8429 (clobber (match_scratch:V16QI
2 "=v"))]
8430 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8433 [(parallel [(set (match_dup
0)
8434 (neg:IEEE128 (match_dup
1)))
8435 (use (match_dup
2))])]
8437 if (GET_CODE (operands[
2]) == SCRATCH)
8438 operands[
2] = gen_reg_rtx (V16QImode);
8440 operands[
3] = gen_reg_rtx (V16QImode);
8441 emit_insn (gen_ieee_128bit_negative_zero (operands[
2]));
8443 [(set_attr "length" "
8")
8444 (set_attr "type" "vecsimple")])
8446 (define_insn "*ieee_128bit_vsx_neg<mode>
2_internal"
8447 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
8448 (neg:IEEE128 (match_operand:IEEE128
1 "register_operand" "wa")))
8449 (use (match_operand:V16QI
2 "register_operand" "v"))]
8450 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8451 "xxlxor %x0,%x1,%x2"
8452 [(set_attr "type" "veclogical")])
8454 ;; IEEE
128-bit absolute value
8455 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>
2"
8456 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
8457 (abs:IEEE128 (match_operand:IEEE128
1 "register_operand" "wa")))
8458 (clobber (match_scratch:V16QI
2 "=v"))]
8459 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8462 [(parallel [(set (match_dup
0)
8463 (abs:IEEE128 (match_dup
1)))
8464 (use (match_dup
2))])]
8466 if (GET_CODE (operands[
2]) == SCRATCH)
8467 operands[
2] = gen_reg_rtx (V16QImode);
8469 operands[
3] = gen_reg_rtx (V16QImode);
8470 emit_insn (gen_ieee_128bit_negative_zero (operands[
2]));
8472 [(set_attr "length" "
8")
8473 (set_attr "type" "vecsimple")])
8475 (define_insn "*ieee_128bit_vsx_abs<mode>
2_internal"
8476 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
8477 (abs:IEEE128 (match_operand:IEEE128
1 "register_operand" "wa")))
8478 (use (match_operand:V16QI
2 "register_operand" "v"))]
8479 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8480 "xxlandc %x0,%x1,%x2"
8481 [(set_attr "type" "veclogical")])
8483 ;; IEEE
128-bit negative absolute value
8484 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>
2"
8485 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
8488 (match_operand:IEEE128
1 "register_operand" "wa"))))
8489 (clobber (match_scratch:V16QI
2 "=v"))]
8490 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8491 && FLOAT128_IEEE_P (<MODE>mode)"
8494 [(parallel [(set (match_dup
0)
8495 (neg:IEEE128 (abs:IEEE128 (match_dup
1))))
8496 (use (match_dup
2))])]
8498 if (GET_CODE (operands[
2]) == SCRATCH)
8499 operands[
2] = gen_reg_rtx (V16QImode);
8501 operands[
3] = gen_reg_rtx (V16QImode);
8502 emit_insn (gen_ieee_128bit_negative_zero (operands[
2]));
8504 [(set_attr "length" "
8")
8505 (set_attr "type" "vecsimple")])
8507 (define_insn "*ieee_128bit_vsx_nabs<mode>
2_internal"
8508 [(set (match_operand:IEEE128
0 "register_operand" "=wa")
8511 (match_operand:IEEE128
1 "register_operand" "wa"))))
8512 (use (match_operand:V16QI
2 "register_operand" "v"))]
8513 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8515 [(set_attr "type" "veclogical")])
8517 ;; Float128 conversion functions. These expand to library function calls.
8518 ;; We use expand to convert from IBM double double to IEEE
128-bit
8519 ;; and trunc for the opposite.
8520 (define_expand "extendiftf2"
8521 [(set (match_operand:TF
0 "gpc_reg_operand")
8522 (float_extend:TF (match_operand:IF
1 "gpc_reg_operand")))]
8523 "TARGET_FLOAT128_TYPE"
8525 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8529 (define_expand "extendifkf2"
8530 [(set (match_operand:KF
0 "gpc_reg_operand")
8531 (float_extend:KF (match_operand:IF
1 "gpc_reg_operand")))]
8532 "TARGET_FLOAT128_TYPE"
8534 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8538 (define_expand "extendtfkf2"
8539 [(set (match_operand:KF
0 "gpc_reg_operand")
8540 (float_extend:KF (match_operand:TF
1 "gpc_reg_operand")))]
8541 "TARGET_FLOAT128_TYPE"
8543 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8547 (define_expand "extendtfif2"
8548 [(set (match_operand:IF
0 "gpc_reg_operand")
8549 (float_extend:IF (match_operand:TF
1 "gpc_reg_operand")))]
8550 "TARGET_FLOAT128_TYPE"
8552 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8556 (define_expand "trunciftf2"
8557 [(set (match_operand:TF
0 "gpc_reg_operand")
8558 (float_truncate:TF (match_operand:IF
1 "gpc_reg_operand")))]
8559 "TARGET_FLOAT128_TYPE"
8561 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8565 (define_expand "truncifkf2"
8566 [(set (match_operand:KF
0 "gpc_reg_operand")
8567 (float_truncate:KF (match_operand:IF
1 "gpc_reg_operand")))]
8568 "TARGET_FLOAT128_TYPE"
8570 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8574 (define_expand "trunckftf2"
8575 [(set (match_operand:TF
0 "gpc_reg_operand")
8576 (float_truncate:TF (match_operand:KF
1 "gpc_reg_operand")))]
8577 "TARGET_FLOAT128_TYPE"
8579 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8583 (define_expand "trunctfif2"
8584 [(set (match_operand:IF
0 "gpc_reg_operand")
8585 (float_truncate:IF (match_operand:TF
1 "gpc_reg_operand")))]
8586 "TARGET_FLOAT128_TYPE"
8588 rs6000_expand_float128_convert (operands[
0], operands[
1], false);
8592 (define_insn_and_split "*extend<mode>tf2_internal"
8593 [(set (match_operand:TF
0 "gpc_reg_operand" "=<IFKF_reg>")
8595 (match_operand:IFKF
1 "gpc_reg_operand" "<IFKF_reg>")))]
8596 "TARGET_FLOAT128_TYPE
8597 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8599 "&& reload_completed"
8600 [(set (match_dup
0) (match_dup
2))]
8602 operands[
2] = gen_rtx_REG (TFmode, REGNO (operands[
1]));
8605 (define_insn_and_split "*extendtf<mode>
2_internal"
8606 [(set (match_operand:IFKF
0 "gpc_reg_operand" "=<IFKF_reg>")
8608 (match_operand:TF
1 "gpc_reg_operand" "<IFKF_reg>")))]
8609 "TARGET_FLOAT128_TYPE
8610 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8612 "&& reload_completed"
8613 [(set (match_dup
0) (match_dup
2))]
8615 operands[
2] = gen_rtx_REG (<MODE>mode, REGNO (operands[
1]));
8619 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8620 ;; must have
3 arguments, and scratch register constraint must be a single
8623 ;; Reload patterns to support gpr load/store with misaligned mem.
8624 ;; and multiple gpr load/store at offset >=
0xfffc
8625 (define_expand "reload_<mode>_store"
8626 [(parallel [(match_operand
0 "memory_operand" "=m")
8627 (match_operand
1 "gpc_reg_operand" "r")
8628 (match_operand:GPR
2 "register_operand" "=&b")])]
8631 rs6000_secondary_reload_gpr (operands[
1], operands[
0], operands[
2], true);
8635 (define_expand "reload_<mode>_load"
8636 [(parallel [(match_operand
0 "gpc_reg_operand" "=r")
8637 (match_operand
1 "memory_operand" "m")
8638 (match_operand:GPR
2 "register_operand" "=b")])]
8641 rs6000_secondary_reload_gpr (operands[
0], operands[
1], operands[
2], false);
8646 ;; Reload patterns for various types using the vector registers. We may need
8647 ;; an additional base register to convert the reg+offset addressing to reg+reg
8648 ;; for vector registers and reg+reg or (reg+reg)&(-
16) addressing to just an
8649 ;; index register for gpr registers.
8650 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8651 [(parallel [(match_operand:RELOAD
0 "memory_operand" "m")
8652 (match_operand:RELOAD
1 "gpc_reg_operand" "wa")
8653 (match_operand:P
2 "register_operand" "=b")])]
8656 rs6000_secondary_reload_inner (operands[
1], operands[
0], operands[
2], true);
8660 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8661 [(parallel [(match_operand:RELOAD
0 "gpc_reg_operand" "wa")
8662 (match_operand:RELOAD
1 "memory_operand" "m")
8663 (match_operand:P
2 "register_operand" "=b")])]
8666 rs6000_secondary_reload_inner (operands[
0], operands[
1], operands[
2], false);
8671 ;; Reload sometimes tries to move the address to a GPR, and can generate
8672 ;; invalid RTL for addresses involving AND -
16. Allow addresses involving
8673 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -
16.
8675 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8676 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
8677 (and:P (plus:P (match_operand:P
1 "gpc_reg_operand" "r")
8678 (match_operand:P
2 "reg_or_cint_operand" "rI"))
8680 "TARGET_ALTIVEC && reload_completed"
8682 "&& reload_completed"
8684 (plus:P (match_dup
1)
8687 (and:P (match_dup
0)
8690 ;; Power8 merge instructions to allow direct move to/from floating point
8691 ;; registers in
32-bit mode. We use TF mode to get two registers to move the
8692 ;; individual
32-bit parts across. Subreg doesn't work too well on the TF
8693 ;; value, since it is allocated in reload and not all of the flow information
8694 ;; is setup for it. We have two patterns to do the two moves between gprs and
8695 ;; fprs. There isn't a dependancy between the two, but we could potentially
8696 ;; schedule other instructions between the two instructions.
8698 (define_insn "p8_fmrgow_<mode>"
8699 [(set (match_operand:FMOVE64X
0 "register_operand" "=d")
8701 (match_operand:DF
1 "register_operand" "d")
8702 (match_operand:DF
2 "register_operand" "d")]
8703 UNSPEC_P8V_FMRGOW))]
8704 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8706 [(set_attr "type" "fpsimple")])
8708 (define_insn "p8_mtvsrwz"
8709 [(set (match_operand:DF
0 "register_operand" "=d")
8710 (unspec:DF [(match_operand:SI
1 "register_operand" "r")]
8711 UNSPEC_P8V_MTVSRWZ))]
8712 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8714 [(set_attr "type" "mffgpr")])
8716 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8717 [(set (match_operand:FMOVE64X
0 "register_operand" "=d")
8718 (unspec:FMOVE64X [(match_operand:FMOVE64X
1 "register_operand" "r")]
8719 UNSPEC_P8V_RELOAD_FROM_GPR))
8720 (clobber (match_operand:IF
2 "register_operand" "=d"))]
8721 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8723 "&& reload_completed"
8726 rtx dest = operands[
0];
8727 rtx src = operands[
1];
8728 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[
2], IFmode,
0);
8729 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[
2], IFmode,
8);
8730 rtx gpr_hi_reg = gen_highpart (SImode, src);
8731 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8733 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8734 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8735 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8738 [(set_attr "length" "
12")
8739 (set_attr "type" "three")])
8741 ;; Move
128 bit values from GPRs to VSX registers in
64-bit mode
8742 (define_insn "p8_mtvsrd_df"
8743 [(set (match_operand:DF
0 "register_operand" "=wa")
8744 (unspec:DF [(match_operand:DI
1 "register_operand" "r")]
8745 UNSPEC_P8V_MTVSRD))]
8746 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8748 [(set_attr "type" "mftgpr")])
8750 (define_insn "p8_xxpermdi_<mode>"
8751 [(set (match_operand:FMOVE128_GPR
0 "register_operand" "=wa")
8752 (unspec:FMOVE128_GPR [
8753 (match_operand:DF
1 "register_operand" "wa")
8754 (match_operand:DF
2 "register_operand" "wa")]
8755 UNSPEC_P8V_XXPERMDI))]
8756 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8757 "xxpermdi %x0,%x1,%x2,
0"
8758 [(set_attr "type" "vecperm")])
8760 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8761 [(set (match_operand:FMOVE128_GPR
0 "register_operand" "=wa")
8762 (unspec:FMOVE128_GPR
8763 [(match_operand:FMOVE128_GPR
1 "register_operand" "r")]
8764 UNSPEC_P8V_RELOAD_FROM_GPR))
8765 (clobber (match_operand:IF
2 "register_operand" "=wa"))]
8766 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8768 "&& reload_completed"
8771 rtx dest = operands[
0];
8772 rtx src = operands[
1];
8773 /* You might think that we could use op0 as one temp and a DF clobber
8774 as op2, but you'd be wrong. Secondary reload move patterns don't
8775 check for overlap of the clobber and the destination. */
8776 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[
2], IFmode,
0);
8777 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[
2], IFmode,
8);
8778 rtx gpr_hi_reg = gen_highpart (DImode, src);
8779 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8781 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8782 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8783 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8786 [(set_attr "length" "
12")
8787 (set_attr "type" "three")])
8790 [(set (match_operand:FMOVE128_GPR
0 "nonimmediate_operand")
8791 (match_operand:FMOVE128_GPR
1 "input_operand"))]
8793 && (int_reg_operand (operands[
0], <MODE>mode)
8794 || int_reg_operand (operands[
1], <MODE>mode))
8795 && (!TARGET_DIRECT_MOVE_128
8796 || (!vsx_register_operand (operands[
0], <MODE>mode)
8797 && !vsx_register_operand (operands[
1], <MODE>mode)))"
8800 rs6000_split_multireg_move (operands[
0], operands[
1]);
8804 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8805 ;; type is stored internally as double precision in the VSX registers, we have
8806 ;; to convert it from the vector format.
8807 (define_insn "p8_mtvsrd_sf"
8808 [(set (match_operand:SF
0 "register_operand" "=wa")
8809 (unspec:SF [(match_operand:DI
1 "register_operand" "r")]
8810 UNSPEC_P8V_MTVSRD))]
8811 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8813 [(set_attr "type" "mffgpr")])
8815 (define_insn_and_split "reload_vsx_from_gprsf"
8816 [(set (match_operand:SF
0 "register_operand" "=wa")
8817 (unspec:SF [(match_operand:SF
1 "register_operand" "r")]
8818 UNSPEC_P8V_RELOAD_FROM_GPR))
8819 (clobber (match_operand:DI
2 "register_operand" "=r"))]
8820 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8822 "&& reload_completed"
8825 rtx op0 = operands[
0];
8826 rtx op1 = operands[
1];
8827 rtx op2 = operands[
2];
8828 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode,
0);
8830 /* Move SF value to upper
32-bits for xscvspdpn. */
8831 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (
32)));
8832 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8833 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8836 [(set_attr "length" "
8")
8837 (set_attr "type" "two")])
8839 ;; Move
128 bit values from VSX registers to GPRs in
64-bit mode by doing a
8840 ;; normal
64-bit move, followed by an xxpermdi to get the bottom
64-bit value,
8841 ;; and then doing a move of that.
8842 (define_insn "p8_mfvsrd_3_<mode>"
8843 [(set (match_operand:DF
0 "register_operand" "=r")
8844 (unspec:DF [(match_operand:FMOVE128_GPR
1 "register_operand" "wa")]
8845 UNSPEC_P8V_RELOAD_FROM_VSX))]
8846 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8848 [(set_attr "type" "mftgpr")])
8850 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8851 [(set (match_operand:FMOVE128_GPR
0 "register_operand" "=r")
8852 (unspec:FMOVE128_GPR
8853 [(match_operand:FMOVE128_GPR
1 "register_operand" "wa")]
8854 UNSPEC_P8V_RELOAD_FROM_VSX))
8855 (clobber (match_operand:FMOVE128_GPR
2 "register_operand" "=wa"))]
8856 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8858 "&& reload_completed"
8861 rtx dest = operands[
0];
8862 rtx src = operands[
1];
8863 rtx tmp = operands[
2];
8864 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8865 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8867 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8868 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (
3)));
8869 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8872 [(set_attr "length" "
12")
8873 (set_attr "type" "three")])
8875 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8876 ;; type is stored internally as double precision, we have to convert it to the
8879 (define_insn_and_split "reload_gpr_from_vsxsf"
8880 [(set (match_operand:SF
0 "register_operand" "=r")
8881 (unspec:SF [(match_operand:SF
1 "register_operand" "wa")]
8882 UNSPEC_P8V_RELOAD_FROM_VSX))
8883 (clobber (match_operand:V4SF
2 "register_operand" "=wa"))]
8884 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8886 "&& reload_completed"
8889 rtx op0 = operands[
0];
8890 rtx op1 = operands[
1];
8891 rtx op2 = operands[
2];
8892 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8893 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8895 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8896 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8899 [(set_attr "length" "
8")
8900 (set_attr "type" "two")
8901 (set_attr "isa" "p8v")])
8903 ;; Next come the multi-word integer load and store and the load and store
8906 ;; List r->r after r->Y, otherwise reload will try to reload a
8907 ;; non-offsettable address by using r->r which won't make progress.
8908 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8909 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8911 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8912 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8913 ;; P9
0 P9 -
1 AVX
0/-
1 VSX
0 VSX -
1 P9 const
8916 (define_insn "*movdi_internal32"
8917 [(set (match_operand:DI
0 "nonimmediate_operand"
8918 "=Y, r, r, m, ^d, ^d,
8919 r, wY, Z, ^v, $v, ^wa,
8920 wa, wa, v, wa, *i, v,
8922 (match_operand:DI
1 "input_operand"
8923 "r, Y, r, ^d, m, ^d,
8924 IJKnF, ^v, $v, wY, Z, ^wa,
8925 Oj, wM, OjwM, Oj, wM, wS,
8928 && (gpc_reg_operand (operands[
0], DImode)
8929 || gpc_reg_operand (operands[
1], DImode))"
8951 "store, load, *, fpstore, fpload, fpsimple,
8952 *, fpstore, fpstore, fpload, fpload, veclogical,
8953 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8955 (set_attr "size" "
64")
8963 *, p9v, p7v, p9v, p7v, *,
8964 p9v, p9v, p7v, *, *, p7v,
8968 [(set (match_operand:DI
0 "gpc_reg_operand")
8969 (match_operand:DI
1 "const_int_operand"))]
8970 "! TARGET_POWERPC64 && reload_completed
8971 && gpr_or_gpr_p (operands[
0], operands[
1])
8972 && !direct_move_p (operands[
0], operands[
1])"
8973 [(set (match_dup
2) (match_dup
4))
8974 (set (match_dup
3) (match_dup
1))]
8976 HOST_WIDE_INT value = INTVAL (operands[
1]);
8977 operands[
2] = operand_subword_force (operands[
0], WORDS_BIG_ENDIAN ==
0,
8979 operands[
3] = operand_subword_force (operands[
0], WORDS_BIG_ENDIAN !=
0,
8981 operands[
4] = GEN_INT (value >>
32);
8982 operands[
1] = GEN_INT (((value &
0xffffffff) ^
0x80000000) -
0x80000000);
8986 [(set (match_operand:DIFD
0 "nonimmediate_operand")
8987 (match_operand:DIFD
1 "input_operand"))]
8988 "reload_completed && !TARGET_POWERPC64
8989 && gpr_or_gpr_p (operands[
0], operands[
1])
8990 && !direct_move_p (operands[
0], operands[
1])"
8993 rs6000_split_multireg_move (operands[
0], operands[
1]);
8997 ;; GPR store GPR load GPR move
8998 ;; GPR li GPR lis GPR pli GPR #
8999 ;; FPR store FPR load FPR move
9000 ;; AVX store AVX store AVX load AVX load VSX move
9001 ;; P9
0 P9 -
1 AVX
0/-
1 VSX
0 VSX -
1
9002 ;; P9 const AVX const
9003 ;; From SPR To SPR SPR<->SPR
9004 ;; VSX->GPR GPR->VSX
9005 (define_insn "*movdi_internal64"
9006 [(set (match_operand:DI
0 "nonimmediate_operand"
9015 (match_operand:DI
1 "input_operand"
9020 Oj, wM, OjwM, Oj, wM,
9025 && (gpc_reg_operand (operands[
0], DImode)
9026 || gpc_reg_operand (operands[
1], DImode))"
9058 fpstore, fpload, fpsimple,
9059 fpstore, fpstore, fpload, fpload, veclogical,
9060 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
9061 vecsimple, vecsimple,
9064 (set_attr "size" "
64")
9078 p9v, p7v, p9v, p7v, *,
9079 p9v, p9v, p7v, *, *,
9084 ; Some DImode loads are best done as a load of -
1 followed by a mask
9087 [(set (match_operand:DI
0 "int_reg_operand_not_pseudo")
9088 (match_operand:DI
1 "const_int_operand"))]
9090 && num_insns_constant (operands[
1], DImode) >
1
9091 && !IN_RANGE (INTVAL (operands[
1]), -
0x80000000,
0xffffffff)
9092 && rs6000_is_valid_and_mask (operands[
1], DImode)"
9096 (and:DI (match_dup
0)
9100 ;; Split a load of a large constant into the appropriate five-instruction
9101 ;; sequence. Handle anything in a constant number of insns.
9102 ;; When non-easy constants can go in the TOC, this should use
9103 ;; easy_fp_constant predicate.
9105 [(set (match_operand:DI
0 "int_reg_operand_not_pseudo")
9106 (match_operand:DI
1 "const_int_operand"))]
9107 "TARGET_POWERPC64 && num_insns_constant (operands[
1], DImode) >
1"
9108 [(set (match_dup
0) (match_dup
2))
9109 (set (match_dup
0) (plus:DI (match_dup
0) (match_dup
3)))]
9111 if (rs6000_emit_set_const (operands[
0], operands[
1]))
9118 [(set (match_operand:DI
0 "int_reg_operand_not_pseudo")
9119 (match_operand:DI
1 "const_scalar_int_operand"))]
9120 "TARGET_POWERPC64 && num_insns_constant (operands[
1], DImode) >
1"
9121 [(set (match_dup
0) (match_dup
2))
9122 (set (match_dup
0) (plus:DI (match_dup
0) (match_dup
3)))]
9124 if (rs6000_emit_set_const (operands[
0], operands[
1]))
9131 [(set (match_operand:DI
0 "altivec_register_operand")
9132 (match_operand:DI
1 "s5bit_cint_operand"))]
9133 "TARGET_VSX && reload_completed"
9136 rtx op0 = operands[
0];
9137 rtx op1 = operands[
1];
9138 int r = REGNO (op0);
9139 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9141 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9142 if (op1 != const0_rtx && op1 != constm1_rtx)
9144 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9145 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9150 ;; Split integer constants that can be loaded with XXSPLTIB and a
9151 ;; sign extend operation.
9153 [(set (match_operand:INT_ISA3
0 "altivec_register_operand")
9154 (match_operand:INT_ISA3
1 "xxspltib_constant_split"))]
9155 "TARGET_P9_VECTOR && reload_completed"
9158 rtx op0 = operands[
0];
9159 rtx op1 = operands[
1];
9160 int r = REGNO (op0);
9161 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9163 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9164 if (<MODE>mode == DImode)
9165 emit_insn (gen_vsx_sign_extend_qi_di (operands[
0], op0_v16qi));
9166 else if (<MODE>mode == SImode)
9167 emit_insn (gen_vsx_sign_extend_qi_si (operands[
0], op0_v16qi));
9168 else if (<MODE>mode == HImode)
9170 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9171 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9177 ;; TImode/PTImode is similar, except that we usually want to compute the
9178 ;; address into a register and use lsi/stsi (the exception is during reload).
9180 (define_insn "*mov<mode>_string"
9181 [(set (match_operand:TI2
0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9182 (match_operand:TI2
1 "input_operand" "r,r,Q,Y,r,n"))]
9184 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9185 && (gpc_reg_operand (operands[
0], <MODE>mode)
9186 || gpc_reg_operand (operands[
1], <MODE>mode))"
9188 [(set_attr "type" "store,store,load,load,*,*")
9189 (set_attr "update" "yes")
9190 (set_attr "indexed" "yes")
9191 (set_attr "cell_micro" "conditional")])
9193 (define_insn "*mov<mode>_ppc64"
9194 [(set (match_operand:TI2
0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9195 (match_operand:TI2
1 "input_operand" "r,r,wQ,Y,r,n"))]
9196 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9197 && (gpc_reg_operand (operands[
0], <MODE>mode)
9198 || gpc_reg_operand (operands[
1], <MODE>mode)))"
9200 return rs6000_output_move_128bit (operands);
9202 [(set_attr "type" "store,store,load,load,*,*")
9203 (set_attr "length" "
8")
9204 (set_attr "max_prefixed_insns" "
2")])
9207 [(set (match_operand:TI2
0 "int_reg_operand")
9208 (match_operand:TI2
1 "const_scalar_int_operand"))]
9210 && (VECTOR_MEM_NONE_P (<MODE>mode)
9211 || (reload_completed && INT_REGNO_P (REGNO (operands[
0]))))"
9212 [(set (match_dup
2) (match_dup
4))
9213 (set (match_dup
3) (match_dup
5))]
9215 operands[
2] = operand_subword_force (operands[
0], WORDS_BIG_ENDIAN ==
0,
9217 operands[
3] = operand_subword_force (operands[
0], WORDS_BIG_ENDIAN !=
0,
9219 if (CONST_WIDE_INT_P (operands[
1]))
9221 operands[
4] = GEN_INT (CONST_WIDE_INT_ELT (operands[
1],
1));
9222 operands[
5] = GEN_INT (CONST_WIDE_INT_ELT (operands[
1],
0));
9224 else if (CONST_INT_P (operands[
1]))
9226 operands[
4] = GEN_INT (- (INTVAL (operands[
1]) <
0));
9227 operands[
5] = operands[
1];
9234 [(set (match_operand:TI2
0 "nonimmediate_operand")
9235 (match_operand:TI2
1 "input_operand"))]
9237 && gpr_or_gpr_p (operands[
0], operands[
1])
9238 && !direct_move_p (operands[
0], operands[
1])
9239 && !quad_load_store_p (operands[
0], operands[
1])"
9242 rs6000_split_multireg_move (operands[
0], operands[
1]);
9246 (define_expand "setmemsi"
9247 [(parallel [(set (match_operand:BLK
0 "")
9248 (match_operand
2 "const_int_operand"))
9249 (use (match_operand:SI
1 ""))
9250 (use (match_operand:SI
3 ""))])]
9253 /* If value to set is not zero, use the library routine. */
9254 if (operands[
2] != const0_rtx)
9257 if (expand_block_clear (operands))
9263 ;; String compare N insn.
9264 ;; Argument
0 is the target (result)
9265 ;; Argument
1 is the destination
9266 ;; Argument
2 is the source
9267 ;; Argument
3 is the length
9268 ;; Argument
4 is the alignment
9270 (define_expand "cmpstrnsi"
9271 [(parallel [(set (match_operand:SI
0)
9272 (compare:SI (match_operand:BLK
1)
9273 (match_operand:BLK
2)))
9274 (use (match_operand:SI
3))
9275 (use (match_operand:SI
4))])]
9276 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9278 if (optimize_insn_for_size_p ())
9281 if (expand_strn_compare (operands,
0))
9287 ;; String compare insn.
9288 ;; Argument
0 is the target (result)
9289 ;; Argument
1 is the destination
9290 ;; Argument
2 is the source
9291 ;; Argument
3 is the alignment
9293 (define_expand "cmpstrsi"
9294 [(parallel [(set (match_operand:SI
0)
9295 (compare:SI (match_operand:BLK
1)
9296 (match_operand:BLK
2)))
9297 (use (match_operand:SI
3))])]
9298 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9300 if (optimize_insn_for_size_p ())
9303 if (expand_strn_compare (operands,
1))
9309 ;; Block compare insn.
9310 ;; Argument
0 is the target (result)
9311 ;; Argument
1 is the destination
9312 ;; Argument
2 is the source
9313 ;; Argument
3 is the length
9314 ;; Argument
4 is the alignment
9316 (define_expand "cmpmemsi"
9317 [(parallel [(set (match_operand:SI
0)
9318 (compare:SI (match_operand:BLK
1)
9319 (match_operand:BLK
2)))
9320 (use (match_operand:SI
3))
9321 (use (match_operand:SI
4))])]
9324 if (expand_block_compare (operands))
9330 ;; String/block copy insn (source and destination must not overlap).
9331 ;; Argument
0 is the destination
9332 ;; Argument
1 is the source
9333 ;; Argument
2 is the length
9334 ;; Argument
3 is the alignment
9336 (define_expand "cpymemsi"
9337 [(parallel [(set (match_operand:BLK
0 "")
9338 (match_operand:BLK
1 ""))
9339 (use (match_operand:SI
2 ""))
9340 (use (match_operand:SI
3 ""))])]
9343 if (expand_block_move (operands, false))
9349 ;; String/block move insn (source and destination may overlap).
9350 ;; Argument
0 is the destination
9351 ;; Argument
1 is the source
9352 ;; Argument
2 is the length
9353 ;; Argument
3 is the alignment
9355 (define_expand "movmemsi"
9356 [(parallel [(set (match_operand:BLK
0 "")
9357 (match_operand:BLK
1 ""))
9358 (use (match_operand:SI
2 ""))
9359 (use (match_operand:SI
3 ""))])]
9362 if (expand_block_move (operands, true))
9369 ;; Define insns that do load or store with update. Some of these we can
9370 ;; get by using pre-decrement or pre-increment, but the hardware can also
9371 ;; do cases where the increment is not the size of the object.
9373 ;; In all these cases, we use operands
0 and
1 for the register being
9374 ;; incremented because those are the operands that local-alloc will
9375 ;; tie and these are the pair most likely to be tieable (and the ones
9376 ;; that will benefit the most).
9378 (define_insn "*movdi_update1"
9379 [(set (match_operand:DI
3 "gpc_reg_operand" "=r,r")
9380 (mem:DI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9381 (match_operand:P
2 "reg_or_aligned_short_operand" "r,I"))))
9382 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9383 (plus:P (match_dup
1) (match_dup
2)))]
9384 "TARGET_POWERPC64 && TARGET_UPDATE
9385 && (!avoiding_indexed_address_p (DImode)
9386 || !gpc_reg_operand (operands[
2], Pmode))"
9390 [(set_attr "type" "load")
9391 (set_attr "update" "yes")
9392 (set_attr "indexed" "yes,no")])
9394 (define_insn "movdi_<mode>_update"
9395 [(set (mem:DI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9396 (match_operand:P
2 "reg_or_aligned_short_operand" "r,I")))
9397 (match_operand:DI
3 "gpc_reg_operand" "r,r"))
9398 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9399 (plus:P (match_dup
1) (match_dup
2)))]
9400 "TARGET_POWERPC64 && TARGET_UPDATE
9401 && (!avoiding_indexed_address_p (DImode)
9402 || !gpc_reg_operand (operands[
2], Pmode)
9403 || (REG_P (operands[
0])
9404 && REGNO (operands[
0]) == STACK_POINTER_REGNUM))"
9408 [(set_attr "type" "store")
9409 (set_attr "update" "yes")
9410 (set_attr "indexed" "yes,no")])
9412 ;; This pattern is only conditional on TARGET_64BIT, as it is
9413 ;; needed for stack allocation, even if the user passes -mno-update.
9414 (define_insn "movdi_update_stack"
9415 [(set (mem:DI (plus:DI (match_operand:DI
1 "gpc_reg_operand" "
0,
0")
9416 (match_operand:DI
2 "reg_or_aligned_short_operand" "r,I")))
9417 (match_operand:DI
3 "gpc_reg_operand" "r,r"))
9418 (set (match_operand:DI
0 "gpc_reg_operand" "=b,b")
9419 (plus:DI (match_dup
1) (match_dup
2)))]
9424 [(set_attr "type" "store")
9425 (set_attr "update" "yes")
9426 (set_attr "indexed" "yes,no")])
9428 (define_insn "*movsi_update1"
9429 [(set (match_operand:SI
3 "gpc_reg_operand" "=r,r")
9430 (mem:SI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9431 (match_operand:P
2 "reg_or_short_operand" "r,I"))))
9432 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9433 (plus:P (match_dup
1) (match_dup
2)))]
9435 && (!avoiding_indexed_address_p (SImode)
9436 || !gpc_reg_operand (operands[
2], Pmode))"
9440 [(set_attr "type" "load")
9441 (set_attr "update" "yes")
9442 (set_attr "indexed" "yes,no")])
9444 (define_insn "*movsi_update2"
9445 [(set (match_operand:EXTSI
3 "gpc_reg_operand" "=r")
9447 (mem:SI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0")
9448 (match_operand:P
2 "gpc_reg_operand" "r")))))
9449 (set (match_operand:P
0 "gpc_reg_operand" "=b")
9450 (plus:P (match_dup
1) (match_dup
2)))]
9451 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9453 [(set_attr "type" "load")
9454 (set_attr "sign_extend" "yes")
9455 (set_attr "update" "yes")
9456 (set_attr "indexed" "yes")])
9458 (define_insn "movsi_<mode>_update"
9459 [(set (mem:SI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9460 (match_operand:P
2 "reg_or_short_operand" "r,I")))
9461 (match_operand:SI
3 "gpc_reg_operand" "r,r"))
9462 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9463 (plus:P (match_dup
1) (match_dup
2)))]
9465 && (!avoiding_indexed_address_p (SImode)
9466 || !gpc_reg_operand (operands[
2], Pmode)
9467 || (REG_P (operands[
0])
9468 && REGNO (operands[
0]) == STACK_POINTER_REGNUM))"
9472 [(set_attr "type" "store")
9473 (set_attr "update" "yes")
9474 (set_attr "indexed" "yes,no")])
9476 ;; This is an unconditional pattern; needed for stack allocation, even
9477 ;; if the user passes -mno-update.
9478 (define_insn "movsi_update_stack"
9479 [(set (mem:SI (plus:SI (match_operand:SI
1 "gpc_reg_operand" "
0,
0")
9480 (match_operand:SI
2 "reg_or_short_operand" "r,I")))
9481 (match_operand:SI
3 "gpc_reg_operand" "r,r"))
9482 (set (match_operand:SI
0 "gpc_reg_operand" "=b,b")
9483 (plus:SI (match_dup
1) (match_dup
2)))]
9488 [(set_attr "type" "store")
9489 (set_attr "update" "yes")
9490 (set_attr "indexed" "yes,no")])
9492 (define_insn "*movhi_update1"
9493 [(set (match_operand:HI
3 "gpc_reg_operand" "=r,r")
9494 (mem:HI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9495 (match_operand:P
2 "reg_or_short_operand" "r,I"))))
9496 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9497 (plus:P (match_dup
1) (match_dup
2)))]
9499 && (!avoiding_indexed_address_p (HImode)
9500 || !gpc_reg_operand (operands[
2], SImode))"
9504 [(set_attr "type" "load")
9505 (set_attr "update" "yes")
9506 (set_attr "indexed" "yes,no")])
9508 (define_insn "*movhi_update2"
9509 [(set (match_operand:EXTHI
3 "gpc_reg_operand" "=r,r")
9511 (mem:HI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9512 (match_operand:P
2 "reg_or_short_operand" "r,I")))))
9513 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9514 (plus:P (match_dup
1) (match_dup
2)))]
9516 && (!avoiding_indexed_address_p (HImode)
9517 || !gpc_reg_operand (operands[
2], Pmode))"
9521 [(set_attr "type" "load")
9522 (set_attr "update" "yes")
9523 (set_attr "indexed" "yes,no")])
9525 (define_insn "*movhi_update3"
9526 [(set (match_operand:EXTHI
3 "gpc_reg_operand" "=r,r")
9528 (mem:HI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9529 (match_operand:P
2 "reg_or_short_operand" "r,I")))))
9530 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9531 (plus:P (match_dup
1) (match_dup
2)))]
9533 && !(avoiding_indexed_address_p (HImode)
9534 && gpc_reg_operand (operands[
2], Pmode))"
9538 [(set_attr "type" "load")
9539 (set_attr "sign_extend" "yes")
9540 (set_attr "update" "yes")
9541 (set_attr "indexed" "yes,no")])
9543 (define_insn "*movhi_update4"
9544 [(set (mem:HI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9545 (match_operand:P
2 "reg_or_short_operand" "r,I")))
9546 (match_operand:HI
3 "gpc_reg_operand" "r,r"))
9547 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9548 (plus:P (match_dup
1) (match_dup
2)))]
9550 && (!avoiding_indexed_address_p (HImode)
9551 || !gpc_reg_operand (operands[
2], Pmode))"
9555 [(set_attr "type" "store")
9556 (set_attr "update" "yes")
9557 (set_attr "indexed" "yes,no")])
9559 (define_insn "*movqi_update1"
9560 [(set (match_operand:QI
3 "gpc_reg_operand" "=r,r")
9561 (mem:QI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9562 (match_operand:P
2 "reg_or_short_operand" "r,I"))))
9563 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9564 (plus:P (match_dup
1) (match_dup
2)))]
9566 && (!avoiding_indexed_address_p (QImode)
9567 || !gpc_reg_operand (operands[
2], Pmode))"
9571 [(set_attr "type" "load")
9572 (set_attr "update" "yes")
9573 (set_attr "indexed" "yes,no")])
9575 (define_insn "*movqi_update2"
9576 [(set (match_operand:EXTQI
3 "gpc_reg_operand" "=r,r")
9578 (mem:QI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9579 (match_operand:P
2 "reg_or_short_operand" "r,I")))))
9580 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9581 (plus:P (match_dup
1) (match_dup
2)))]
9583 && (!avoiding_indexed_address_p (QImode)
9584 || !gpc_reg_operand (operands[
2], Pmode))"
9588 [(set_attr "type" "load")
9589 (set_attr "update" "yes")
9590 (set_attr "indexed" "yes,no")])
9592 (define_insn "*movqi_update3"
9593 [(set (mem:QI (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9594 (match_operand:P
2 "reg_or_short_operand" "r,I")))
9595 (match_operand:QI
3 "gpc_reg_operand" "r,r"))
9596 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9597 (plus:P (match_dup
1) (match_dup
2)))]
9599 && (!avoiding_indexed_address_p (QImode)
9600 || !gpc_reg_operand (operands[
2], Pmode))"
9604 [(set_attr "type" "store")
9605 (set_attr "update" "yes")
9606 (set_attr "indexed" "yes,no")])
9608 (define_insn "*mov<SFDF:mode>_update1"
9609 [(set (match_operand:SFDF
3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9610 (mem:SFDF (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9611 (match_operand:P
2 "reg_or_short_operand" "r,I"))))
9612 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9613 (plus:P (match_dup
1) (match_dup
2)))]
9614 "TARGET_HARD_FLOAT && TARGET_UPDATE
9615 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9616 || !gpc_reg_operand (operands[
2], Pmode))"
9620 [(set_attr "type" "fpload")
9621 (set_attr "update" "yes")
9622 (set_attr "indexed" "yes,no")
9623 (set_attr "size" "<SFDF:bits>")])
9625 (define_insn "*mov<SFDF:mode>_update2"
9626 [(set (mem:SFDF (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9627 (match_operand:P
2 "reg_or_short_operand" "r,I")))
9628 (match_operand:SFDF
3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9629 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9630 (plus:P (match_dup
1) (match_dup
2)))]
9631 "TARGET_HARD_FLOAT && TARGET_UPDATE
9632 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9633 || !gpc_reg_operand (operands[
2], Pmode))"
9637 [(set_attr "type" "fpstore")
9638 (set_attr "update" "yes")
9639 (set_attr "indexed" "yes,no")
9640 (set_attr "size" "<SFDF:bits>")])
9642 (define_insn "*movsf_update3"
9643 [(set (match_operand:SF
3 "gpc_reg_operand" "=r,r")
9644 (mem:SF (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9645 (match_operand:P
2 "reg_or_short_operand" "r,I"))))
9646 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9647 (plus:P (match_dup
1) (match_dup
2)))]
9648 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9649 && (!avoiding_indexed_address_p (SFmode)
9650 || !gpc_reg_operand (operands[
2], Pmode))"
9654 [(set_attr "type" "load")
9655 (set_attr "update" "yes")
9656 (set_attr "indexed" "yes,no")])
9658 (define_insn "*movsf_update4"
9659 [(set (mem:SF (plus:P (match_operand:P
1 "gpc_reg_operand" "
0,
0")
9660 (match_operand:P
2 "reg_or_short_operand" "r,I")))
9661 (match_operand:SF
3 "gpc_reg_operand" "r,r"))
9662 (set (match_operand:P
0 "gpc_reg_operand" "=b,b")
9663 (plus:P (match_dup
1) (match_dup
2)))]
9664 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9665 && (!avoiding_indexed_address_p (SFmode)
9666 || !gpc_reg_operand (operands[
2], Pmode))"
9670 [(set_attr "type" "store")
9671 (set_attr "update" "yes")
9672 (set_attr "indexed" "yes,no")])
9675 ;; After inserting conditional returns we can sometimes have
9676 ;; unnecessary register moves. Unfortunately we cannot have a
9677 ;; modeless peephole here, because some single SImode sets have early
9678 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9679 ;; sequences, using get_attr_length here will smash the operands
9680 ;; array. Neither is there an early_cobbler_p predicate.
9681 ;; Also this optimization interferes with scalars going into
9682 ;; altivec registers (the code does reloading through the FPRs).
9684 [(set (match_operand:DF
0 "gpc_reg_operand")
9685 (match_operand:DF
1 "any_operand"))
9686 (set (match_operand:DF
2 "gpc_reg_operand")
9689 && peep2_reg_dead_p (
2, operands[
0])"
9690 [(set (match_dup
2) (match_dup
1))])
9693 [(set (match_operand:SF
0 "gpc_reg_operand")
9694 (match_operand:SF
1 "any_operand"))
9695 (set (match_operand:SF
2 "gpc_reg_operand")
9698 && peep2_reg_dead_p (
2, operands[
0])"
9699 [(set (match_dup
2) (match_dup
1))])
9704 (define_insn "*tls_gd_pcrel<bits>"
9705 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9706 (unspec:P [(match_operand:P
1 "rs6000_tls_symbol_ref" "")
9709 "HAVE_AS_TLS && TARGET_ELF"
9710 "la %
0,%
1@got@tlsgd@pcrel"
9711 [(set_attr "prefixed" "yes")])
9713 (define_insn_and_split "*tls_gd<bits>"
9714 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9715 (unspec:P [(match_operand:P
1 "rs6000_tls_symbol_ref" "")
9716 (match_operand:P
2 "gpc_reg_operand" "b")]
9718 "HAVE_AS_TLS && TARGET_ELF"
9719 "addi %
0,%
2,%
1@got@tlsgd"
9720 "&& TARGET_CMODEL != CMODEL_SMALL"
9723 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGD)))
9725 (lo_sum:P (match_dup
3)
9726 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGD)))]
9728 operands[
3] = gen_reg_rtx (<MODE>mode);
9730 [(set (attr "length")
9731 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9735 (define_insn "*tls_gd_high<bits>"
9736 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9738 (unspec:P [(match_operand:P
1 "rs6000_tls_symbol_ref" "")
9739 (match_operand:P
2 "gpc_reg_operand" "b")]
9741 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9742 "addis %
0,%
2,%
1@got@tlsgd@ha")
9744 (define_insn "*tls_gd_low<bits>"
9745 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9746 (lo_sum:P (match_operand:P
1 "gpc_reg_operand" "b")
9747 (unspec:P [(match_operand:P
2 "rs6000_tls_symbol_ref" "")
9748 (match_operand:P
3 "gpc_reg_operand" "b")]
9750 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9751 "addi %
0,%
1,%
2@got@tlsgd@l")
9753 (define_insn "*tls_ld_pcrel<bits>"
9754 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9755 (unspec:P [(const_int
0)]
9757 "HAVE_AS_TLS && TARGET_ELF"
9758 "la %
0,%&@got@tlsld@pcrel"
9759 [(set_attr "prefixed" "yes")])
9761 (define_insn_and_split "*tls_ld<bits>"
9762 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9763 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")]
9765 "HAVE_AS_TLS && TARGET_ELF"
9766 "addi %
0,%
1,%&@got@tlsld"
9767 "&& TARGET_CMODEL != CMODEL_SMALL"
9770 (unspec:P [(match_dup
1)] UNSPEC_TLSLD)))
9772 (lo_sum:P (match_dup
2)
9773 (unspec:P [(match_dup
1)] UNSPEC_TLSLD)))]
9775 operands[
2] = gen_reg_rtx (<MODE>mode);
9777 [(set (attr "length")
9778 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9782 (define_insn "*tls_ld_high<bits>"
9783 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9785 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")]
9787 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9788 "addis %
0,%
1,%&@got@tlsld@ha")
9790 (define_insn "*tls_ld_low<bits>"
9791 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9792 (lo_sum:P (match_operand:P
1 "gpc_reg_operand" "b")
9793 (unspec:P [(match_operand:P
2 "gpc_reg_operand" "b")]
9795 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9796 "addi %
0,%
1,%&@got@tlsld@l")
9798 (define_insn "tls_dtprel_<bits>"
9799 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9800 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9801 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9804 "addi %
0,%
1,%
2@dtprel"
9805 [(set (attr "prefixed")
9806 (if_then_else (match_test "rs6000_tls_size ==
16")
9808 (const_string "yes")))])
9810 (define_insn "tls_dtprel_ha_<bits>"
9811 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9812 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9813 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9814 UNSPEC_TLSDTPRELHA))]
9816 "addis %
0,%
1,%
2@dtprel@ha")
9818 (define_insn "tls_dtprel_lo_<bits>"
9819 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9820 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9821 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9822 UNSPEC_TLSDTPRELLO))]
9824 "addi %
0,%
1,%
2@dtprel@l")
9826 (define_insn_and_split "tls_got_dtprel_<bits>"
9827 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9828 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9829 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9830 UNSPEC_TLSGOTDTPREL))]
9832 "<ptrload> %
0,%
2@got@dtprel(%
1)"
9833 "&& TARGET_CMODEL != CMODEL_SMALL"
9836 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGOTDTPREL)))
9838 (lo_sum:P (match_dup
3)
9839 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGOTDTPREL)))]
9841 operands[
3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9843 [(set (attr "length")
9844 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9848 (define_insn "*tls_got_dtprel_high<bits>"
9849 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9851 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9852 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9853 UNSPEC_TLSGOTDTPREL)))]
9854 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9855 "addis %
0,%
1,%
2@got@dtprel@ha")
9857 (define_insn "*tls_got_dtprel_low<bits>"
9858 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9859 (lo_sum:P (match_operand:P
1 "gpc_reg_operand" "b")
9860 (unspec:P [(match_operand:P
3 "gpc_reg_operand" "b")
9861 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9862 UNSPEC_TLSGOTDTPREL)))]
9863 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9864 "<ptrload> %
0,%
2@got@dtprel@l(%
1)")
9866 (define_insn "tls_tprel_<bits>"
9867 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9868 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9869 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9872 "addi %
0,%
1,%
2@tprel"
9873 [(set (attr "prefixed")
9874 (if_then_else (match_test "rs6000_tls_size ==
16")
9876 (const_string "yes")))])
9878 (define_insn "tls_tprel_ha_<bits>"
9879 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9880 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9881 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9882 UNSPEC_TLSTPRELHA))]
9884 "addis %
0,%
1,%
2@tprel@ha")
9886 (define_insn "tls_tprel_lo_<bits>"
9887 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9888 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9889 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9890 UNSPEC_TLSTPRELLO))]
9892 "addi %
0,%
1,%
2@tprel@l")
9894 (define_insn "*tls_got_tprel_pcrel_<bits>"
9895 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9896 (unspec:P [(const_int
0)
9897 (match_operand:P
1 "rs6000_tls_symbol_ref" "")]
9898 UNSPEC_TLSGOTTPREL))]
9900 "<ptrload> %
0,%
1@got@tprel@pcrel"
9901 [(set_attr "prefixed" "yes")])
9903 ;; "b" output constraint here and on tls_tls input to support linker tls
9904 ;; optimization. The linker may edit the instructions emitted by a
9905 ;; tls_got_tprel/tls_tls pair to addis,addi.
9906 (define_insn_and_split "tls_got_tprel_<bits>"
9907 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9908 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9909 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9910 UNSPEC_TLSGOTTPREL))]
9912 "<ptrload> %
0,%
2@got@tprel(%
1)"
9913 "&& TARGET_CMODEL != CMODEL_SMALL"
9916 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGOTTPREL)))
9918 (lo_sum:P (match_dup
3)
9919 (unspec:P [(match_dup
1) (match_dup
2)] UNSPEC_TLSGOTTPREL)))]
9921 operands[
3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9923 [(set (attr "length")
9924 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9928 (define_insn "*tls_got_tprel_high<bits>"
9929 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
9931 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9932 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9933 UNSPEC_TLSGOTTPREL)))]
9934 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9935 "addis %
0,%
1,%
2@got@tprel@ha")
9937 (define_insn "*tls_got_tprel_low<bits>"
9938 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9939 (lo_sum:P (match_operand:P
1 "gpc_reg_operand" "b")
9940 (unspec:P [(match_operand:P
3 "gpc_reg_operand" "b")
9941 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9942 UNSPEC_TLSGOTTPREL)))]
9943 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9944 "<ptrload> %
0,%
2@got@tprel@l(%
1)")
9946 (define_insn "tls_tls_pcrel_<bits>"
9947 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9948 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9949 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9950 UNSPEC_TLSTLS_PCREL))]
9951 "TARGET_ELF && HAVE_AS_TLS"
9952 "add %
0,%
1,%
2@tls@pcrel")
9954 (define_insn "tls_tls_<bits>"
9955 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
9956 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
9957 (match_operand:P
2 "rs6000_tls_symbol_ref" "")]
9959 "TARGET_ELF && HAVE_AS_TLS"
9962 (define_expand "tls_get_tpointer"
9963 [(set (match_operand:SI
0 "gpc_reg_operand")
9964 (unspec:SI [(const_int
0)] UNSPEC_TLSTLS))]
9965 "TARGET_XCOFF && HAVE_AS_TLS"
9967 emit_insn (gen_tls_get_tpointer_internal ());
9968 emit_move_insn (operands[
0], gen_rtx_REG (SImode,
3));
9972 (define_insn "tls_get_tpointer_internal"
9974 (unspec:SI [(const_int
0)] UNSPEC_TLSTLS))
9975 (clobber (reg:SI LR_REGNO))]
9976 "TARGET_XCOFF && HAVE_AS_TLS"
9977 "bla __get_tpointer")
9979 (define_expand "tls_get_addr<mode>"
9980 [(set (match_operand:P
0 "gpc_reg_operand")
9981 (unspec:P [(match_operand:P
1 "gpc_reg_operand")
9982 (match_operand:P
2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9983 "TARGET_XCOFF && HAVE_AS_TLS"
9985 emit_move_insn (gen_rtx_REG (Pmode,
3), operands[
1]);
9986 emit_move_insn (gen_rtx_REG (Pmode,
4), operands[
2]);
9987 emit_insn (gen_tls_get_addr_internal<mode> ());
9988 emit_move_insn (operands[
0], gen_rtx_REG (Pmode,
3));
9992 (define_insn "tls_get_addr_internal<mode>"
9994 (unspec:P [(reg:P
3) (reg:P
4)] UNSPEC_TLSTLS))
9998 (clobber (reg:P
11))
9999 (clobber (reg:CC CR0_REGNO))
10000 (clobber (reg:P LR_REGNO))]
10001 "TARGET_XCOFF && HAVE_AS_TLS"
10002 "bla __tls_get_addr")
10004 ;; Next come insns related to the calling sequence.
10006 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10007 ;; We move the back-chain and decrement the stack pointer.
10009 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
10010 ;; constant alloca, using that predicate will force the generic code to put
10011 ;; the constant size into a register before calling the expander.
10013 ;; As a result the expander would not have the constant size information
10014 ;; in those cases and would have to generate less efficient code.
10016 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10017 ;; the constant size. The value is forced into a register if necessary.
10019 (define_expand "allocate_stack"
10020 [(set (match_operand
0 "gpc_reg_operand")
10021 (minus (reg
1) (match_operand
1 "reg_or_cint_operand")))
10023 (minus (reg
1) (match_dup
1)))]
10026 rtx chain = gen_reg_rtx (Pmode);
10027 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10029 rtx insn, par, set, mem;
10031 /* By allowing reg_or_cint_operand as the predicate we can get
10032 better code for stack-clash-protection because we do not lose
10033 size information. But the rest of the code expects the operand
10034 to be reg_or_short_operand. If it isn't, then force it into
10036 rtx orig_op1 = operands[
1];
10037 if (!reg_or_short_operand (operands[
1], Pmode))
10038 operands[
1] = force_reg (Pmode, operands[
1]);
10040 emit_move_insn (chain, stack_bot);
10042 /* Check stack bounds if necessary. */
10043 if (crtl->limit_stack)
10046 available = expand_binop (Pmode, sub_optab,
10047 stack_pointer_rtx, stack_limit_rtx,
10048 NULL_RTX,
1, OPTAB_WIDEN);
10049 emit_insn (gen_cond_trap (LTU, available, operands[
1], const0_rtx));
10052 /* Allocate and probe if requested.
10053 This may look similar to the loop we use for prologue allocations,
10054 but it is critically different. For the former we know the loop
10055 will iterate, but do not know that generally here. The former
10056 uses that knowledge to rotate the loop. Combining them would be
10057 possible with some performance cost. */
10058 if (flag_stack_clash_protection)
10060 rtx rounded_size, last_addr, residual;
10061 HOST_WIDE_INT probe_interval;
10062 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10063 &residual, &probe_interval,
10066 /* We do occasionally get in here with constant sizes, we might
10067 as well do a reasonable job when we obviously can. */
10068 if (rounded_size != const0_rtx)
10070 rtx loop_lab, end_loop;
10071 bool rotated = CONST_INT_P (rounded_size);
10072 rtx update = GEN_INT (-probe_interval);
10073 if (probe_interval >
32768)
10074 update = force_reg (Pmode, update);
10076 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10077 last_addr, rotated);
10080 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10084 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
10087 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10088 last_addr, rotated);
10091 /* Now handle residuals. We just have to set operands[
1] correctly
10092 and let the rest of the expander run. */
10093 operands[
1] = residual;
10096 if (!(CONST_INT_P (operands[
1])
10097 && IN_RANGE (INTVAL (operands[
1]), -
32767,
32768)))
10099 operands[
1] = force_reg (Pmode, operands[
1]);
10100 neg_op0 = gen_reg_rtx (Pmode);
10101 emit_insn (gen_neg2 (Pmode, neg_op0, operands[
1]));
10104 neg_op0 = GEN_INT (-INTVAL (operands[
1]));
10106 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10107 : gen_movdi_update_stack))
10108 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10110 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10111 it now and set the alias set/attributes. The above gen_*_update
10112 calls will generate a PARALLEL with the MEM set being the first
10114 par = PATTERN (insn);
10115 gcc_assert (GET_CODE (par) == PARALLEL);
10116 set = XVECEXP (par,
0,
0);
10117 gcc_assert (GET_CODE (set) == SET);
10118 mem = SET_DEST (set);
10119 gcc_assert (MEM_P (mem));
10120 MEM_NOTRAP_P (mem) =
1;
10121 set_mem_alias_set (mem, get_frame_alias_set ());
10123 emit_move_insn (operands[
0], virtual_stack_dynamic_rtx);
10127 ;; These patterns say how to save and restore the stack pointer. We need not
10128 ;; save the stack pointer at function level since we are careful to
10129 ;; preserve the backchain. At block level, we have to restore the backchain
10130 ;; when we restore the stack pointer.
10132 ;; For nonlocal gotos, we must save both the stack pointer and its
10133 ;; backchain and restore both. Note that in the nonlocal case, the
10134 ;; save area is a memory location.
10136 (define_expand "save_stack_function"
10137 [(match_operand
0 "any_operand")
10138 (match_operand
1 "any_operand")]
10142 (define_expand "restore_stack_function"
10143 [(match_operand
0 "any_operand")
10144 (match_operand
1 "any_operand")]
10148 ;; Adjust stack pointer (op0) to a new value (op1).
10149 ;; First copy old stack backchain to new location, and ensure that the
10150 ;; scheduler won't reorder the sp assignment before the backchain write.
10151 (define_expand "restore_stack_block"
10152 [(set (match_dup
2) (match_dup
3))
10153 (set (match_dup
4) (match_dup
2))
10155 (set (match_operand
0 "register_operand")
10156 (match_operand
1 "register_operand"))]
10161 operands[
1] = force_reg (Pmode, operands[
1]);
10162 operands[
2] = gen_reg_rtx (Pmode);
10163 operands[
3] = gen_frame_mem (Pmode, operands[
0]);
10164 operands[
4] = gen_frame_mem (Pmode, operands[
1]);
10165 p = rtvec_alloc (
1);
10166 RTVEC_ELT (p,
0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[
0]),
10168 operands[
5] = gen_rtx_PARALLEL (VOIDmode, p);
10171 (define_expand "save_stack_nonlocal"
10172 [(set (match_dup
3) (match_dup
4))
10173 (set (match_operand
0 "memory_operand") (match_dup
3))
10174 (set (match_dup
2) (match_operand
1 "register_operand"))]
10177 int units_per_word = (TARGET_32BIT) ?
4 :
8;
10179 /* Copy the backchain to the first word, sp to the second. */
10180 operands[
0] = adjust_address_nv (operands[
0], Pmode,
0);
10181 operands[
2] = adjust_address_nv (operands[
0], Pmode, units_per_word);
10182 operands[
3] = gen_reg_rtx (Pmode);
10183 operands[
4] = gen_frame_mem (Pmode, operands[
1]);
10186 (define_expand "restore_stack_nonlocal"
10187 [(set (match_dup
2) (match_operand
1 "memory_operand"))
10188 (set (match_dup
3) (match_dup
4))
10189 (set (match_dup
5) (match_dup
2))
10191 (set (match_operand
0 "register_operand") (match_dup
3))]
10194 int units_per_word = (TARGET_32BIT) ?
4 :
8;
10197 /* Restore the backchain from the first word, sp from the second. */
10198 operands[
2] = gen_reg_rtx (Pmode);
10199 operands[
3] = gen_reg_rtx (Pmode);
10200 operands[
1] = adjust_address_nv (operands[
1], Pmode,
0);
10201 operands[
4] = adjust_address_nv (operands[
1], Pmode, units_per_word);
10202 operands[
5] = gen_frame_mem (Pmode, operands[
3]);
10203 p = rtvec_alloc (
1);
10204 RTVEC_ELT (p,
0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[
0]),
10206 operands[
6] = gen_rtx_PARALLEL (VOIDmode, p);
10209 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10210 ;; to the symbol or label.
10211 (define_insn "*pcrel_local_addr"
10212 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
10213 (match_operand:DI
1 "pcrel_local_address"))]
10216 [(set_attr "prefixed" "yes")])
10218 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10219 ;; program are both defined in the main program, the linker will optimize this
10220 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10221 ;; the dynamic linker and loaded up. Print_operand_address will append a
10222 ;; @got@pcrel to the symbol.
10223 (define_insn "*pcrel_extern_addr"
10224 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
10225 (match_operand:DI
1 "pcrel_external_address"))]
10228 [(set_attr "prefixed" "yes")
10229 (set_attr "type" "load")])
10231 ;; TOC register handling.
10233 ;; Code to initialize the TOC register...
10235 (define_insn "load_toc_aix_si"
10236 [(parallel [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
10237 (unspec:SI [(const_int
0)] UNSPEC_TOC))
10238 (use (reg:SI
2))])]
10239 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10242 extern int need_toc_init;
10244 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
1);
10245 operands[
1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10246 operands[
2] = gen_rtx_REG (Pmode,
2);
10247 return "lwz %
0,%
1(%
2)";
10249 [(set_attr "type" "load")
10250 (set_attr "update" "no")
10251 (set_attr "indexed" "no")])
10253 (define_insn "load_toc_aix_di"
10254 [(parallel [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
10255 (unspec:DI [(const_int
0)] UNSPEC_TOC))
10256 (use (reg:DI
2))])]
10257 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10260 extern int need_toc_init;
10262 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10263 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10265 strcat (buf, "@toc");
10266 operands[
1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10267 operands[
2] = gen_rtx_REG (Pmode,
2);
10268 return "ld %
0,%
1(%
2)";
10270 [(set_attr "type" "load")
10271 (set_attr "update" "no")
10272 (set_attr "indexed" "no")])
10274 (define_insn "load_toc_v4_pic_si"
10275 [(set (reg:SI LR_REGNO)
10276 (unspec:SI [(const_int
0)] UNSPEC_TOC))]
10277 "DEFAULT_ABI == ABI_V4 && flag_pic ==
1 && TARGET_32BIT"
10278 "bl _GLOBAL_OFFSET_TABLE_@local-
4"
10279 [(set_attr "type" "branch")])
10281 (define_expand "load_toc_v4_PIC_1"
10282 [(parallel [(set (reg:SI LR_REGNO)
10283 (match_operand:SI
0 "immediate_operand" "s"))
10284 (use (unspec [(match_dup
0)] UNSPEC_TOC))])]
10285 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10286 && (flag_pic ==
2 || (flag_pic && TARGET_SECURE_PLT))"
10289 (define_insn "load_toc_v4_PIC_1_normal"
10290 [(set (reg:SI LR_REGNO)
10291 (match_operand:SI
0 "immediate_operand" "s"))
10292 (use (unspec [(match_dup
0)] UNSPEC_TOC))]
10293 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10294 && (flag_pic ==
2 || (flag_pic && TARGET_SECURE_PLT))"
10295 "bcl
20,
31,%
0\n%
0:"
10296 [(set_attr "type" "branch")
10297 (set_attr "cannot_copy" "yes")])
10299 (define_insn "load_toc_v4_PIC_1_476"
10300 [(set (reg:SI LR_REGNO)
10301 (match_operand:SI
0 "immediate_operand" "s"))
10302 (use (unspec [(match_dup
0)] UNSPEC_TOC))]
10303 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10304 && (flag_pic ==
2 || (flag_pic && TARGET_SECURE_PLT))"
10307 static char templ[
32];
10309 get_ppc476_thunk_name (name);
10310 sprintf (templ, "bl %s
\n%%
0:", name);
10313 [(set_attr "type" "branch")
10314 (set_attr "cannot_copy" "yes")])
10316 (define_expand "load_toc_v4_PIC_1b"
10317 [(parallel [(set (reg:SI LR_REGNO)
10318 (unspec:SI [(match_operand:SI
0 "immediate_operand" "s")
10319 (label_ref (match_operand
1 ""))]
10322 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic ==
2"
10325 (define_insn "load_toc_v4_PIC_1b_normal"
10326 [(set (reg:SI LR_REGNO)
10327 (unspec:SI [(match_operand:SI
0 "immediate_operand" "s")
10328 (label_ref (match_operand
1 "" ""))]
10331 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic ==
2"
10332 "bcl
20,
31,$+
8\;.long %
0-$"
10333 [(set_attr "type" "branch")
10334 (set_attr "length" "
8")])
10336 (define_insn "load_toc_v4_PIC_1b_476"
10337 [(set (reg:SI LR_REGNO)
10338 (unspec:SI [(match_operand:SI
0 "immediate_operand" "s")
10339 (label_ref (match_operand
1 "" ""))]
10342 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic ==
2"
10345 static char templ[
32];
10347 get_ppc476_thunk_name (name);
10348 sprintf (templ, "bl %s\;b $+
8\;.long %%
0-$", name);
10351 [(set_attr "type" "branch")
10352 (set_attr "length" "
16")])
10354 (define_insn "load_toc_v4_PIC_2"
10355 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
10357 (match_operand:SI
1 "gpc_reg_operand" "b")
10359 (minus:SI (match_operand:SI
2 "immediate_operand" "s")
10360 (match_operand:SI
3 "immediate_operand" "s"))))))]
10361 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic ==
2"
10363 [(set_attr "type" "load")])
10365 (define_insn "load_toc_v4_PIC_3b"
10366 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
10368 (match_operand:SI
1 "gpc_reg_operand" "b")
10371 (minus:SI (match_operand:SI
2 "symbol_ref_operand" "s")
10372 (match_operand:SI
3 "symbol_ref_operand" "s"))))))]
10373 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10374 "addis %
0,%
1,%
2-%
3@ha")
10376 (define_insn "load_toc_v4_PIC_3c"
10377 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
10379 (match_operand:SI
1 "gpc_reg_operand" "b")
10381 (minus:SI (match_operand:SI
2 "symbol_ref_operand" "s")
10382 (match_operand:SI
3 "symbol_ref_operand" "s")))))]
10383 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10384 "addi %
0,%
1,%
2-%
3@l")
10386 ;; If the TOC is shared over a translation unit, as happens with all
10387 ;; the kinds of PIC that we support, we need to restore the TOC
10388 ;; pointer only when jumping over units of translation.
10389 ;; On Darwin, we need to reload the picbase.
10391 (define_expand "builtin_setjmp_receiver"
10392 [(use (label_ref (match_operand
0 "")))]
10393 "(DEFAULT_ABI == ABI_V4 && flag_pic ==
1)
10394 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10395 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10398 if (DEFAULT_ABI == ABI_DARWIN)
10400 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10401 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10405 crtl->uses_pic_offset_table =
1;
10406 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10407 CODE_LABEL_NUMBER (operands[
0]));
10408 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10410 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10411 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10412 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10413 picrtx, tmplabrtx));
10417 rs6000_emit_load_toc_table (FALSE);
10421 ;; Largetoc support
10422 (define_insn "*largetoc_high"
10423 [(set (match_operand:DI
0 "gpc_reg_operand" "=b*r")
10425 (unspec [(match_operand:DI
1 "" "")
10426 (match_operand:DI
2 "gpc_reg_operand" "b")]
10428 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10429 "addis %
0,%
2,%
1@toc@ha")
10431 (define_insn "*largetoc_high_aix<mode>"
10432 [(set (match_operand:P
0 "gpc_reg_operand" "=b*r")
10434 (unspec [(match_operand:P
1 "" "")
10435 (match_operand:P
2 "gpc_reg_operand" "b")]
10437 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10438 "addis %
0,%
1@u(%
2)")
10440 (define_insn "*largetoc_high_plus"
10441 [(set (match_operand:DI
0 "gpc_reg_operand" "=b*r")
10444 (unspec [(match_operand:DI
1 "" "")
10445 (match_operand:DI
2 "gpc_reg_operand" "b")]
10447 (match_operand:DI
3 "add_cint_operand" "n"))))]
10448 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10449 "addis %
0,%
2,%
1+%
3@toc@ha")
10451 (define_insn "*largetoc_high_plus_aix<mode>"
10452 [(set (match_operand:P
0 "gpc_reg_operand" "=b*r")
10455 (unspec [(match_operand:P
1 "" "")
10456 (match_operand:P
2 "gpc_reg_operand" "b")]
10458 (match_operand:P
3 "add_cint_operand" "n"))))]
10459 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10460 "addis %
0,%
1+%
3@u(%
2)")
10462 (define_insn "*largetoc_low"
10463 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
10464 (lo_sum:DI (match_operand:DI
1 "gpc_reg_operand" "b")
10465 (match_operand:DI
2 "" "")))]
10466 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10469 (define_insn "*largetoc_low_aix<mode>"
10470 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10471 (lo_sum:P (match_operand:P
1 "gpc_reg_operand" "b")
10472 (match_operand:P
2 "" "")))]
10473 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10476 (define_insn_and_split "*tocref<mode>"
10477 [(set (match_operand:P
0 "gpc_reg_operand" "=b")
10478 (match_operand:P
1 "small_toc_ref" "R"))]
10480 && legitimate_constant_pool_address_p (operands[
1], QImode, false)"
10482 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10483 [(set (match_dup
0) (high:P (match_dup
1)))
10484 (set (match_dup
0) (lo_sum:P (match_dup
0) (match_dup
1)))])
10486 ;; Elf specific ways of loading addresses for non-PIC code.
10487 ;; The output of this could be r0, but we make a very strong
10488 ;; preference for a base register because it will usually
10489 ;; be needed there.
10490 (define_insn "elf_high"
10491 [(set (match_operand:SI
0 "gpc_reg_operand" "=b*r")
10492 (high:SI (match_operand
1 "" "")))]
10493 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10496 (define_insn "elf_low"
10497 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
10498 (lo_sum:SI (match_operand:SI
1 "gpc_reg_operand" "b")
10499 (match_operand
2 "" "")))]
10500 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10503 (define_insn "*pltseq_tocsave_<mode>"
10504 [(set (match_operand:P
0 "memory_operand" "=m")
10505 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "b")
10506 (match_operand:P
2 "symbol_ref_operand" "s")
10507 (match_operand:P
3 "" "")]
10510 && DEFAULT_ABI == ABI_ELFv2"
10512 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10515 (define_insn "*pltseq_plt16_ha_<mode>"
10516 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10517 (unspec:P [(match_operand:P
1 "" "")
10518 (match_operand:P
2 "symbol_ref_operand" "s")
10519 (match_operand:P
3 "" "")]
10523 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10526 (define_insn "*pltseq_plt16_lo_<mode>"
10527 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10528 (unspec_volatile:P [(match_operand:P
1 "gpc_reg_operand" "b")
10529 (match_operand:P
2 "symbol_ref_operand" "s")
10530 (match_operand:P
3 "" "")]
10531 UNSPECV_PLT16_LO))]
10534 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10536 [(set_attr "type" "load")])
10538 (define_insn "*pltseq_mtctr_<mode>"
10539 [(set (match_operand:P
0 "register_operand" "=c")
10540 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "r")
10541 (match_operand:P
2 "symbol_ref_operand" "s")
10542 (match_operand:P
3 "" "")]
10546 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10549 (define_insn "*pltseq_plt_pcrel<mode>"
10550 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
10551 (unspec_volatile:P [(match_operand:P
1 "" "")
10552 (match_operand:P
2 "symbol_ref_operand" "s")
10553 (match_operand:P
3 "" "")]
10554 UNSPECV_PLT_PCREL))]
10555 "HAVE_AS_PLTSEQ && TARGET_ELF
10556 && rs6000_pcrel_p (cfun)"
10558 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10560 [(set_attr "type" "load")
10561 (set_attr "length" "
12")])
10563 ;; Call and call_value insns
10564 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10565 (define_expand "call"
10566 [(parallel [(call (mem:SI (match_operand
0 "address_operand"))
10567 (match_operand
1 ""))
10568 (use (match_operand
2 ""))
10569 (clobber (reg:SI LR_REGNO))])]
10573 if (MACHOPIC_INDIRECT)
10574 operands[
0] = machopic_indirect_call_target (operands[
0]);
10577 gcc_assert (MEM_P (operands[
0]));
10579 operands[
0] = XEXP (operands[
0],
0);
10581 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10582 rs6000_call_aix (NULL_RTX, operands[
0], operands[
1], operands[
2]);
10583 else if (DEFAULT_ABI == ABI_V4)
10584 rs6000_call_sysv (NULL_RTX, operands[
0], operands[
1], operands[
2]);
10585 else if (DEFAULT_ABI == ABI_DARWIN)
10586 rs6000_call_darwin (NULL_RTX, operands[
0], operands[
1], operands[
2]);
10588 gcc_unreachable ();
10593 (define_expand "call_value"
10594 [(parallel [(set (match_operand
0 "")
10595 (call (mem:SI (match_operand
1 "address_operand"))
10596 (match_operand
2 "")))
10597 (use (match_operand
3 ""))
10598 (clobber (reg:SI LR_REGNO))])]
10602 if (MACHOPIC_INDIRECT)
10603 operands[
1] = machopic_indirect_call_target (operands[
1]);
10606 gcc_assert (MEM_P (operands[
1]));
10608 operands[
1] = XEXP (operands[
1],
0);
10610 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10611 rs6000_call_aix (operands[
0], operands[
1], operands[
2], operands[
3]);
10612 else if (DEFAULT_ABI == ABI_V4)
10613 rs6000_call_sysv (operands[
0], operands[
1], operands[
2], operands[
3]);
10614 else if (DEFAULT_ABI == ABI_DARWIN)
10615 rs6000_call_darwin (operands[
0], operands[
1], operands[
2], operands[
3]);
10617 gcc_unreachable ();
10622 ;; Call to function in current module. No TOC pointer reload needed.
10623 ;; Operand2 is nonzero if we are using the V
.4 calling sequence and
10624 ;; either the function was not prototyped, or it was prototyped as a
10625 ;; variable argument function. It is >
0 if FP registers were passed
10626 ;; and <
0 if they were not.
10628 (define_insn "*call_local<mode>"
10629 [(call (mem:SI (match_operand:P
0 "current_file_function_operand" "s,s"))
10631 (use (match_operand:SI
2 "immediate_operand" "O,n"))
10632 (clobber (reg:P LR_REGNO))]
10633 "(INTVAL (operands[
2]) & CALL_LONG) ==
0"
10635 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
10636 output_asm_insn ("crxor
6,
6,
6", operands);
10638 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
10639 output_asm_insn ("creqv
6,
6,
6", operands);
10641 if (rs6000_pcrel_p (cfun))
10642 return "bl %z0@notoc";
10643 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10645 [(set_attr "type" "branch")
10646 (set_attr "length" "
4,
8")])
10648 (define_insn "*call_value_local<mode>"
10649 [(set (match_operand
0 "" "")
10650 (call (mem:SI (match_operand:P
1 "current_file_function_operand" "s,s"))
10651 (match_operand
2)))
10652 (use (match_operand:SI
3 "immediate_operand" "O,n"))
10653 (clobber (reg:P LR_REGNO))]
10654 "(INTVAL (operands[
3]) & CALL_LONG) ==
0"
10656 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
10657 output_asm_insn ("crxor
6,
6,
6", operands);
10659 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
10660 output_asm_insn ("creqv
6,
6,
6", operands);
10662 if (rs6000_pcrel_p (cfun))
10663 return "bl %z1@notoc";
10664 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10666 [(set_attr "type" "branch")
10667 (set_attr "length" "
4,
8")])
10670 ;; A function pointer under System V is just a normal pointer
10671 ;; operands[
0] is the function pointer
10672 ;; operands[
1] is the tls call arg
10673 ;; operands[
2] is the value FUNCTION_ARG returns for the VOID argument
10674 ;; which indicates how to set cr1
10676 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10677 [(call (mem:SI (match_operand:P
0 "indirect_call_operand" "c,*l,X"))
10679 (use (match_operand:SI
2 "immediate_operand" "n,n,n"))
10680 (clobber (reg:P LR_REGNO))]
10681 "DEFAULT_ABI == ABI_V4
10682 || DEFAULT_ABI == ABI_DARWIN"
10684 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
10685 output_asm_insn ("crxor
6,
6,
6", operands);
10687 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
10688 output_asm_insn ("creqv
6,
6,
6", operands);
10690 return rs6000_indirect_call_template (operands,
0);
10692 [(set_attr "type" "jmpreg")
10693 (set (attr "length")
10694 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10695 (match_test "which_alternative !=
1"))
10696 (match_test "(INTVAL (operands[
2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10697 (const_string "
12")
10698 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10699 (match_test "which_alternative !=
1"))
10700 (match_test "(INTVAL (operands[
2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10701 (const_string "
8")]
10702 (const_string "
4")))])
10704 (define_insn "*call_nonlocal_sysv<mode>"
10705 [(call (mem:SI (match_operand:P
0 "symbol_ref_operand" "s,s"))
10707 (use (match_operand:SI
2 "immediate_operand" "O,n"))
10708 (clobber (reg:P LR_REGNO))]
10709 "(DEFAULT_ABI == ABI_DARWIN
10710 || (DEFAULT_ABI == ABI_V4
10711 && (INTVAL (operands[
2]) & CALL_LONG) ==
0))"
10713 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
10714 output_asm_insn ("crxor
6,
6,
6", operands);
10716 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
10717 output_asm_insn ("creqv
6,
6,
6", operands);
10719 return rs6000_call_template (operands,
0);
10721 [(set_attr "type" "branch,branch")
10722 (set_attr "length" "
4,
8")])
10724 (define_insn "*call_nonlocal_sysv_secure<mode>"
10725 [(call (mem:SI (match_operand:P
0 "symbol_ref_operand" "s,s"))
10727 (use (match_operand:SI
2 "immediate_operand" "O,n"))
10728 (use (match_operand:SI
3 "register_operand" "r,r"))
10729 (clobber (reg:P LR_REGNO))]
10730 "(DEFAULT_ABI == ABI_V4
10731 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[
0])
10732 && (INTVAL (operands[
2]) & CALL_LONG) ==
0)"
10734 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
10735 output_asm_insn ("crxor
6,
6,
6", operands);
10737 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
10738 output_asm_insn ("creqv
6,
6,
6", operands);
10740 return rs6000_call_template (operands,
0);
10742 [(set_attr "type" "branch,branch")
10743 (set_attr "length" "
4,
8")])
10745 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10746 [(set (match_operand
0 "" "")
10747 (call (mem:SI (match_operand:P
1 "indirect_call_operand" "c,*l,X"))
10748 (match_operand:P
2 "unspec_tls" "")))
10749 (use (match_operand:SI
3 "immediate_operand" "n,n,n"))
10750 (clobber (reg:P LR_REGNO))]
10751 "DEFAULT_ABI == ABI_V4
10752 || DEFAULT_ABI == ABI_DARWIN"
10754 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
10755 output_asm_insn ("crxor
6,
6,
6", operands);
10757 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
10758 output_asm_insn ("creqv
6,
6,
6", operands);
10760 return rs6000_indirect_call_template (operands,
1);
10762 [(set_attr "type" "jmpreg")
10763 (set (attr "length")
10765 (if_then_else (match_test "IS_V4_FP_ARGS (operands[
3])")
10768 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10769 (match_test "which_alternative !=
1"))
10773 (define_insn "*call_value_nonlocal_sysv<mode>"
10774 [(set (match_operand
0 "" "")
10775 (call (mem:SI (match_operand:P
1 "symbol_ref_operand" "s"))
10776 (match_operand:P
2 "unspec_tls" "")))
10777 (use (match_operand:SI
3 "immediate_operand" "n"))
10778 (clobber (reg:P LR_REGNO))]
10779 "(DEFAULT_ABI == ABI_DARWIN
10780 || (DEFAULT_ABI == ABI_V4
10781 && (INTVAL (operands[
3]) & CALL_LONG) ==
0))"
10783 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
10784 output_asm_insn ("crxor
6,
6,
6", operands);
10786 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
10787 output_asm_insn ("creqv
6,
6,
6", operands);
10789 return rs6000_call_template (operands,
1);
10791 [(set_attr "type" "branch")
10792 (set (attr "length")
10793 (if_then_else (match_test "IS_V4_FP_ARGS (operands[
3])")
10797 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10798 [(set (match_operand
0 "" "")
10799 (call (mem:SI (match_operand:P
1 "symbol_ref_operand" "s"))
10800 (match_operand:P
2 "unspec_tls" "")))
10801 (use (match_operand:SI
3 "immediate_operand" "n"))
10802 (use (match_operand:SI
4 "register_operand" "r"))
10803 (clobber (reg:P LR_REGNO))]
10804 "(DEFAULT_ABI == ABI_V4
10805 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[
1])
10806 && (INTVAL (operands[
3]) & CALL_LONG) ==
0)"
10808 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
10809 output_asm_insn ("crxor
6,
6,
6", operands);
10811 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
10812 output_asm_insn ("creqv
6,
6,
6", operands);
10814 return rs6000_call_template (operands,
1);
10816 [(set_attr "type" "branch")
10817 (set (attr "length")
10818 (if_then_else (match_test "IS_V4_FP_ARGS (operands[
3])")
10822 ;; Call to AIX abi function which may be in another module.
10823 ;; Restore the TOC pointer (r2) after the call.
10825 (define_insn "*call_nonlocal_aix<mode>"
10826 [(call (mem:SI (match_operand:P
0 "symbol_ref_operand" "s"))
10828 (use (match_operand:SI
2 "immediate_operand" "n"))
10829 (clobber (reg:P LR_REGNO))]
10830 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10831 && (INTVAL (operands[
2]) & CALL_LONG) ==
0"
10833 return rs6000_call_template (operands,
0);
10835 [(set_attr "type" "branch")
10836 (set (attr "length")
10837 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10841 (define_insn "*call_value_nonlocal_aix<mode>"
10842 [(set (match_operand
0 "" "")
10843 (call (mem:SI (match_operand:P
1 "symbol_ref_operand" "s"))
10844 (match_operand:P
2 "unspec_tls" "")))
10845 (use (match_operand:SI
3 "immediate_operand" "n"))
10846 (clobber (reg:P LR_REGNO))]
10847 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10848 && (INTVAL (operands[
3]) & CALL_LONG) ==
0"
10850 return rs6000_call_template (operands,
1);
10852 [(set_attr "type" "branch")
10853 (set (attr "length")
10854 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10858 ;; Call to indirect functions with the AIX abi using a
3 word descriptor.
10859 ;; Operand0 is the addresss of the function to call
10860 ;; Operand3 is the location in the function descriptor to load r2 from
10861 ;; Operand4 is the offset of the stack location holding the current TOC pointer
10863 (define_insn "*call_indirect_aix<mode>"
10864 [(call (mem:SI (match_operand:P
0 "indirect_call_operand" "c,*l,X"))
10866 (use (match_operand:SI
2 "immediate_operand" "n,n,n"))
10867 (use (match_operand:P
3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10868 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P
4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10869 (clobber (reg:P LR_REGNO))]
10870 "DEFAULT_ABI == ABI_AIX"
10872 return rs6000_indirect_call_template (operands,
0);
10874 [(set_attr "type" "jmpreg")
10875 (set (attr "length")
10876 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10877 (match_test "which_alternative !=
1"))
10878 (const_string "
16")
10879 (const_string "
12")))])
10881 (define_insn "*call_value_indirect_aix<mode>"
10882 [(set (match_operand
0 "" "")
10883 (call (mem:SI (match_operand:P
1 "indirect_call_operand" "c,*l,X"))
10884 (match_operand:P
2 "unspec_tls" "")))
10885 (use (match_operand:SI
3 "immediate_operand" "n,n,n"))
10886 (use (match_operand:P
4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10887 (set (reg:P TOC_REGNUM)
10888 (unspec:P [(match_operand:P
5 "const_int_operand" "n,n,n")]
10890 (clobber (reg:P LR_REGNO))]
10891 "DEFAULT_ABI == ABI_AIX"
10893 return rs6000_indirect_call_template (operands,
1);
10895 [(set_attr "type" "jmpreg")
10896 (set (attr "length")
10897 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10898 (match_test "which_alternative !=
1"))
10899 (const_string "
16")
10900 (const_string "
12")))])
10902 ;; Call to indirect functions with the ELFv2 ABI.
10903 ;; Operand0 is the addresss of the function to call
10904 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10906 (define_insn "*call_indirect_elfv2<mode>"
10907 [(call (mem:SI (match_operand:P
0 "indirect_call_operand" "c,*l,X"))
10909 (use (match_operand:SI
2 "immediate_operand" "n,n,n"))
10910 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P
3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10911 (clobber (reg:P LR_REGNO))]
10912 "DEFAULT_ABI == ABI_ELFv2"
10914 return rs6000_indirect_call_template (operands,
0);
10916 [(set_attr "type" "jmpreg")
10917 (set (attr "length")
10918 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10919 (match_test "which_alternative !=
1"))
10920 (const_string "
12")
10921 (const_string "
8")))])
10923 (define_insn "*call_indirect_pcrel<mode>"
10924 [(call (mem:SI (match_operand:P
0 "indirect_call_operand" "c,*l,X"))
10926 (use (match_operand:SI
2 "immediate_operand" "n,n,n"))
10927 (clobber (reg:P LR_REGNO))]
10928 "rs6000_pcrel_p (cfun)"
10930 return rs6000_indirect_call_template (operands,
0);
10932 [(set_attr "type" "jmpreg")
10933 (set (attr "length")
10934 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10935 (match_test "which_alternative !=
1"))
10937 (const_string "
4")))])
10939 (define_insn "*call_value_indirect_elfv2<mode>"
10940 [(set (match_operand
0 "" "")
10941 (call (mem:SI (match_operand:P
1 "indirect_call_operand" "c,*l,X"))
10942 (match_operand:P
2 "unspec_tls" "")))
10943 (use (match_operand:SI
3 "immediate_operand" "n,n,n"))
10944 (set (reg:P TOC_REGNUM)
10945 (unspec:P [(match_operand:P
4 "const_int_operand" "n,n,n")]
10947 (clobber (reg:P LR_REGNO))]
10948 "DEFAULT_ABI == ABI_ELFv2"
10950 return rs6000_indirect_call_template (operands,
1);
10952 [(set_attr "type" "jmpreg")
10953 (set (attr "length")
10954 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10955 (match_test "which_alternative !=
1"))
10956 (const_string "
12")
10957 (const_string "
8")))])
10959 (define_insn "*call_value_indirect_pcrel<mode>"
10960 [(set (match_operand
0 "" "")
10961 (call (mem:SI (match_operand:P
1 "indirect_call_operand" "c,*l,X"))
10962 (match_operand:P
2 "unspec_tls" "")))
10963 (use (match_operand:SI
3 "immediate_operand" "n,n,n"))
10964 (clobber (reg:P LR_REGNO))]
10965 "rs6000_pcrel_p (cfun)"
10967 return rs6000_indirect_call_template (operands,
1);
10969 [(set_attr "type" "jmpreg")
10970 (set (attr "length")
10971 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10972 (match_test "which_alternative !=
1"))
10974 (const_string "
4")))])
10976 ;; Call subroutine returning any type.
10977 (define_expand "untyped_call"
10978 [(parallel [(call (match_operand
0 "")
10980 (match_operand
1 "")
10981 (match_operand
2 "")])]
10986 emit_call_insn (gen_call (operands[
0], const0_rtx, const0_rtx));
10988 for (int i =
0; i < XVECLEN (operands[
2],
0); i++)
10989 emit_clobber (SET_SRC (XVECEXP (operands[
2],
0, i)));
10990 emit_insn (gen_blockage ());
10992 for (i =
0; i < XVECLEN (operands[
2],
0); i++)
10994 rtx set = XVECEXP (operands[
2],
0, i);
10995 emit_move_insn (SET_DEST (set), SET_SRC (set));
10998 /* The optimizer does not know that the call sets the function value
10999 registers we stored in the result block. We avoid problems by
11000 claiming that all hard registers are used and clobbered at this
11002 emit_insn (gen_blockage ());
11007 ;; sibling call patterns
11008 (define_expand "sibcall"
11009 [(parallel [(call (mem:SI (match_operand
0 "address_operand"))
11010 (match_operand
1 ""))
11011 (use (match_operand
2 ""))
11016 if (MACHOPIC_INDIRECT)
11017 operands[
0] = machopic_indirect_call_target (operands[
0]);
11020 gcc_assert (MEM_P (operands[
0]));
11021 gcc_assert (CONST_INT_P (operands[
1]));
11023 operands[
0] = XEXP (operands[
0],
0);
11025 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11026 rs6000_sibcall_aix (NULL_RTX, operands[
0], operands[
1], operands[
2]);
11027 else if (DEFAULT_ABI == ABI_V4)
11028 rs6000_sibcall_sysv (NULL_RTX, operands[
0], operands[
1], operands[
2]);
11029 else if (DEFAULT_ABI == ABI_DARWIN)
11030 rs6000_sibcall_darwin (NULL_RTX, operands[
0], operands[
1], operands[
2]);
11032 gcc_unreachable ();
11037 (define_expand "sibcall_value"
11038 [(parallel [(set (match_operand
0 "register_operand")
11039 (call (mem:SI (match_operand
1 "address_operand"))
11040 (match_operand
2 "")))
11041 (use (match_operand
3 ""))
11046 if (MACHOPIC_INDIRECT)
11047 operands[
1] = machopic_indirect_call_target (operands[
1]);
11050 gcc_assert (MEM_P (operands[
1]));
11051 gcc_assert (CONST_INT_P (operands[
2]));
11053 operands[
1] = XEXP (operands[
1],
0);
11055 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11056 rs6000_sibcall_aix (operands[
0], operands[
1], operands[
2], operands[
3]);
11057 else if (DEFAULT_ABI == ABI_V4)
11058 rs6000_sibcall_sysv (operands[
0], operands[
1], operands[
2], operands[
3]);
11059 else if (DEFAULT_ABI == ABI_DARWIN)
11060 rs6000_sibcall_darwin (operands[
0], operands[
1], operands[
2], operands[
3]);
11062 gcc_unreachable ();
11067 (define_insn "*sibcall_local<mode>"
11068 [(call (mem:SI (match_operand:P
0 "current_file_function_operand" "s,s"))
11070 (use (match_operand:SI
2 "immediate_operand" "O,n"))
11072 "(INTVAL (operands[
2]) & CALL_LONG) ==
0"
11074 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
11075 output_asm_insn ("crxor
6,
6,
6", operands);
11077 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
11078 output_asm_insn ("creqv
6,
6,
6", operands);
11080 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11082 [(set_attr "type" "branch")
11083 (set_attr "length" "
4,
8")])
11085 (define_insn "*sibcall_value_local<mode>"
11086 [(set (match_operand
0 "" "")
11087 (call (mem:SI (match_operand:P
1 "current_file_function_operand" "s,s"))
11088 (match_operand
2)))
11089 (use (match_operand:SI
3 "immediate_operand" "O,n"))
11091 "(INTVAL (operands[
3]) & CALL_LONG) ==
0"
11093 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
11094 output_asm_insn ("crxor
6,
6,
6", operands);
11096 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
11097 output_asm_insn ("creqv
6,
6,
6", operands);
11099 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11101 [(set_attr "type" "branch")
11102 (set_attr "length" "
4,
8")])
11104 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11105 [(call (mem:SI (match_operand:P
0 "indirect_call_operand" "c,*l,X"))
11107 (use (match_operand:SI
2 "immediate_operand" "n,n,n"))
11109 "DEFAULT_ABI == ABI_V4
11110 || DEFAULT_ABI == ABI_DARWIN"
11112 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
11113 output_asm_insn ("crxor
6,
6,
6", operands);
11115 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
11116 output_asm_insn ("creqv
6,
6,
6", operands);
11118 return rs6000_indirect_sibcall_template (operands,
0);
11120 [(set_attr "type" "jmpreg")
11121 (set (attr "length")
11122 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11123 (match_test "which_alternative !=
1"))
11124 (match_test "(INTVAL (operands[
2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11125 (const_string "
12")
11126 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11127 (match_test "which_alternative !=
1"))
11128 (match_test "(INTVAL (operands[
2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11129 (const_string "
8")]
11130 (const_string "
4")))])
11132 (define_insn "*sibcall_nonlocal_sysv<mode>"
11133 [(call (mem:SI (match_operand:P
0 "symbol_ref_operand" "s,s"))
11135 (use (match_operand
2 "immediate_operand" "O,n"))
11137 "(DEFAULT_ABI == ABI_DARWIN
11138 || DEFAULT_ABI == ABI_V4)
11139 && (INTVAL (operands[
2]) & CALL_LONG) ==
0"
11141 if (INTVAL (operands[
2]) & CALL_V4_SET_FP_ARGS)
11142 output_asm_insn ("crxor
6,
6,
6", operands);
11144 else if (INTVAL (operands[
2]) & CALL_V4_CLEAR_FP_ARGS)
11145 output_asm_insn ("creqv
6,
6,
6", operands);
11147 return rs6000_sibcall_template (operands,
0);
11149 [(set_attr "type" "branch")
11150 (set_attr "length" "
4,
8")])
11152 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11153 [(set (match_operand
0 "" "")
11154 (call (mem:SI (match_operand:P
1 "indirect_call_operand" "c,*l,X"))
11155 (match_operand
2)))
11156 (use (match_operand:SI
3 "immediate_operand" "n,n,n"))
11158 "DEFAULT_ABI == ABI_V4
11159 || DEFAULT_ABI == ABI_DARWIN"
11161 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
11162 output_asm_insn ("crxor
6,
6,
6", operands);
11164 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
11165 output_asm_insn ("creqv
6,
6,
6", operands);
11167 return rs6000_indirect_sibcall_template (operands,
1);
11169 [(set_attr "type" "jmpreg")
11170 (set (attr "length")
11171 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11172 (match_test "which_alternative !=
1"))
11173 (match_test "(INTVAL (operands[
3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11174 (const_string "
12")
11175 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11176 (match_test "which_alternative !=
1"))
11177 (match_test "(INTVAL (operands[
3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11178 (const_string "
8")]
11179 (const_string "
4")))])
11181 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11182 [(set (match_operand
0 "" "")
11183 (call (mem:SI (match_operand:P
1 "symbol_ref_operand" "s,s"))
11184 (match_operand
2)))
11185 (use (match_operand:SI
3 "immediate_operand" "O,n"))
11187 "(DEFAULT_ABI == ABI_DARWIN
11188 || DEFAULT_ABI == ABI_V4)
11189 && (INTVAL (operands[
3]) & CALL_LONG) ==
0"
11191 if (INTVAL (operands[
3]) & CALL_V4_SET_FP_ARGS)
11192 output_asm_insn ("crxor
6,
6,
6", operands);
11194 else if (INTVAL (operands[
3]) & CALL_V4_CLEAR_FP_ARGS)
11195 output_asm_insn ("creqv
6,
6,
6", operands);
11197 return rs6000_sibcall_template (operands,
1);
11199 [(set_attr "type" "branch")
11200 (set_attr "length" "
4,
8")])
11202 ;; AIX ABI sibling call patterns.
11204 (define_insn "*sibcall_aix<mode>"
11205 [(call (mem:SI (match_operand:P
0 "call_operand" "s,c"))
11208 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11210 if (which_alternative ==
0)
11211 return rs6000_sibcall_template (operands,
0);
11215 [(set_attr "type" "branch")])
11217 (define_insn "*sibcall_value_aix<mode>"
11218 [(set (match_operand
0 "" "")
11219 (call (mem:SI (match_operand:P
1 "call_operand" "s,c"))
11220 (match_operand
2)))
11222 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11224 if (which_alternative ==
0)
11225 return rs6000_sibcall_template (operands,
1);
11229 [(set_attr "type" "branch")])
11231 (define_expand "sibcall_epilogue"
11232 [(use (const_int
0))]
11235 if (!TARGET_SCHED_PROLOG)
11236 emit_insn (gen_blockage ());
11237 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11241 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11242 ;; all of memory. This blocks insns from being moved across this point.
11244 (define_insn "blockage"
11245 [(unspec_volatile [(const_int
0)] UNSPECV_BLOCK)]
11248 [(set_attr "length" "
0")])
11250 (define_expand "probe_stack_address"
11251 [(use (match_operand
0 "address_operand"))]
11254 operands[
0] = gen_rtx_MEM (Pmode, operands[
0]);
11255 MEM_VOLATILE_P (operands[
0]) =
1;
11258 emit_insn (gen_probe_stack_di (operands[
0]));
11260 emit_insn (gen_probe_stack_si (operands[
0]));
11264 (define_insn "probe_stack_<mode>"
11265 [(set (match_operand:P
0 "memory_operand" "=m")
11266 (unspec:P [(const_int
0)] UNSPEC_PROBE_STACK))]
11269 operands[
1] = gen_rtx_REG (Pmode,
0);
11270 return "st<wd>%U0%X0 %
1,%
0";
11272 [(set_attr "type" "store")
11273 (set (attr "update")
11274 (if_then_else (match_operand
0 "update_address_mem")
11275 (const_string "yes")
11276 (const_string "no")))
11277 (set (attr "indexed")
11278 (if_then_else (match_operand
0 "indexed_address_mem")
11279 (const_string "yes")
11280 (const_string "no")))])
11282 (define_insn "probe_stack_range<P:mode>"
11283 [(set (match_operand:P
0 "register_operand" "=&r")
11284 (unspec_volatile:P [(match_operand:P
1 "register_operand" "
0")
11285 (match_operand:P
2 "register_operand" "r")
11286 (match_operand:P
3 "register_operand" "r")]
11287 UNSPECV_PROBE_STACK_RANGE))]
11289 "* return output_probe_stack_range (operands[
0], operands[
2], operands[
3]);"
11290 [(set_attr "type" "three")])
11292 ;; Compare insns are next. Note that the RS/
6000 has two types of compares,
11293 ;; signed & unsigned, and one type of branch.
11295 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11296 ;; insns, and branches.
11298 (define_expand "cbranch<mode>
4"
11299 [(use (match_operator
0 "comparison_operator"
11300 [(match_operand:GPR
1 "gpc_reg_operand")
11301 (match_operand:GPR
2 "reg_or_short_operand")]))
11302 (use (match_operand
3))]
11305 /* Take care of the possibility that operands[
2] might be negative but
11306 this might be a logical operation. That insn doesn't exist. */
11307 if (CONST_INT_P (operands[
2])
11308 && INTVAL (operands[
2]) <
0)
11310 operands[
2] = force_reg (<MODE>mode, operands[
2]);
11311 operands[
0] = gen_rtx_fmt_ee (GET_CODE (operands[
0]),
11312 GET_MODE (operands[
0]),
11313 operands[
1], operands[
2]);
11316 rs6000_emit_cbranch (<MODE>mode, operands);
11320 (define_expand "cbranch<mode>
4"
11321 [(use (match_operator
0 "comparison_operator"
11322 [(match_operand:FP
1 "gpc_reg_operand")
11323 (match_operand:FP
2 "gpc_reg_operand")]))
11324 (use (match_operand
3))]
11327 rs6000_emit_cbranch (<MODE>mode, operands);
11331 (define_expand "cstore<mode>
4_signed"
11332 [(use (match_operator
1 "signed_comparison_operator"
11333 [(match_operand:P
2 "gpc_reg_operand")
11334 (match_operand:P
3 "gpc_reg_operand")]))
11335 (clobber (match_operand:P
0 "gpc_reg_operand"))]
11338 enum rtx_code cond_code = GET_CODE (operands[
1]);
11340 rtx op0 = operands[
0];
11341 rtx op1 = operands[
2];
11342 rtx op2 = operands[
3];
11344 if (cond_code == GE || cond_code == LT)
11346 cond_code = swap_condition (cond_code);
11347 std::swap (op1, op2);
11350 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11351 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11352 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11354 int sh = GET_MODE_BITSIZE (<MODE>mode) -
1;
11355 emit_insn (gen_lshr<mode>
3 (tmp1, op1, GEN_INT (sh)));
11356 emit_insn (gen_ashr<mode>
3 (tmp2, op2, GEN_INT (sh)));
11358 emit_insn (gen_subf<mode>
3_carry (tmp3, op1, op2));
11360 if (cond_code == LE)
11361 emit_insn (gen_add<mode>
3_carry_in (op0, tmp1, tmp2));
11364 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11365 emit_insn (gen_add<mode>
3_carry_in (tmp4, tmp1, tmp2));
11366 emit_insn (gen_xor<mode>
3 (op0, tmp4, const1_rtx));
11372 (define_expand "cstore<mode>
4_unsigned"
11373 [(use (match_operator
1 "unsigned_comparison_operator"
11374 [(match_operand:P
2 "gpc_reg_operand")
11375 (match_operand:P
3 "reg_or_short_operand")]))
11376 (clobber (match_operand:P
0 "gpc_reg_operand"))]
11379 enum rtx_code cond_code = GET_CODE (operands[
1]);
11381 rtx op0 = operands[
0];
11382 rtx op1 = operands[
2];
11383 rtx op2 = operands[
3];
11385 if (cond_code == GEU || cond_code == LTU)
11387 cond_code = swap_condition (cond_code);
11388 std::swap (op1, op2);
11391 if (!gpc_reg_operand (op1, <MODE>mode))
11392 op1 = force_reg (<MODE>mode, op1);
11393 if (!reg_or_short_operand (op2, <MODE>mode))
11394 op2 = force_reg (<MODE>mode, op2);
11396 rtx tmp = gen_reg_rtx (<MODE>mode);
11397 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11399 emit_insn (gen_subf<mode>
3_carry (tmp, op1, op2));
11400 emit_insn (gen_subf<mode>
3_carry_in_xx (tmp2));
11402 if (cond_code == LEU)
11403 emit_insn (gen_add<mode>
3 (op0, tmp2, const1_rtx));
11405 emit_insn (gen_neg<mode>
2 (op0, tmp2));
11410 (define_expand "cstore_si_as_di"
11411 [(use (match_operator
1 "unsigned_comparison_operator"
11412 [(match_operand:SI
2 "gpc_reg_operand")
11413 (match_operand:SI
3 "reg_or_short_operand")]))
11414 (clobber (match_operand:SI
0 "gpc_reg_operand"))]
11417 int uns_flag = unsigned_comparison_operator (operands[
1], VOIDmode) ?
1 :
0;
11418 enum rtx_code cond_code = signed_condition (GET_CODE (operands[
1]));
11420 operands[
2] = force_reg (SImode, operands[
2]);
11421 operands[
3] = force_reg (SImode, operands[
3]);
11422 rtx op1 = gen_reg_rtx (DImode);
11423 rtx op2 = gen_reg_rtx (DImode);
11424 convert_move (op1, operands[
2], uns_flag);
11425 convert_move (op2, operands[
3], uns_flag);
11427 if (cond_code == GT || cond_code == LE)
11429 cond_code = swap_condition (cond_code);
11430 std::swap (op1, op2);
11433 rtx tmp = gen_reg_rtx (DImode);
11434 rtx tmp2 = gen_reg_rtx (DImode);
11435 emit_insn (gen_subdi3 (tmp, op1, op2));
11436 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (
63)));
11442 gcc_unreachable ();
11447 tmp3 = gen_reg_rtx (DImode);
11448 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11452 convert_move (operands[
0], tmp3,
1);
11457 (define_expand "cstore<mode>
4_signed_imm"
11458 [(use (match_operator
1 "signed_comparison_operator"
11459 [(match_operand:GPR
2 "gpc_reg_operand")
11460 (match_operand:GPR
3 "immediate_operand")]))
11461 (clobber (match_operand:GPR
0 "gpc_reg_operand"))]
11464 bool invert = false;
11466 enum rtx_code cond_code = GET_CODE (operands[
1]);
11468 rtx op0 = operands[
0];
11469 rtx op1 = operands[
2];
11470 HOST_WIDE_INT val = INTVAL (operands[
3]);
11472 if (cond_code == GE || cond_code == GT)
11474 cond_code = reverse_condition (cond_code);
11478 if (cond_code == LE)
11481 rtx tmp = gen_reg_rtx (<MODE>mode);
11482 emit_insn (gen_add<mode>
3 (tmp, op1, GEN_INT (-val)));
11483 rtx x = gen_reg_rtx (<MODE>mode);
11485 emit_insn (gen_and<mode>
3 (x, op1, tmp));
11487 emit_insn (gen_ior<mode>
3 (x, op1, tmp));
11491 rtx tmp = gen_reg_rtx (<MODE>mode);
11492 emit_insn (gen_one_cmpl<mode>
2 (tmp, x));
11496 int sh = GET_MODE_BITSIZE (<MODE>mode) -
1;
11497 emit_insn (gen_lshr<mode>
3 (op0, x, GEN_INT (sh)));
11502 (define_expand "cstore<mode>
4_unsigned_imm"
11503 [(use (match_operator
1 "unsigned_comparison_operator"
11504 [(match_operand:GPR
2 "gpc_reg_operand")
11505 (match_operand:GPR
3 "immediate_operand")]))
11506 (clobber (match_operand:GPR
0 "gpc_reg_operand"))]
11509 bool invert = false;
11511 enum rtx_code cond_code = GET_CODE (operands[
1]);
11513 rtx op0 = operands[
0];
11514 rtx op1 = operands[
2];
11515 HOST_WIDE_INT val = INTVAL (operands[
3]);
11517 if (cond_code == GEU || cond_code == GTU)
11519 cond_code = reverse_condition (cond_code);
11523 if (cond_code == LEU)
11526 rtx tmp = gen_reg_rtx (<MODE>mode);
11527 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11528 emit_insn (gen_add<mode>
3 (tmp, op1, GEN_INT (-val)));
11529 emit_insn (gen_one_cmpl<mode>
2 (tmp2, op1));
11530 rtx x = gen_reg_rtx (<MODE>mode);
11532 emit_insn (gen_ior<mode>
3 (x, tmp, tmp2));
11534 emit_insn (gen_and<mode>
3 (x, tmp, tmp2));
11538 rtx tmp = gen_reg_rtx (<MODE>mode);
11539 emit_insn (gen_one_cmpl<mode>
2 (tmp, x));
11543 int sh = GET_MODE_BITSIZE (<MODE>mode) -
1;
11544 emit_insn (gen_lshr<mode>
3 (op0, x, GEN_INT (sh)));
11549 (define_expand "cstore<mode>
4"
11550 [(use (match_operator
1 "comparison_operator"
11551 [(match_operand:GPR
2 "gpc_reg_operand")
11552 (match_operand:GPR
3 "reg_or_short_operand")]))
11553 (clobber (match_operand:GPR
0 "gpc_reg_operand"))]
11556 /* Everything is best done with setbc[r] if available. */
11557 if (TARGET_POWER10)
11558 rs6000_emit_int_cmove (operands[
0], operands[
1], const1_rtx, const0_rtx);
11560 /* Expanding EQ and NE directly to some machine instructions does not help
11561 but does hurt combine. So don't. */
11562 if (GET_CODE (operands[
1]) == EQ)
11563 emit_insn (gen_eq<mode>
3 (operands[
0], operands[
2], operands[
3]));
11564 else if (<MODE>mode == Pmode
11565 && GET_CODE (operands[
1]) == NE)
11566 emit_insn (gen_ne<mode>
3 (operands[
0], operands[
2], operands[
3]));
11567 else if (GET_CODE (operands[
1]) == NE)
11569 rtx tmp = gen_reg_rtx (<MODE>mode);
11570 emit_insn (gen_eq<mode>
3 (tmp, operands[
2], operands[
3]));
11571 emit_insn (gen_xor<mode>
3 (operands[
0], tmp, const1_rtx));
11574 /* If ISEL is fast, expand to it. */
11575 else if (TARGET_ISEL)
11576 rs6000_emit_int_cmove (operands[
0], operands[
1], const1_rtx, const0_rtx);
11578 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11579 etc. combinations magically work out just right. */
11580 else if (<MODE>mode == Pmode
11581 && unsigned_comparison_operator (operands[
1], VOIDmode))
11582 emit_insn (gen_cstore<mode>
4_unsigned (operands[
0], operands[
1],
11583 operands[
2], operands[
3]));
11585 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11586 else if (<MODE>mode == SImode && Pmode == DImode)
11587 emit_insn (gen_cstore_si_as_di (operands[
0], operands[
1],
11588 operands[
2], operands[
3]));
11590 /* For signed comparisons against a constant, we can do some simple
11592 else if (signed_comparison_operator (operands[
1], VOIDmode)
11593 && CONST_INT_P (operands[
3]))
11594 emit_insn (gen_cstore<mode>
4_signed_imm (operands[
0], operands[
1],
11595 operands[
2], operands[
3]));
11597 /* And similarly for unsigned comparisons. */
11598 else if (unsigned_comparison_operator (operands[
1], VOIDmode)
11599 && CONST_INT_P (operands[
3]))
11600 emit_insn (gen_cstore<mode>
4_unsigned_imm (operands[
0], operands[
1],
11601 operands[
2], operands[
3]));
11603 /* We also do not want to use mfcr for signed comparisons. */
11604 else if (<MODE>mode == Pmode
11605 && signed_comparison_operator (operands[
1], VOIDmode))
11606 emit_insn (gen_cstore<mode>
4_signed (operands[
0], operands[
1],
11607 operands[
2], operands[
3]));
11609 /* Everything else, use the mfcr brute force. */
11611 rs6000_emit_sCOND (<MODE>mode, operands);
11616 (define_expand "cstore<mode>
4"
11617 [(use (match_operator
1 "comparison_operator"
11618 [(match_operand:FP
2 "gpc_reg_operand")
11619 (match_operand:FP
3 "gpc_reg_operand")]))
11620 (clobber (match_operand:SI
0 "gpc_reg_operand"))]
11623 rs6000_emit_sCOND (<MODE>mode, operands);
11628 (define_expand "stack_protect_set"
11629 [(match_operand
0 "memory_operand")
11630 (match_operand
1 "memory_operand")]
11633 if (rs6000_stack_protector_guard == SSP_TLS)
11635 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11636 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11637 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11638 operands[
1] = gen_rtx_MEM (Pmode, addr);
11642 emit_insn (gen_stack_protect_setdi (operands[
0], operands[
1]));
11644 emit_insn (gen_stack_protect_setsi (operands[
0], operands[
1]));
11649 (define_insn "stack_protect_setsi"
11650 [(set (match_operand:SI
0 "memory_operand" "=m")
11651 (unspec:SI [(match_operand:SI
1 "memory_operand" "m")] UNSPEC_SP_SET))
11652 (set (match_scratch:SI
2 "=&r") (const_int
0))]
11654 "lwz%U1%X1 %
2,%
1\;stw%U0%X0 %
2,%
0\;li %
2,
0"
11655 [(set_attr "type" "three")
11656 (set_attr "length" "
12")])
11658 ;; We can't use the prefixed attribute here because there are two memory
11659 ;; instructions. We can't split the insn due to the fact that this operation
11660 ;; needs to be done in one piece.
11661 (define_insn "stack_protect_setdi"
11662 [(set (match_operand:DI
0 "memory_operand" "=Y")
11663 (unspec:DI [(match_operand:DI
1 "memory_operand" "Y")] UNSPEC_SP_SET))
11664 (set (match_scratch:DI
2 "=&r") (const_int
0))]
11667 if (prefixed_memory (operands[
1], DImode))
11668 output_asm_insn ("pld %
2,%
1", operands);
11670 output_asm_insn ("ld%U1%X1 %
2,%
1", operands);
11672 if (prefixed_memory (operands[
0], DImode))
11673 output_asm_insn ("pstd %
2,%
0", operands);
11675 output_asm_insn ("std%U0%X0 %
2,%
0", operands);
11679 [(set_attr "type" "three")
11681 ;; Back to back prefixed memory instructions take
20 bytes (
8 bytes for each
11682 ;; prefixed instruction +
4 bytes for the possible NOP). Add in
4 bytes for
11683 ;; the LI
0 at the end.
11684 (set_attr "prefixed" "no")
11685 (set_attr "num_insns" "
3")
11686 (set (attr "length")
11687 (cond [(and (match_operand
0 "prefixed_memory")
11688 (match_operand
1 "prefixed_memory"))
11691 (ior (match_operand
0 "prefixed_memory")
11692 (match_operand
1 "prefixed_memory"))
11697 (define_expand "stack_protect_test"
11698 [(match_operand
0 "memory_operand")
11699 (match_operand
1 "memory_operand")
11700 (match_operand
2 "")]
11703 rtx guard = operands[
1];
11705 if (rs6000_stack_protector_guard == SSP_TLS)
11707 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11708 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11709 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11710 guard = gen_rtx_MEM (Pmode, addr);
11713 operands[
1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (
1, guard), UNSPEC_SP_TEST);
11714 rtx test = gen_rtx_EQ (VOIDmode, operands[
0], operands[
1]);
11715 rtx jump = gen_cbranchsi4 (test, operands[
0], operands[
1], operands[
2]);
11716 emit_jump_insn (jump);
11721 (define_insn "stack_protect_testsi"
11722 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=x,?y")
11723 (unspec:CCEQ [(match_operand:SI
1 "memory_operand" "m,m")
11724 (match_operand:SI
2 "memory_operand" "m,m")]
11726 (set (match_scratch:SI
4 "=r,r") (const_int
0))
11727 (clobber (match_scratch:SI
3 "=&r,&r"))]
11730 lwz%U1%X1 %
3,%
1\;lwz%U2%X2 %
4,%
2\;xor. %
3,%
3,%
4\;li %
4,
0
11731 lwz%U1%X1 %
3,%
1\;lwz%U2%X2 %
4,%
2\;cmplw %
0,%
3,%
4\;li %
3,
0\;li %
4,
0"
11732 [(set_attr "length" "
16,
20")])
11734 ;; We can't use the prefixed attribute here because there are two memory
11735 ;; instructions. We can't split the insn due to the fact that this operation
11736 ;; needs to be done in one piece.
11737 (define_insn "stack_protect_testdi"
11738 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=x,?y")
11739 (unspec:CCEQ [(match_operand:DI
1 "memory_operand" "Y,Y")
11740 (match_operand:DI
2 "memory_operand" "Y,Y")]
11742 (set (match_scratch:DI
4 "=r,r") (const_int
0))
11743 (clobber (match_scratch:DI
3 "=&r,&r"))]
11746 if (prefixed_memory (operands[
1], DImode))
11747 output_asm_insn ("pld %
3,%
1", operands);
11749 output_asm_insn ("ld%U1%X1 %
3,%
1", operands);
11751 if (prefixed_memory (operands[
2], DImode))
11752 output_asm_insn ("pld %
4,%
2", operands);
11754 output_asm_insn ("ld%U2%X2 %
4,%
2", operands);
11756 if (which_alternative ==
0)
11757 output_asm_insn ("xor. %
3,%
3,%
4", operands);
11759 output_asm_insn ("cmpld %
0,%
3,%
4\;li %
3,
0", operands);
11763 ;; Back to back prefixed memory instructions take
20 bytes (
8 bytes for each
11764 ;; prefixed instruction +
4 bytes for the possible NOP). Add in either
4 or
11765 ;;
8 bytes to do the test.
11766 [(set_attr "prefixed" "no")
11767 (set_attr "num_insns" "
4,
5")
11768 (set (attr "length")
11769 (cond [(and (match_operand
1 "prefixed_memory")
11770 (match_operand
2 "prefixed_memory"))
11771 (if_then_else (eq_attr "alternative" "
0")
11775 (ior (match_operand
1 "prefixed_memory")
11776 (match_operand
2 "prefixed_memory"))
11777 (if_then_else (eq_attr "alternative" "
0")
11781 (if_then_else (eq_attr "alternative" "
0")
11783 (const_int
20))))])
11786 ;; Here are the actual compare insns.
11787 (define_insn "*cmp<mode>_signed"
11788 [(set (match_operand:CC
0 "cc_reg_operand" "=y")
11789 (compare:CC (match_operand:GPR
1 "gpc_reg_operand" "r")
11790 (match_operand:GPR
2 "reg_or_short_operand" "rI")))]
11792 "cmp<wd>%I2 %
0,%
1,%
2"
11793 [(set_attr "type" "cmp")])
11795 (define_insn "*cmp<mode>_unsigned"
11796 [(set (match_operand:CCUNS
0 "cc_reg_operand" "=y")
11797 (compare:CCUNS (match_operand:GPR
1 "gpc_reg_operand" "r")
11798 (match_operand:GPR
2 "reg_or_u_short_operand" "rK")))]
11800 "cmpl<wd>%I2 %
0,%
1,%
2"
11801 [(set_attr "type" "cmp")])
11803 ;; If we are comparing a register for equality with a large constant,
11804 ;; we can do this with an XOR followed by a compare. But this is profitable
11805 ;; only if the large constant is only used for the comparison (and in this
11806 ;; case we already have a register to reuse as scratch).
11808 ;; For
64-bit registers, we could only do so if the constant's bit
15 is clear:
11809 ;; otherwise we'd need to XOR with FFFFFFFF????
0000 which is not available.
11812 [(set (match_operand:SI
0 "register_operand")
11813 (match_operand:SI
1 "logical_const_operand"))
11814 (set (match_dup
0) (match_operator:SI
3 "boolean_or_operator"
11816 (match_operand:SI
2 "logical_const_operand")]))
11817 (set (match_operand:CC
4 "cc_reg_operand")
11818 (compare:CC (match_operand:SI
5 "gpc_reg_operand")
11821 (if_then_else (match_operator
6 "equality_operator"
11822 [(match_dup
4) (const_int
0)])
11823 (match_operand
7 "")
11824 (match_operand
8 "")))]
11825 "peep2_reg_dead_p (
3, operands[
0])
11826 && peep2_reg_dead_p (
4, operands[
4])
11827 && REGNO (operands[
0]) != REGNO (operands[
5])"
11828 [(set (match_dup
0) (xor:SI (match_dup
5) (match_dup
9)))
11829 (set (match_dup
4) (compare:CC (match_dup
0) (match_dup
10)))
11830 (set (pc) (if_then_else (match_dup
6) (match_dup
7) (match_dup
8)))]
11833 /* Get the constant we are comparing against, and see what it looks like
11834 when sign-extended from
16 to
32 bits. Then see what constant we could
11835 XOR with SEXTC to get the sign-extended value. */
11836 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[
3]),
11838 operands[
1], operands[
2]);
11839 HOST_WIDE_INT c = INTVAL (cnst);
11840 HOST_WIDE_INT sextc = ((c &
0xffff) ^
0x8000) -
0x8000;
11841 HOST_WIDE_INT xorv = c ^ sextc;
11843 operands[
9] = GEN_INT (xorv);
11844 operands[
10] = GEN_INT (sextc);
11847 ;; Only need to compare second words if first words equal
11848 (define_insn "*cmp<mode>_internal1"
11849 [(set (match_operand:CCFP
0 "cc_reg_operand" "=y")
11850 (compare:CCFP (match_operand:IBM128
1 "gpc_reg_operand" "d")
11851 (match_operand:IBM128
2 "gpc_reg_operand" "d")))]
11852 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11853 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11854 "fcmpu %
0,%
1,%
2\;bne %
0,$+
8\;fcmpu %
0,%L1,%L2"
11855 [(set_attr "type" "fpcompare")
11856 (set_attr "length" "
12")])
11858 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11859 [(set (match_operand:CCFP
0 "cc_reg_operand" "=y")
11860 (compare:CCFP (match_operand:IBM128
1 "gpc_reg_operand" "d")
11861 (match_operand:IBM128
2 "gpc_reg_operand" "d")))
11862 (clobber (match_scratch:DF
3 "=d"))
11863 (clobber (match_scratch:DF
4 "=d"))
11864 (clobber (match_scratch:DF
5 "=d"))
11865 (clobber (match_scratch:DF
6 "=d"))
11866 (clobber (match_scratch:DF
7 "=d"))
11867 (clobber (match_scratch:DF
8 "=d"))
11868 (clobber (match_scratch:DF
9 "=d"))
11869 (clobber (match_scratch:DF
10 "=d"))
11870 (clobber (match_scratch:GPR
11 "=b"))]
11871 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11872 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11874 "&& reload_completed"
11875 [(set (match_dup
3) (match_dup
14))
11876 (set (match_dup
4) (match_dup
15))
11877 (set (match_dup
9) (abs:DF (match_dup
5)))
11878 (set (match_dup
0) (compare:CCFP (match_dup
9) (match_dup
3)))
11879 (set (pc) (if_then_else (ne (match_dup
0) (const_int
0))
11880 (label_ref (match_dup
12))
11882 (set (match_dup
0) (compare:CCFP (match_dup
5) (match_dup
7)))
11883 (set (pc) (label_ref (match_dup
13)))
11885 (set (match_dup
10) (minus:DF (match_dup
5) (match_dup
7)))
11886 (set (match_dup
9) (minus:DF (match_dup
6) (match_dup
8)))
11887 (set (match_dup
9) (plus:DF (match_dup
10) (match_dup
9)))
11888 (set (match_dup
0) (compare:CCFP (match_dup
9) (match_dup
4)))
11891 REAL_VALUE_TYPE rv;
11892 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) :
0;
11893 const int hi_word = LONG_DOUBLE_LARGE_FIRST ?
0 : GET_MODE_SIZE (DFmode);
11895 operands[
5] = simplify_gen_subreg (DFmode, operands[
1],
11896 <IBM128:MODE>mode, hi_word);
11897 operands[
6] = simplify_gen_subreg (DFmode, operands[
1],
11898 <IBM128:MODE>mode, lo_word);
11899 operands[
7] = simplify_gen_subreg (DFmode, operands[
2],
11900 <IBM128:MODE>mode, hi_word);
11901 operands[
8] = simplify_gen_subreg (DFmode, operands[
2],
11902 <IBM128:MODE>mode, lo_word);
11903 operands[
12] = gen_label_rtx ();
11904 operands[
13] = gen_label_rtx ();
11906 operands[
14] = force_const_mem (DFmode,
11907 const_double_from_real_value (rv, DFmode));
11908 operands[
15] = force_const_mem (DFmode,
11909 const_double_from_real_value (dconst0,
11914 tocref = create_TOC_reference (XEXP (operands[
14],
0), operands[
11]);
11915 operands[
14] = gen_const_mem (DFmode, tocref);
11916 tocref = create_TOC_reference (XEXP (operands[
15],
0), operands[
11]);
11917 operands[
15] = gen_const_mem (DFmode, tocref);
11918 set_mem_alias_set (operands[
14], get_TOC_alias_set ());
11919 set_mem_alias_set (operands[
15], get_TOC_alias_set ());
11923 ;; Now we have the scc insns. We can do some combinations because of the
11924 ;; way the machine works.
11926 ;; Note that this is probably faster if we can put an insn between the
11927 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11928 ;; cases the insns below which don't use an intermediate CR field will
11929 ;; be used instead.
11930 (define_insn "set<mode>_cc"
11931 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
11932 (match_operator:GPR
1 "scc_comparison_operator"
11933 [(match_operand
2 "cc_reg_operand" "y")
11936 "mfcr %
0%Q2\;rlwinm %
0,%
0,%J1,
1"
11937 [(set (attr "type")
11938 (cond [(match_test "TARGET_MFCRF")
11939 (const_string "mfcrf")
11941 (const_string "mfcr")))
11942 (set_attr "length" "
8")])
11945 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11946 (define_code_attr UNS [(eq "CC")
11948 (lt "CC") (ltu "CCUNS")
11949 (gt "CC") (gtu "CCUNS")
11950 (le "CC") (leu "CCUNS")
11951 (ge "CC") (geu "CCUNS")])
11952 (define_code_attr UNSu_ [(eq "")
11957 (ge "") (geu "u_")])
11958 (define_code_attr UNSIK [(eq "I")
11963 (ge "I") (geu "K")])
11965 (define_insn_and_split "<code><GPR:mode><GPR2:mode>
2_isel"
11966 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
11967 (cmp:GPR (match_operand:GPR2
1 "gpc_reg_operand" "r")
11968 (match_operand:GPR2
2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11969 (clobber (match_scratch:GPR
3 "=r"))
11970 (clobber (match_scratch:GPR
4 "=r"))
11971 (clobber (match_scratch:<UNS>
5 "=y"))]
11972 "!TARGET_POWER10 && TARGET_ISEL
11973 && !(<CODE> == EQ && operands[
2] == const0_rtx)
11974 && !(<CODE> == NE && operands[
2] == const0_rtx
11975 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11980 rtx_code code = <CODE>;
11981 if (CONST_INT_P (operands[
2]) && code != EQ && code != NE)
11983 HOST_WIDE_INT val = INTVAL (operands[
2]);
11984 if (code == LT && val != -
0x8000)
11989 if (code == GT && val !=
0x7fff)
11994 if (code == LTU && val !=
0)
11999 if (code == GTU && val !=
0xffff)
12004 operands[
2] = GEN_INT (val);
12007 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
12008 operands[
3] = const0_rtx;
12011 if (GET_CODE (operands[
3]) == SCRATCH)
12012 operands[
3] = gen_reg_rtx (<GPR:MODE>mode);
12013 emit_move_insn (operands[
3], const0_rtx);
12016 if (GET_CODE (operands[
4]) == SCRATCH)
12017 operands[
4] = gen_reg_rtx (<GPR:MODE>mode);
12018 emit_move_insn (operands[
4], const1_rtx);
12020 if (GET_CODE (operands[
5]) == SCRATCH)
12021 operands[
5] = gen_reg_rtx (<UNS>mode);
12023 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[
1], operands[
2]);
12024 emit_insn (gen_rtx_SET (operands[
5], c1));
12026 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[
5], const0_rtx);
12027 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[
4], operands[
3]);
12028 emit_move_insn (operands[
0], x);
12032 [(set (attr "cost")
12033 (if_then_else (match_test "(CONST_INT_P (operands[
2]) && <CODE> != EQ)
12035 || <CODE> == LE || <CODE> == GE
12036 || <CODE> == LEU || <CODE> == GEU")
12038 (const_string "
10")))])
12040 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12043 (define_expand "eq<mode>
3"
12045 (set (match_operand:GPR
0 "gpc_reg_operand" "=r")
12046 (eq:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
12047 (match_operand:GPR
2 "scc_eq_operand" "<scc_eq_op2>")))
12048 (clobber (match_scratch:GPR
3 "=r"))
12049 (clobber (match_scratch:GPR
4 "=r"))])]
12052 if (TARGET_POWER10)
12054 rtx cc = gen_reg_rtx (CCmode);
12055 rtx compare = gen_rtx_COMPARE (CCmode, operands[
1], operands[
2]);
12056 emit_insn (gen_rtx_SET (cc, compare));
12057 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
12058 emit_insn (gen_setbc_signed_<mode> (operands[
0], eq, cc));
12062 if (TARGET_ISEL && operands[
2] != const0_rtx)
12064 emit_insn (gen_eq<mode><mode>
2_isel (operands[
0], operands[
1],
12070 (define_insn_and_split "*eq<mode>
3"
12071 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
12072 (eq:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
12073 (match_operand:GPR
2 "scc_eq_operand" "<scc_eq_op2>")))
12074 (clobber (match_scratch:GPR
3 "=r"))
12075 (clobber (match_scratch:GPR
4 "=r"))]
12076 "!TARGET_POWER10 && !(TARGET_ISEL && operands[
2] != const0_rtx)"
12079 [(set (match_dup
4)
12080 (clz:GPR (match_dup
3)))
12082 (lshiftrt:GPR (match_dup
4)
12085 operands[
3] = rs6000_emit_eqne (<MODE>mode,
12086 operands[
1], operands[
2], operands[
3]);
12088 if (GET_CODE (operands[
4]) == SCRATCH)
12089 operands[
4] = gen_reg_rtx (<MODE>mode);
12091 operands[
5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12093 [(set (attr "length")
12094 (if_then_else (match_test "operands[
2] == const0_rtx")
12096 (const_string "
12")))])
12098 (define_expand "ne<mode>
3"
12100 (set (match_operand:GPR
0 "gpc_reg_operand" "=r")
12101 (ne:GPR (match_operand:GPR
1 "gpc_reg_operand" "r")
12102 (match_operand:GPR
2 "scc_eq_operand" "<scc_eq_op2>")))
12103 (clobber (match_scratch:GPR
3 "=r"))
12104 (clobber (match_scratch:GPR
4 "=r"))
12105 (clobber (reg:GPR CA_REGNO))])]
12108 if (TARGET_POWER10)
12110 rtx cc = gen_reg_rtx (CCmode);
12111 rtx compare = gen_rtx_COMPARE (CCmode, operands[
1], operands[
2]);
12112 emit_insn (gen_rtx_SET (cc, compare));
12113 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
12114 emit_insn (gen_setbc_signed_<mode> (operands[
0], ne, cc));
12118 if (<MODE>mode != Pmode)
12120 rtx x = gen_reg_rtx (<MODE>mode);
12121 emit_insn (gen_eq<mode>
3 (x, operands[
1], operands[
2]));
12122 emit_insn (gen_xor<mode>
3 (operands[
0], x, const1_rtx));
12126 if (TARGET_ISEL && operands[
2] != const0_rtx)
12128 emit_insn (gen_ne<mode><mode>
2_isel (operands[
0], operands[
1],
12134 (define_insn_and_split "*ne<mode>
3"
12135 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12136 (ne:P (match_operand:P
1 "gpc_reg_operand" "r")
12137 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>")))
12138 (clobber (match_scratch:P
3 "=r"))
12139 (clobber (match_scratch:P
4 "=r"))
12140 (clobber (reg:P CA_REGNO))]
12141 "!TARGET_POWER10 && !(TARGET_ISEL && operands[
2] != const0_rtx)"
12144 [(parallel [(set (match_dup
4)
12145 (plus:P (match_dup
3)
12147 (set (reg:P CA_REGNO)
12148 (ne:P (match_dup
3)
12150 (parallel [(set (match_dup
0)
12151 (plus:P (plus:P (not:P (match_dup
4))
12154 (clobber (reg:P CA_REGNO))])]
12156 operands[
3] = rs6000_emit_eqne (<MODE>mode,
12157 operands[
1], operands[
2], operands[
3]);
12159 if (GET_CODE (operands[
4]) == SCRATCH)
12160 operands[
4] = gen_reg_rtx (<MODE>mode);
12162 [(set (attr "length")
12163 (if_then_else (match_test "operands[
2] == const0_rtx")
12165 (const_string "
12")))])
12167 (define_insn_and_split "*neg_eq_<mode>"
12168 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12169 (neg:P (eq:P (match_operand:P
1 "gpc_reg_operand" "r")
12170 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))))
12171 (clobber (match_scratch:P
3 "=r"))
12172 (clobber (match_scratch:P
4 "=r"))
12173 (clobber (reg:P CA_REGNO))]
12177 [(parallel [(set (match_dup
4)
12178 (plus:P (match_dup
3)
12180 (set (reg:P CA_REGNO)
12181 (ne:P (match_dup
3)
12183 (parallel [(set (match_dup
0)
12184 (plus:P (reg:P CA_REGNO)
12186 (clobber (reg:P CA_REGNO))])]
12188 operands[
3] = rs6000_emit_eqne (<MODE>mode,
12189 operands[
1], operands[
2], operands[
3]);
12191 if (GET_CODE (operands[
4]) == SCRATCH)
12192 operands[
4] = gen_reg_rtx (<MODE>mode);
12194 [(set (attr "length")
12195 (if_then_else (match_test "operands[
2] == const0_rtx")
12197 (const_string "
12")))])
12199 (define_insn_and_split "*neg_ne_<mode>"
12200 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12201 (neg:P (ne:P (match_operand:P
1 "gpc_reg_operand" "r")
12202 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))))
12203 (clobber (match_scratch:P
3 "=r"))
12204 (clobber (match_scratch:P
4 "=r"))
12205 (clobber (reg:P CA_REGNO))]
12209 [(parallel [(set (match_dup
4)
12210 (neg:P (match_dup
3)))
12211 (set (reg:P CA_REGNO)
12212 (eq:P (match_dup
3)
12214 (parallel [(set (match_dup
0)
12215 (plus:P (reg:P CA_REGNO)
12217 (clobber (reg:P CA_REGNO))])]
12219 operands[
3] = rs6000_emit_eqne (<MODE>mode,
12220 operands[
1], operands[
2], operands[
3]);
12222 if (GET_CODE (operands[
4]) == SCRATCH)
12223 operands[
4] = gen_reg_rtx (<MODE>mode);
12225 [(set (attr "length")
12226 (if_then_else (match_test "operands[
2] == const0_rtx")
12228 (const_string "
12")))])
12230 (define_insn_and_split "*plus_eq_<mode>"
12231 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12232 (plus:P (eq:P (match_operand:P
1 "gpc_reg_operand" "r")
12233 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))
12234 (match_operand:P
3 "gpc_reg_operand" "r")))
12235 (clobber (match_scratch:P
4 "=r"))
12236 (clobber (match_scratch:P
5 "=r"))
12237 (clobber (reg:P CA_REGNO))]
12241 [(parallel [(set (match_dup
5)
12242 (neg:P (match_dup
4)))
12243 (set (reg:P CA_REGNO)
12244 (eq:P (match_dup
4)
12246 (parallel [(set (match_dup
0)
12247 (plus:P (match_dup
3)
12249 (clobber (reg:P CA_REGNO))])]
12251 operands[
4] = rs6000_emit_eqne (<MODE>mode,
12252 operands[
1], operands[
2], operands[
4]);
12254 if (GET_CODE (operands[
5]) == SCRATCH)
12255 operands[
5] = gen_reg_rtx (<MODE>mode);
12257 [(set (attr "length")
12258 (if_then_else (match_test "operands[
2] == const0_rtx")
12260 (const_string "
12")))])
12262 (define_insn_and_split "*plus_ne_<mode>"
12263 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12264 (plus:P (ne:P (match_operand:P
1 "gpc_reg_operand" "r")
12265 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))
12266 (match_operand:P
3 "gpc_reg_operand" "r")))
12267 (clobber (match_scratch:P
4 "=r"))
12268 (clobber (match_scratch:P
5 "=r"))
12269 (clobber (reg:P CA_REGNO))]
12273 [(parallel [(set (match_dup
5)
12274 (plus:P (match_dup
4)
12276 (set (reg:P CA_REGNO)
12277 (ne:P (match_dup
4)
12279 (parallel [(set (match_dup
0)
12280 (plus:P (match_dup
3)
12282 (clobber (reg:P CA_REGNO))])]
12284 operands[
4] = rs6000_emit_eqne (<MODE>mode,
12285 operands[
1], operands[
2], operands[
4]);
12287 if (GET_CODE (operands[
5]) == SCRATCH)
12288 operands[
5] = gen_reg_rtx (<MODE>mode);
12290 [(set (attr "length")
12291 (if_then_else (match_test "operands[
2] == const0_rtx")
12293 (const_string "
12")))])
12295 (define_insn_and_split "*minus_eq_<mode>"
12296 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12297 (minus:P (match_operand:P
3 "gpc_reg_operand" "r")
12298 (eq:P (match_operand:P
1 "gpc_reg_operand" "r")
12299 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))))
12300 (clobber (match_scratch:P
4 "=r"))
12301 (clobber (match_scratch:P
5 "=r"))
12302 (clobber (reg:P CA_REGNO))]
12306 [(parallel [(set (match_dup
5)
12307 (plus:P (match_dup
4)
12309 (set (reg:P CA_REGNO)
12310 (ne:P (match_dup
4)
12312 (parallel [(set (match_dup
0)
12313 (plus:P (plus:P (match_dup
3)
12316 (clobber (reg:P CA_REGNO))])]
12318 operands[
4] = rs6000_emit_eqne (<MODE>mode,
12319 operands[
1], operands[
2], operands[
4]);
12321 if (GET_CODE (operands[
5]) == SCRATCH)
12322 operands[
5] = gen_reg_rtx (<MODE>mode);
12324 [(set (attr "length")
12325 (if_then_else (match_test "operands[
2] == const0_rtx")
12327 (const_string "
12")))])
12329 (define_insn_and_split "*minus_ne_<mode>"
12330 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
12331 (minus:P (match_operand:P
3 "gpc_reg_operand" "r")
12332 (ne:P (match_operand:P
1 "gpc_reg_operand" "r")
12333 (match_operand:P
2 "scc_eq_operand" "<scc_eq_op2>"))))
12334 (clobber (match_scratch:P
4 "=r"))
12335 (clobber (match_scratch:P
5 "=r"))
12336 (clobber (reg:P CA_REGNO))]
12340 [(parallel [(set (match_dup
5)
12341 (neg:P (match_dup
4)))
12342 (set (reg:P CA_REGNO)
12343 (eq:P (match_dup
4)
12345 (parallel [(set (match_dup
0)
12346 (plus:P (plus:P (match_dup
3)
12349 (clobber (reg:P CA_REGNO))])]
12351 operands[
4] = rs6000_emit_eqne (<MODE>mode,
12352 operands[
1], operands[
2], operands[
4]);
12354 if (GET_CODE (operands[
5]) == SCRATCH)
12355 operands[
5] = gen_reg_rtx (<MODE>mode);
12357 [(set (attr "length")
12358 (if_then_else (match_test "operands[
2] == const0_rtx")
12360 (const_string "
12")))])
12362 (define_insn_and_split "*eqsi3_ext<mode>"
12363 [(set (match_operand:EXTSI
0 "gpc_reg_operand" "=r")
12364 (eq:EXTSI (match_operand:SI
1 "gpc_reg_operand" "r")
12365 (match_operand:SI
2 "scc_eq_operand" "rKLI")))
12366 (clobber (match_scratch:SI
3 "=r"))
12367 (clobber (match_scratch:SI
4 "=r"))]
12371 [(set (match_dup
4)
12372 (clz:SI (match_dup
3)))
12375 (lshiftrt:SI (match_dup
4)
12378 operands[
3] = rs6000_emit_eqne (SImode,
12379 operands[
1], operands[
2], operands[
3]);
12381 if (GET_CODE (operands[
4]) == SCRATCH)
12382 operands[
4] = gen_reg_rtx (SImode);
12384 [(set (attr "length")
12385 (if_then_else (match_test "operands[
2] == const0_rtx")
12387 (const_string "
12")))])
12389 (define_insn_and_split "*nesi3_ext<mode>"
12390 [(set (match_operand:EXTSI
0 "gpc_reg_operand" "=r")
12391 (ne:EXTSI (match_operand:SI
1 "gpc_reg_operand" "r")
12392 (match_operand:SI
2 "scc_eq_operand" "rKLI")))
12393 (clobber (match_scratch:SI
3 "=r"))
12394 (clobber (match_scratch:SI
4 "=r"))
12395 (clobber (match_scratch:EXTSI
5 "=r"))]
12399 [(set (match_dup
4)
12400 (clz:SI (match_dup
3)))
12403 (lshiftrt:SI (match_dup
4)
12406 (xor:EXTSI (match_dup
5)
12409 operands[
3] = rs6000_emit_eqne (SImode,
12410 operands[
1], operands[
2], operands[
3]);
12412 if (GET_CODE (operands[
4]) == SCRATCH)
12413 operands[
4] = gen_reg_rtx (SImode);
12414 if (GET_CODE (operands[
5]) == SCRATCH)
12415 operands[
5] = gen_reg_rtx (<MODE>mode);
12417 [(set (attr "length")
12418 (if_then_else (match_test "operands[
2] == const0_rtx")
12419 (const_string "
12")
12420 (const_string "
16")))])
12423 (define_code_iterator fp_rev [ordered ne unle unge])
12424 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12426 (define_insn_and_split "*<code><mode>_cc"
12427 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
12428 (fp_rev:GPR (match_operand:CCFP
1 "cc_reg_operand" "y")
12430 "!flag_finite_math_only"
12435 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12436 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[
1], const0_rtx);
12437 rtx tmp = gen_reg_rtx (<MODE>mode);
12438 emit_move_insn (tmp, eq);
12439 emit_insn (gen_xor<mode>
3 (operands[
0], tmp, const1_rtx));
12442 [(set_attr "length" "
12")])
12444 (define_insn_and_split "*<code><mode>_cc"
12445 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
12446 (fp_two:GPR (match_operand:CCFP
1 "cc_reg_operand" "y")
12448 "!flag_finite_math_only"
12453 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[
1]);
12455 emit_move_insn (operands[
0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12458 [(set_attr "length" "
12")])
12460 ;; Conditional branches.
12461 ;; These either are a single bc insn, or a bc around a b.
12463 (define_insn "*cbranch"
12465 (if_then_else (match_operator
1 "branch_comparison_operator"
12466 [(match_operand
2 "cc_reg_operand" "y")
12468 (label_ref (match_operand
0))
12472 return output_cbranch (operands[
1], "%l0",
0, insn);
12474 [(set_attr "type" "branch")
12475 (set (attr "length")
12476 (if_then_else (and (ge (minus (match_dup
0) (pc))
12477 (const_int -
32768))
12478 (lt (minus (match_dup
0) (pc))
12479 (const_int
32764)))
12483 (define_insn_and_split "*cbranch_2insn"
12485 (if_then_else (match_operator
1 "extra_insn_branch_comparison_operator"
12486 [(match_operand
2 "cc_reg_operand" "y")
12488 (label_ref (match_operand
0))
12490 "!flag_finite_math_only"
12495 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[
1]), SImode, operands[
2]);
12497 rtx note = find_reg_note (curr_insn, REG_BR_PROB,
0);
12499 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[
0]);
12500 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12501 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12502 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12506 profile_probability prob
12507 = profile_probability::from_reg_br_prob_note (XINT (note,
0));
12509 add_reg_br_prob_note (get_last_insn (), prob);
12514 [(set_attr "type" "branch")
12515 (set (attr "length")
12516 (if_then_else (and (ge (minus (match_dup
0) (pc))
12517 (const_int -
32764))
12518 (lt (minus (match_dup
0) (pc))
12519 (const_int
32760)))
12523 ;; Conditional return.
12524 (define_insn "*creturn"
12526 (if_then_else (match_operator
0 "branch_comparison_operator"
12527 [(match_operand
1 "cc_reg_operand" "y")
12533 return output_cbranch (operands[
0], NULL,
0, insn);
12535 [(set_attr "type" "jmpreg")])
12537 ;; Logic on condition register values.
12539 ; This pattern matches things like
12540 ; (set (reg:CCEQ
68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP
68) (const_int
0))
12541 ; (eq:SI (reg:CCFP
68) (const_int
0)))
12543 ; which are generated by the branch logic.
12544 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12546 (define_insn "@cceq_ior_compare_<mode>"
12547 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=y,?y")
12548 (compare:CCEQ (match_operator:GPR
1 "boolean_operator"
12549 [(match_operator:GPR
2
12550 "branch_positive_comparison_operator"
12552 "cc_reg_operand" "y,y")
12554 (match_operator:GPR
4
12555 "branch_positive_comparison_operator"
12557 "cc_reg_operand" "
0,y")
12561 "cr%q1 %E0,%j2,%j4"
12562 [(set_attr "type" "cr_logical")
12563 (set_attr "cr_logical_3op" "no,yes")])
12565 ; Why is the constant -
1 here, but
1 in the previous pattern?
12566 ; Because ~
1 has all but the low bit set.
12567 (define_insn "cceq_ior_compare_complement"
12568 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=y,?y")
12569 (compare:CCEQ (match_operator:SI
1 "boolean_operator"
12570 [(not:SI (match_operator:SI
2
12571 "branch_positive_comparison_operator"
12573 "cc_reg_operand" "y,y")
12575 (match_operator:SI
4
12576 "branch_positive_comparison_operator"
12578 "cc_reg_operand" "
0,y")
12582 "cr%q1 %E0,%j2,%j4"
12583 [(set_attr "type" "cr_logical")
12584 (set_attr "cr_logical_3op" "no,yes")])
12586 (define_insn "@cceq_rev_compare_<mode>"
12587 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=y,?y")
12588 (compare:CCEQ (match_operator:GPR
1
12589 "branch_positive_comparison_operator"
12591 "cc_reg_operand" "
0,y")
12596 [(set_attr "type" "cr_logical")
12597 (set_attr "cr_logical_3op" "no,yes")])
12599 ;; If we are comparing the result of two comparisons, this can be done
12600 ;; using creqv or crxor.
12602 (define_insn_and_split ""
12603 [(set (match_operand:CCEQ
0 "cc_reg_operand" "=y")
12604 (compare:CCEQ (match_operator
1 "branch_comparison_operator"
12605 [(match_operand
2 "cc_reg_operand" "y")
12607 (match_operator
3 "branch_comparison_operator"
12608 [(match_operand
4 "cc_reg_operand" "y")
12613 [(set (match_dup
0) (compare:CCEQ (xor:SI (match_dup
1) (match_dup
3))
12616 int positive_1, positive_2;
12618 positive_1 = branch_positive_comparison_operator (operands[
1],
12619 GET_MODE (operands[
1]));
12620 positive_2 = branch_positive_comparison_operator (operands[
3],
12621 GET_MODE (operands[
3]));
12624 operands[
1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[
2]),
12625 GET_CODE (operands[
1])),
12627 operands[
2], const0_rtx);
12628 else if (GET_MODE (operands[
1]) != SImode)
12629 operands[
1] = gen_rtx_fmt_ee (GET_CODE (operands[
1]), SImode,
12630 operands[
2], const0_rtx);
12633 operands[
3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[
4]),
12634 GET_CODE (operands[
3])),
12636 operands[
4], const0_rtx);
12637 else if (GET_MODE (operands[
3]) != SImode)
12638 operands[
3] = gen_rtx_fmt_ee (GET_CODE (operands[
3]), SImode,
12639 operands[
4], const0_rtx);
12641 if (positive_1 == positive_2)
12643 operands[
1] = gen_rtx_NOT (SImode, operands[
1]);
12644 operands[
5] = constm1_rtx;
12648 operands[
5] = const1_rtx;
12652 ;; Unconditional branch and return.
12654 (define_insn "jump"
12656 (label_ref (match_operand
0)))]
12659 [(set_attr "type" "branch")])
12661 (define_insn "<return_str>return"
12665 [(set_attr "type" "jmpreg")])
12667 (define_expand "indirect_jump"
12668 [(set (pc) (match_operand
0 "register_operand"))]
12671 if (!rs6000_speculate_indirect_jumps) {
12672 rtx ccreg = gen_reg_rtx (CCmode);
12673 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[
0], ccreg));
12678 (define_insn "*indirect_jump<mode>"
12680 (match_operand:P
0 "register_operand" "c,*l"))]
12681 "rs6000_speculate_indirect_jumps"
12683 [(set_attr "type" "jmpreg")])
12685 (define_insn "@indirect_jump<mode>_nospec"
12686 [(set (pc) (match_operand:P
0 "register_operand" "c,*l"))
12687 (clobber (match_operand:CC
1 "cc_reg_operand" "=y,y"))]
12688 "!rs6000_speculate_indirect_jumps"
12689 "crset %E1\;beq%T0- %
1\;b $"
12690 [(set_attr "type" "jmpreg")
12691 (set_attr "length" "
12")])
12693 ;; Table jump for switch statements:
12694 (define_expand "tablejump"
12695 [(use (match_operand
0))
12696 (use (label_ref (match_operand
1)))]
12699 if (rs6000_speculate_indirect_jumps)
12702 emit_jump_insn (gen_tablejumpsi (operands[
0], operands[
1]));
12704 emit_jump_insn (gen_tablejumpdi (operands[
0], operands[
1]));
12708 rtx ccreg = gen_reg_rtx (CCmode);
12711 jump = gen_tablejumpsi_nospec (operands[
0], operands[
1], ccreg);
12713 jump = gen_tablejumpdi_nospec (operands[
0], operands[
1], ccreg);
12714 emit_jump_insn (jump);
12719 (define_expand "tablejumpsi"
12720 [(set (match_dup
3)
12721 (plus:SI (match_operand:SI
0)
12723 (parallel [(set (pc)
12725 (use (label_ref (match_operand
1)))])]
12726 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12728 operands[
0] = force_reg (SImode, operands[
0]);
12729 operands[
2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[
1]));
12730 operands[
3] = gen_reg_rtx (SImode);
12733 (define_expand "tablejumpsi_nospec"
12734 [(set (match_dup
4)
12735 (plus:SI (match_operand:SI
0)
12737 (parallel [(set (pc)
12739 (use (label_ref (match_operand
1)))
12740 (clobber (match_operand
2))])]
12741 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12743 operands[
0] = force_reg (SImode, operands[
0]);
12744 operands[
3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[
1]));
12745 operands[
4] = gen_reg_rtx (SImode);
12748 (define_expand "tablejumpdi"
12749 [(set (match_dup
4)
12750 (sign_extend:DI (match_operand:SI
0 "lwa_operand")))
12752 (plus:DI (match_dup
4)
12754 (parallel [(set (pc)
12756 (use (label_ref (match_operand
1)))])]
12757 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12759 operands[
2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[
1]));
12760 operands[
3] = gen_reg_rtx (DImode);
12761 operands[
4] = gen_reg_rtx (DImode);
12764 (define_expand "tablejumpdi_nospec"
12765 [(set (match_dup
5)
12766 (sign_extend:DI (match_operand:SI
0 "lwa_operand")))
12768 (plus:DI (match_dup
5)
12770 (parallel [(set (pc)
12772 (use (label_ref (match_operand
1)))
12773 (clobber (match_operand
2))])]
12774 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12776 operands[
3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[
1]));
12777 operands[
4] = gen_reg_rtx (DImode);
12778 operands[
5] = gen_reg_rtx (DImode);
12781 (define_insn "*tablejump<mode>_internal1"
12783 (match_operand:P
0 "register_operand" "c,*l"))
12784 (use (label_ref (match_operand
1)))]
12785 "rs6000_speculate_indirect_jumps"
12787 [(set_attr "type" "jmpreg")])
12789 (define_insn "*tablejump<mode>_internal1_nospec"
12791 (match_operand:P
0 "register_operand" "c,*l"))
12792 (use (label_ref (match_operand
1)))
12793 (clobber (match_operand:CC
2 "cc_reg_operand" "=y,y"))]
12794 "!rs6000_speculate_indirect_jumps"
12795 "crset %E2\;beq%T0- %
2\;b $"
12796 [(set_attr "type" "jmpreg")
12797 (set_attr "length" "
12")])
12800 [(unspec [(const_int
0)] UNSPEC_NOP)]
12804 (define_insn "group_ending_nop"
12805 [(unspec [(const_int
0)] UNSPEC_GRP_END_NOP)]
12808 operands[
0] = gen_rtx_REG (Pmode,
12809 rs6000_tune == PROCESSOR_POWER6 ?
1 :
2);
12810 return "ori %
0,%
0,
0";
12813 (define_insn "speculation_barrier"
12814 [(unspec_volatile:BLK [(const_int
0)] UNSPECV_SPEC_BARRIER)]
12817 operands[
0] = gen_rtx_REG (Pmode,
31);
12818 return "ori %
0,%
0,
0";
12821 ;; Define the subtract-one-and-jump insns, starting with the template
12822 ;; so loop.c knows what to generate.
12824 (define_expand "doloop_end"
12825 [(use (match_operand
0)) ; loop pseudo
12826 (use (match_operand
1))] ; label
12829 if (GET_MODE (operands[
0]) != Pmode)
12832 emit_jump_insn (gen_ctr (Pmode, operands[
0], operands[
1]));
12836 (define_expand "@ctr<mode>"
12837 [(parallel [(set (pc)
12838 (if_then_else (ne (match_operand:P
0 "register_operand")
12840 (label_ref (match_operand
1))
12843 (plus:P (match_dup
0)
12845 (clobber (match_scratch:CC
2))
12846 (clobber (match_scratch:P
3))])]
12850 ;; We need to be able to do this for any operand, including MEM, or we
12851 ;; will cause reload to blow up since we don't allow output reloads on
12853 ;; For the length attribute to be calculated correctly, the
12854 ;; label MUST be operand
0.
12855 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12856 ;; the ctr<mode> insns.
12858 (define_code_iterator eqne [eq ne])
12859 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12860 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12862 (define_insn "<bd>_<mode>"
12864 (if_then_else (eqne (match_operand:P
1 "register_operand" "c,*b,*b,*b")
12866 (label_ref (match_operand
0))
12868 (set (match_operand:P
2 "nonimmediate_operand" "=
1,*r,m,*d*wa*c*l")
12869 (plus:P (match_dup
1)
12871 (clobber (match_scratch:CC
3 "=X,&x,&x,&x"))
12872 (clobber (match_scratch:P
4 "=X,X,&r,r"))]
12875 if (which_alternative !=
0)
12877 else if (get_attr_length (insn) ==
4)
12880 return "<bd_neg> $+
8\;b %l0";
12882 [(set_attr "type" "branch")
12883 (set_attr_alternative "length"
12884 [(if_then_else (and (ge (minus (match_dup
0) (pc))
12885 (const_int -
32768))
12886 (lt (minus (match_dup
0) (pc))
12887 (const_int
32764)))
12890 (const_string "
16")
12891 (const_string "
20")
12892 (const_string "
20")])])
12894 ;; Now the splitter if we could not allocate the CTR register
12897 (if_then_else (match_operator
2 "comparison_operator"
12898 [(match_operand:P
1 "gpc_reg_operand")
12901 (match_operand
6)))
12902 (set (match_operand:P
0 "nonimmediate_operand")
12903 (plus:P (match_dup
1)
12905 (clobber (match_scratch:CC
3))
12906 (clobber (match_scratch:P
4))]
12909 (if_then_else (match_dup
7)
12913 operands[
7] = gen_rtx_fmt_ee (GET_CODE (operands[
2]), VOIDmode, operands[
3],
12915 emit_insn (gen_rtx_SET (operands[
3],
12916 gen_rtx_COMPARE (CCmode, operands[
1], const1_rtx)));
12917 if (int_reg_operand (operands[
0], <MODE>mode))
12918 emit_insn (gen_add<mode>
3 (operands[
0], operands[
1], constm1_rtx));
12921 emit_insn (gen_add<mode>
3 (operands[
4], operands[
1], constm1_rtx));
12922 emit_move_insn (operands[
0], operands[
4]);
12924 /* No DONE so branch comes from the pattern. */
12927 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12928 ;; Note that in the case of long branches we have to decompose this into
12929 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12930 ;; and the CR bit, which means there is no way to conveniently invert the
12931 ;; comparison as is done with plain bdnz/bdz.
12933 (define_insn "<bd>tf_<mode>"
12937 (eqne (match_operand:P
1 "register_operand" "c,*b,*b,*b")
12939 (match_operator
3 "branch_comparison_operator"
12940 [(match_operand
4 "cc_reg_operand" "y,y,y,y")
12942 (label_ref (match_operand
0))
12944 (set (match_operand:P
2 "nonimmediate_operand" "=
1,*r,m,*d*wa*c*l")
12945 (plus:P (match_dup
1)
12947 (clobber (match_scratch:P
5 "=X,X,&r,r"))
12948 (clobber (match_scratch:CC
6 "=X,&y,&y,&y"))
12949 (clobber (match_scratch:CCEQ
7 "=X,&y,&y,&y"))]
12952 if (which_alternative !=
0)
12954 else if (get_attr_length (insn) ==
4)
12956 if (branch_positive_comparison_operator (operands[
3],
12957 GET_MODE (operands[
3])))
12958 return "<bd>t %j3,%l0";
12960 return "<bd>f %j3,%l0";
12964 static char seq[
96];
12965 char *bcs = output_cbranch (operands[
3], ".Lshort%=",
1, insn);
12966 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12970 [(set_attr "type" "branch")
12971 (set_attr_alternative "length"
12972 [(if_then_else (and (ge (minus (match_dup
0) (pc))
12973 (const_int -
32768))
12974 (lt (minus (match_dup
0) (pc))
12975 (const_int
32764)))
12978 (const_string "
16")
12979 (const_string "
20")
12980 (const_string "
20")])])
12982 ;; Now the splitter if we could not allocate the CTR register
12987 (match_operator
1 "comparison_operator"
12988 [(match_operand:P
0 "gpc_reg_operand")
12990 (match_operator
3 "branch_comparison_operator"
12991 [(match_operand
2 "cc_reg_operand")
12994 (match_operand
5)))
12995 (set (match_operand:P
6 "nonimmediate_operand")
12996 (plus:P (match_dup
0)
12998 (clobber (match_scratch:P
7))
12999 (clobber (match_scratch:CC
8))
13000 (clobber (match_scratch:CCEQ
9))]
13004 rtx ctr = operands[
0];
13005 rtx ctrcmp = operands[
1];
13006 rtx ccin = operands[
2];
13007 rtx cccmp = operands[
3];
13008 rtx dst1 = operands[
4];
13009 rtx dst2 = operands[
5];
13010 rtx ctrout = operands[
6];
13011 rtx ctrtmp = operands[
7];
13012 enum rtx_code cmpcode = GET_CODE (ctrcmp);
13013 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
13015 cmpcode = reverse_condition (cmpcode);
13016 /* Generate crand/crandc here. */
13017 emit_insn (gen_rtx_SET (operands[
8],
13018 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
13019 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[
8], const0_rtx);
13021 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
13023 emit_insn (gen_cceq_ior_compare (SImode, operands[
9], andexpr, ctrcmpcc,
13024 operands[
8], cccmp, ccin));
13026 emit_insn (gen_cceq_ior_compare_complement (operands[
9], andexpr, ctrcmpcc,
13027 operands[
8], cccmp, ccin));
13028 if (int_reg_operand (ctrout, <MODE>mode))
13029 emit_insn (gen_add<mode>
3 (ctrout, ctr, constm1_rtx));
13032 emit_insn (gen_add<mode>
3 (ctrtmp, ctr, constm1_rtx));
13033 emit_move_insn (ctrout, ctrtmp);
13035 rtx cmp = gen_rtx_EQ (CCEQmode, operands[
9], const0_rtx);
13036 emit_jump_insn (gen_rtx_SET (pc_rtx,
13037 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
13043 (define_insn "trap"
13044 [(trap_if (const_int
1) (const_int
0))]
13047 [(set_attr "type" "trap")])
13049 (define_expand "ctrap<mode>
4"
13050 [(trap_if (match_operator
0 "ordered_comparison_operator"
13051 [(match_operand:GPR
1 "register_operand")
13052 (match_operand:GPR
2 "reg_or_short_operand")])
13053 (match_operand
3 "zero_constant" ""))]
13058 [(trap_if (match_operator
0 "ordered_comparison_operator"
13059 [(match_operand:GPR
1 "register_operand" "r")
13060 (match_operand:GPR
2 "reg_or_short_operand" "rI")])
13063 "t<wd>%V0%I2 %
1,%
2"
13064 [(set_attr "type" "trap")])
13066 ;; Insns related to generating the function prologue and epilogue.
13068 (define_expand "prologue"
13069 [(use (const_int
0))]
13072 rs6000_emit_prologue ();
13073 if (!TARGET_SCHED_PROLOG)
13074 emit_insn (gen_blockage ());
13078 (define_insn "*movesi_from_cr_one"
13079 [(match_parallel
0 "mfcr_operation"
13080 [(set (match_operand:SI
1 "gpc_reg_operand" "=r")
13081 (unspec:SI [(match_operand:CC
2 "cc_reg_operand" "y")
13082 (match_operand
3 "immediate_operand" "n")]
13083 UNSPEC_MOVESI_FROM_CR))])]
13088 for (i =
0; i < XVECLEN (operands[
0],
0); i++)
13090 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[
0],
0, i)),
0,
1));
13091 operands[
4] = GEN_INT (mask);
13092 output_asm_insn ("mfcr %
1,%
4", operands);
13096 [(set_attr "type" "mfcrf")])
13098 ;; Don't include the volatile CRs since their values are not used wrt CR save
13099 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13100 ;; prologue past an insn (early exit test) that defines a register used in the
13102 (define_insn "prologue_movesi_from_cr"
13103 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
13104 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13105 (reg:CC CR4_REGNO)]
13106 UNSPEC_MOVESI_FROM_CR))]
13109 [(set_attr "type" "mfcr")])
13111 (define_insn "*crsave"
13112 [(match_parallel
0 "crsave_operation"
13113 [(set (match_operand:SI
1 "memory_operand" "=m")
13114 (match_operand:SI
2 "gpc_reg_operand" "r"))])]
13117 [(set_attr "type" "store")])
13119 (define_insn "*stmw"
13120 [(match_parallel
0 "stmw_operation"
13121 [(set (match_operand:SI
1 "memory_operand" "=m")
13122 (match_operand:SI
2 "gpc_reg_operand" "r"))])]
13125 [(set_attr "type" "store")
13126 (set_attr "update" "yes")
13127 (set_attr "indexed" "yes")])
13129 ; The following comment applies to:
13133 ; return_and_restore_gpregs*
13134 ; return_and_restore_fpregs*
13135 ; return_and_restore_fpregs_aix*
13137 ; The out-of-line save / restore functions expects one input argument.
13138 ; Since those are not standard call_insn's, we must avoid using
13139 ; MATCH_OPERAND for that argument. That way the register rename
13140 ; optimization will not try to rename this register.
13141 ; Each pattern is repeated for each possible register number used in
13142 ; various ABIs (r11, r1, and for some functions r12)
13144 (define_insn "*save_gpregs_<mode>_r11"
13145 [(match_parallel
0 "any_parallel_operand"
13146 [(clobber (reg:P LR_REGNO))
13147 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13149 (set (match_operand:P
2 "memory_operand" "=m")
13150 (match_operand:P
3 "gpc_reg_operand" "r"))])]
13153 [(set_attr "type" "branch")])
13155 (define_insn "*save_gpregs_<mode>_r12"
13156 [(match_parallel
0 "any_parallel_operand"
13157 [(clobber (reg:P LR_REGNO))
13158 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13160 (set (match_operand:P
2 "memory_operand" "=m")
13161 (match_operand:P
3 "gpc_reg_operand" "r"))])]
13164 [(set_attr "type" "branch")])
13166 (define_insn "*save_gpregs_<mode>_r1"
13167 [(match_parallel
0 "any_parallel_operand"
13168 [(clobber (reg:P LR_REGNO))
13169 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13171 (set (match_operand:P
2 "memory_operand" "=m")
13172 (match_operand:P
3 "gpc_reg_operand" "r"))])]
13175 [(set_attr "type" "branch")])
13177 (define_insn "*save_fpregs_<mode>_r11"
13178 [(match_parallel
0 "any_parallel_operand"
13179 [(clobber (reg:P LR_REGNO))
13180 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13182 (set (match_operand:DF
2 "memory_operand" "=m")
13183 (match_operand:DF
3 "gpc_reg_operand" "d"))])]
13186 [(set_attr "type" "branch")])
13188 (define_insn "*save_fpregs_<mode>_r12"
13189 [(match_parallel
0 "any_parallel_operand"
13190 [(clobber (reg:P LR_REGNO))
13191 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13193 (set (match_operand:DF
2 "memory_operand" "=m")
13194 (match_operand:DF
3 "gpc_reg_operand" "d"))])]
13197 [(set_attr "type" "branch")])
13199 (define_insn "*save_fpregs_<mode>_r1"
13200 [(match_parallel
0 "any_parallel_operand"
13201 [(clobber (reg:P LR_REGNO))
13202 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13204 (set (match_operand:DF
2 "memory_operand" "=m")
13205 (match_operand:DF
3 "gpc_reg_operand" "d"))])]
13208 [(set_attr "type" "branch")])
13210 ; This is to explain that changes to the stack pointer should
13211 ; not be moved over loads from or stores to stack memory.
13212 (define_insn "stack_tie"
13213 [(match_parallel
0 "tie_operand"
13214 [(set (mem:BLK (reg
1)) (const_int
0))])]
13217 [(set_attr "length" "
0")])
13219 ; Some
32-bit ABIs do not have a red zone, so the stack deallocation has to
13220 ; stay behind all restores from the stack, it cannot be reordered to before
13221 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13222 (define_insn "stack_restore_tie"
13223 [(set (match_operand:SI
0 "gpc_reg_operand" "=r,r")
13224 (plus:SI (match_operand:SI
1 "gpc_reg_operand" "r,r")
13225 (match_operand:SI
2 "reg_or_cint_operand" "O,rI")))
13226 (set (mem:BLK (scratch)) (const_int
0))]
13231 [(set_attr "type" "*,add")])
13233 (define_expand "epilogue"
13234 [(use (const_int
0))]
13237 if (!TARGET_SCHED_PROLOG)
13238 emit_insn (gen_blockage ());
13239 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13243 ; On some processors, doing the mtcrf one CC register at a time is
13244 ; faster (like on the
604e). On others, doing them all at once is
13245 ; faster; for instance, on the
601 and
750.
13247 (define_expand "movsi_to_cr_one"
13248 [(set (match_operand:CC
0 "cc_reg_operand")
13249 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand")
13250 (match_dup
2)] UNSPEC_MOVESI_TO_CR))]
13252 "operands[
2] = GEN_INT (
1 << (
7 - (REGNO (operands[
0]) - CR0_REGNO)));")
13254 (define_insn "*movsi_to_cr"
13255 [(match_parallel
0 "mtcrf_operation"
13256 [(set (match_operand:CC
1 "cc_reg_operand" "=y")
13257 (unspec:CC [(match_operand:SI
2 "gpc_reg_operand" "r")
13258 (match_operand
3 "immediate_operand" "n")]
13259 UNSPEC_MOVESI_TO_CR))])]
13264 for (i =
0; i < XVECLEN (operands[
0],
0); i++)
13265 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[
0],
0, i)),
0,
1));
13266 operands[
4] = GEN_INT (mask);
13267 return "mtcrf %
4,%
2";
13269 [(set_attr "type" "mtcr")])
13271 (define_insn "*mtcrfsi"
13272 [(set (match_operand:CC
0 "cc_reg_operand" "=y")
13273 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
13274 (match_operand
2 "immediate_operand" "n")]
13275 UNSPEC_MOVESI_TO_CR))]
13276 "REG_P (operands[
0])
13277 && CR_REGNO_P (REGNO (operands[
0]))
13278 && CONST_INT_P (operands[
2])
13279 && INTVAL (operands[
2]) ==
1 << (
7 - (REGNO (operands[
0]) - CR0_REGNO))"
13281 [(set_attr "type" "mtcr")])
13283 ; The load-multiple instructions have similar properties.
13284 ; Note that "load_multiple" is a name known to the machine-independent
13285 ; code that actually corresponds to the PowerPC load-string.
13287 (define_insn "*lmw"
13288 [(match_parallel
0 "lmw_operation"
13289 [(set (match_operand:SI
1 "gpc_reg_operand" "=r")
13290 (match_operand:SI
2 "memory_operand" "m"))])]
13293 [(set_attr "type" "load")
13294 (set_attr "update" "yes")
13295 (set_attr "indexed" "yes")
13296 (set_attr "cell_micro" "always")])
13298 ; FIXME: "any_parallel_operand" is a bit flexible...
13300 ; The following comment applies to:
13304 ; return_and_restore_gpregs*
13305 ; return_and_restore_fpregs*
13306 ; return_and_restore_fpregs_aix*
13308 ; The out-of-line save / restore functions expects one input argument.
13309 ; Since those are not standard call_insn's, we must avoid using
13310 ; MATCH_OPERAND for that argument. That way the register rename
13311 ; optimization will not try to rename this register.
13312 ; Each pattern is repeated for each possible register number used in
13313 ; various ABIs (r11, r1, and for some functions r12)
13315 (define_insn "*restore_gpregs_<mode>_r11"
13316 [(match_parallel
0 "any_parallel_operand"
13317 [(clobber (reg:P LR_REGNO))
13318 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13320 (set (match_operand:P
2 "gpc_reg_operand" "=r")
13321 (match_operand:P
3 "memory_operand" "m"))])]
13324 [(set_attr "type" "branch")])
13326 (define_insn "*restore_gpregs_<mode>_r12"
13327 [(match_parallel
0 "any_parallel_operand"
13328 [(clobber (reg:P LR_REGNO))
13329 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13331 (set (match_operand:P
2 "gpc_reg_operand" "=r")
13332 (match_operand:P
3 "memory_operand" "m"))])]
13335 [(set_attr "type" "branch")])
13337 (define_insn "*restore_gpregs_<mode>_r1"
13338 [(match_parallel
0 "any_parallel_operand"
13339 [(clobber (reg:P LR_REGNO))
13340 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13342 (set (match_operand:P
2 "gpc_reg_operand" "=r")
13343 (match_operand:P
3 "memory_operand" "m"))])]
13346 [(set_attr "type" "branch")])
13348 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13349 [(match_parallel
0 "any_parallel_operand"
13351 (clobber (reg:P LR_REGNO))
13352 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13354 (set (match_operand:P
2 "gpc_reg_operand" "=r")
13355 (match_operand:P
3 "memory_operand" "m"))])]
13358 [(set_attr "type" "branch")])
13360 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13361 [(match_parallel
0 "any_parallel_operand"
13363 (clobber (reg:P LR_REGNO))
13364 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13366 (set (match_operand:P
2 "gpc_reg_operand" "=r")
13367 (match_operand:P
3 "memory_operand" "m"))])]
13370 [(set_attr "type" "branch")])
13372 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13373 [(match_parallel
0 "any_parallel_operand"
13375 (clobber (reg:P LR_REGNO))
13376 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13378 (set (match_operand:P
2 "gpc_reg_operand" "=r")
13379 (match_operand:P
3 "memory_operand" "m"))])]
13382 [(set_attr "type" "branch")])
13384 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13385 [(match_parallel
0 "any_parallel_operand"
13387 (clobber (reg:P LR_REGNO))
13388 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13390 (set (match_operand:DF
2 "gpc_reg_operand" "=d")
13391 (match_operand:DF
3 "memory_operand" "m"))])]
13394 [(set_attr "type" "branch")])
13396 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13397 [(match_parallel
0 "any_parallel_operand"
13399 (clobber (reg:P LR_REGNO))
13400 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13402 (set (match_operand:DF
2 "gpc_reg_operand" "=d")
13403 (match_operand:DF
3 "memory_operand" "m"))])]
13406 [(set_attr "type" "branch")])
13408 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13409 [(match_parallel
0 "any_parallel_operand"
13411 (clobber (reg:P LR_REGNO))
13412 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13414 (set (match_operand:DF
2 "gpc_reg_operand" "=d")
13415 (match_operand:DF
3 "memory_operand" "m"))])]
13418 [(set_attr "type" "branch")])
13420 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13421 [(match_parallel
0 "any_parallel_operand"
13423 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13425 (set (match_operand:DF
2 "gpc_reg_operand" "=d")
13426 (match_operand:DF
3 "memory_operand" "m"))])]
13429 [(set_attr "type" "branch")])
13431 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13432 [(match_parallel
0 "any_parallel_operand"
13434 (use (match_operand:P
1 "symbol_ref_operand" "s"))
13436 (set (match_operand:DF
2 "gpc_reg_operand" "=d")
13437 (match_operand:DF
3 "memory_operand" "m"))])]
13440 [(set_attr "type" "branch")])
13442 ; This is used in compiling the unwind routines.
13443 (define_expand "eh_return"
13444 [(use (match_operand
0 "general_operand"))]
13447 emit_insn (gen_eh_set_lr (Pmode, operands[
0]));
13451 ; We can't expand this before we know where the link register is stored.
13452 (define_insn_and_split "@eh_set_lr_<mode>"
13453 [(unspec_volatile [(match_operand:P
0 "register_operand" "r")] UNSPECV_EH_RR)
13454 (clobber (match_scratch:P
1 "=&b"))]
13460 rs6000_emit_eh_reg_restore (operands[
0], operands[
1]);
13464 (define_insn "prefetch"
13465 [(prefetch (match_operand
0 "indexed_or_indirect_address" "a")
13466 (match_operand:SI
1 "const_int_operand" "n")
13467 (match_operand:SI
2 "const_int_operand" "n"))]
13472 /* dcbtstt, dcbtt and TH=
0b10000 support starts with ISA
2.06 (Power7).
13473 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13474 The AIX assembler does not support the three operand form of dcbt
13475 and dcbtst on Power
7 (-mpwr7). */
13476 int inst_select = INTVAL (operands[
2]) || !TARGET_DIRECT_MOVE;
13478 if (REG_P (operands[
0]))
13480 if (INTVAL (operands[
1]) ==
0)
13481 return inst_select ? "dcbt
0,%
0" : "dcbt
0,%
0,
16";
13483 return inst_select ? "dcbtst
0,%
0" : "dcbtst
0,%
0,
16";
13487 if (INTVAL (operands[
1]) ==
0)
13488 return inst_select ? "dcbt %a0" : "dcbt %a0,
16";
13490 return inst_select ? "dcbtst %a0" : "dcbtst %a0,
16";
13493 [(set_attr "type" "load")])
13495 ;; Handle -fsplit-stack.
13497 (define_expand "split_stack_prologue"
13501 rs6000_expand_split_stack_prologue ();
13505 (define_expand "load_split_stack_limit"
13506 [(set (match_operand
0)
13507 (unspec [(const_int
0)] UNSPEC_STACK_CHECK))]
13510 emit_insn (gen_rtx_SET (operands[
0],
13511 gen_rtx_UNSPEC (Pmode,
13512 gen_rtvec (
1, const0_rtx),
13513 UNSPEC_STACK_CHECK)));
13517 (define_insn "load_split_stack_limit_di"
13518 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
13519 (unspec:DI [(const_int
0)] UNSPEC_STACK_CHECK))]
13521 "ld %
0,-
0x7040(
13)"
13522 [(set_attr "type" "load")
13523 (set_attr "update" "no")
13524 (set_attr "indexed" "no")])
13526 (define_insn "load_split_stack_limit_si"
13527 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
13528 (unspec:SI [(const_int
0)] UNSPEC_STACK_CHECK))]
13530 "lwz %
0,-
0x7020(
2)"
13531 [(set_attr "type" "load")
13532 (set_attr "update" "no")
13533 (set_attr "indexed" "no")])
13535 ;; A return instruction which the middle-end doesn't see.
13536 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13537 ;; after the call to __morestack.
13538 (define_insn "split_stack_return"
13539 [(unspec_volatile [(reg:SI
0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13542 [(set_attr "type" "jmpreg")])
13544 ;; If there are operand
0 bytes available on the stack, jump to
13546 (define_expand "split_stack_space_check"
13547 [(set (match_dup
2)
13548 (unspec [(const_int
0)] UNSPEC_STACK_CHECK))
13550 (minus (reg STACK_POINTER_REGNUM)
13551 (match_operand
0)))
13552 (set (match_dup
4) (compare:CCUNS (match_dup
3) (match_dup
2)))
13553 (set (pc) (if_then_else
13554 (geu (match_dup
4) (const_int
0))
13555 (label_ref (match_operand
1))
13559 rs6000_split_stack_space_check (operands[
0], operands[
1]);
13563 (define_insn "bpermd_<mode>"
13564 [(set (match_operand:P
0 "gpc_reg_operand" "=r")
13565 (unspec:P [(match_operand:P
1 "gpc_reg_operand" "r")
13566 (match_operand:P
2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13569 [(set_attr "type" "popcnt")])
13572 ;; Builtin fma support. Handle
13573 ;; Note that the conditions for expansion are in the FMA_F iterator.
13575 (define_expand "fma<mode>
4"
13576 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
13578 (match_operand:FMA_F
1 "gpc_reg_operand")
13579 (match_operand:FMA_F
2 "gpc_reg_operand")
13580 (match_operand:FMA_F
3 "gpc_reg_operand")))]
13584 (define_insn "*fma<mode>
4_fpr"
13585 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa,wa")
13587 (match_operand:SFDF
1 "gpc_reg_operand" "%<Ff>,wa,wa")
13588 (match_operand:SFDF
2 "gpc_reg_operand" "<Ff>,wa,
0")
13589 (match_operand:SFDF
3 "gpc_reg_operand" "<Ff>,
0,wa")))]
13590 "TARGET_HARD_FLOAT"
13592 fmadd<s> %
0,%
1,%
2,%
3
13593 xsmadda<sd>p %x0,%x1,%x2
13594 xsmaddm<sd>p %x0,%x1,%x3"
13595 [(set_attr "type" "fp")
13596 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13598 ; Altivec only has fma and nfms.
13599 (define_expand "fms<mode>
4"
13600 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
13602 (match_operand:FMA_F
1 "gpc_reg_operand")
13603 (match_operand:FMA_F
2 "gpc_reg_operand")
13604 (neg:FMA_F (match_operand:FMA_F
3 "gpc_reg_operand"))))]
13605 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13608 (define_insn "*fms<mode>
4_fpr"
13609 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa,wa")
13611 (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,wa,wa")
13612 (match_operand:SFDF
2 "gpc_reg_operand" "<Ff>,wa,
0")
13613 (neg:SFDF (match_operand:SFDF
3 "gpc_reg_operand" "<Ff>,
0,wa"))))]
13614 "TARGET_HARD_FLOAT"
13616 fmsub<s> %
0,%
1,%
2,%
3
13617 xsmsuba<sd>p %x0,%x1,%x2
13618 xsmsubm<sd>p %x0,%x1,%x3"
13619 [(set_attr "type" "fp")
13620 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13622 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13623 (define_expand "fnma<mode>
4"
13624 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
13627 (match_operand:FMA_F
1 "gpc_reg_operand")
13628 (match_operand:FMA_F
2 "gpc_reg_operand")
13629 (neg:FMA_F (match_operand:FMA_F
3 "gpc_reg_operand")))))]
13630 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13633 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13634 (define_expand "fnms<mode>
4"
13635 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
13638 (match_operand:FMA_F
1 "gpc_reg_operand")
13639 (match_operand:FMA_F
2 "gpc_reg_operand")
13640 (match_operand:FMA_F
3 "gpc_reg_operand"))))]
13641 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13644 ; Not an official optab name, but used from builtins.
13645 (define_expand "nfma<mode>
4"
13646 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
13649 (match_operand:FMA_F
1 "gpc_reg_operand")
13650 (match_operand:FMA_F
2 "gpc_reg_operand")
13651 (match_operand:FMA_F
3 "gpc_reg_operand"))))]
13652 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13655 (define_insn "*nfma<mode>
4_fpr"
13656 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa,wa")
13659 (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,wa,wa")
13660 (match_operand:SFDF
2 "gpc_reg_operand" "<Ff>,wa,
0")
13661 (match_operand:SFDF
3 "gpc_reg_operand" "<Ff>,
0,wa"))))]
13662 "TARGET_HARD_FLOAT"
13664 fnmadd<s> %
0,%
1,%
2,%
3
13665 xsnmadda<sd>p %x0,%x1,%x2
13666 xsnmaddm<sd>p %x0,%x1,%x3"
13667 [(set_attr "type" "fp")
13668 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13670 ; Not an official optab name, but used from builtins.
13671 (define_expand "nfms<mode>
4"
13672 [(set (match_operand:FMA_F
0 "gpc_reg_operand")
13675 (match_operand:FMA_F
1 "gpc_reg_operand")
13676 (match_operand:FMA_F
2 "gpc_reg_operand")
13677 (neg:FMA_F (match_operand:FMA_F
3 "gpc_reg_operand")))))]
13681 (define_insn "*nfmssf4_fpr"
13682 [(set (match_operand:SFDF
0 "gpc_reg_operand" "=<Ff>,wa,wa")
13685 (match_operand:SFDF
1 "gpc_reg_operand" "<Ff>,wa,wa")
13686 (match_operand:SFDF
2 "gpc_reg_operand" "<Ff>,wa,
0")
13688 (match_operand:SFDF
3 "gpc_reg_operand" "<Ff>,
0,wa")))))]
13689 "TARGET_HARD_FLOAT"
13691 fnmsub<s> %
0,%
1,%
2,%
3
13692 xsnmsuba<sd>p %x0,%x1,%x2
13693 xsnmsubm<sd>p %x0,%x1,%x3"
13694 [(set_attr "type" "fp")
13695 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13697 (define_expand "rs6000_get_timebase"
13698 [(use (match_operand:DI
0 "gpc_reg_operand"))]
13701 if (TARGET_POWERPC64)
13702 emit_insn (gen_rs6000_mftb_di (operands[
0]));
13704 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[
0]));
13708 (define_insn "rs6000_get_timebase_ppc32"
13709 [(set (match_operand:DI
0 "gpc_reg_operand" "=r")
13710 (unspec_volatile:DI [(const_int
0)] UNSPECV_MFTB))
13711 (clobber (match_scratch:SI
1 "=r"))
13712 (clobber (match_scratch:CC
2 "=y"))]
13713 "!TARGET_POWERPC64"
13715 if (WORDS_BIG_ENDIAN)
13718 return "mfspr %
0,
269\;"
13726 return "mftbu %
0\;"
13735 return "mfspr %L0,
269\;"
13743 return "mftbu %L0\;"
13750 [(set_attr "length" "
20")])
13752 (define_insn "rs6000_mftb_<mode>"
13753 [(set (match_operand:GPR
0 "gpc_reg_operand" "=r")
13754 (unspec_volatile:GPR [(const_int
0)] UNSPECV_MFTB))]
13758 return "mfspr %
0,
268";
13764 ;; The ISA
3.0 mffsl instruction is a lower latency instruction
13765 ;; for reading bits [
29:
31], [
45:
51] and [
56:
63] of the FPSCR.
13766 (define_insn "rs6000_mffsl_hw"
13767 [(set (match_operand:DF
0 "gpc_reg_operand" "=d")
13768 (unspec_volatile:DF [(const_int
0)] UNSPECV_MFFSL))]
13769 "TARGET_HARD_FLOAT"
13772 (define_expand "rs6000_mffsl"
13773 [(set (match_operand:DF
0 "gpc_reg_operand")
13774 (unspec_volatile:DF [(const_int
0)] UNSPECV_MFFSL))]
13775 "TARGET_HARD_FLOAT"
13777 /* If the low latency mffsl instruction (ISA
3.0) is available use it,
13778 otherwise fall back to the older mffs instruction to emulate the mffsl
13781 if (!TARGET_P9_MISC)
13783 rtx tmp1 = gen_reg_rtx (DFmode);
13785 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13786 instruction using the mffs instruction and masking the result. */
13787 emit_insn (gen_rs6000_mffs (tmp1));
13789 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode,
0);
13790 rtx tmp2 = gen_reg_rtx (DImode);
13791 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (
0x70007f0ffLL)));
13793 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode,
0);
13794 emit_move_insn (operands[
0], tmp2df);
13798 emit_insn (gen_rs6000_mffsl_hw (operands[
0]));
13802 (define_insn "rs6000_mffs"
13803 [(set (match_operand:DF
0 "gpc_reg_operand" "=d")
13804 (unspec_volatile:DF [(const_int
0)] UNSPECV_MFFS))]
13805 "TARGET_HARD_FLOAT"
13808 (define_insn "rs6000_mtfsf"
13809 [(unspec_volatile [(match_operand:SI
0 "const_int_operand" "i")
13810 (match_operand:DF
1 "gpc_reg_operand" "d")]
13812 "TARGET_HARD_FLOAT"
13815 (define_insn "rs6000_mtfsf_hi"
13816 [(unspec_volatile [(match_operand:SI
0 "const_int_operand" "n")
13817 (match_operand:DF
1 "gpc_reg_operand" "d")]
13819 "TARGET_HARD_FLOAT"
13823 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13824 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13825 ;; register that is being loaded. The fused ops must be physically adjacent.
13827 ;; On Power8 GPR loads, we try to use the register that is being load. The
13828 ;; peephole2 then gathers any other fused possibilities that it can find after
13829 ;; register allocation. If power9 fusion is selected, we also fuse floating
13830 ;; point loads/stores.
13832 ;; Find cases where the addis that feeds into a load instruction is either used
13833 ;; once or is the same as the target register, and replace it with the fusion
13837 [(set (match_operand:P
0 "base_reg_operand")
13838 (match_operand:P
1 "fusion_gpr_addis"))
13839 (set (match_operand:INT1
2 "base_reg_operand")
13840 (match_operand:INT1
3 "fusion_gpr_mem_load"))]
13842 && fusion_gpr_load_p (operands[
0], operands[
1], operands[
2],
13846 expand_fusion_gpr_load (operands);
13850 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13853 (define_insn "*fusion_gpr_load_<mode>"
13854 [(set (match_operand:INT1
0 "base_reg_operand" "=b")
13855 (unspec:INT1 [(match_operand:INT1
1 "fusion_addis_mem_combo_load" "wF")]
13856 UNSPEC_FUSION_GPR))]
13859 return emit_fusion_gpr_load (operands[
0], operands[
1]);
13861 [(set_attr "type" "load")
13862 (set_attr "length" "
8")])
13865 ;; Optimize cases where we want to do a D-form load (register+offset) on
13866 ;; ISA
2.06/
2.07 to an Altivec register, and the register allocator
13871 ;; and we change this to:
13876 [(match_scratch:P
0 "b")
13877 (set (match_operand:ALTIVEC_DFORM
1 "fpr_reg_operand")
13878 (match_operand:ALTIVEC_DFORM
2 "simple_offsettable_mem_operand"))
13879 (set (match_operand:ALTIVEC_DFORM
3 "altivec_register_operand")
13881 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (
2, operands[
1])"
13882 [(set (match_dup
0)
13887 rtx tmp_reg = operands[
0];
13888 rtx mem = operands[
2];
13889 rtx addr = XEXP (mem,
0);
13890 rtx add_op0, add_op1, new_addr;
13892 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13893 add_op0 = XEXP (addr,
0);
13894 add_op1 = XEXP (addr,
1);
13895 gcc_assert (REG_P (add_op0));
13896 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13898 operands[
4] = add_op1;
13899 operands[
5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13902 ;; Optimize cases were want to do a D-form store on ISA
2.06/
2.07 from an
13903 ;; Altivec register, and the register allocator has generated:
13907 ;; and we change this to:
13912 [(match_scratch:P
0 "b")
13913 (set (match_operand:ALTIVEC_DFORM
1 "fpr_reg_operand")
13914 (match_operand:ALTIVEC_DFORM
2 "altivec_register_operand"))
13915 (set (match_operand:ALTIVEC_DFORM
3 "simple_offsettable_mem_operand")
13917 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (
2, operands[
1])"
13918 [(set (match_dup
0)
13923 rtx tmp_reg = operands[
0];
13924 rtx mem = operands[
3];
13925 rtx addr = XEXP (mem,
0);
13926 rtx add_op0, add_op1, new_addr;
13928 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13929 add_op0 = XEXP (addr,
0);
13930 add_op1 = XEXP (addr,
1);
13931 gcc_assert (REG_P (add_op0));
13932 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13934 operands[
4] = add_op1;
13935 operands[
5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13939 ;; Miscellaneous ISA
2.06 (power7) instructions
13940 (define_insn "addg6s"
13941 [(set (match_operand:SI
0 "register_operand" "=r")
13942 (unspec:SI [(match_operand:SI
1 "register_operand" "r")
13943 (match_operand:SI
2 "register_operand" "r")]
13947 [(set_attr "type" "integer")])
13949 (define_insn "cdtbcd"
13950 [(set (match_operand:SI
0 "register_operand" "=r")
13951 (unspec:SI [(match_operand:SI
1 "register_operand" "r")]
13955 [(set_attr "type" "integer")])
13957 (define_insn "cbcdtd"
13958 [(set (match_operand:SI
0 "register_operand" "=r")
13959 (unspec:SI [(match_operand:SI
1 "register_operand" "r")]
13963 [(set_attr "type" "integer")])
13965 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13968 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13969 (UNSPEC_DIVEU "eu")])
13971 (define_insn "div<div_extend>_<mode>"
13972 [(set (match_operand:GPR
0 "register_operand" "=r")
13973 (unspec:GPR [(match_operand:GPR
1 "register_operand" "r")
13974 (match_operand:GPR
2 "register_operand" "r")]
13975 UNSPEC_DIV_EXTEND))]
13977 "div<wd><div_extend> %
0,%
1,%
2"
13978 [(set_attr "type" "div")
13979 (set_attr "size" "<bits>")])
13982 ;; Pack/unpack
128-bit floating point types that take
2 scalar registers
13984 ; Type of the
64-bit part when packing/unpacking
128-bit floating point types
13985 (define_mode_attr FP128_64 [(TF "DF")
13990 (define_expand "unpack<mode>"
13991 [(set (match_operand:<FP128_64>
0 "nonimmediate_operand")
13993 [(match_operand:FMOVE128
1 "register_operand")
13994 (match_operand:QI
2 "const_0_to_1_operand")]
13995 UNSPEC_UNPACK_128BIT))]
13996 "FLOAT128_2REG_P (<MODE>mode)"
13999 (define_insn_and_split "unpack<mode>_dm"
14000 [(set (match_operand:<FP128_64>
0 "nonimmediate_operand" "=d,m,d,r,m")
14002 [(match_operand:FMOVE128
1 "register_operand" "d,d,r,d,r")
14003 (match_operand:QI
2 "const_0_to_1_operand" "i,i,i,i,i")]
14004 UNSPEC_UNPACK_128BIT))]
14005 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14007 "&& reload_completed"
14008 [(set (match_dup
0) (match_dup
3))]
14010 unsigned fp_regno = REGNO (operands[
1]) + UINTVAL (operands[
2]);
14012 if (REG_P (operands[
0]) && REGNO (operands[
0]) == fp_regno)
14014 emit_note (NOTE_INSN_DELETED);
14018 operands[
3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14020 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
14022 (define_insn_and_split "unpack<mode>_nodm"
14023 [(set (match_operand:<FP128_64>
0 "nonimmediate_operand" "=d,m")
14025 [(match_operand:FMOVE128
1 "register_operand" "d,d")
14026 (match_operand:QI
2 "const_0_to_1_operand" "i,i")]
14027 UNSPEC_UNPACK_128BIT))]
14028 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14030 "&& reload_completed"
14031 [(set (match_dup
0) (match_dup
3))]
14033 unsigned fp_regno = REGNO (operands[
1]) + UINTVAL (operands[
2]);
14035 if (REG_P (operands[
0]) && REGNO (operands[
0]) == fp_regno)
14037 emit_note (NOTE_INSN_DELETED);
14041 operands[
3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14043 [(set_attr "type" "fp,fpstore")])
14045 (define_insn_and_split "pack<mode>"
14046 [(set (match_operand:FMOVE128
0 "register_operand" "=&d")
14048 [(match_operand:<FP128_64>
1 "register_operand" "d")
14049 (match_operand:<FP128_64>
2 "register_operand" "d")]
14050 UNSPEC_PACK_128BIT))]
14051 "FLOAT128_2REG_P (<MODE>mode)"
14053 "&& reload_completed"
14054 [(set (match_dup
3) (match_dup
1))
14055 (set (match_dup
4) (match_dup
2))]
14057 unsigned dest_hi = REGNO (operands[
0]);
14058 unsigned dest_lo = dest_hi +
1;
14060 gcc_assert (!IN_RANGE (REGNO (operands[
1]), dest_hi, dest_lo));
14061 gcc_assert (!IN_RANGE (REGNO (operands[
2]), dest_hi, dest_lo));
14063 operands[
3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14064 operands[
4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14066 [(set_attr "type" "fp")
14067 (set_attr "length" "
8")])
14069 (define_insn "unpack<mode>"
14070 [(set (match_operand:DI
0 "register_operand" "=wa,wa")
14071 (unspec:DI [(match_operand:FMOVE128_VSX
1 "register_operand" "
0,wa")
14072 (match_operand:QI
2 "const_0_to_1_operand" "O,i")]
14073 UNSPEC_UNPACK_128BIT))]
14074 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14076 if (REGNO (operands[
0]) == REGNO (operands[
1]) && INTVAL (operands[
2]) ==
0)
14077 return ASM_COMMENT_START " xxpermdi to same register";
14079 operands[
3] = GEN_INT (INTVAL (operands[
2]) ==
0 ?
0 :
3);
14080 return "xxpermdi %x0,%x1,%x1,%
3";
14082 [(set_attr "type" "vecperm")])
14084 (define_insn "pack<mode>"
14085 [(set (match_operand:FMOVE128_VSX
0 "register_operand" "=wa")
14086 (unspec:FMOVE128_VSX
14087 [(match_operand:DI
1 "register_operand" "wa")
14088 (match_operand:DI
2 "register_operand" "wa")]
14089 UNSPEC_PACK_128BIT))]
14091 "xxpermdi %x0,%x1,%x2,
0"
14092 [(set_attr "type" "vecperm")])
14096 ;; ISA
2.08 IEEE
128-bit floating point support.
14098 (define_insn "add<mode>
3"
14099 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14101 (match_operand:IEEE128
1 "altivec_register_operand" "v")
14102 (match_operand:IEEE128
2 "altivec_register_operand" "v")))]
14103 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14105 [(set_attr "type" "vecfloat")
14106 (set_attr "size" "
128")])
14108 (define_insn "sub<mode>
3"
14109 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14111 (match_operand:IEEE128
1 "altivec_register_operand" "v")
14112 (match_operand:IEEE128
2 "altivec_register_operand" "v")))]
14113 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14115 [(set_attr "type" "vecfloat")
14116 (set_attr "size" "
128")])
14118 (define_insn "mul<mode>
3"
14119 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14121 (match_operand:IEEE128
1 "altivec_register_operand" "v")
14122 (match_operand:IEEE128
2 "altivec_register_operand" "v")))]
14123 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14125 [(set_attr "type" "qmul")
14126 (set_attr "size" "
128")])
14128 (define_insn "div<mode>
3"
14129 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14131 (match_operand:IEEE128
1 "altivec_register_operand" "v")
14132 (match_operand:IEEE128
2 "altivec_register_operand" "v")))]
14133 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14135 [(set_attr "type" "vecdiv")
14136 (set_attr "size" "
128")])
14138 (define_insn "sqrt<mode>
2"
14139 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14141 (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
14142 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14144 [(set_attr "type" "vecdiv")
14145 (set_attr "size" "
128")])
14147 (define_expand "copysign<mode>
3"
14148 [(use (match_operand:IEEE128
0 "altivec_register_operand"))
14149 (use (match_operand:IEEE128
1 "altivec_register_operand"))
14150 (use (match_operand:IEEE128
2 "altivec_register_operand"))]
14151 "FLOAT128_IEEE_P (<MODE>mode)"
14153 if (TARGET_FLOAT128_HW)
14154 emit_insn (gen_copysign<mode>
3_hard (operands[
0], operands[
1],
14157 emit_insn (gen_copysign<mode>
3_soft (operands[
0], operands[
1],
14162 (define_insn "copysign<mode>
3_hard"
14163 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14165 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
14166 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
14168 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14169 "xscpsgnqp %
0,%
2,%
1"
14170 [(set_attr "type" "vecmove")
14171 (set_attr "size" "
128")])
14173 (define_insn "copysign<mode>
3_soft"
14174 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14176 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
14177 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
14179 (clobber (match_scratch:IEEE128
3 "=&v"))]
14180 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14181 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,
1"
14182 [(set_attr "type" "veccomplex")
14183 (set_attr "length" "
8")])
14185 (define_insn "@neg<mode>
2_hw"
14186 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14188 (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
14189 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14191 [(set_attr "type" "vecmove")
14192 (set_attr "size" "
128")])
14195 (define_insn "@abs<mode>
2_hw"
14196 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14198 (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
14199 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14201 [(set_attr "type" "vecmove")
14202 (set_attr "size" "
128")])
14205 (define_insn "*nabs<mode>
2_hw"
14206 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14209 (match_operand:IEEE128
1 "altivec_register_operand" "v"))))]
14210 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14212 [(set_attr "type" "vecmove")
14213 (set_attr "size" "
128")])
14215 ;; Initially don't worry about doing fusion
14216 (define_insn "fma<mode>
4_hw"
14217 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14219 (match_operand:IEEE128
1 "altivec_register_operand" "%v")
14220 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14221 (match_operand:IEEE128
3 "altivec_register_operand" "
0")))]
14222 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14223 "xsmaddqp %
0,%
1,%
2"
14224 [(set_attr "type" "qmul")
14225 (set_attr "size" "
128")])
14227 (define_insn "*fms<mode>
4_hw"
14228 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14230 (match_operand:IEEE128
1 "altivec_register_operand" "%v")
14231 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14233 (match_operand:IEEE128
3 "altivec_register_operand" "
0"))))]
14234 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14235 "xsmsubqp %
0,%
1,%
2"
14236 [(set_attr "type" "qmul")
14237 (set_attr "size" "
128")])
14239 (define_insn "*nfma<mode>
4_hw"
14240 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14243 (match_operand:IEEE128
1 "altivec_register_operand" "%v")
14244 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14245 (match_operand:IEEE128
3 "altivec_register_operand" "
0"))))]
14246 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14247 "xsnmaddqp %
0,%
1,%
2"
14248 [(set_attr "type" "qmul")
14249 (set_attr "size" "
128")])
14251 (define_insn "*nfms<mode>
4_hw"
14252 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14255 (match_operand:IEEE128
1 "altivec_register_operand" "%v")
14256 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14258 (match_operand:IEEE128
3 "altivec_register_operand" "
0")))))]
14259 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14260 "xsnmsubqp %
0,%
1,%
2"
14261 [(set_attr "type" "qmul")
14262 (set_attr "size" "
128")])
14264 (define_insn "extend<SFDF:mode><IEEE128:mode>
2_hw"
14265 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14266 (float_extend:IEEE128
14267 (match_operand:SFDF
1 "altivec_register_operand" "v")))]
14268 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14270 [(set_attr "type" "vecfloat")
14271 (set_attr "size" "
128")])
14273 ;; Conversion between KFmode and TFmode if TFmode is ieee
128-bit floating
14274 ;; point is a simple copy.
14275 (define_insn_and_split "extendkftf2"
14276 [(set (match_operand:TF
0 "vsx_register_operand" "=wa,?wa")
14277 (float_extend:TF (match_operand:KF
1 "vsx_register_operand" "
0,wa")))]
14278 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14282 "&& reload_completed && REGNO (operands[
0]) == REGNO (operands[
1])"
14285 emit_note (NOTE_INSN_DELETED);
14288 [(set_attr "type" "*,veclogical")
14289 (set_attr "length" "
0,
4")])
14291 (define_insn_and_split "trunctfkf2"
14292 [(set (match_operand:KF
0 "vsx_register_operand" "=wa,?wa")
14293 (float_extend:KF (match_operand:TF
1 "vsx_register_operand" "
0,wa")))]
14294 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14298 "&& reload_completed && REGNO (operands[
0]) == REGNO (operands[
1])"
14301 emit_note (NOTE_INSN_DELETED);
14304 [(set_attr "type" "*,veclogical")
14305 (set_attr "length" "
0,
4")])
14307 (define_insn "trunc<mode>df2_hw"
14308 [(set (match_operand:DF
0 "altivec_register_operand" "=v")
14310 (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
14311 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14313 [(set_attr "type" "vecfloat")
14314 (set_attr "size" "
128")])
14316 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14317 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14319 (define_insn_and_split "trunc<mode>sf2_hw"
14320 [(set (match_operand:SF
0 "vsx_register_operand" "=wa")
14322 (match_operand:IEEE128
1 "altivec_register_operand" "v")))
14323 (clobber (match_scratch:DF
2 "=v"))]
14324 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14327 [(set (match_dup
2)
14328 (unspec:DF [(match_dup
1)]
14329 UNSPEC_TRUNC_ROUND_TO_ODD))
14331 (float_truncate:SF (match_dup
2)))]
14333 if (GET_CODE (operands[
2]) == SCRATCH)
14334 operands[
2] = gen_reg_rtx (DFmode);
14336 [(set_attr "type" "vecfloat")
14337 (set_attr "length" "
8")
14338 (set_attr "isa" "p8v")])
14340 ;; Conversion between IEEE
128-bit and integer types
14342 ;; The fix function for DImode and SImode was declared earlier as a
14343 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14344 ;; have IEEE
128-bit hardware support. QImode and HImode are not provided
14345 ;; unless we have the IEEE
128-bit hardware.
14347 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14348 ;; to provide a GPR target that used direct move and a conversion in the GPR
14349 ;; which works around QImode/HImode not being allowed in vector registers in
14350 ;; ISA
2.07 (power8).
14351 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>
2_hw"
14352 [(set (match_operand:SDI
0 "altivec_register_operand" "=v")
14353 (any_fix:SDI (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
14354 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14355 "xscvqp<su><wd>z %
0,%
1"
14356 [(set_attr "type" "vecfloat")
14357 (set_attr "size" "
128")])
14359 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>
2"
14360 [(set (match_operand:QHI
0 "altivec_register_operand" "=v")
14362 (match_operand:IEEE128
1 "altivec_register_operand" "v")))]
14363 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14364 "xscvqp<su>wz %
0,%
1"
14365 [(set_attr "type" "vecfloat")
14366 (set_attr "size" "
128")])
14368 ;; Combiner patterns to prevent moving the result of converting an IEEE
128-bit
14369 ;; floating point value to
8/
16/
32-bit integer to GPR in order to save it.
14370 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>
2_mem"
14371 [(set (match_operand:QHSI
0 "memory_operand" "=Z")
14373 (match_operand:IEEE128
1 "altivec_register_operand" "v")))
14374 (clobber (match_scratch:QHSI
2 "=v"))]
14375 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14377 "&& reload_completed"
14378 [(set (match_dup
2)
14379 (any_fix:QHSI (match_dup
1)))
14383 (define_insn "float_<mode>di2_hw"
14384 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14385 (float:IEEE128 (match_operand:DI
1 "altivec_register_operand" "v")))]
14386 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14388 [(set_attr "type" "vecfloat")
14389 (set_attr "size" "
128")])
14391 (define_insn_and_split "float_<mode>si2_hw"
14392 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14393 (float:IEEE128 (match_operand:SI
1 "nonimmediate_operand" "vrZ")))
14394 (clobber (match_scratch:DI
2 "=v"))]
14395 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14398 [(set (match_dup
2)
14399 (sign_extend:DI (match_dup
1)))
14401 (float:IEEE128 (match_dup
2)))]
14403 if (GET_CODE (operands[
2]) == SCRATCH)
14404 operands[
2] = gen_reg_rtx (DImode);
14406 if (MEM_P (operands[
1]))
14407 operands[
1] = rs6000_force_indexed_or_indirect_mem (operands[
1]);
14410 (define_insn_and_split "float<QHI:mode><IEEE128:mode>
2"
14411 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v,v,v")
14412 (float:IEEE128 (match_operand:QHI
1 "nonimmediate_operand" "v,r,Z")))
14413 (clobber (match_scratch:DI
2 "=X,r,X"))]
14414 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14416 "&& reload_completed"
14419 rtx dest = operands[
0];
14420 rtx src = operands[
1];
14421 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14423 if (altivec_register_operand (src, <QHI:MODE>mode))
14424 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14425 else if (int_reg_operand (src, <QHI:MODE>mode))
14427 rtx ext_di = operands[
2];
14428 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14429 emit_move_insn (dest_di, ext_di);
14431 else if (MEM_P (src))
14433 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14434 emit_move_insn (dest_qhi, src);
14435 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14438 gcc_unreachable ();
14440 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14443 [(set_attr "length" "
8,
12,
12")
14444 (set_attr "type" "vecfloat")
14445 (set_attr "size" "
128")])
14447 (define_insn "floatuns_<mode>di2_hw"
14448 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14449 (unsigned_float:IEEE128
14450 (match_operand:DI
1 "altivec_register_operand" "v")))]
14451 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14453 [(set_attr "type" "vecfloat")
14454 (set_attr "size" "
128")])
14456 (define_insn_and_split "floatuns_<mode>si2_hw"
14457 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14458 (unsigned_float:IEEE128
14459 (match_operand:SI
1 "nonimmediate_operand" "vrZ")))
14460 (clobber (match_scratch:DI
2 "=v"))]
14461 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14464 [(set (match_dup
2)
14465 (zero_extend:DI (match_dup
1)))
14467 (float:IEEE128 (match_dup
2)))]
14469 if (GET_CODE (operands[
2]) == SCRATCH)
14470 operands[
2] = gen_reg_rtx (DImode);
14472 if (MEM_P (operands[
1]))
14473 operands[
1] = rs6000_force_indexed_or_indirect_mem (operands[
1]);
14476 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>
2"
14477 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v,v,v")
14478 (unsigned_float:IEEE128
14479 (match_operand:QHI
1 "nonimmediate_operand" "v,r,Z")))
14480 (clobber (match_scratch:DI
2 "=X,r,X"))]
14481 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14483 "&& reload_completed"
14486 rtx dest = operands[
0];
14487 rtx src = operands[
1];
14488 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14490 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14491 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14492 else if (int_reg_operand (src, <QHI:MODE>mode))
14494 rtx ext_di = operands[
2];
14495 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14496 emit_move_insn (dest_di, ext_di);
14499 gcc_unreachable ();
14501 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14504 [(set_attr "length" "
8,
12,
8")
14505 (set_attr "type" "vecfloat")
14506 (set_attr "size" "
128")])
14508 ;; IEEE
128-bit round to integer built-in functions
14509 (define_insn "floor<mode>
2"
14510 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14512 [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
14514 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14516 [(set_attr "type" "vecfloat")
14517 (set_attr "size" "
128")])
14519 (define_insn "ceil<mode>
2"
14520 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14522 [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
14524 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14526 [(set_attr "type" "vecfloat")
14527 (set_attr "size" "
128")])
14529 (define_insn "btrunc<mode>
2"
14530 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14532 [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
14534 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14536 [(set_attr "type" "vecfloat")
14537 (set_attr "size" "
128")])
14539 (define_insn "round<mode>
2"
14540 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14542 [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
14544 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14546 [(set_attr "type" "vecfloat")
14547 (set_attr "size" "
128")])
14549 ;; IEEE
128-bit instructions with round to odd semantics
14550 (define_insn "add<mode>
3_odd"
14551 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14553 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
14554 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
14555 UNSPEC_ADD_ROUND_TO_ODD))]
14556 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14557 "xsaddqpo %
0,%
1,%
2"
14558 [(set_attr "type" "vecfloat")
14559 (set_attr "size" "
128")])
14561 (define_insn "sub<mode>
3_odd"
14562 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14564 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
14565 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
14566 UNSPEC_SUB_ROUND_TO_ODD))]
14567 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14568 "xssubqpo %
0,%
1,%
2"
14569 [(set_attr "type" "vecfloat")
14570 (set_attr "size" "
128")])
14572 (define_insn "mul<mode>
3_odd"
14573 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14575 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
14576 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
14577 UNSPEC_MUL_ROUND_TO_ODD))]
14578 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14579 "xsmulqpo %
0,%
1,%
2"
14580 [(set_attr "type" "qmul")
14581 (set_attr "size" "
128")])
14583 (define_insn "div<mode>
3_odd"
14584 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14586 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
14587 (match_operand:IEEE128
2 "altivec_register_operand" "v")]
14588 UNSPEC_DIV_ROUND_TO_ODD))]
14589 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14590 "xsdivqpo %
0,%
1,%
2"
14591 [(set_attr "type" "vecdiv")
14592 (set_attr "size" "
128")])
14594 (define_insn "sqrt<mode>
2_odd"
14595 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14597 [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
14598 UNSPEC_SQRT_ROUND_TO_ODD))]
14599 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14601 [(set_attr "type" "vecdiv")
14602 (set_attr "size" "
128")])
14604 (define_insn "fma<mode>
4_odd"
14605 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14607 [(match_operand:IEEE128
1 "altivec_register_operand" "v")
14608 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14609 (match_operand:IEEE128
3 "altivec_register_operand" "
0")]
14610 UNSPEC_FMA_ROUND_TO_ODD))]
14611 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14612 "xsmaddqpo %
0,%
1,%
2"
14613 [(set_attr "type" "qmul")
14614 (set_attr "size" "
128")])
14616 (define_insn "*fms<mode>
4_odd"
14617 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14619 [(match_operand:IEEE128
1 "altivec_register_operand" "%v")
14620 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14622 (match_operand:IEEE128
3 "altivec_register_operand" "
0"))]
14623 UNSPEC_FMA_ROUND_TO_ODD))]
14624 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14625 "xsmsubqpo %
0,%
1,%
2"
14626 [(set_attr "type" "qmul")
14627 (set_attr "size" "
128")])
14629 (define_insn "*nfma<mode>
4_odd"
14630 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14633 [(match_operand:IEEE128
1 "altivec_register_operand" "%v")
14634 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14635 (match_operand:IEEE128
3 "altivec_register_operand" "
0")]
14636 UNSPEC_FMA_ROUND_TO_ODD)))]
14637 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14638 "xsnmaddqpo %
0,%
1,%
2"
14639 [(set_attr "type" "qmul")
14640 (set_attr "size" "
128")])
14642 (define_insn "*nfms<mode>
4_odd"
14643 [(set (match_operand:IEEE128
0 "altivec_register_operand" "=v")
14646 [(match_operand:IEEE128
1 "altivec_register_operand" "%v")
14647 (match_operand:IEEE128
2 "altivec_register_operand" "v")
14649 (match_operand:IEEE128
3 "altivec_register_operand" "
0"))]
14650 UNSPEC_FMA_ROUND_TO_ODD)))]
14651 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14652 "xsnmsubqpo %
0,%
1,%
2"
14653 [(set_attr "type" "qmul")
14654 (set_attr "size" "
128")])
14656 (define_insn "trunc<mode>df2_odd"
14657 [(set (match_operand:DF
0 "vsx_register_operand" "=v")
14658 (unspec:DF [(match_operand:IEEE128
1 "altivec_register_operand" "v")]
14659 UNSPEC_TRUNC_ROUND_TO_ODD))]
14660 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14662 [(set_attr "type" "vecfloat")
14663 (set_attr "size" "
128")])
14665 ;; IEEE
128-bit comparisons
14666 (define_insn "*cmp<mode>_hw"
14667 [(set (match_operand:CCFP
0 "cc_reg_operand" "=y")
14668 (compare:CCFP (match_operand:IEEE128
1 "altivec_register_operand" "v")
14669 (match_operand:IEEE128
2 "altivec_register_operand" "v")))]
14670 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14671 "xscmpuqp %
0,%
1,%
2"
14672 [(set_attr "type" "veccmp")
14673 (set_attr "size" "
128")])
14675 ;; Miscellaneous ISA
3.0 (power9) instructions
14677 (define_insn "darn_32"
14678 [(set (match_operand:SI
0 "register_operand" "=r")
14679 (unspec_volatile:SI [(const_int
0)] UNSPECV_DARN_32))]
14682 [(set_attr "type" "integer")])
14684 (define_insn "darn_raw"
14685 [(set (match_operand:DI
0 "register_operand" "=r")
14686 (unspec_volatile:DI [(const_int
0)] UNSPECV_DARN_RAW))]
14687 "TARGET_P9_MISC && TARGET_64BIT"
14689 [(set_attr "type" "integer")])
14691 (define_insn "darn"
14692 [(set (match_operand:DI
0 "register_operand" "=r")
14693 (unspec_volatile:DI [(const_int
0)] UNSPECV_DARN))]
14694 "TARGET_P9_MISC && TARGET_64BIT"
14696 [(set_attr "type" "integer")])
14698 ;; Test byte within range.
14700 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
14701 ;; represents a byte whose value is ignored in this context and
14702 ;; vv, the least significant byte, holds the byte value that is to
14703 ;; be tested for membership within the range specified by operand
2.
14704 ;; The bytes of operand
2 are organized as xx:xx:hi:lo.
14706 ;; Return in target register operand
0 a value of
1 if lo <= vv and
14707 ;; vv <= hi. Otherwise, set register operand
0 to
0.
14709 ;; Though the instructions to which this expansion maps operate on
14710 ;;
64-bit registers, the current implementation only operates on
14711 ;; SI-mode operands as the high-order bits provide no information
14712 ;; that is not already available in the low-order bits. To avoid the
14713 ;; costs of data widening operations, future enhancements might allow
14714 ;; DI mode for operand
0 and/or might allow operand
1 to be QI mode.
14715 (define_expand "cmprb"
14716 [(set (match_dup
3)
14717 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
14718 (match_operand:SI
2 "gpc_reg_operand" "r")]
14720 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
14721 (if_then_else:SI (lt (match_dup
3)
14724 (if_then_else (gt (match_dup
3)
14730 operands[
3] = gen_reg_rtx (CCmode);
14733 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
14734 ;; represents a byte whose value is ignored in this context and
14735 ;; vv, the least significant byte, holds the byte value that is to
14736 ;; be tested for membership within the range specified by operand
2.
14737 ;; The bytes of operand
2 are organized as xx:xx:hi:lo.
14739 ;; Set bit
1 (the GT bit,
0x4) of CR register operand
0 to
1 if
14740 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to
0. The other
14741 ;;
3 bits of the target CR register are all set to
0.
14742 (define_insn "*cmprb_internal"
14743 [(set (match_operand:CC
0 "cc_reg_operand" "=y")
14744 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
14745 (match_operand:SI
2 "gpc_reg_operand" "r")]
14749 [(set_attr "type" "logical")])
14751 ;; Set operand
0 register to -
1 if the LT bit (
0x8) of condition
14752 ;; register operand
1 is on. Otherwise, set operand
0 register to
1
14753 ;; if the GT bit (
0x4) of condition register operand
1 is on.
14754 ;; Otherwise, set operand
0 to
0. Note that the result stored into
14755 ;; register operand
0 is non-zero iff either the LT or GT bits are on
14756 ;; within condition register operand
1.
14757 (define_insn "setb_signed"
14758 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
14759 (if_then_else:SI (lt (match_operand:CC
1 "cc_reg_operand" "y")
14762 (if_then_else (gt (match_dup
1)
14768 [(set_attr "type" "logical")])
14770 (define_insn "setb_unsigned"
14771 [(set (match_operand:SI
0 "gpc_reg_operand" "=r")
14772 (if_then_else:SI (ltu (match_operand:CCUNS
1 "cc_reg_operand" "y")
14775 (if_then_else (gtu (match_dup
1)
14781 [(set_attr "type" "logical")])
14783 ;; Test byte within two ranges.
14785 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
14786 ;; represents a byte whose value is ignored in this context and
14787 ;; vv, the least significant byte, holds the byte value that is to
14788 ;; be tested for membership within the range specified by operand
2.
14789 ;; The bytes of operand
2 are organized as hi_1:lo_1:hi_2:lo_2.
14791 ;; Return in target register operand
0 a value of
1 if (lo_1 <= vv and
14792 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
14795 ;; Though the instructions to which this expansion maps operate on
14796 ;;
64-bit registers, the current implementation only operates on
14797 ;; SI-mode operands as the high-order bits provide no information
14798 ;; that is not already available in the low-order bits. To avoid the
14799 ;; costs of data widening operations, future enhancements might allow
14800 ;; DI mode for operand
0 and/or might allow operand
1 to be QI mode.
14801 (define_expand "cmprb2"
14802 [(set (match_dup
3)
14803 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
14804 (match_operand:SI
2 "gpc_reg_operand" "r")]
14806 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
14807 (if_then_else:SI (lt (match_dup
3)
14810 (if_then_else (gt (match_dup
3)
14816 operands[
3] = gen_reg_rtx (CCmode);
14819 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
14820 ;; represents a byte whose value is ignored in this context and
14821 ;; vv, the least significant byte, holds the byte value that is to
14822 ;; be tested for membership within the ranges specified by operand
2.
14823 ;; The bytes of operand
2 are organized as hi_1:lo_1:hi_2:lo_2.
14825 ;; Set bit
1 (the GT bit,
0x4) of CR register operand
0 to
1 if
14826 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14827 ;; Otherwise, set the GT bit to
0. The other
3 bits of the target
14828 ;; CR register are all set to
0.
14829 (define_insn "*cmprb2_internal"
14830 [(set (match_operand:CC
0 "cc_reg_operand" "=y")
14831 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
14832 (match_operand:SI
2 "gpc_reg_operand" "r")]
14836 [(set_attr "type" "logical")])
14838 ;; Test byte membership within set of
8 bytes.
14840 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
14841 ;; represents a byte whose value is ignored in this context and
14842 ;; vv, the least significant byte, holds the byte value that is to
14843 ;; be tested for membership within the set specified by operand
2.
14844 ;; The bytes of operand
2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14846 ;; Return in target register operand
0 a value of
1 if vv equals one
14847 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
14848 ;; register operand
0 to
0. Note that the
8 byte values held within
14849 ;; operand
2 need not be unique.
14851 ;; Though the instructions to which this expansion maps operate on
14852 ;;
64-bit registers, the current implementation requires that operands
14853 ;;
0 and
1 have mode SI as the high-order bits provide no information
14854 ;; that is not already available in the low-order bits. To avoid the
14855 ;; costs of data widening operations, future enhancements might allow
14856 ;; DI mode for operand
0 and/or might allow operand
1 to be QI mode.
14857 (define_expand "cmpeqb"
14858 [(set (match_dup
3)
14859 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
14860 (match_operand:DI
2 "gpc_reg_operand" "r")]
14862 (set (match_operand:SI
0 "gpc_reg_operand" "=r")
14863 (if_then_else:SI (lt (match_dup
3)
14866 (if_then_else (gt (match_dup
3)
14870 "TARGET_P9_MISC && TARGET_64BIT"
14872 operands[
3] = gen_reg_rtx (CCmode);
14875 ;; The bytes of operand
1 are organized as xx:xx:xx:vv, where xx
14876 ;; represents a byte whose value is ignored in this context and
14877 ;; vv, the least significant byte, holds the byte value that is to
14878 ;; be tested for membership within the set specified by operand
2.
14879 ;; The bytes of operand
2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14881 ;; Set bit
1 (the GT bit,
0x4) of CR register operand
0 to
1 if vv
14882 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
14883 ;; set the GT bit to zero. The other
3 bits of the target CR register
14884 ;; are all set to
0.
14885 (define_insn "*cmpeqb_internal"
14886 [(set (match_operand:CC
0 "cc_reg_operand" "=y")
14887 (unspec:CC [(match_operand:SI
1 "gpc_reg_operand" "r")
14888 (match_operand:DI
2 "gpc_reg_operand" "r")]
14890 "TARGET_P9_MISC && TARGET_64BIT"
14892 [(set_attr "type" "logical")])
14895 (include "sync.md")
14896 (include "vector.md")
14898 (include "altivec.md")
14901 (include "crypto.md")