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
90 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
108 UNSPEC_MACHOPIC_OFFSET
122 UNSPEC_P8V_RELOAD_FROM_GPR
125 UNSPEC_P8V_RELOAD_FROM_VSX
139 UNSPEC_ADD_ROUND_TO_ODD
140 UNSPEC_SUB_ROUND_TO_ODD
141 UNSPEC_MUL_ROUND_TO_ODD
142 UNSPEC_DIV_ROUND_TO_ODD
143 UNSPEC_FMA_ROUND_TO_ODD
144 UNSPEC_SQRT_ROUND_TO_ODD
145 UNSPEC_TRUNC_ROUND_TO_ODD
154 ;; UNSPEC_VOLATILE usage
157 (define_c_enum "unspecv"
159 UNSPECV_LL ; load-locked
160 UNSPECV_SC ; store-conditional
161 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
162 UNSPECV_EH_RR ; eh_reg_restore
163 UNSPECV_ISYNC ; isync instruction
164 UNSPECV_MFTB ; move from time base
165 UNSPECV_DARN ; darn 1 (deliver a random number)
166 UNSPECV_DARN_32 ; darn 2
167 UNSPECV_DARN_RAW ; darn 0
168 UNSPECV_NLGR ; non-local goto receiver
169 UNSPECV_MFFS ; Move from FPSCR
170 UNSPECV_MFFSL ; Move from FPSCR light instruction version
171 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
172 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
173 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
174 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
175 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
176 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
177 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
178 UNSPECV_SPEC_BARRIER ; Speculation barrier
183 ; The three different kinds of epilogue.
184 (define_enum "epilogue_type" [normal sibcall eh_return])
186 ;; Define an insn type attribute. This is used in function unit delay
190 add,logical,shift,insert,
192 exts,cntlz,popcnt,isel,
193 load,store,fpload,fpstore,vecload,vecstore,
195 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
196 cr_logical,mfcr,mfcrf,mtcr,
197 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
198 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
199 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
200 veclogical,veccmpfx,vecexts,vecmove,
202 (const_string "integer"))
204 ;; What data size does this instruction work on?
205 ;; This is used for insert, mul and others as necessary.
206 (define_attr "size" "8,16,32,64,128" (const_string "32"))
208 ;; What is the insn_cost for this insn? The target hook can still override
209 ;; this. For optimizing for size the "length" attribute is used instead.
210 (define_attr "cost" "" (const_int 0))
212 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
213 ;; This is used for add, logical, shift, exts, mul.
214 (define_attr "dot" "no,yes" (const_string "no"))
216 ;; Does this instruction sign-extend its result?
217 ;; This is used for load insns.
218 (define_attr "sign_extend" "no,yes" (const_string "no"))
220 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
221 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
223 ;; Does this instruction use indexed (that is, reg+reg) addressing?
224 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
225 ;; it is automatically set based on that. If a load or store instruction
226 ;; has fewer than two operands it needs to set this attribute manually
227 ;; or the compiler will crash.
228 (define_attr "indexed" "no,yes"
229 (if_then_else (ior (match_operand 0 "indexed_address_mem")
230 (match_operand 1 "indexed_address_mem"))
232 (const_string "no")))
234 ;; Does this instruction use update addressing?
235 ;; This is used for load and store insns. See the comments for "indexed".
236 (define_attr "update" "no,yes"
237 (if_then_else (ior (match_operand 0 "update_address_mem")
238 (match_operand 1 "update_address_mem"))
240 (const_string "no")))
242 ;; Is this instruction using operands[2] as shift amount, and can that be a
244 ;; This is used for shift insns.
245 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
247 ;; Is this instruction using a shift amount from a register?
248 ;; This is used for shift insns.
249 (define_attr "var_shift" "no,yes"
250 (if_then_else (and (eq_attr "type" "shift")
251 (eq_attr "maybe_var_shift" "yes"))
252 (if_then_else (match_operand 2 "gpc_reg_operand")
255 (const_string "no")))
257 ;; Is copying of this instruction disallowed?
258 (define_attr "cannot_copy" "no,yes" (const_string "no"))
261 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
262 ;; before the instruction. A prefixed instruction has a prefix instruction
263 ;; word that extends the immediate value of the instructions from 12-16 bits to
264 ;; 34 bits. The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
265 ;; insns. The default "length" attribute will also be adjusted by default to
267 (define_attr "prefixed" "no,yes"
268 (cond [(ior (match_test "!TARGET_PREFIXED")
269 (match_test "!NONJUMP_INSN_P (insn)"))
272 (eq_attr "type" "load,fpload,vecload")
273 (if_then_else (match_test "prefixed_load_p (insn)")
277 (eq_attr "type" "store,fpstore,vecstore")
278 (if_then_else (match_test "prefixed_store_p (insn)")
282 (eq_attr "type" "integer,add")
283 (if_then_else (match_test "prefixed_paddi_p (insn)")
285 (const_string "no"))]
287 (const_string "no")))
289 ;; Return the number of real hardware instructions in a combined insn. If it
290 ;; is 0, just use the length / 4.
291 (define_attr "num_insns" "" (const_int 0))
293 ;; If an insn is prefixed, return the maximum number of prefixed instructions
294 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
296 (define_attr "max_prefixed_insns" "" (const_int 1))
298 ;; Length of the instruction (in bytes). This length does not consider the
299 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
300 ;; the length if there are prefixed instructions.
302 ;; While it might be tempting to use num_insns to calculate the length, it can
303 ;; be problematical unless all insn lengths are adjusted to use num_insns
304 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
305 ;; num_insns and recurse).
306 (define_attr "length" "" (const_int 4))
308 ;; Processor type -- this attribute must exactly match the processor_type
309 ;; enumeration in rs6000-opts.h.
311 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
312 ppc750,ppc7400,ppc7450,
313 ppc403,ppc405,ppc440,ppc476,
314 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
315 power4,power5,power6,power7,power8,power9,future,
316 rs64a,mpccore,cell,ppca2,titan"
317 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
319 ;; The ISA we implement.
320 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,fut"
321 (const_string "any"))
323 ;; Is this alternative enabled for the current CPU/ISA/etc.?
324 (define_attr "enabled" ""
326 [(eq_attr "isa" "any")
329 (and (eq_attr "isa" "p5")
330 (match_test "TARGET_POPCNTB"))
333 (and (eq_attr "isa" "p6")
334 (match_test "TARGET_CMPB"))
337 (and (eq_attr "isa" "p7")
338 (match_test "TARGET_POPCNTD"))
341 (and (eq_attr "isa" "p7v")
342 (match_test "TARGET_VSX"))
345 (and (eq_attr "isa" "p8v")
346 (match_test "TARGET_P8_VECTOR"))
349 (and (eq_attr "isa" "p9v")
350 (match_test "TARGET_P9_VECTOR"))
353 (and (eq_attr "isa" "p9kf")
354 (match_test "TARGET_FLOAT128_TYPE"))
357 (and (eq_attr "isa" "p9tf")
358 (match_test "FLOAT128_VECTOR_P (TFmode)"))
361 (and (eq_attr "isa" "fut")
362 (match_test "TARGET_FUTURE"))
366 ;; If this instruction is microcoded on the CELL processor
367 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
368 (define_attr "cell_micro" "not,conditional,always"
369 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
370 (eq_attr "dot" "yes"))
371 (and (eq_attr "type" "load")
372 (eq_attr "sign_extend" "yes"))
373 (and (eq_attr "type" "shift")
374 (eq_attr "var_shift" "yes")))
375 (const_string "always")
376 (const_string "not")))
378 (automata_option "ndfa")
391 (include "e300c2c3.md")
392 (include "e500mc.md")
393 (include "e500mc64.md")
396 (include "power4.md")
397 (include "power5.md")
398 (include "power6.md")
399 (include "power7.md")
400 (include "power8.md")
401 (include "power9.md")
402 (include "future.md")
407 (include "predicates.md")
408 (include "constraints.md")
413 ; This mode iterator allows :GPR to be used to indicate the allowable size
414 ; of whole values in GPRs.
415 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
417 ; And again, for patterns that need two (potentially) different integer modes.
418 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
420 ; Any supported integer mode.
421 (define_mode_iterator INT [QI HI SI DI TI PTI])
423 ; Any supported integer mode that fits in one register.
424 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
426 ; Integer modes supported in VSX registers with ISA 3.0 instructions
427 (define_mode_iterator INT_ISA3 [QI HI SI DI])
429 ; Everything we can extend QImode to.
430 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
432 ; Everything we can extend HImode to.
433 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
435 ; Everything we can extend SImode to.
436 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
438 ; QImode or HImode for small integer moves and small atomic ops
439 (define_mode_iterator QHI [QI HI])
441 ; QImode, HImode, SImode for fused ops only for GPR loads
442 (define_mode_iterator QHSI [QI HI SI])
444 ; HImode or SImode for sign extended fusion ops
445 (define_mode_iterator HSI [HI SI])
447 ; SImode or DImode, even if DImode doesn't fit in GPRs.
448 (define_mode_iterator SDI [SI DI])
450 ; The size of a pointer. Also, the size of the value that a record-condition
451 ; (one with a '.') will compare; and the size used for arithmetic carries.
452 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
454 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
455 ; PTImode is GPR only)
456 (define_mode_iterator TI2 [TI PTI])
458 ; Any hardware-supported floating-point mode
459 (define_mode_iterator FP [
460 (SF "TARGET_HARD_FLOAT")
461 (DF "TARGET_HARD_FLOAT")
462 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
463 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
464 (KF "TARGET_FLOAT128_TYPE")
468 ; Any fma capable floating-point mode.
469 (define_mode_iterator FMA_F [
470 (SF "TARGET_HARD_FLOAT")
471 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
472 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
473 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
474 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
475 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
478 ; Floating point move iterators to combine binary and decimal moves
479 (define_mode_iterator FMOVE32 [SF SD])
480 (define_mode_iterator FMOVE64 [DF DD])
481 (define_mode_iterator FMOVE64X [DI DF DD])
482 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
483 (IF "FLOAT128_IBM_P (IFmode)")
484 (TD "TARGET_HARD_FLOAT")])
486 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
487 (IF "FLOAT128_2REG_P (IFmode)")
488 (TD "TARGET_HARD_FLOAT")])
490 ; Iterators for 128 bit types for direct move
491 (define_mode_iterator FMOVE128_GPR [TI
499 (KF "FLOAT128_VECTOR_P (KFmode)")
500 (TF "FLOAT128_VECTOR_P (TFmode)")])
502 ; Iterator for 128-bit VSX types for pack/unpack
503 (define_mode_iterator FMOVE128_VSX [V1TI KF])
505 ; Iterators for converting to/from TFmode
506 (define_mode_iterator IFKF [IF KF])
508 ; Constraints for moving IF/KFmode.
509 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
511 ; Whether a floating point move is ok, don't allow SD without hardware FP
512 (define_mode_attr fmove_ok [(SF "")
514 (SD "TARGET_HARD_FLOAT")
517 ; Convert REAL_VALUE to the appropriate bits
518 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
519 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
520 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
521 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
523 ; Whether 0.0 has an all-zero bit pattern
524 (define_mode_attr zero_fp [(SF "j")
533 ; Definitions for 64-bit VSX
534 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
536 ; Definitions for 64-bit direct move
537 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
539 ; Definitions for 64-bit use of altivec registers
540 (define_mode_attr f64_av [(DF "v") (DD "wn")])
542 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
543 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
545 ; These modes do not fit in integer registers in 32-bit mode.
546 (define_mode_iterator DIFD [DI DF DD])
548 ; Iterator for reciprocal estimate instructions
549 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
552 (define_mode_iterator SFDF [SF DF])
554 ; And again, for when we need two FP modes in a pattern.
555 (define_mode_iterator SFDF2 [SF DF])
557 ; A generic s/d attribute, for sp/dp for example.
558 (define_mode_attr sd [(SF "s") (DF "d")
559 (V4SF "s") (V2DF "d")])
561 ; "s" or nothing, for fmuls/fmul for example.
562 (define_mode_attr s [(SF "s") (DF "")])
564 ; Iterator for 128-bit floating point that uses the IBM double-double format
565 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
566 (TF "FLOAT128_IBM_P (TFmode)")])
568 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
569 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
570 (TF "FLOAT128_IEEE_P (TFmode)")])
572 ; Iterator for 128-bit floating point
573 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
574 (IF "TARGET_FLOAT128_TYPE")
575 (TF "TARGET_LONG_DOUBLE_128")])
577 ; Iterator for signbit on 64-bit machines with direct move
578 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
579 (TF "FLOAT128_VECTOR_P (TFmode)")])
581 ; Iterator for ISA 3.0 supported floating point types
582 (define_mode_iterator FP_ISA3 [SF DF])
584 ; SF/DF constraint for arithmetic on traditional floating point registers
585 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
587 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
588 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
589 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
591 (define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")])
593 ; Which isa is needed for those float instructions?
594 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
597 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
599 ; Conditional returns.
600 (define_code_iterator any_return [return simple_return])
601 (define_code_attr return_pred [(return "direct_return ()")
602 (simple_return "1")])
603 (define_code_attr return_str [(return "") (simple_return "simple_")])
606 (define_code_iterator iorxor [ior xor])
607 (define_code_iterator and_ior_xor [and ior xor])
609 ; Signed/unsigned variants of ops.
610 (define_code_iterator any_extend [sign_extend zero_extend])
611 (define_code_iterator any_fix [fix unsigned_fix])
612 (define_code_iterator any_float [float unsigned_float])
614 (define_code_attr u [(sign_extend "")
619 (define_code_attr su [(sign_extend "s")
624 (unsigned_float "u")])
626 (define_code_attr az [(sign_extend "a")
631 (unsigned_float "z")])
633 (define_code_attr uns [(fix "")
636 (unsigned_float "uns")])
638 ; Various instructions that come in SI and DI forms.
639 ; A generic w/d attribute, for things like cmpw/cmpd.
640 (define_mode_attr wd [(QI "b")
651 ;; How many bits in this mode?
652 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
653 (SF "32") (DF "64")])
656 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
658 ;; Bitmask for shift instructions
659 (define_mode_attr hH [(SI "h") (DI "H")])
661 ;; A mode twice the size of the given mode
662 (define_mode_attr dmode [(SI "di") (DI "ti")])
663 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
665 ;; Suffix for reload patterns
666 (define_mode_attr ptrsize [(SI "32bit")
669 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
670 (DI "TARGET_64BIT")])
672 (define_mode_attr mptrsize [(SI "si")
675 (define_mode_attr ptrload [(SI "lwz")
678 (define_mode_attr ptrm [(SI "m")
681 (define_mode_attr rreg [(SF "f")
688 (define_mode_attr rreg2 [(SF "f")
691 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
692 (DF "TARGET_FCFID")])
694 ;; Mode iterator for logical operations on 128-bit types
695 (define_mode_iterator BOOL_128 [TI
697 (V16QI "TARGET_ALTIVEC")
698 (V8HI "TARGET_ALTIVEC")
699 (V4SI "TARGET_ALTIVEC")
700 (V4SF "TARGET_ALTIVEC")
701 (V2DI "TARGET_ALTIVEC")
702 (V2DF "TARGET_ALTIVEC")
703 (V1TI "TARGET_ALTIVEC")])
705 ;; For the GPRs we use 3 constraints for register outputs, two that are the
706 ;; same as the output register, and a third where the output register is an
707 ;; early clobber, so we don't have to deal with register overlaps. For the
708 ;; vector types, we prefer to use the vector registers. For TI mode, allow
711 ;; Mode attribute for boolean operation register constraints for output
712 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
714 (V16QI "wa,v,&?r,?r,?r")
715 (V8HI "wa,v,&?r,?r,?r")
716 (V4SI "wa,v,&?r,?r,?r")
717 (V4SF "wa,v,&?r,?r,?r")
718 (V2DI "wa,v,&?r,?r,?r")
719 (V2DF "wa,v,&?r,?r,?r")
720 (V1TI "wa,v,&?r,?r,?r")])
722 ;; Mode attribute for boolean operation register constraints for operand1
723 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
731 (V1TI "wa,v,r,0,r")])
733 ;; Mode attribute for boolean operation register constraints for operand2
734 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
742 (V1TI "wa,v,r,r,0")])
744 ;; Mode attribute for boolean operation register constraints for operand1
745 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
746 ;; is used for operand1 or operand2
747 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
755 (V1TI "wa,v,r,0,0")])
757 ;; Reload iterator for creating the function to allocate a base register to
758 ;; supplement addressing modes.
759 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
760 SF SD SI DF DD DI TI PTI KF IF TF])
762 ;; Iterate over smin, smax
763 (define_code_iterator fp_minmax [smin smax])
765 (define_code_attr minmax [(smin "min")
768 (define_code_attr SMINMAX [(smin "SMIN")
771 ;; Iterator to optimize the following cases:
772 ;; D-form load to FPR register & move to Altivec register
773 ;; Move Altivec register to FPR register and store
774 (define_mode_iterator ALTIVEC_DFORM [DF
775 (SF "TARGET_P8_VECTOR")
776 (DI "TARGET_POWERPC64")])
778 (include "darwin.md")
780 ;; Start with fixed-point load and store insns. Here we put only the more
781 ;; complex forms. Basic data transfer is done later.
783 (define_insn "zero_extendqi<mode>2"
784 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
785 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
792 [(set_attr "type" "load,shift,fpload,vecperm")
793 (set_attr "isa" "*,*,p9v,p9v")])
795 (define_insn_and_split "*zero_extendqi<mode>2_dot"
796 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
797 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
799 (clobber (match_scratch:EXTQI 0 "=r,r"))]
804 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
806 (zero_extend:EXTQI (match_dup 1)))
808 (compare:CC (match_dup 0)
811 [(set_attr "type" "logical")
812 (set_attr "dot" "yes")
813 (set_attr "length" "4,8")])
815 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
816 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
817 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
819 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
820 (zero_extend:EXTQI (match_dup 1)))]
825 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
827 (zero_extend:EXTQI (match_dup 1)))
829 (compare:CC (match_dup 0)
832 [(set_attr "type" "logical")
833 (set_attr "dot" "yes")
834 (set_attr "length" "4,8")])
837 (define_insn "zero_extendhi<mode>2"
838 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
839 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
843 rlwinm %0,%1,0,0xffff
846 [(set_attr "type" "load,shift,fpload,vecperm")
847 (set_attr "isa" "*,*,p9v,p9v")])
849 (define_insn_and_split "*zero_extendhi<mode>2_dot"
850 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
851 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
853 (clobber (match_scratch:EXTHI 0 "=r,r"))]
858 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
860 (zero_extend:EXTHI (match_dup 1)))
862 (compare:CC (match_dup 0)
865 [(set_attr "type" "logical")
866 (set_attr "dot" "yes")
867 (set_attr "length" "4,8")])
869 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
870 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
871 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
873 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
874 (zero_extend:EXTHI (match_dup 1)))]
879 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
881 (zero_extend:EXTHI (match_dup 1)))
883 (compare:CC (match_dup 0)
886 [(set_attr "type" "logical")
887 (set_attr "dot" "yes")
888 (set_attr "length" "4,8")])
891 (define_insn "zero_extendsi<mode>2"
892 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
893 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
902 xxextractuw %x0,%x1,4"
903 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
904 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
906 (define_insn_and_split "*zero_extendsi<mode>2_dot"
907 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
910 (clobber (match_scratch:EXTSI 0 "=r,r"))]
915 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
917 (zero_extend:DI (match_dup 1)))
919 (compare:CC (match_dup 0)
922 [(set_attr "type" "shift")
923 (set_attr "dot" "yes")
924 (set_attr "length" "4,8")])
926 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
927 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
928 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
930 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
931 (zero_extend:EXTSI (match_dup 1)))]
936 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
938 (zero_extend:EXTSI (match_dup 1)))
940 (compare:CC (match_dup 0)
943 [(set_attr "type" "shift")
944 (set_attr "dot" "yes")
945 (set_attr "length" "4,8")])
948 (define_insn "extendqi<mode>2"
949 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
950 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
955 [(set_attr "type" "exts,vecperm")
956 (set_attr "isa" "*,p9v")])
958 (define_insn_and_split "*extendqi<mode>2_dot"
959 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
960 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
962 (clobber (match_scratch:EXTQI 0 "=r,r"))]
967 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
969 (sign_extend:EXTQI (match_dup 1)))
971 (compare:CC (match_dup 0)
974 [(set_attr "type" "exts")
975 (set_attr "dot" "yes")
976 (set_attr "length" "4,8")])
978 (define_insn_and_split "*extendqi<mode>2_dot2"
979 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
982 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
983 (sign_extend:EXTQI (match_dup 1)))]
988 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
990 (sign_extend:EXTQI (match_dup 1)))
992 (compare:CC (match_dup 0)
995 [(set_attr "type" "exts")
996 (set_attr "dot" "yes")
997 (set_attr "length" "4,8")])
1000 (define_expand "extendhi<mode>2"
1001 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1002 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1006 (define_insn "*extendhi<mode>2"
1007 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1008 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1015 [(set_attr "type" "load,exts,fpload,vecperm")
1016 (set_attr "sign_extend" "yes")
1017 (set_attr "length" "*,*,8,*")
1018 (set_attr "isa" "*,*,p9v,p9v")])
1021 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1023 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1024 "TARGET_P9_VECTOR && reload_completed"
1028 (sign_extend:EXTHI (match_dup 2)))]
1030 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1033 (define_insn_and_split "*extendhi<mode>2_dot"
1034 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1035 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1037 (clobber (match_scratch:EXTHI 0 "=r,r"))]
1042 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1044 (sign_extend:EXTHI (match_dup 1)))
1046 (compare:CC (match_dup 0)
1049 [(set_attr "type" "exts")
1050 (set_attr "dot" "yes")
1051 (set_attr "length" "4,8")])
1053 (define_insn_and_split "*extendhi<mode>2_dot2"
1054 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1055 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1057 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1058 (sign_extend:EXTHI (match_dup 1)))]
1063 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1065 (sign_extend:EXTHI (match_dup 1)))
1067 (compare:CC (match_dup 0)
1070 [(set_attr "type" "exts")
1071 (set_attr "dot" "yes")
1072 (set_attr "length" "4,8")])
1075 (define_insn "extendsi<mode>2"
1076 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1077 "=r, r, d, wa, wa, v, v, wr")
1078 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1079 "YZ, r, Z, Z, r, v, v, ?wa")))]
1090 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1091 (set_attr "sign_extend" "yes")
1092 (set_attr "length" "*,*,*,*,*,*,8,8")
1093 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1096 [(set (match_operand:EXTSI 0 "int_reg_operand")
1097 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1098 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1102 (sign_extend:DI (match_dup 2)))]
1104 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1108 [(set (match_operand:DI 0 "altivec_register_operand")
1109 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1110 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1113 rtx dest = operands[0];
1114 rtx src = operands[1];
1115 int dest_regno = REGNO (dest);
1116 int src_regno = REGNO (src);
1117 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1118 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1120 if (BYTES_BIG_ENDIAN)
1122 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1123 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1127 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1128 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1133 (define_insn_and_split "*extendsi<mode>2_dot"
1134 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1135 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1137 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1142 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1144 (sign_extend:EXTSI (match_dup 1)))
1146 (compare:CC (match_dup 0)
1149 [(set_attr "type" "exts")
1150 (set_attr "dot" "yes")
1151 (set_attr "length" "4,8")])
1153 (define_insn_and_split "*extendsi<mode>2_dot2"
1154 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1155 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1157 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1158 (sign_extend:EXTSI (match_dup 1)))]
1163 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1165 (sign_extend:EXTSI (match_dup 1)))
1167 (compare:CC (match_dup 0)
1170 [(set_attr "type" "exts")
1171 (set_attr "dot" "yes")
1172 (set_attr "length" "4,8")])
1174 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1176 (define_insn "*macchwc"
1177 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1178 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1179 (match_operand:SI 2 "gpc_reg_operand" "r")
1182 (match_operand:HI 1 "gpc_reg_operand" "r")))
1183 (match_operand:SI 4 "gpc_reg_operand" "0"))
1185 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1186 (plus:SI (mult:SI (ashiftrt:SI
1194 [(set_attr "type" "halfmul")])
1196 (define_insn "*macchw"
1197 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1198 (plus:SI (mult:SI (ashiftrt:SI
1199 (match_operand:SI 2 "gpc_reg_operand" "r")
1202 (match_operand:HI 1 "gpc_reg_operand" "r")))
1203 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1206 [(set_attr "type" "halfmul")])
1208 (define_insn "*macchwuc"
1209 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1210 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1211 (match_operand:SI 2 "gpc_reg_operand" "r")
1214 (match_operand:HI 1 "gpc_reg_operand" "r")))
1215 (match_operand:SI 4 "gpc_reg_operand" "0"))
1217 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1218 (plus:SI (mult:SI (lshiftrt:SI
1226 [(set_attr "type" "halfmul")])
1228 (define_insn "*macchwu"
1229 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1230 (plus:SI (mult:SI (lshiftrt:SI
1231 (match_operand:SI 2 "gpc_reg_operand" "r")
1234 (match_operand:HI 1 "gpc_reg_operand" "r")))
1235 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1238 [(set_attr "type" "halfmul")])
1240 (define_insn "*machhwc"
1241 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1242 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1243 (match_operand:SI 1 "gpc_reg_operand" "%r")
1246 (match_operand:SI 2 "gpc_reg_operand" "r")
1248 (match_operand:SI 4 "gpc_reg_operand" "0"))
1250 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1251 (plus:SI (mult:SI (ashiftrt:SI
1260 [(set_attr "type" "halfmul")])
1262 (define_insn "*machhw"
1263 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1264 (plus:SI (mult:SI (ashiftrt:SI
1265 (match_operand:SI 1 "gpc_reg_operand" "%r")
1268 (match_operand:SI 2 "gpc_reg_operand" "r")
1270 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1273 [(set_attr "type" "halfmul")])
1275 (define_insn "*machhwuc"
1276 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1277 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1278 (match_operand:SI 1 "gpc_reg_operand" "%r")
1281 (match_operand:SI 2 "gpc_reg_operand" "r")
1283 (match_operand:SI 4 "gpc_reg_operand" "0"))
1285 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1286 (plus:SI (mult:SI (lshiftrt:SI
1295 [(set_attr "type" "halfmul")])
1297 (define_insn "*machhwu"
1298 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1299 (plus:SI (mult:SI (lshiftrt:SI
1300 (match_operand:SI 1 "gpc_reg_operand" "%r")
1303 (match_operand:SI 2 "gpc_reg_operand" "r")
1305 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1308 [(set_attr "type" "halfmul")])
1310 (define_insn "*maclhwc"
1311 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1312 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1313 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1315 (match_operand:HI 2 "gpc_reg_operand" "r")))
1316 (match_operand:SI 4 "gpc_reg_operand" "0"))
1318 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1319 (plus:SI (mult:SI (sign_extend:SI
1326 [(set_attr "type" "halfmul")])
1328 (define_insn "*maclhw"
1329 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1330 (plus:SI (mult:SI (sign_extend:SI
1331 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1333 (match_operand:HI 2 "gpc_reg_operand" "r")))
1334 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1337 [(set_attr "type" "halfmul")])
1339 (define_insn "*maclhwuc"
1340 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1341 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1342 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1344 (match_operand:HI 2 "gpc_reg_operand" "r")))
1345 (match_operand:SI 4 "gpc_reg_operand" "0"))
1347 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1348 (plus:SI (mult:SI (zero_extend:SI
1355 [(set_attr "type" "halfmul")])
1357 (define_insn "*maclhwu"
1358 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1359 (plus:SI (mult:SI (zero_extend:SI
1360 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1362 (match_operand:HI 2 "gpc_reg_operand" "r")))
1363 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1366 [(set_attr "type" "halfmul")])
1368 (define_insn "*nmacchwc"
1369 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1370 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1371 (mult:SI (ashiftrt:SI
1372 (match_operand:SI 2 "gpc_reg_operand" "r")
1375 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1377 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1378 (minus:SI (match_dup 4)
1379 (mult:SI (ashiftrt:SI
1386 [(set_attr "type" "halfmul")])
1388 (define_insn "*nmacchw"
1389 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1390 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1391 (mult:SI (ashiftrt:SI
1392 (match_operand:SI 2 "gpc_reg_operand" "r")
1395 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1398 [(set_attr "type" "halfmul")])
1400 (define_insn "*nmachhwc"
1401 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1402 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1403 (mult:SI (ashiftrt:SI
1404 (match_operand:SI 1 "gpc_reg_operand" "%r")
1407 (match_operand:SI 2 "gpc_reg_operand" "r")
1410 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1411 (minus:SI (match_dup 4)
1412 (mult:SI (ashiftrt:SI
1420 [(set_attr "type" "halfmul")])
1422 (define_insn "*nmachhw"
1423 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1424 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1425 (mult:SI (ashiftrt:SI
1426 (match_operand:SI 1 "gpc_reg_operand" "%r")
1429 (match_operand:SI 2 "gpc_reg_operand" "r")
1433 [(set_attr "type" "halfmul")])
1435 (define_insn "*nmaclhwc"
1436 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1437 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1438 (mult:SI (sign_extend:SI
1439 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1441 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1443 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1444 (minus:SI (match_dup 4)
1445 (mult:SI (sign_extend:SI
1451 [(set_attr "type" "halfmul")])
1453 (define_insn "*nmaclhw"
1454 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1455 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1456 (mult:SI (sign_extend:SI
1457 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1459 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1462 [(set_attr "type" "halfmul")])
1464 (define_insn "*mulchwc"
1465 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1466 (compare:CC (mult:SI (ashiftrt:SI
1467 (match_operand:SI 2 "gpc_reg_operand" "r")
1470 (match_operand:HI 1 "gpc_reg_operand" "r")))
1472 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1473 (mult:SI (ashiftrt:SI
1480 [(set_attr "type" "halfmul")])
1482 (define_insn "*mulchw"
1483 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1484 (mult:SI (ashiftrt:SI
1485 (match_operand:SI 2 "gpc_reg_operand" "r")
1488 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1491 [(set_attr "type" "halfmul")])
1493 (define_insn "*mulchwuc"
1494 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1495 (compare:CC (mult:SI (lshiftrt:SI
1496 (match_operand:SI 2 "gpc_reg_operand" "r")
1499 (match_operand:HI 1 "gpc_reg_operand" "r")))
1501 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1502 (mult:SI (lshiftrt:SI
1509 [(set_attr "type" "halfmul")])
1511 (define_insn "*mulchwu"
1512 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1513 (mult:SI (lshiftrt:SI
1514 (match_operand:SI 2 "gpc_reg_operand" "r")
1517 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1520 [(set_attr "type" "halfmul")])
1522 (define_insn "*mulhhwc"
1523 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1524 (compare:CC (mult:SI (ashiftrt:SI
1525 (match_operand:SI 1 "gpc_reg_operand" "%r")
1528 (match_operand:SI 2 "gpc_reg_operand" "r")
1531 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1532 (mult:SI (ashiftrt:SI
1540 [(set_attr "type" "halfmul")])
1542 (define_insn "*mulhhw"
1543 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1544 (mult:SI (ashiftrt:SI
1545 (match_operand:SI 1 "gpc_reg_operand" "%r")
1548 (match_operand:SI 2 "gpc_reg_operand" "r")
1552 [(set_attr "type" "halfmul")])
1554 (define_insn "*mulhhwuc"
1555 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1556 (compare:CC (mult:SI (lshiftrt:SI
1557 (match_operand:SI 1 "gpc_reg_operand" "%r")
1560 (match_operand:SI 2 "gpc_reg_operand" "r")
1563 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1564 (mult:SI (lshiftrt:SI
1572 [(set_attr "type" "halfmul")])
1574 (define_insn "*mulhhwu"
1575 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1576 (mult:SI (lshiftrt:SI
1577 (match_operand:SI 1 "gpc_reg_operand" "%r")
1580 (match_operand:SI 2 "gpc_reg_operand" "r")
1584 [(set_attr "type" "halfmul")])
1586 (define_insn "*mullhwc"
1587 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1588 (compare:CC (mult:SI (sign_extend:SI
1589 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1591 (match_operand:HI 2 "gpc_reg_operand" "r")))
1593 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1594 (mult:SI (sign_extend:SI
1600 [(set_attr "type" "halfmul")])
1602 (define_insn "*mullhw"
1603 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1604 (mult:SI (sign_extend:SI
1605 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1607 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1610 [(set_attr "type" "halfmul")])
1612 (define_insn "*mullhwuc"
1613 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1614 (compare:CC (mult:SI (zero_extend:SI
1615 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1617 (match_operand:HI 2 "gpc_reg_operand" "r")))
1619 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1620 (mult:SI (zero_extend:SI
1626 [(set_attr "type" "halfmul")])
1628 (define_insn "*mullhwu"
1629 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1630 (mult:SI (zero_extend:SI
1631 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1633 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1636 [(set_attr "type" "halfmul")])
1638 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1639 (define_insn "dlmzb"
1640 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1641 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1642 (match_operand:SI 2 "gpc_reg_operand" "r")]
1644 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1645 (unspec:SI [(match_dup 1)
1651 (define_expand "strlensi"
1652 [(set (match_operand:SI 0 "gpc_reg_operand")
1653 (unspec:SI [(match_operand:BLK 1 "general_operand")
1654 (match_operand:QI 2 "const_int_operand")
1655 (match_operand 3 "const_int_operand")]
1656 UNSPEC_DLMZB_STRLEN))
1657 (clobber (match_scratch:CC 4))]
1658 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1660 rtx result = operands[0];
1661 rtx src = operands[1];
1662 rtx search_char = operands[2];
1663 rtx align = operands[3];
1664 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1665 rtx loop_label, end_label, mem, cr0, cond;
1666 if (search_char != const0_rtx
1667 || !CONST_INT_P (align)
1668 || INTVAL (align) < 8)
1670 word1 = gen_reg_rtx (SImode);
1671 word2 = gen_reg_rtx (SImode);
1672 scratch_dlmzb = gen_reg_rtx (SImode);
1673 scratch_string = gen_reg_rtx (Pmode);
1674 loop_label = gen_label_rtx ();
1675 end_label = gen_label_rtx ();
1676 addr = force_reg (Pmode, XEXP (src, 0));
1677 emit_move_insn (scratch_string, addr);
1678 emit_label (loop_label);
1679 mem = change_address (src, SImode, scratch_string);
1680 emit_move_insn (word1, mem);
1681 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1682 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1683 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1684 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1685 emit_jump_insn (gen_rtx_SET (pc_rtx,
1686 gen_rtx_IF_THEN_ELSE (VOIDmode,
1692 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1693 emit_jump_insn (gen_rtx_SET (pc_rtx,
1694 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1696 emit_label (end_label);
1697 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1698 emit_insn (gen_subsi3 (result, scratch_string, addr));
1699 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1703 ;; Fixed-point arithmetic insns.
1705 (define_expand "add<mode>3"
1706 [(set (match_operand:SDI 0 "gpc_reg_operand")
1707 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1708 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1711 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1713 rtx lo0 = gen_lowpart (SImode, operands[0]);
1714 rtx lo1 = gen_lowpart (SImode, operands[1]);
1715 rtx lo2 = gen_lowpart (SImode, operands[2]);
1716 rtx hi0 = gen_highpart (SImode, operands[0]);
1717 rtx hi1 = gen_highpart (SImode, operands[1]);
1718 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1720 if (!reg_or_short_operand (lo2, SImode))
1721 lo2 = force_reg (SImode, lo2);
1722 if (!adde_operand (hi2, SImode))
1723 hi2 = force_reg (SImode, hi2);
1725 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1726 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1730 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1732 rtx tmp = ((!can_create_pseudo_p ()
1733 || rtx_equal_p (operands[0], operands[1]))
1734 ? operands[0] : gen_reg_rtx (<MODE>mode));
1736 /* Adding a constant to r0 is not a valid insn, so use a different
1737 strategy in that case. */
1738 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1740 if (operands[0] == operands[1])
1742 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1743 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1747 HOST_WIDE_INT val = INTVAL (operands[2]);
1748 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1749 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1751 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1754 /* The ordering here is important for the prolog expander.
1755 When space is allocated from the stack, adding 'low' first may
1756 produce a temporary deallocation (which would be bad). */
1757 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1758 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1763 (define_insn "*add<mode>3"
1764 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1765 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1766 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1773 [(set_attr "type" "add")
1774 (set_attr "isa" "*,*,*,fut")])
1776 (define_insn "*addsi3_high"
1777 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1778 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1779 (high:SI (match_operand 2 "" ""))))]
1780 "TARGET_MACHO && !TARGET_64BIT"
1781 "addis %0,%1,ha16(%2)"
1782 [(set_attr "type" "add")])
1784 (define_insn_and_split "*add<mode>3_dot"
1785 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1786 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1787 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1789 (clobber (match_scratch:GPR 0 "=r,r"))]
1790 "<MODE>mode == Pmode"
1794 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1796 (plus:GPR (match_dup 1)
1799 (compare:CC (match_dup 0)
1802 [(set_attr "type" "add")
1803 (set_attr "dot" "yes")
1804 (set_attr "length" "4,8")])
1806 (define_insn_and_split "*add<mode>3_dot2"
1807 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1808 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1809 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1811 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1812 (plus:GPR (match_dup 1)
1814 "<MODE>mode == Pmode"
1818 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1820 (plus:GPR (match_dup 1)
1823 (compare:CC (match_dup 0)
1826 [(set_attr "type" "add")
1827 (set_attr "dot" "yes")
1828 (set_attr "length" "4,8")])
1830 (define_insn_and_split "*add<mode>3_imm_dot"
1831 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1832 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1833 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1835 (clobber (match_scratch:GPR 0 "=r,r"))
1836 (clobber (reg:GPR CA_REGNO))]
1837 "<MODE>mode == Pmode"
1841 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1843 (plus:GPR (match_dup 1)
1846 (compare:CC (match_dup 0)
1849 [(set_attr "type" "add")
1850 (set_attr "dot" "yes")
1851 (set_attr "length" "4,8")])
1853 (define_insn_and_split "*add<mode>3_imm_dot2"
1854 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1855 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1856 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1858 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1859 (plus:GPR (match_dup 1)
1861 (clobber (reg:GPR CA_REGNO))]
1862 "<MODE>mode == Pmode"
1866 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1868 (plus:GPR (match_dup 1)
1871 (compare:CC (match_dup 0)
1874 [(set_attr "type" "add")
1875 (set_attr "dot" "yes")
1876 (set_attr "length" "4,8")])
1878 ;; Split an add that we can't do in one insn into two insns, each of which
1879 ;; does one 16-bit part. This is used by combine. Note that the low-order
1880 ;; add should be last in case the result gets used in an address.
1883 [(set (match_operand:GPR 0 "gpc_reg_operand")
1884 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1885 (match_operand:GPR 2 "non_add_cint_operand")))]
1887 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1888 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1890 HOST_WIDE_INT val = INTVAL (operands[2]);
1891 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1892 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1894 operands[4] = GEN_INT (low);
1895 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1896 operands[3] = GEN_INT (rest);
1897 else if (can_create_pseudo_p ())
1899 operands[3] = gen_reg_rtx (DImode);
1900 emit_move_insn (operands[3], operands[2]);
1901 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1909 (define_insn "add<mode>3_carry"
1910 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1911 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1912 (match_operand:P 2 "reg_or_short_operand" "rI")))
1913 (set (reg:P CA_REGNO)
1914 (ltu:P (plus:P (match_dup 1)
1919 [(set_attr "type" "add")])
1921 (define_insn "*add<mode>3_imm_carry_pos"
1922 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1923 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1924 (match_operand:P 2 "short_cint_operand" "n")))
1925 (set (reg:P CA_REGNO)
1926 (geu:P (match_dup 1)
1927 (match_operand:P 3 "const_int_operand" "n")))]
1928 "INTVAL (operands[2]) > 0
1929 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1931 [(set_attr "type" "add")])
1933 (define_insn "*add<mode>3_imm_carry_0"
1934 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1935 (match_operand:P 1 "gpc_reg_operand" "r"))
1936 (set (reg:P CA_REGNO)
1940 [(set_attr "type" "add")])
1942 (define_insn "*add<mode>3_imm_carry_m1"
1943 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1944 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1946 (set (reg:P CA_REGNO)
1951 [(set_attr "type" "add")])
1953 (define_insn "*add<mode>3_imm_carry_neg"
1954 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1955 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1956 (match_operand:P 2 "short_cint_operand" "n")))
1957 (set (reg:P CA_REGNO)
1958 (gtu:P (match_dup 1)
1959 (match_operand:P 3 "const_int_operand" "n")))]
1960 "INTVAL (operands[2]) < 0
1961 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1963 [(set_attr "type" "add")])
1966 (define_expand "add<mode>3_carry_in"
1968 (set (match_operand:GPR 0 "gpc_reg_operand")
1969 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1970 (match_operand:GPR 2 "adde_operand"))
1971 (reg:GPR CA_REGNO)))
1972 (clobber (reg:GPR CA_REGNO))])]
1975 if (operands[2] == const0_rtx)
1977 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1980 if (operands[2] == constm1_rtx)
1982 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1987 (define_insn "*add<mode>3_carry_in_internal"
1988 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1989 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1990 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1991 (reg:GPR CA_REGNO)))
1992 (clobber (reg:GPR CA_REGNO))]
1995 [(set_attr "type" "add")])
1997 (define_insn "*add<mode>3_carry_in_internal2"
1998 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1999 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2001 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2002 (clobber (reg:GPR CA_REGNO))]
2005 [(set_attr "type" "add")])
2007 (define_insn "add<mode>3_carry_in_0"
2008 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2009 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2010 (reg:GPR CA_REGNO)))
2011 (clobber (reg:GPR CA_REGNO))]
2014 [(set_attr "type" "add")])
2016 (define_insn "add<mode>3_carry_in_m1"
2017 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2018 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2021 (clobber (reg:GPR CA_REGNO))]
2024 [(set_attr "type" "add")])
2027 (define_expand "one_cmpl<mode>2"
2028 [(set (match_operand:SDI 0 "gpc_reg_operand")
2029 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2032 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2034 rs6000_split_logical (operands, NOT, false, false, false);
2039 (define_insn "*one_cmpl<mode>2"
2040 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2041 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2045 (define_insn_and_split "*one_cmpl<mode>2_dot"
2046 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2047 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2049 (clobber (match_scratch:GPR 0 "=r,r"))]
2050 "<MODE>mode == Pmode"
2054 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2056 (not:GPR (match_dup 1)))
2058 (compare:CC (match_dup 0)
2061 [(set_attr "type" "logical")
2062 (set_attr "dot" "yes")
2063 (set_attr "length" "4,8")])
2065 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2066 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2067 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2069 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2070 (not:GPR (match_dup 1)))]
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")])
2087 (define_expand "sub<mode>3"
2088 [(set (match_operand:SDI 0 "gpc_reg_operand")
2089 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2090 (match_operand:SDI 2 "gpc_reg_operand")))]
2093 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2095 rtx lo0 = gen_lowpart (SImode, operands[0]);
2096 rtx lo1 = gen_lowpart (SImode, operands[1]);
2097 rtx lo2 = gen_lowpart (SImode, operands[2]);
2098 rtx hi0 = gen_highpart (SImode, operands[0]);
2099 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2100 rtx hi2 = gen_highpart (SImode, operands[2]);
2102 if (!reg_or_short_operand (lo1, SImode))
2103 lo1 = force_reg (SImode, lo1);
2104 if (!adde_operand (hi1, SImode))
2105 hi1 = force_reg (SImode, hi1);
2107 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2108 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2112 if (short_cint_operand (operands[1], <MODE>mode))
2114 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2119 (define_insn "*subf<mode>3"
2120 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2121 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2122 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2125 [(set_attr "type" "add")])
2127 (define_insn_and_split "*subf<mode>3_dot"
2128 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2129 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2130 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2132 (clobber (match_scratch:GPR 0 "=r,r"))]
2133 "<MODE>mode == Pmode"
2137 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2139 (minus:GPR (match_dup 2)
2142 (compare:CC (match_dup 0)
2145 [(set_attr "type" "add")
2146 (set_attr "dot" "yes")
2147 (set_attr "length" "4,8")])
2149 (define_insn_and_split "*subf<mode>3_dot2"
2150 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2151 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2152 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2154 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2155 (minus:GPR (match_dup 2)
2157 "<MODE>mode == Pmode"
2161 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2163 (minus:GPR (match_dup 2)
2166 (compare:CC (match_dup 0)
2169 [(set_attr "type" "add")
2170 (set_attr "dot" "yes")
2171 (set_attr "length" "4,8")])
2173 (define_insn "subf<mode>3_imm"
2174 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2175 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2176 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2177 (clobber (reg:GPR CA_REGNO))]
2180 [(set_attr "type" "add")])
2182 (define_insn_and_split "subf<mode>3_carry_dot2"
2183 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2184 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2185 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2187 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2188 (minus:P (match_dup 2)
2190 (set (reg:P CA_REGNO)
2191 (leu:P (match_dup 1)
2193 "<MODE>mode == Pmode"
2197 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2198 [(parallel [(set (match_dup 0)
2199 (minus:P (match_dup 2)
2201 (set (reg:P CA_REGNO)
2202 (leu:P (match_dup 1)
2205 (compare:CC (match_dup 0)
2208 [(set_attr "type" "add")
2209 (set_attr "dot" "yes")
2210 (set_attr "length" "4,8")])
2212 (define_insn "subf<mode>3_carry"
2213 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2214 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2215 (match_operand:P 1 "gpc_reg_operand" "r")))
2216 (set (reg:P CA_REGNO)
2217 (leu:P (match_dup 1)
2221 [(set_attr "type" "add")])
2223 (define_insn "*subf<mode>3_imm_carry_0"
2224 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2225 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2226 (set (reg:P CA_REGNO)
2231 [(set_attr "type" "add")])
2233 (define_insn "*subf<mode>3_imm_carry_m1"
2234 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2235 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2236 (set (reg:P CA_REGNO)
2240 [(set_attr "type" "add")])
2243 (define_expand "subf<mode>3_carry_in"
2245 (set (match_operand:GPR 0 "gpc_reg_operand")
2246 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2248 (match_operand:GPR 2 "adde_operand")))
2249 (clobber (reg:GPR CA_REGNO))])]
2252 if (operands[2] == const0_rtx)
2254 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2257 if (operands[2] == constm1_rtx)
2259 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2264 (define_insn "*subf<mode>3_carry_in_internal"
2265 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2266 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2268 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2269 (clobber (reg:GPR CA_REGNO))]
2272 [(set_attr "type" "add")])
2274 (define_insn "subf<mode>3_carry_in_0"
2275 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2276 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2277 (reg:GPR CA_REGNO)))
2278 (clobber (reg:GPR CA_REGNO))]
2281 [(set_attr "type" "add")])
2283 (define_insn "subf<mode>3_carry_in_m1"
2284 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2285 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2286 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2288 (clobber (reg:GPR CA_REGNO))]
2291 [(set_attr "type" "add")])
2293 (define_insn "subf<mode>3_carry_in_xx"
2294 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2295 (plus:GPR (reg:GPR CA_REGNO)
2297 (clobber (reg:GPR CA_REGNO))]
2300 [(set_attr "type" "add")])
2303 (define_insn "@neg<mode>2"
2304 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2305 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2308 [(set_attr "type" "add")])
2310 (define_insn_and_split "*neg<mode>2_dot"
2311 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2312 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2314 (clobber (match_scratch:GPR 0 "=r,r"))]
2315 "<MODE>mode == Pmode"
2319 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2321 (neg:GPR (match_dup 1)))
2323 (compare:CC (match_dup 0)
2326 [(set_attr "type" "add")
2327 (set_attr "dot" "yes")
2328 (set_attr "length" "4,8")])
2330 (define_insn_and_split "*neg<mode>2_dot2"
2331 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2332 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2334 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2335 (neg:GPR (match_dup 1)))]
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")])
2352 (define_insn "clz<mode>2"
2353 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2354 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2357 [(set_attr "type" "cntlz")])
2359 (define_expand "ctz<mode>2"
2360 [(set (match_operand:GPR 0 "gpc_reg_operand")
2361 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2366 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2370 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2371 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2372 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2376 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2377 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2378 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2379 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2383 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2384 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2385 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2386 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2392 (define_insn "ctz<mode>2_hw"
2393 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2394 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2397 [(set_attr "type" "cntlz")])
2399 (define_expand "ffs<mode>2"
2400 [(set (match_operand:GPR 0 "gpc_reg_operand")
2401 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2404 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2405 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2406 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2407 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2408 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2409 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2410 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2415 (define_expand "popcount<mode>2"
2416 [(set (match_operand:GPR 0 "gpc_reg_operand")
2417 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2418 "TARGET_POPCNTB || TARGET_POPCNTD"
2420 rs6000_emit_popcount (operands[0], operands[1]);
2424 (define_insn "popcntb<mode>2"
2425 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2426 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2430 [(set_attr "type" "popcnt")])
2432 (define_insn "popcntd<mode>2"
2433 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2434 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2437 [(set_attr "type" "popcnt")])
2440 (define_expand "parity<mode>2"
2441 [(set (match_operand:GPR 0 "gpc_reg_operand")
2442 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2445 rs6000_emit_parity (operands[0], operands[1]);
2449 (define_insn "parity<mode>2_cmpb"
2450 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2451 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2452 "TARGET_CMPB && TARGET_POPCNTB"
2454 [(set_attr "type" "popcnt")])
2456 (define_insn "cmpb<mode>3"
2457 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2458 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2459 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2462 [(set_attr "type" "cmp")])
2464 ;; Since the hardware zeros the upper part of the register, save generating the
2465 ;; AND immediate if we are converting to unsigned
2466 (define_insn "*bswap<mode>2_extenddi"
2467 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2469 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2472 [(set_attr "type" "load")])
2474 (define_insn "*bswaphi2_extendsi"
2475 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2477 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2480 [(set_attr "type" "load")])
2482 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2483 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2484 ;; load with byte swap, which can be slower than doing it in the registers. It
2485 ;; also prevents certain failures with the RELOAD register allocator.
2487 (define_expand "bswap<mode>2"
2488 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2489 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2492 rtx dest = operands[0];
2493 rtx src = operands[1];
2495 if (!REG_P (dest) && !REG_P (src))
2496 src = force_reg (<MODE>mode, src);
2500 src = rs6000_force_indexed_or_indirect_mem (src);
2501 emit_insn (gen_bswap<mode>2_load (dest, src));
2503 else if (MEM_P (dest))
2505 dest = rs6000_force_indexed_or_indirect_mem (dest);
2506 emit_insn (gen_bswap<mode>2_store (dest, src));
2509 emit_insn (gen_bswap<mode>2_reg (dest, src));
2513 (define_insn "bswap<mode>2_load"
2514 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2515 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2518 [(set_attr "type" "load")])
2520 (define_insn "bswap<mode>2_store"
2521 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2522 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2525 [(set_attr "type" "store")])
2527 (define_insn_and_split "bswaphi2_reg"
2528 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2530 (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2531 (clobber (match_scratch:SI 2 "=&r,X"))]
2536 "reload_completed && int_reg_operand (operands[0], HImode)"
2538 (and:SI (lshiftrt:SI (match_dup 4)
2542 (and:SI (ashift:SI (match_dup 4)
2544 (const_int 65280))) ;; 0xff00
2546 (ior:SI (match_dup 3)
2549 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2550 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2552 [(set_attr "length" "12,4")
2553 (set_attr "type" "*,vecperm")
2554 (set_attr "isa" "*,p9v")])
2556 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2557 ;; zero_extract insns do not change for -mlittle.
2558 (define_insn_and_split "bswapsi2_reg"
2559 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2561 (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2566 "reload_completed && int_reg_operand (operands[0], SImode)"
2567 [(set (match_dup 0) ; DABC
2568 (rotate:SI (match_dup 1)
2570 (set (match_dup 0) ; DCBC
2571 (ior:SI (and:SI (ashift:SI (match_dup 1)
2573 (const_int 16711680))
2574 (and:SI (match_dup 0)
2575 (const_int -16711681))))
2576 (set (match_dup 0) ; DCBA
2577 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2580 (and:SI (match_dup 0)
2581 (const_int -256))))]
2583 [(set_attr "length" "12,4")
2584 (set_attr "type" "*,vecperm")
2585 (set_attr "isa" "*,p9v")])
2587 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2588 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2591 (define_expand "bswapdi2"
2592 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2594 (match_operand:DI 1 "reg_or_mem_operand")))
2595 (clobber (match_scratch:DI 2))
2596 (clobber (match_scratch:DI 3))])]
2599 rtx dest = operands[0];
2600 rtx src = operands[1];
2602 if (!REG_P (dest) && !REG_P (src))
2603 operands[1] = src = force_reg (DImode, src);
2605 if (TARGET_POWERPC64 && TARGET_LDBRX)
2609 src = rs6000_force_indexed_or_indirect_mem (src);
2610 emit_insn (gen_bswapdi2_load (dest, src));
2612 else if (MEM_P (dest))
2614 dest = rs6000_force_indexed_or_indirect_mem (dest);
2615 emit_insn (gen_bswapdi2_store (dest, src));
2617 else if (TARGET_P9_VECTOR)
2618 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2620 emit_insn (gen_bswapdi2_reg (dest, src));
2624 if (!TARGET_POWERPC64)
2626 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2627 that uses 64-bit registers needs the same scratch registers as 64-bit
2629 emit_insn (gen_bswapdi2_32bit (dest, src));
2634 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2635 (define_insn "bswapdi2_load"
2636 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2637 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2638 "TARGET_POWERPC64 && TARGET_LDBRX"
2640 [(set_attr "type" "load")])
2642 (define_insn "bswapdi2_store"
2643 [(set (match_operand:DI 0 "memory_operand" "=Z")
2644 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2645 "TARGET_POWERPC64 && TARGET_LDBRX"
2647 [(set_attr "type" "store")])
2649 (define_insn "bswapdi2_xxbrd"
2650 [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2651 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2654 [(set_attr "type" "vecperm")
2655 (set_attr "isa" "p9v")])
2657 (define_insn "bswapdi2_reg"
2658 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2659 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2660 (clobber (match_scratch:DI 2 "=&r"))
2661 (clobber (match_scratch:DI 3 "=&r"))]
2662 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2664 [(set_attr "length" "36")])
2666 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2667 (define_insn "*bswapdi2_64bit"
2668 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2669 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2670 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2671 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2672 "TARGET_POWERPC64 && !TARGET_LDBRX
2673 && (REG_P (operands[0]) || REG_P (operands[1]))
2674 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2675 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2677 [(set_attr "length" "16,12,36")])
2680 [(set (match_operand:DI 0 "gpc_reg_operand")
2681 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2682 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2683 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2684 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2687 rtx dest = operands[0];
2688 rtx src = operands[1];
2689 rtx op2 = operands[2];
2690 rtx op3 = operands[3];
2691 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2692 BYTES_BIG_ENDIAN ? 4 : 0);
2693 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2694 BYTES_BIG_ENDIAN ? 4 : 0);
2700 addr1 = XEXP (src, 0);
2701 if (GET_CODE (addr1) == PLUS)
2703 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2704 if (TARGET_AVOID_XFORM)
2706 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2710 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2712 else if (TARGET_AVOID_XFORM)
2714 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2719 emit_move_insn (op2, GEN_INT (4));
2720 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2723 word1 = change_address (src, SImode, addr1);
2724 word2 = change_address (src, SImode, addr2);
2726 if (BYTES_BIG_ENDIAN)
2728 emit_insn (gen_bswapsi2 (op3_32, word2));
2729 emit_insn (gen_bswapsi2 (dest_32, word1));
2733 emit_insn (gen_bswapsi2 (op3_32, word1));
2734 emit_insn (gen_bswapsi2 (dest_32, word2));
2737 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2738 emit_insn (gen_iordi3 (dest, dest, op3));
2743 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2744 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2745 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2746 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2747 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2750 rtx dest = operands[0];
2751 rtx src = operands[1];
2752 rtx op2 = operands[2];
2753 rtx op3 = operands[3];
2754 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2755 BYTES_BIG_ENDIAN ? 4 : 0);
2756 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2757 BYTES_BIG_ENDIAN ? 4 : 0);
2763 addr1 = XEXP (dest, 0);
2764 if (GET_CODE (addr1) == PLUS)
2766 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2767 if (TARGET_AVOID_XFORM)
2769 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2773 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2775 else if (TARGET_AVOID_XFORM)
2777 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2782 emit_move_insn (op2, GEN_INT (4));
2783 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2786 word1 = change_address (dest, SImode, addr1);
2787 word2 = change_address (dest, SImode, addr2);
2789 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2791 if (BYTES_BIG_ENDIAN)
2793 emit_insn (gen_bswapsi2 (word1, src_si));
2794 emit_insn (gen_bswapsi2 (word2, op3_si));
2798 emit_insn (gen_bswapsi2 (word2, src_si));
2799 emit_insn (gen_bswapsi2 (word1, op3_si));
2805 [(set (match_operand:DI 0 "gpc_reg_operand")
2806 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2807 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2808 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2809 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2812 rtx dest = operands[0];
2813 rtx src = operands[1];
2814 rtx op2 = operands[2];
2815 rtx op3 = operands[3];
2816 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2817 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2818 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2819 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2820 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2822 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2823 emit_insn (gen_bswapsi2 (dest_si, src_si));
2824 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2825 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2826 emit_insn (gen_iordi3 (dest, dest, op3));
2830 (define_insn "bswapdi2_32bit"
2831 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2832 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2833 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2834 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2836 [(set_attr "length" "16,12,36")])
2839 [(set (match_operand:DI 0 "gpc_reg_operand")
2840 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2841 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2842 "!TARGET_POWERPC64 && reload_completed"
2845 rtx dest = operands[0];
2846 rtx src = operands[1];
2847 rtx op2 = operands[2];
2848 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2849 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2855 addr1 = XEXP (src, 0);
2856 if (GET_CODE (addr1) == PLUS)
2858 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2859 if (TARGET_AVOID_XFORM
2860 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2862 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2866 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2868 else if (TARGET_AVOID_XFORM
2869 || REGNO (addr1) == REGNO (dest2))
2871 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2876 emit_move_insn (op2, GEN_INT (4));
2877 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2880 word1 = change_address (src, SImode, addr1);
2881 word2 = change_address (src, SImode, addr2);
2883 emit_insn (gen_bswapsi2 (dest2, word1));
2884 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2885 thus allowing us to omit an early clobber on the output. */
2886 emit_insn (gen_bswapsi2 (dest1, word2));
2891 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2892 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2893 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2894 "!TARGET_POWERPC64 && reload_completed"
2897 rtx dest = operands[0];
2898 rtx src = operands[1];
2899 rtx op2 = operands[2];
2900 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2901 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2907 addr1 = XEXP (dest, 0);
2908 if (GET_CODE (addr1) == PLUS)
2910 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2911 if (TARGET_AVOID_XFORM)
2913 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2917 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2919 else if (TARGET_AVOID_XFORM)
2921 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2926 emit_move_insn (op2, GEN_INT (4));
2927 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2930 word1 = change_address (dest, SImode, addr1);
2931 word2 = change_address (dest, SImode, addr2);
2933 emit_insn (gen_bswapsi2 (word2, src1));
2934 emit_insn (gen_bswapsi2 (word1, src2));
2939 [(set (match_operand:DI 0 "gpc_reg_operand")
2940 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2941 (clobber (match_operand:SI 2 ""))]
2942 "!TARGET_POWERPC64 && reload_completed"
2945 rtx dest = operands[0];
2946 rtx src = operands[1];
2947 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2948 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2949 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2950 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2952 emit_insn (gen_bswapsi2 (dest1, src2));
2953 emit_insn (gen_bswapsi2 (dest2, src1));
2958 (define_insn "mul<mode>3"
2959 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2960 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2961 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2966 [(set_attr "type" "mul")
2968 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2970 (match_operand:GPR 2 "short_cint_operand")
2971 (const_string "16")]
2972 (const_string "<bits>")))])
2974 (define_insn_and_split "*mul<mode>3_dot"
2975 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2976 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2977 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2979 (clobber (match_scratch:GPR 0 "=r,r"))]
2980 "<MODE>mode == Pmode"
2984 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2986 (mult:GPR (match_dup 1)
2989 (compare:CC (match_dup 0)
2992 [(set_attr "type" "mul")
2993 (set_attr "size" "<bits>")
2994 (set_attr "dot" "yes")
2995 (set_attr "length" "4,8")])
2997 (define_insn_and_split "*mul<mode>3_dot2"
2998 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2999 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3000 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3002 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3003 (mult:GPR (match_dup 1)
3005 "<MODE>mode == Pmode"
3009 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3011 (mult:GPR (match_dup 1)
3014 (compare:CC (match_dup 0)
3017 [(set_attr "type" "mul")
3018 (set_attr "size" "<bits>")
3019 (set_attr "dot" "yes")
3020 (set_attr "length" "4,8")])
3023 (define_expand "<su>mul<mode>3_highpart"
3024 [(set (match_operand:GPR 0 "gpc_reg_operand")
3026 (mult:<DMODE> (any_extend:<DMODE>
3027 (match_operand:GPR 1 "gpc_reg_operand"))
3029 (match_operand:GPR 2 "gpc_reg_operand")))
3033 if (<MODE>mode == SImode && TARGET_POWERPC64)
3035 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3040 if (!WORDS_BIG_ENDIAN)
3042 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3048 (define_insn "*<su>mul<mode>3_highpart"
3049 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3051 (mult:<DMODE> (any_extend:<DMODE>
3052 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3054 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3056 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3057 "mulh<wd><u> %0,%1,%2"
3058 [(set_attr "type" "mul")
3059 (set_attr "size" "<bits>")])
3061 (define_insn "<su>mulsi3_highpart_le"
3062 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3064 (mult:DI (any_extend:DI
3065 (match_operand:SI 1 "gpc_reg_operand" "r"))
3067 (match_operand:SI 2 "gpc_reg_operand" "r")))
3069 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3071 [(set_attr "type" "mul")])
3073 (define_insn "<su>muldi3_highpart_le"
3074 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3076 (mult:TI (any_extend:TI
3077 (match_operand:DI 1 "gpc_reg_operand" "r"))
3079 (match_operand:DI 2 "gpc_reg_operand" "r")))
3081 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3083 [(set_attr "type" "mul")
3084 (set_attr "size" "64")])
3086 (define_insn "<su>mulsi3_highpart_64"
3087 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3090 (mult:DI (any_extend:DI
3091 (match_operand:SI 1 "gpc_reg_operand" "r"))
3093 (match_operand:SI 2 "gpc_reg_operand" "r")))
3097 [(set_attr "type" "mul")])
3099 (define_expand "<u>mul<mode><dmode>3"
3100 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3101 (mult:<DMODE> (any_extend:<DMODE>
3102 (match_operand:GPR 1 "gpc_reg_operand"))
3104 (match_operand:GPR 2 "gpc_reg_operand"))))]
3105 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3107 rtx l = gen_reg_rtx (<MODE>mode);
3108 rtx h = gen_reg_rtx (<MODE>mode);
3109 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3110 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3111 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3112 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3116 (define_insn "*maddld<mode>4"
3117 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3118 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3119 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3120 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3122 "maddld %0,%1,%2,%3"
3123 [(set_attr "type" "mul")])
3125 (define_insn "udiv<mode>3"
3126 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3127 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3128 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3131 [(set_attr "type" "div")
3132 (set_attr "size" "<bits>")])
3135 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3136 ;; modulus. If it isn't a power of two, force operands into register and do
3138 (define_expand "div<mode>3"
3139 [(set (match_operand:GPR 0 "gpc_reg_operand")
3140 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3141 (match_operand:GPR 2 "reg_or_cint_operand")))]
3144 if (CONST_INT_P (operands[2])
3145 && INTVAL (operands[2]) > 0
3146 && exact_log2 (INTVAL (operands[2])) >= 0)
3148 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3152 operands[2] = force_reg (<MODE>mode, operands[2]);
3155 (define_insn "*div<mode>3"
3156 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3157 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3158 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3161 [(set_attr "type" "div")
3162 (set_attr "size" "<bits>")])
3164 (define_insn "div<mode>3_sra"
3165 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3166 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3167 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3168 (clobber (reg:GPR CA_REGNO))]
3170 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3171 [(set_attr "type" "two")
3172 (set_attr "length" "8")])
3174 (define_insn_and_split "*div<mode>3_sra_dot"
3175 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3176 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3177 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3179 (clobber (match_scratch:GPR 0 "=r,r"))
3180 (clobber (reg:GPR CA_REGNO))]
3181 "<MODE>mode == Pmode"
3183 sra<wd>i %0,%1,%p2\;addze. %0,%0
3185 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3186 [(parallel [(set (match_dup 0)
3187 (div:GPR (match_dup 1)
3189 (clobber (reg:GPR CA_REGNO))])
3191 (compare:CC (match_dup 0)
3194 [(set_attr "type" "two")
3195 (set_attr "length" "8,12")
3196 (set_attr "cell_micro" "not")])
3198 (define_insn_and_split "*div<mode>3_sra_dot2"
3199 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3200 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3201 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3203 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3204 (div:GPR (match_dup 1)
3206 (clobber (reg:GPR CA_REGNO))]
3207 "<MODE>mode == Pmode"
3209 sra<wd>i %0,%1,%p2\;addze. %0,%0
3211 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3212 [(parallel [(set (match_dup 0)
3213 (div:GPR (match_dup 1)
3215 (clobber (reg:GPR CA_REGNO))])
3217 (compare:CC (match_dup 0)
3220 [(set_attr "type" "two")
3221 (set_attr "length" "8,12")
3222 (set_attr "cell_micro" "not")])
3224 (define_expand "mod<mode>3"
3225 [(set (match_operand:GPR 0 "gpc_reg_operand")
3226 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3227 (match_operand:GPR 2 "reg_or_cint_operand")))]
3234 if (!CONST_INT_P (operands[2])
3235 || INTVAL (operands[2]) <= 0
3236 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3241 operands[2] = force_reg (<MODE>mode, operands[2]);
3245 temp1 = gen_reg_rtx (<MODE>mode);
3246 temp2 = gen_reg_rtx (<MODE>mode);
3248 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3249 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3250 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3255 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3256 ;; mod, prefer putting the result of mod into a different register
3257 (define_insn "*mod<mode>3"
3258 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3259 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3260 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3263 [(set_attr "type" "div")
3264 (set_attr "size" "<bits>")])
3267 (define_insn "umod<mode>3"
3268 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3269 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3270 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3273 [(set_attr "type" "div")
3274 (set_attr "size" "<bits>")])
3276 ;; On machines with modulo support, do a combined div/mod the old fashioned
3277 ;; method, since the multiply/subtract is faster than doing the mod instruction
3281 [(set (match_operand:GPR 0 "gpc_reg_operand")
3282 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3283 (match_operand:GPR 2 "gpc_reg_operand")))
3284 (set (match_operand:GPR 3 "gpc_reg_operand")
3285 (mod:GPR (match_dup 1)
3288 && ! reg_mentioned_p (operands[0], operands[1])
3289 && ! reg_mentioned_p (operands[0], operands[2])
3290 && ! reg_mentioned_p (operands[3], operands[1])
3291 && ! reg_mentioned_p (operands[3], operands[2])"
3293 (div:GPR (match_dup 1)
3296 (mult:GPR (match_dup 0)
3299 (minus:GPR (match_dup 1)
3303 [(set (match_operand:GPR 0 "gpc_reg_operand")
3304 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3305 (match_operand:GPR 2 "gpc_reg_operand")))
3306 (set (match_operand:GPR 3 "gpc_reg_operand")
3307 (umod:GPR (match_dup 1)
3310 && ! reg_mentioned_p (operands[0], operands[1])
3311 && ! reg_mentioned_p (operands[0], operands[2])
3312 && ! reg_mentioned_p (operands[3], operands[1])
3313 && ! reg_mentioned_p (operands[3], operands[2])"
3315 (udiv:GPR (match_dup 1)
3318 (mult:GPR (match_dup 0)
3321 (minus:GPR (match_dup 1)
3325 ;; Logical instructions
3326 ;; The logical instructions are mostly combined by using match_operator,
3327 ;; but the plain AND insns are somewhat different because there is no
3328 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3329 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3331 (define_expand "and<mode>3"
3332 [(set (match_operand:SDI 0 "gpc_reg_operand")
3333 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3334 (match_operand:SDI 2 "reg_or_cint_operand")))]
3337 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3339 rs6000_split_logical (operands, AND, false, false, false);
3343 if (CONST_INT_P (operands[2]))
3345 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3347 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3351 if (logical_const_operand (operands[2], <MODE>mode))
3353 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3357 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3359 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3363 operands[2] = force_reg (<MODE>mode, operands[2]);
3368 (define_insn "and<mode>3_imm"
3369 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3370 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3371 (match_operand:GPR 2 "logical_const_operand" "n")))
3372 (clobber (match_scratch:CC 3 "=x"))]
3373 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3374 "andi%e2. %0,%1,%u2"
3375 [(set_attr "type" "logical")
3376 (set_attr "dot" "yes")])
3378 (define_insn_and_split "*and<mode>3_imm_dot"
3379 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3380 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3381 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3383 (clobber (match_scratch:GPR 0 "=r,r"))
3384 (clobber (match_scratch:CC 4 "=X,x"))]
3385 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3386 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3390 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3391 [(parallel [(set (match_dup 0)
3392 (and:GPR (match_dup 1)
3394 (clobber (match_dup 4))])
3396 (compare:CC (match_dup 0)
3399 [(set_attr "type" "logical")
3400 (set_attr "dot" "yes")
3401 (set_attr "length" "4,8")])
3403 (define_insn_and_split "*and<mode>3_imm_dot2"
3404 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3405 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3406 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3408 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3409 (and:GPR (match_dup 1)
3411 (clobber (match_scratch:CC 4 "=X,x"))]
3412 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3413 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3417 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3418 [(parallel [(set (match_dup 0)
3419 (and:GPR (match_dup 1)
3421 (clobber (match_dup 4))])
3423 (compare:CC (match_dup 0)
3426 [(set_attr "type" "logical")
3427 (set_attr "dot" "yes")
3428 (set_attr "length" "4,8")])
3430 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3431 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3432 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3433 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3435 (clobber (match_scratch:GPR 0 "=r,r"))]
3436 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3437 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3441 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3443 (and:GPR (match_dup 1)
3446 (compare:CC (match_dup 0)
3449 [(set_attr "type" "logical")
3450 (set_attr "dot" "yes")
3451 (set_attr "length" "4,8")])
3453 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3454 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3455 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3456 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3458 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3459 (and:GPR (match_dup 1)
3461 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3462 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3466 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3468 (and:GPR (match_dup 1)
3471 (compare:CC (match_dup 0)
3474 [(set_attr "type" "logical")
3475 (set_attr "dot" "yes")
3476 (set_attr "length" "4,8")])
3478 (define_insn "*and<mode>3_imm_dot_shifted"
3479 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3482 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3483 (match_operand:SI 4 "const_int_operand" "n"))
3484 (match_operand:GPR 2 "const_int_operand" "n"))
3486 (clobber (match_scratch:GPR 0 "=r"))]
3487 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3488 << INTVAL (operands[4])),
3490 && (<MODE>mode == Pmode
3491 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3493 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3494 return "andi%e2. %0,%1,%u2";
3496 [(set_attr "type" "logical")
3497 (set_attr "dot" "yes")])
3500 (define_insn "and<mode>3_mask"
3501 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3502 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3503 (match_operand:GPR 2 "const_int_operand" "n")))]
3504 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3506 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3508 [(set_attr "type" "shift")])
3510 (define_insn_and_split "*and<mode>3_mask_dot"
3511 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3512 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3513 (match_operand:GPR 2 "const_int_operand" "n,n"))
3515 (clobber (match_scratch:GPR 0 "=r,r"))]
3516 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3517 && !logical_const_operand (operands[2], <MODE>mode)
3518 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3520 if (which_alternative == 0)
3521 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3525 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3527 (and:GPR (match_dup 1)
3530 (compare:CC (match_dup 0)
3533 [(set_attr "type" "shift")
3534 (set_attr "dot" "yes")
3535 (set_attr "length" "4,8")])
3537 (define_insn_and_split "*and<mode>3_mask_dot2"
3538 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3539 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3540 (match_operand:GPR 2 "const_int_operand" "n,n"))
3542 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3543 (and:GPR (match_dup 1)
3545 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3546 && !logical_const_operand (operands[2], <MODE>mode)
3547 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3549 if (which_alternative == 0)
3550 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3554 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3556 (and:GPR (match_dup 1)
3559 (compare:CC (match_dup 0)
3562 [(set_attr "type" "shift")
3563 (set_attr "dot" "yes")
3564 (set_attr "length" "4,8")])
3567 (define_insn_and_split "*and<mode>3_2insn"
3568 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3569 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3570 (match_operand:GPR 2 "const_int_operand" "n")))]
3571 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3572 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3573 || logical_const_operand (operands[2], <MODE>mode))"
3578 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3581 [(set_attr "type" "shift")
3582 (set_attr "length" "8")])
3584 (define_insn_and_split "*and<mode>3_2insn_dot"
3585 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3586 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3587 (match_operand:GPR 2 "const_int_operand" "n,n"))
3589 (clobber (match_scratch:GPR 0 "=r,r"))]
3590 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3591 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3592 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3593 || logical_const_operand (operands[2], <MODE>mode))"
3595 "&& reload_completed"
3598 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3601 [(set_attr "type" "shift")
3602 (set_attr "dot" "yes")
3603 (set_attr "length" "8,12")])
3605 (define_insn_and_split "*and<mode>3_2insn_dot2"
3606 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3607 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3608 (match_operand:GPR 2 "const_int_operand" "n,n"))
3610 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3611 (and:GPR (match_dup 1)
3613 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3614 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3615 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3616 || logical_const_operand (operands[2], <MODE>mode))"
3618 "&& reload_completed"
3621 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3624 [(set_attr "type" "shift")
3625 (set_attr "dot" "yes")
3626 (set_attr "length" "8,12")])
3629 (define_expand "<code><mode>3"
3630 [(set (match_operand:SDI 0 "gpc_reg_operand")
3631 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3632 (match_operand:SDI 2 "reg_or_cint_operand")))]
3635 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3637 rs6000_split_logical (operands, <CODE>, false, false, false);
3641 if (non_logical_cint_operand (operands[2], <MODE>mode))
3643 rtx tmp = ((!can_create_pseudo_p ()
3644 || rtx_equal_p (operands[0], operands[1]))
3645 ? operands[0] : gen_reg_rtx (<MODE>mode));
3647 HOST_WIDE_INT value = INTVAL (operands[2]);
3648 HOST_WIDE_INT lo = value & 0xffff;
3649 HOST_WIDE_INT hi = value - lo;
3651 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3652 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3656 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3657 operands[2] = force_reg (<MODE>mode, operands[2]);
3661 [(set (match_operand:GPR 0 "gpc_reg_operand")
3662 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3663 (match_operand:GPR 2 "non_logical_cint_operand")))]
3666 (iorxor:GPR (match_dup 1)
3669 (iorxor:GPR (match_dup 3)
3672 operands[3] = ((!can_create_pseudo_p ()
3673 || rtx_equal_p (operands[0], operands[1]))
3674 ? operands[0] : gen_reg_rtx (<MODE>mode));
3676 HOST_WIDE_INT value = INTVAL (operands[2]);
3677 HOST_WIDE_INT lo = value & 0xffff;
3678 HOST_WIDE_INT hi = value - lo;
3680 operands[4] = GEN_INT (hi);
3681 operands[5] = GEN_INT (lo);
3684 (define_insn "*bool<mode>3_imm"
3685 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3686 (match_operator:GPR 3 "boolean_or_operator"
3687 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3688 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3691 [(set_attr "type" "logical")])
3693 (define_insn "*bool<mode>3"
3694 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3695 (match_operator:GPR 3 "boolean_operator"
3696 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3697 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3700 [(set_attr "type" "logical")])
3702 (define_insn_and_split "*bool<mode>3_dot"
3703 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3704 (compare:CC (match_operator:GPR 3 "boolean_operator"
3705 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3706 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3708 (clobber (match_scratch:GPR 0 "=r,r"))]
3709 "<MODE>mode == Pmode"
3713 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3717 (compare:CC (match_dup 0)
3720 [(set_attr "type" "logical")
3721 (set_attr "dot" "yes")
3722 (set_attr "length" "4,8")])
3724 (define_insn_and_split "*bool<mode>3_dot2"
3725 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3726 (compare:CC (match_operator:GPR 3 "boolean_operator"
3727 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3728 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3730 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3732 "<MODE>mode == Pmode"
3736 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3740 (compare:CC (match_dup 0)
3743 [(set_attr "type" "logical")
3744 (set_attr "dot" "yes")
3745 (set_attr "length" "4,8")])
3748 (define_insn "*boolc<mode>3"
3749 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3750 (match_operator:GPR 3 "boolean_operator"
3751 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3752 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3755 [(set_attr "type" "logical")])
3757 (define_insn_and_split "*boolc<mode>3_dot"
3758 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3759 (compare:CC (match_operator:GPR 3 "boolean_operator"
3760 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3761 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3763 (clobber (match_scratch:GPR 0 "=r,r"))]
3764 "<MODE>mode == Pmode"
3768 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3772 (compare:CC (match_dup 0)
3775 [(set_attr "type" "logical")
3776 (set_attr "dot" "yes")
3777 (set_attr "length" "4,8")])
3779 (define_insn_and_split "*boolc<mode>3_dot2"
3780 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3781 (compare:CC (match_operator:GPR 3 "boolean_operator"
3782 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3783 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3785 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3787 "<MODE>mode == Pmode"
3791 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3795 (compare:CC (match_dup 0)
3798 [(set_attr "type" "logical")
3799 (set_attr "dot" "yes")
3800 (set_attr "length" "4,8")])
3803 (define_insn "*boolcc<mode>3"
3804 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3805 (match_operator:GPR 3 "boolean_operator"
3806 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3807 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3810 [(set_attr "type" "logical")])
3812 (define_insn_and_split "*boolcc<mode>3_dot"
3813 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3814 (compare:CC (match_operator:GPR 3 "boolean_operator"
3815 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3816 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3818 (clobber (match_scratch:GPR 0 "=r,r"))]
3819 "<MODE>mode == Pmode"
3823 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3827 (compare:CC (match_dup 0)
3830 [(set_attr "type" "logical")
3831 (set_attr "dot" "yes")
3832 (set_attr "length" "4,8")])
3834 (define_insn_and_split "*boolcc<mode>3_dot2"
3835 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3836 (compare:CC (match_operator:GPR 3 "boolean_operator"
3837 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3838 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3840 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3842 "<MODE>mode == Pmode"
3846 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3850 (compare:CC (match_dup 0)
3853 [(set_attr "type" "logical")
3854 (set_attr "dot" "yes")
3855 (set_attr "length" "4,8")])
3858 ;; TODO: Should have dots of this as well.
3859 (define_insn "*eqv<mode>3"
3860 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3861 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3862 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3865 [(set_attr "type" "logical")])
3867 ;; Rotate-and-mask and insert.
3869 (define_insn "*rotl<mode>3_mask"
3870 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3871 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3872 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3873 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3874 (match_operand:GPR 3 "const_int_operand" "n")))]
3875 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3877 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3879 [(set_attr "type" "shift")
3880 (set_attr "maybe_var_shift" "yes")])
3882 (define_insn_and_split "*rotl<mode>3_mask_dot"
3883 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3885 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3886 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3887 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3888 (match_operand:GPR 3 "const_int_operand" "n,n"))
3890 (clobber (match_scratch:GPR 0 "=r,r"))]
3891 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3892 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3894 if (which_alternative == 0)
3895 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3899 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3901 (and:GPR (match_dup 4)
3904 (compare:CC (match_dup 0)
3907 [(set_attr "type" "shift")
3908 (set_attr "maybe_var_shift" "yes")
3909 (set_attr "dot" "yes")
3910 (set_attr "length" "4,8")])
3912 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3913 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3915 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3916 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3917 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3918 (match_operand:GPR 3 "const_int_operand" "n,n"))
3920 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3921 (and:GPR (match_dup 4)
3923 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3924 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3926 if (which_alternative == 0)
3927 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3931 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3933 (and:GPR (match_dup 4)
3936 (compare:CC (match_dup 0)
3939 [(set_attr "type" "shift")
3940 (set_attr "maybe_var_shift" "yes")
3941 (set_attr "dot" "yes")
3942 (set_attr "length" "4,8")])
3944 ; Special case for less-than-0. We can do it with just one machine
3945 ; instruction, but the generic optimizers do not realise it is cheap.
3946 (define_insn "*lt0_<mode>di"
3947 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3948 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3952 [(set_attr "type" "shift")])
3954 (define_insn "*lt0_<mode>si"
3955 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3956 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3959 "rlwinm %0,%1,1,31,31"
3960 [(set_attr "type" "shift")])
3964 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3965 ; both are an AND so are the same precedence).
3966 (define_insn "*rotl<mode>3_insert"
3967 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3968 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3969 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3970 (match_operand:SI 2 "const_int_operand" "n")])
3971 (match_operand:GPR 3 "const_int_operand" "n"))
3972 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3973 (match_operand:GPR 6 "const_int_operand" "n"))))]
3974 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3975 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3977 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3979 [(set_attr "type" "insert")])
3980 ; FIXME: this needs an attr "size", so that the scheduler can see the
3981 ; difference between rlwimi and rldimi. We also might want dot forms,
3982 ; but not for rlwimi on POWER4 and similar processors.
3984 (define_insn "*rotl<mode>3_insert_2"
3985 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3986 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3987 (match_operand:GPR 6 "const_int_operand" "n"))
3988 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3989 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3990 (match_operand:SI 2 "const_int_operand" "n")])
3991 (match_operand:GPR 3 "const_int_operand" "n"))))]
3992 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3993 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3995 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3997 [(set_attr "type" "insert")])
3999 ; There are also some forms without one of the ANDs.
4000 (define_insn "*rotl<mode>3_insert_3"
4001 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4002 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4003 (match_operand:GPR 4 "const_int_operand" "n"))
4004 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4005 (match_operand:SI 2 "const_int_operand" "n"))))]
4006 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4008 if (<MODE>mode == SImode)
4009 return "rlwimi %0,%1,%h2,0,31-%h2";
4011 return "rldimi %0,%1,%H2,0";
4013 [(set_attr "type" "insert")])
4015 (define_insn "*rotl<mode>3_insert_4"
4016 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4017 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4018 (match_operand:GPR 4 "const_int_operand" "n"))
4019 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4020 (match_operand:SI 2 "const_int_operand" "n"))))]
4021 "<MODE>mode == SImode &&
4022 GET_MODE_PRECISION (<MODE>mode)
4023 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4025 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4026 - INTVAL (operands[2]));
4027 if (<MODE>mode == SImode)
4028 return "rlwimi %0,%1,%h2,32-%h2,31";
4030 return "rldimi %0,%1,%H2,64-%H2";
4032 [(set_attr "type" "insert")])
4034 (define_insn "*rotlsi3_insert_5"
4035 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4036 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4037 (match_operand:SI 2 "const_int_operand" "n,n"))
4038 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4039 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4040 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4041 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4042 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4046 [(set_attr "type" "insert")])
4048 (define_insn "*rotldi3_insert_6"
4049 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4050 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4051 (match_operand:DI 2 "const_int_operand" "n"))
4052 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4053 (match_operand:DI 4 "const_int_operand" "n"))))]
4054 "exact_log2 (-UINTVAL (operands[2])) > 0
4055 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4057 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4058 return "rldimi %0,%3,0,%5";
4060 [(set_attr "type" "insert")
4061 (set_attr "size" "64")])
4063 (define_insn "*rotldi3_insert_7"
4064 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4065 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4066 (match_operand:DI 4 "const_int_operand" "n"))
4067 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4068 (match_operand:DI 2 "const_int_operand" "n"))))]
4069 "exact_log2 (-UINTVAL (operands[2])) > 0
4070 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4072 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4073 return "rldimi %0,%3,0,%5";
4075 [(set_attr "type" "insert")
4076 (set_attr "size" "64")])
4079 ; This handles the important case of multiple-precision shifts. There is
4080 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4082 [(set (match_operand:GPR 0 "gpc_reg_operand")
4083 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4084 (match_operand:SI 3 "const_int_operand"))
4085 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4086 (match_operand:SI 4 "const_int_operand"))))]
4087 "can_create_pseudo_p ()
4088 && INTVAL (operands[3]) + INTVAL (operands[4])
4089 >= GET_MODE_PRECISION (<MODE>mode)"
4091 (lshiftrt:GPR (match_dup 2)
4094 (ior:GPR (and:GPR (match_dup 5)
4096 (ashift:GPR (match_dup 1)
4099 unsigned HOST_WIDE_INT mask = 1;
4100 mask = (mask << INTVAL (operands[3])) - 1;
4101 operands[5] = gen_reg_rtx (<MODE>mode);
4102 operands[6] = GEN_INT (mask);
4106 [(set (match_operand:GPR 0 "gpc_reg_operand")
4107 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4108 (match_operand:SI 4 "const_int_operand"))
4109 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4110 (match_operand:SI 3 "const_int_operand"))))]
4111 "can_create_pseudo_p ()
4112 && INTVAL (operands[3]) + INTVAL (operands[4])
4113 >= GET_MODE_PRECISION (<MODE>mode)"
4115 (lshiftrt:GPR (match_dup 2)
4118 (ior:GPR (and:GPR (match_dup 5)
4120 (ashift:GPR (match_dup 1)
4123 unsigned HOST_WIDE_INT mask = 1;
4124 mask = (mask << INTVAL (operands[3])) - 1;
4125 operands[5] = gen_reg_rtx (<MODE>mode);
4126 operands[6] = GEN_INT (mask);
4130 ; Another important case is setting some bits to 1; we can do that with
4131 ; an insert instruction, in many cases.
4132 (define_insn_and_split "*ior<mode>_mask"
4133 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4134 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4135 (match_operand:GPR 2 "const_int_operand" "n")))
4136 (clobber (match_scratch:GPR 3 "=r"))]
4137 "!logical_const_operand (operands[2], <MODE>mode)
4138 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4144 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4147 (and:GPR (match_dup 1)
4151 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4152 if (GET_CODE (operands[3]) == SCRATCH)
4153 operands[3] = gen_reg_rtx (<MODE>mode);
4154 operands[4] = GEN_INT (ne);
4155 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4157 [(set_attr "type" "two")
4158 (set_attr "length" "8")])
4161 ; Yet another case is an rldimi with the second value coming from memory.
4162 ; The zero_extend that should become part of the rldimi is merged into the
4163 ; load from memory instead. Split things properly again.
4165 [(set (match_operand:DI 0 "gpc_reg_operand")
4166 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4167 (match_operand:SI 2 "const_int_operand"))
4168 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4169 "INTVAL (operands[2]) == <bits>"
4171 (zero_extend:DI (match_dup 3)))
4173 (ior:DI (and:DI (match_dup 4)
4175 (ashift:DI (match_dup 1)
4178 operands[4] = gen_reg_rtx (DImode);
4179 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4184 [(set (match_operand:SI 0 "gpc_reg_operand")
4185 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4186 (match_operand:SI 2 "const_int_operand"))
4187 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4188 "INTVAL (operands[2]) == <bits>"
4190 (zero_extend:SI (match_dup 3)))
4192 (ior:SI (and:SI (match_dup 4)
4194 (ashift:SI (match_dup 1)
4197 operands[4] = gen_reg_rtx (SImode);
4198 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4202 ;; Now the simple shifts.
4204 (define_insn "rotl<mode>3"
4205 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4206 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4207 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4209 "rotl<wd>%I2 %0,%1,%<hH>2"
4210 [(set_attr "type" "shift")
4211 (set_attr "maybe_var_shift" "yes")])
4213 (define_insn "*rotlsi3_64"
4214 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4216 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4217 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4219 "rotlw%I2 %0,%1,%h2"
4220 [(set_attr "type" "shift")
4221 (set_attr "maybe_var_shift" "yes")])
4223 (define_insn_and_split "*rotl<mode>3_dot"
4224 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4225 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4226 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4228 (clobber (match_scratch:GPR 0 "=r,r"))]
4229 "<MODE>mode == Pmode"
4231 rotl<wd>%I2. %0,%1,%<hH>2
4233 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4235 (rotate:GPR (match_dup 1)
4238 (compare:CC (match_dup 0)
4241 [(set_attr "type" "shift")
4242 (set_attr "maybe_var_shift" "yes")
4243 (set_attr "dot" "yes")
4244 (set_attr "length" "4,8")])
4246 (define_insn_and_split "*rotl<mode>3_dot2"
4247 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4248 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4249 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4251 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4252 (rotate:GPR (match_dup 1)
4254 "<MODE>mode == Pmode"
4256 rotl<wd>%I2. %0,%1,%<hH>2
4258 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4260 (rotate:GPR (match_dup 1)
4263 (compare:CC (match_dup 0)
4266 [(set_attr "type" "shift")
4267 (set_attr "maybe_var_shift" "yes")
4268 (set_attr "dot" "yes")
4269 (set_attr "length" "4,8")])
4272 (define_insn "ashl<mode>3"
4273 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4274 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4275 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4277 "sl<wd>%I2 %0,%1,%<hH>2"
4278 [(set_attr "type" "shift")
4279 (set_attr "maybe_var_shift" "yes")])
4281 (define_insn "*ashlsi3_64"
4282 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4284 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4285 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4288 [(set_attr "type" "shift")
4289 (set_attr "maybe_var_shift" "yes")])
4291 (define_insn_and_split "*ashl<mode>3_dot"
4292 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4293 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4294 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4296 (clobber (match_scratch:GPR 0 "=r,r"))]
4297 "<MODE>mode == Pmode"
4299 sl<wd>%I2. %0,%1,%<hH>2
4301 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4303 (ashift:GPR (match_dup 1)
4306 (compare:CC (match_dup 0)
4309 [(set_attr "type" "shift")
4310 (set_attr "maybe_var_shift" "yes")
4311 (set_attr "dot" "yes")
4312 (set_attr "length" "4,8")])
4314 (define_insn_and_split "*ashl<mode>3_dot2"
4315 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4316 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4317 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4319 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4320 (ashift:GPR (match_dup 1)
4322 "<MODE>mode == Pmode"
4324 sl<wd>%I2. %0,%1,%<hH>2
4326 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4328 (ashift:GPR (match_dup 1)
4331 (compare:CC (match_dup 0)
4334 [(set_attr "type" "shift")
4335 (set_attr "maybe_var_shift" "yes")
4336 (set_attr "dot" "yes")
4337 (set_attr "length" "4,8")])
4339 ;; Pretend we have a memory form of extswsli until register allocation is done
4340 ;; so that we use LWZ to load the value from memory, instead of LWA.
4341 (define_insn_and_split "ashdi3_extswsli"
4342 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4344 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4345 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4350 "&& reload_completed && MEM_P (operands[1])"
4354 (ashift:DI (sign_extend:DI (match_dup 3))
4357 operands[3] = gen_lowpart (SImode, operands[0]);
4359 [(set_attr "type" "shift")
4360 (set_attr "maybe_var_shift" "no")])
4363 (define_insn_and_split "ashdi3_extswsli_dot"
4364 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4367 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4368 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4370 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4377 "&& reload_completed
4378 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4379 || memory_operand (operands[1], SImode))"
4382 rtx dest = operands[0];
4383 rtx src = operands[1];
4384 rtx shift = operands[2];
4385 rtx cr = operands[3];
4392 src2 = gen_lowpart (SImode, dest);
4393 emit_move_insn (src2, src);
4396 if (REGNO (cr) == CR0_REGNO)
4398 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4402 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4403 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4406 [(set_attr "type" "shift")
4407 (set_attr "maybe_var_shift" "no")
4408 (set_attr "dot" "yes")
4409 (set_attr "length" "4,8,8,12")])
4411 (define_insn_and_split "ashdi3_extswsli_dot2"
4412 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4415 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4416 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4418 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4419 (ashift:DI (sign_extend:DI (match_dup 1))
4427 "&& reload_completed
4428 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4429 || memory_operand (operands[1], SImode))"
4432 rtx dest = operands[0];
4433 rtx src = operands[1];
4434 rtx shift = operands[2];
4435 rtx cr = operands[3];
4442 src2 = gen_lowpart (SImode, dest);
4443 emit_move_insn (src2, src);
4446 if (REGNO (cr) == CR0_REGNO)
4448 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4452 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4453 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4456 [(set_attr "type" "shift")
4457 (set_attr "maybe_var_shift" "no")
4458 (set_attr "dot" "yes")
4459 (set_attr "length" "4,8,8,12")])
4461 (define_insn "lshr<mode>3"
4462 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4463 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4464 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4466 "sr<wd>%I2 %0,%1,%<hH>2"
4467 [(set_attr "type" "shift")
4468 (set_attr "maybe_var_shift" "yes")])
4470 (define_insn "*lshrsi3_64"
4471 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4473 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4474 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4477 [(set_attr "type" "shift")
4478 (set_attr "maybe_var_shift" "yes")])
4480 (define_insn_and_split "*lshr<mode>3_dot"
4481 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4482 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4483 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4485 (clobber (match_scratch:GPR 0 "=r,r"))]
4486 "<MODE>mode == Pmode"
4488 sr<wd>%I2. %0,%1,%<hH>2
4490 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4492 (lshiftrt:GPR (match_dup 1)
4495 (compare:CC (match_dup 0)
4498 [(set_attr "type" "shift")
4499 (set_attr "maybe_var_shift" "yes")
4500 (set_attr "dot" "yes")
4501 (set_attr "length" "4,8")])
4503 (define_insn_and_split "*lshr<mode>3_dot2"
4504 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4505 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4506 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4508 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4509 (lshiftrt:GPR (match_dup 1)
4511 "<MODE>mode == Pmode"
4513 sr<wd>%I2. %0,%1,%<hH>2
4515 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4517 (lshiftrt:GPR (match_dup 1)
4520 (compare:CC (match_dup 0)
4523 [(set_attr "type" "shift")
4524 (set_attr "maybe_var_shift" "yes")
4525 (set_attr "dot" "yes")
4526 (set_attr "length" "4,8")])
4529 (define_insn "ashr<mode>3"
4530 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4531 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4532 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4533 (clobber (reg:GPR CA_REGNO))]
4535 "sra<wd>%I2 %0,%1,%<hH>2"
4536 [(set_attr "type" "shift")
4537 (set_attr "maybe_var_shift" "yes")])
4539 (define_insn "*ashrsi3_64"
4540 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4542 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4543 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4544 (clobber (reg:SI CA_REGNO))]
4547 [(set_attr "type" "shift")
4548 (set_attr "maybe_var_shift" "yes")])
4550 (define_insn_and_split "*ashr<mode>3_dot"
4551 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4552 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4553 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4555 (clobber (match_scratch:GPR 0 "=r,r"))
4556 (clobber (reg:GPR CA_REGNO))]
4557 "<MODE>mode == Pmode"
4559 sra<wd>%I2. %0,%1,%<hH>2
4561 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4562 [(parallel [(set (match_dup 0)
4563 (ashiftrt:GPR (match_dup 1)
4565 (clobber (reg:GPR CA_REGNO))])
4567 (compare:CC (match_dup 0)
4570 [(set_attr "type" "shift")
4571 (set_attr "maybe_var_shift" "yes")
4572 (set_attr "dot" "yes")
4573 (set_attr "length" "4,8")])
4575 (define_insn_and_split "*ashr<mode>3_dot2"
4576 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4577 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4578 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4580 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4581 (ashiftrt:GPR (match_dup 1)
4583 (clobber (reg:GPR CA_REGNO))]
4584 "<MODE>mode == Pmode"
4586 sra<wd>%I2. %0,%1,%<hH>2
4588 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4589 [(parallel [(set (match_dup 0)
4590 (ashiftrt:GPR (match_dup 1)
4592 (clobber (reg:GPR CA_REGNO))])
4594 (compare:CC (match_dup 0)
4597 [(set_attr "type" "shift")
4598 (set_attr "maybe_var_shift" "yes")
4599 (set_attr "dot" "yes")
4600 (set_attr "length" "4,8")])
4602 ;; Builtins to replace a division to generate FRE reciprocal estimate
4603 ;; instructions and the necessary fixup instructions
4604 (define_expand "recip<mode>3"
4605 [(match_operand:RECIPF 0 "gpc_reg_operand")
4606 (match_operand:RECIPF 1 "gpc_reg_operand")
4607 (match_operand:RECIPF 2 "gpc_reg_operand")]
4608 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4610 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4614 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4615 ;; hardware division. This is only done before register allocation and with
4616 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4617 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4618 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4620 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4621 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4622 (match_operand 2 "gpc_reg_operand")))]
4623 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4624 && can_create_pseudo_p () && flag_finite_math_only
4625 && !flag_trapping_math && flag_reciprocal_math"
4628 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4632 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4633 ;; appropriate fixup.
4634 (define_expand "rsqrt<mode>2"
4635 [(match_operand:RECIPF 0 "gpc_reg_operand")
4636 (match_operand:RECIPF 1 "gpc_reg_operand")]
4637 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4639 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4643 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4644 ;; modes here, and also add in conditional vsx/power8-vector support to access
4645 ;; values in the traditional Altivec registers if the appropriate
4646 ;; -mupper-regs-{df,sf} option is enabled.
4648 (define_expand "abs<mode>2"
4649 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4650 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4654 (define_insn "*abs<mode>2_fpr"
4655 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4656 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4661 [(set_attr "type" "fpsimple")])
4663 (define_insn "*nabs<mode>2_fpr"
4664 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4667 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4672 [(set_attr "type" "fpsimple")])
4674 (define_expand "neg<mode>2"
4675 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4676 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4680 (define_insn "*neg<mode>2_fpr"
4681 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4682 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4687 [(set_attr "type" "fpsimple")])
4689 (define_expand "add<mode>3"
4690 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4691 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4692 (match_operand:SFDF 2 "gpc_reg_operand")))]
4696 (define_insn "*add<mode>3_fpr"
4697 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4698 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4699 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4703 xsadd<sd>p %x0,%x1,%x2"
4704 [(set_attr "type" "fp")
4705 (set_attr "isa" "*,<Fisa>")])
4707 (define_expand "sub<mode>3"
4708 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4709 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4710 (match_operand:SFDF 2 "gpc_reg_operand")))]
4714 (define_insn "*sub<mode>3_fpr"
4715 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4716 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4717 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4721 xssub<sd>p %x0,%x1,%x2"
4722 [(set_attr "type" "fp")
4723 (set_attr "isa" "*,<Fisa>")])
4725 (define_expand "mul<mode>3"
4726 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4727 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4728 (match_operand:SFDF 2 "gpc_reg_operand")))]
4732 (define_insn "*mul<mode>3_fpr"
4733 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4734 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4735 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4739 xsmul<sd>p %x0,%x1,%x2"
4740 [(set_attr "type" "dmul")
4741 (set_attr "isa" "*,<Fisa>")])
4743 (define_expand "div<mode>3"
4744 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4745 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4746 (match_operand:SFDF 2 "gpc_reg_operand")))]
4749 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4750 && can_create_pseudo_p () && flag_finite_math_only
4751 && !flag_trapping_math && flag_reciprocal_math)
4753 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4758 (define_insn "*div<mode>3_fpr"
4759 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4760 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4761 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4765 xsdiv<sd>p %x0,%x1,%x2"
4766 [(set_attr "type" "<sd>div")
4767 (set_attr "isa" "*,<Fisa>")])
4769 (define_insn "*sqrt<mode>2_internal"
4770 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4771 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4772 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4775 xssqrt<sd>p %x0,%x1"
4776 [(set_attr "type" "<sd>sqrt")
4777 (set_attr "isa" "*,<Fisa>")])
4779 (define_expand "sqrt<mode>2"
4780 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4781 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4782 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4784 if (<MODE>mode == SFmode
4785 && TARGET_RECIP_PRECISION
4786 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4787 && !optimize_function_for_size_p (cfun)
4788 && flag_finite_math_only && !flag_trapping_math
4789 && flag_unsafe_math_optimizations)
4791 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4796 ;; Floating point reciprocal approximation
4797 (define_insn "fre<sd>"
4798 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4799 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4805 [(set_attr "type" "fp")
4806 (set_attr "isa" "*,<Fisa>")])
4808 (define_insn "*rsqrt<mode>2"
4809 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4810 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4812 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4815 xsrsqrte<sd>p %x0,%x1"
4816 [(set_attr "type" "fp")
4817 (set_attr "isa" "*,<Fisa>")])
4819 ;; Floating point comparisons
4820 (define_insn "*cmp<mode>_fpr"
4821 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4822 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4823 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4827 xscmpudp %0,%x1,%x2"
4828 [(set_attr "type" "fpcompare")
4829 (set_attr "isa" "*,<Fisa>")])
4831 ;; Floating point conversions
4832 (define_expand "extendsfdf2"
4833 [(set (match_operand:DF 0 "gpc_reg_operand")
4834 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4837 if (HONOR_SNANS (SFmode))
4838 operands[1] = force_reg (SFmode, operands[1]);
4841 (define_insn_and_split "*extendsfdf2_fpr"
4842 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4843 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4844 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4850 xscpsgndp %x0,%x1,%x1
4853 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4856 emit_note (NOTE_INSN_DELETED);
4859 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4860 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4862 (define_insn "*extendsfdf2_snan"
4863 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4864 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4865 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4869 [(set_attr "type" "fp")
4870 (set_attr "isa" "*,p8v")])
4872 (define_expand "truncdfsf2"
4873 [(set (match_operand:SF 0 "gpc_reg_operand")
4874 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4878 (define_insn "*truncdfsf2_fpr"
4879 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4880 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4885 [(set_attr "type" "fp")
4886 (set_attr "isa" "*,p8v")])
4888 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4889 ;; builtins.c and optabs.c that are not correct for IBM long double
4890 ;; when little-endian.
4891 (define_expand "signbit<mode>2"
4893 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4895 (subreg:DI (match_dup 2) 0))
4898 (set (match_operand:SI 0 "gpc_reg_operand")
4901 && (!FLOAT128_IEEE_P (<MODE>mode)
4902 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4904 if (FLOAT128_IEEE_P (<MODE>mode))
4906 rtx dest = operands[0];
4907 rtx src = operands[1];
4908 rtx tmp = gen_reg_rtx (DImode);
4909 rtx dest_di = gen_lowpart (DImode, dest);
4911 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4912 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4915 operands[2] = gen_reg_rtx (DFmode);
4916 operands[3] = gen_reg_rtx (DImode);
4917 if (TARGET_POWERPC64)
4919 operands[4] = gen_reg_rtx (DImode);
4920 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4921 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4922 WORDS_BIG_ENDIAN ? 4 : 0);
4926 operands[4] = gen_reg_rtx (SImode);
4927 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4928 WORDS_BIG_ENDIAN ? 0 : 4);
4929 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4933 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4934 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4935 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4936 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4938 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4939 ;; split allows the post reload phases to eliminate the move, and do the shift
4940 ;; directly with the register that contains the signbit.
4941 (define_insn_and_split "@signbit<mode>2_dm"
4942 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4943 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4945 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4949 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4953 operands[2] = gen_highpart (DImode, operands[1]);
4955 [(set_attr "type" "mftgpr,*")])
4957 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4958 ;; register and then doing a direct move if the value comes from memory. On
4959 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4960 (define_insn_and_split "*signbit<mode>2_dm_mem"
4961 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4962 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4964 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4970 rtx dest = operands[0];
4971 rtx src = operands[1];
4972 rtx addr = XEXP (src, 0);
4974 if (WORDS_BIG_ENDIAN)
4975 operands[2] = adjust_address (src, DImode, 0);
4977 else if (REG_P (addr) || SUBREG_P (addr))
4978 operands[2] = adjust_address (src, DImode, 8);
4980 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4981 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4982 operands[2] = adjust_address (src, DImode, 8);
4986 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4987 emit_insn (gen_rtx_SET (tmp, addr));
4988 operands[2] = change_address (src, DImode,
4989 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4993 (define_expand "copysign<mode>3"
4995 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4997 (neg:SFDF (abs:SFDF (match_dup 1))))
4998 (set (match_operand:SFDF 0 "gpc_reg_operand")
4999 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5004 && ((TARGET_PPC_GFXOPT
5005 && !HONOR_NANS (<MODE>mode)
5006 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5008 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5010 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5012 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5017 operands[3] = gen_reg_rtx (<MODE>mode);
5018 operands[4] = gen_reg_rtx (<MODE>mode);
5019 operands[5] = CONST0_RTX (<MODE>mode);
5022 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5023 ;; compiler from optimizing -0.0
5024 (define_insn "copysign<mode>3_fcpsgn"
5025 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5026 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5027 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5029 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5032 xscpsgndp %x0,%x2,%x1"
5033 [(set_attr "type" "fpsimple")])
5035 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5036 ;; fsel instruction and some auxiliary computations. Then we just have a
5037 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5039 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5040 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5041 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5042 ;; define_splits to make them if made by combine. On VSX machines we have the
5043 ;; min/max instructions.
5045 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5046 ;; to allow either DF/SF to use only traditional registers.
5048 (define_expand "s<minmax><mode>3"
5049 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5050 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5051 (match_operand:SFDF 2 "gpc_reg_operand")))]
5054 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5058 (define_insn "*s<minmax><mode>3_vsx"
5059 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5060 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5061 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5062 "TARGET_VSX && TARGET_HARD_FLOAT"
5064 return (TARGET_P9_MINMAX
5065 ? "xs<minmax>cdp %x0,%x1,%x2"
5066 : "xs<minmax>dp %x0,%x1,%x2");
5068 [(set_attr "type" "fp")])
5070 ;; The conditional move instructions allow us to perform max and min operations
5071 ;; even when we don't have the appropriate max/min instruction using the FSEL
5074 (define_insn_and_split "*s<minmax><mode>3_fpr"
5075 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5076 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5077 (match_operand:SFDF 2 "gpc_reg_operand")))]
5078 "!TARGET_VSX && TARGET_MINMAX"
5083 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5087 (define_expand "mov<mode>cc"
5088 [(set (match_operand:GPR 0 "gpc_reg_operand")
5089 (if_then_else:GPR (match_operand 1 "comparison_operator")
5090 (match_operand:GPR 2 "gpc_reg_operand")
5091 (match_operand:GPR 3 "gpc_reg_operand")))]
5094 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5100 ;; We use the BASE_REGS for the isel input operands because, if rA is
5101 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5102 ;; because we may switch the operands and rB may end up being rA.
5104 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5105 ;; leave out the mode in operand 4 and use one pattern, but reload can
5106 ;; change the mode underneath our feet and then gets confused trying
5107 ;; to reload the value.
5108 (define_mode_iterator CCEITHER [CC CCUNS])
5109 (define_mode_attr un [(CC "") (CCUNS "un")])
5110 (define_insn "isel_<un>signed_<GPR:mode>"
5111 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5113 (match_operator 1 "scc_comparison_operator"
5114 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5116 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5117 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5120 [(set_attr "type" "isel")])
5122 ;; These patterns can be useful for combine; they let combine know that
5123 ;; isel can handle reversed comparisons so long as the operands are
5126 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5127 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5129 (match_operator 1 "scc_rev_comparison_operator"
5130 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5132 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5133 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5136 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5137 return "isel %0,%3,%2,%j1";
5139 [(set_attr "type" "isel")])
5141 ;; Floating point conditional move
5142 (define_expand "mov<mode>cc"
5143 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5144 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5145 (match_operand:SFDF 2 "gpc_reg_operand")
5146 (match_operand:SFDF 3 "gpc_reg_operand")))]
5147 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5149 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5155 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5156 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5158 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5159 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5160 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5161 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5162 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5164 [(set_attr "type" "fp")])
5166 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5167 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5169 (match_operator:CCFP 1 "fpmask_comparison_operator"
5170 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5171 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5172 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5173 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5174 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5179 (if_then_else:V2DI (match_dup 1)
5183 (if_then_else:SFDF (ne (match_dup 6)
5188 if (GET_CODE (operands[6]) == SCRATCH)
5189 operands[6] = gen_reg_rtx (V2DImode);
5191 operands[7] = CONSTM1_RTX (V2DImode);
5192 operands[8] = CONST0_RTX (V2DImode);
5194 [(set_attr "length" "8")
5195 (set_attr "type" "vecperm")])
5197 ;; Handle inverting the fpmask comparisons.
5198 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5199 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5201 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5202 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5203 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5204 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5205 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5206 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5211 (if_then_else:V2DI (match_dup 9)
5215 (if_then_else:SFDF (ne (match_dup 6)
5220 rtx op1 = operands[1];
5221 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5223 if (GET_CODE (operands[6]) == SCRATCH)
5224 operands[6] = gen_reg_rtx (V2DImode);
5226 operands[7] = CONSTM1_RTX (V2DImode);
5227 operands[8] = CONST0_RTX (V2DImode);
5229 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5231 [(set_attr "length" "8")
5232 (set_attr "type" "vecperm")])
5234 (define_insn "*fpmask<mode>"
5235 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5237 (match_operator:CCFP 1 "fpmask_comparison_operator"
5238 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5239 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5240 (match_operand:V2DI 4 "all_ones_constant" "")
5241 (match_operand:V2DI 5 "zero_constant" "")))]
5243 "xscmp%V1dp %x0,%x2,%x3"
5244 [(set_attr "type" "fpcompare")])
5246 (define_insn "*xxsel<mode>"
5247 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5248 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5249 (match_operand:V2DI 2 "zero_constant" ""))
5250 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5251 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5253 "xxsel %x0,%x4,%x3,%x1"
5254 [(set_attr "type" "vecmove")])
5257 ;; Conversions to and from floating-point.
5259 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5260 ; don't want to support putting SImode in FPR registers.
5261 (define_insn "lfiwax"
5262 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5263 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5265 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5271 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5272 (set_attr "isa" "*,p8v,p8v,p9v")])
5274 ; This split must be run before register allocation because it allocates the
5275 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5276 ; it earlier to allow for the combiner to merge insns together where it might
5277 ; not be needed and also in case the insns are deleted as dead code.
5279 (define_insn_and_split "floatsi<mode>2_lfiwax"
5280 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5281 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5282 (clobber (match_scratch:DI 2 "=d,wa"))]
5283 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5284 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5289 rtx dest = operands[0];
5290 rtx src = operands[1];
5293 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5294 tmp = convert_to_mode (DImode, src, false);
5298 if (GET_CODE (tmp) == SCRATCH)
5299 tmp = gen_reg_rtx (DImode);
5302 src = rs6000_force_indexed_or_indirect_mem (src);
5303 emit_insn (gen_lfiwax (tmp, src));
5307 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5308 emit_move_insn (stack, src);
5309 emit_insn (gen_lfiwax (tmp, stack));
5312 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5315 [(set_attr "length" "12")
5316 (set_attr "type" "fpload")])
5318 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5319 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5322 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5323 (clobber (match_scratch:DI 2 "=d,wa"))]
5324 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5329 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5330 if (GET_CODE (operands[2]) == SCRATCH)
5331 operands[2] = gen_reg_rtx (DImode);
5332 if (TARGET_P8_VECTOR)
5333 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5335 emit_insn (gen_lfiwax (operands[2], operands[1]));
5336 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5339 [(set_attr "length" "8")
5340 (set_attr "type" "fpload")])
5342 (define_insn "lfiwzx"
5343 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5344 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5346 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5351 xxextractuw %x0,%x1,4"
5352 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5353 (set_attr "isa" "*,p8v,p8v,p9v")])
5355 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5356 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5357 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5358 (clobber (match_scratch:DI 2 "=d,wa"))]
5359 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5364 rtx dest = operands[0];
5365 rtx src = operands[1];
5368 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5369 tmp = convert_to_mode (DImode, src, true);
5373 if (GET_CODE (tmp) == SCRATCH)
5374 tmp = gen_reg_rtx (DImode);
5377 src = rs6000_force_indexed_or_indirect_mem (src);
5378 emit_insn (gen_lfiwzx (tmp, src));
5382 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5383 emit_move_insn (stack, src);
5384 emit_insn (gen_lfiwzx (tmp, stack));
5387 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5390 [(set_attr "length" "12")
5391 (set_attr "type" "fpload")])
5393 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5394 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5395 (unsigned_float:SFDF
5397 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5398 (clobber (match_scratch:DI 2 "=d,wa"))]
5399 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5404 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5405 if (GET_CODE (operands[2]) == SCRATCH)
5406 operands[2] = gen_reg_rtx (DImode);
5407 if (TARGET_P8_VECTOR)
5408 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5410 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5411 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5414 [(set_attr "length" "8")
5415 (set_attr "type" "fpload")])
5417 ; For each of these conversions, there is a define_expand, a define_insn
5418 ; with a '#' template, and a define_split (with C code). The idea is
5419 ; to allow constant folding with the template of the define_insn,
5420 ; then to have the insns split later (between sched1 and final).
5422 (define_expand "floatsidf2"
5423 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5424 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5427 (clobber (match_dup 4))
5428 (clobber (match_dup 5))
5429 (clobber (match_dup 6))])]
5432 if (TARGET_LFIWAX && TARGET_FCFID)
5434 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5437 else if (TARGET_FCFID)
5439 rtx dreg = operands[1];
5441 dreg = force_reg (SImode, dreg);
5442 dreg = convert_to_mode (DImode, dreg, false);
5443 emit_insn (gen_floatdidf2 (operands[0], dreg));
5447 if (!REG_P (operands[1]))
5448 operands[1] = force_reg (SImode, operands[1]);
5449 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5450 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5451 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5452 operands[5] = gen_reg_rtx (DFmode);
5453 operands[6] = gen_reg_rtx (SImode);
5456 (define_insn_and_split "*floatsidf2_internal"
5457 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5458 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5459 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5460 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5461 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5462 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5463 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5464 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5469 rtx lowword, highword;
5470 gcc_assert (MEM_P (operands[4]));
5471 highword = adjust_address (operands[4], SImode, 0);
5472 lowword = adjust_address (operands[4], SImode, 4);
5473 if (! WORDS_BIG_ENDIAN)
5474 std::swap (lowword, highword);
5476 emit_insn (gen_xorsi3 (operands[6], operands[1],
5477 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5478 emit_move_insn (lowword, operands[6]);
5479 emit_move_insn (highword, operands[2]);
5480 emit_move_insn (operands[5], operands[4]);
5481 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5484 [(set_attr "length" "24")
5485 (set_attr "type" "fp")])
5487 ;; If we don't have a direct conversion to single precision, don't enable this
5488 ;; conversion for 32-bit without fast math, because we don't have the insn to
5489 ;; generate the fixup swizzle to avoid double rounding problems.
5490 (define_expand "floatunssisf2"
5491 [(set (match_operand:SF 0 "gpc_reg_operand")
5492 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5494 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5496 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5498 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5500 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5505 rtx dreg = operands[1];
5507 dreg = force_reg (SImode, dreg);
5508 dreg = convert_to_mode (DImode, dreg, true);
5509 emit_insn (gen_floatdisf2 (operands[0], dreg));
5514 (define_expand "floatunssidf2"
5515 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5516 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5519 (clobber (match_dup 4))
5520 (clobber (match_dup 5))])]
5523 if (TARGET_LFIWZX && TARGET_FCFID)
5525 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5528 else if (TARGET_FCFID)
5530 rtx dreg = operands[1];
5532 dreg = force_reg (SImode, dreg);
5533 dreg = convert_to_mode (DImode, dreg, true);
5534 emit_insn (gen_floatdidf2 (operands[0], dreg));
5538 if (!REG_P (operands[1]))
5539 operands[1] = force_reg (SImode, operands[1]);
5540 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5541 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5542 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5543 operands[5] = gen_reg_rtx (DFmode);
5546 (define_insn_and_split "*floatunssidf2_internal"
5547 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5548 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5549 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5550 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5551 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5552 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5553 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5554 && !(TARGET_FCFID && TARGET_POWERPC64)"
5559 rtx lowword, highword;
5560 gcc_assert (MEM_P (operands[4]));
5561 highword = adjust_address (operands[4], SImode, 0);
5562 lowword = adjust_address (operands[4], SImode, 4);
5563 if (! WORDS_BIG_ENDIAN)
5564 std::swap (lowword, highword);
5566 emit_move_insn (lowword, operands[1]);
5567 emit_move_insn (highword, operands[2]);
5568 emit_move_insn (operands[5], operands[4]);
5569 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5572 [(set_attr "length" "20")
5573 (set_attr "type" "fp")])
5575 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5576 ;; vector registers. These insns favor doing the sign/zero extension in
5577 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5578 ;; extension and then a direct move.
5580 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5581 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5583 (match_operand:QHI 1 "input_operand")))
5584 (clobber (match_scratch:DI 2))
5585 (clobber (match_scratch:DI 3))
5586 (clobber (match_scratch:<QHI:MODE> 4))])]
5587 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5589 if (MEM_P (operands[1]))
5590 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5593 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5594 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5596 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5597 (clobber (match_scratch:DI 2 "=v,wa,v"))
5598 (clobber (match_scratch:DI 3 "=X,r,X"))
5599 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5600 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5602 "&& reload_completed"
5605 rtx result = operands[0];
5606 rtx input = operands[1];
5607 rtx di = operands[2];
5611 rtx tmp = operands[3];
5612 if (altivec_register_operand (input, <QHI:MODE>mode))
5613 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5614 else if (GET_CODE (tmp) == SCRATCH)
5615 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5618 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5619 emit_move_insn (di, tmp);
5624 rtx tmp = operands[4];
5625 emit_move_insn (tmp, input);
5626 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5629 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5632 [(set_attr "isa" "p9v,*,p9v")])
5634 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5635 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5636 (unsigned_float:FP_ISA3
5637 (match_operand:QHI 1 "input_operand")))
5638 (clobber (match_scratch:DI 2))
5639 (clobber (match_scratch:DI 3))])]
5640 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5642 if (MEM_P (operands[1]))
5643 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5646 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5647 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5648 (unsigned_float:FP_ISA3
5649 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5650 (clobber (match_scratch:DI 2 "=v,wa,wa"))
5651 (clobber (match_scratch:DI 3 "=X,r,X"))]
5652 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5654 "&& reload_completed"
5657 rtx result = operands[0];
5658 rtx input = operands[1];
5659 rtx di = operands[2];
5661 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5662 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5665 rtx tmp = operands[3];
5666 if (GET_CODE (tmp) == SCRATCH)
5667 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5670 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5671 emit_move_insn (di, tmp);
5675 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5678 [(set_attr "isa" "p9v,*,p9v")])
5680 (define_expand "fix_trunc<mode>si2"
5681 [(set (match_operand:SI 0 "gpc_reg_operand")
5682 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5685 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5687 rtx src = force_reg (<MODE>mode, operands[1]);
5690 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5693 rtx tmp = gen_reg_rtx (DImode);
5694 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5695 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5702 ; Like the convert to float patterns, this insn must be split before
5703 ; register allocation so that it can allocate the memory slot if it
5705 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5706 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5707 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5708 (clobber (match_scratch:DI 2 "=d"))]
5709 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5710 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5715 rtx dest = operands[0];
5716 rtx src = operands[1];
5717 rtx tmp = operands[2];
5719 if (GET_CODE (tmp) == SCRATCH)
5720 tmp = gen_reg_rtx (DImode);
5722 emit_insn (gen_fctiwz_<mode> (tmp, src));
5723 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5725 dest = rs6000_force_indexed_or_indirect_mem (dest);
5726 emit_insn (gen_stfiwx (dest, tmp));
5729 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5731 dest = gen_lowpart (DImode, dest);
5732 emit_move_insn (dest, tmp);
5737 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5738 emit_insn (gen_stfiwx (stack, tmp));
5739 emit_move_insn (dest, stack);
5743 [(set_attr "length" "12")
5744 (set_attr "type" "fp")])
5746 (define_insn_and_split "fix_trunc<mode>si2_internal"
5747 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5748 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5749 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5750 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5752 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5758 gcc_assert (MEM_P (operands[3]));
5759 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5761 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5762 emit_move_insn (operands[3], operands[2]);
5763 emit_move_insn (operands[0], lowword);
5766 [(set_attr "length" "16")
5767 (set_attr "type" "fp")])
5769 (define_expand "fix_trunc<mode>di2"
5770 [(set (match_operand:DI 0 "gpc_reg_operand")
5771 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5772 "TARGET_HARD_FLOAT && TARGET_FCFID"
5775 (define_insn "*fix_trunc<mode>di2_fctidz"
5776 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5777 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5778 "TARGET_HARD_FLOAT && TARGET_FCFID"
5782 [(set_attr "type" "fp")])
5784 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5785 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5786 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5787 ;; values can go in VSX registers. Keeping the direct move part through
5788 ;; register allocation prevents the register allocator from doing a direct move
5789 ;; of the SImode value to a GPR, and then a store/load.
5790 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5791 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5792 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5793 (clobber (match_scratch:SI 2 "=X,X,wa"))]
5794 "TARGET_DIRECT_MOVE"
5797 xscvdp<su>xws %x0,%x1
5799 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5801 (any_fix:SI (match_dup 1)))
5805 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5807 [(set_attr "type" "fp")
5808 (set_attr "length" "4,4,8")
5809 (set_attr "isa" "p9v,p9v,*")])
5811 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5812 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5813 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5814 "TARGET_DIRECT_MOVE"
5817 xscvdp<su>xws %x0,%x1"
5818 [(set_attr "type" "fp")])
5820 ;; Keep the convert and store together through register allocation to prevent
5821 ;; the register allocator from getting clever and doing a direct move to a GPR
5822 ;; and then store for reg+offset stores.
5823 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5824 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5825 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5826 (clobber (match_scratch:SI 2 "=wa"))]
5827 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5829 "&& reload_completed"
5831 (any_fix:SI (match_dup 1)))
5835 operands[3] = (<QHSI:MODE>mode == SImode
5837 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5840 (define_expand "fixuns_trunc<mode>si2"
5841 [(set (match_operand:SI 0 "gpc_reg_operand")
5842 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5843 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5845 if (!TARGET_P8_VECTOR)
5847 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5852 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5853 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5854 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5855 (clobber (match_scratch:DI 2 "=d"))]
5856 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5857 && TARGET_STFIWX && can_create_pseudo_p ()
5858 && !TARGET_P8_VECTOR"
5863 rtx dest = operands[0];
5864 rtx src = operands[1];
5865 rtx tmp = operands[2];
5867 if (GET_CODE (tmp) == SCRATCH)
5868 tmp = gen_reg_rtx (DImode);
5870 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5873 dest = rs6000_force_indexed_or_indirect_mem (dest);
5874 emit_insn (gen_stfiwx (dest, tmp));
5877 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5879 dest = gen_lowpart (DImode, dest);
5880 emit_move_insn (dest, tmp);
5885 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5886 emit_insn (gen_stfiwx (stack, tmp));
5887 emit_move_insn (dest, stack);
5891 [(set_attr "length" "12")
5892 (set_attr "type" "fp")])
5894 (define_insn "fixuns_trunc<mode>di2"
5895 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5896 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5897 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5901 [(set_attr "type" "fp")])
5903 (define_insn "rs6000_mtfsb0"
5904 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5908 [(set_attr "type" "fp")])
5910 (define_insn "rs6000_mtfsb1"
5911 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5915 [(set_attr "type" "fp")])
5917 (define_insn "rs6000_mffscrn"
5918 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5919 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5923 [(set_attr "type" "fp")])
5925 (define_insn "rs6000_mffscdrn"
5926 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5927 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5928 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5931 [(set_attr "type" "fp")])
5933 (define_expand "rs6000_set_fpscr_rn"
5934 [(match_operand:DI 0 "reg_or_cint_operand")]
5937 rtx tmp_df = gen_reg_rtx (DFmode);
5939 /* The floating point rounding control bits are FPSCR[62:63]. Put the
5940 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
5943 rtx src_df = force_reg (DImode, operands[0]);
5944 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5945 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5949 if (CONST_INT_P (operands[0]))
5951 if ((INTVAL (operands[0]) & 0x1) == 0x1)
5952 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5954 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5956 if ((INTVAL (operands[0]) & 0x2) == 0x2)
5957 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5959 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5963 rtx tmp_rn = gen_reg_rtx (DImode);
5964 rtx tmp_di = gen_reg_rtx (DImode);
5966 /* Extract new RN mode from operand. */
5967 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5969 /* Insert new RN mode into FSCPR. */
5970 emit_insn (gen_rs6000_mffs (tmp_df));
5971 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5972 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5973 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5975 /* Need to write to field k=15. The fields are [0:15]. Hence with
5976 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
5977 8-bit field[0:7]. Need to set the bit that corresponds to the
5978 value of i that you want [0:7]. */
5979 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5980 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5985 (define_expand "rs6000_set_fpscr_drn"
5986 [(match_operand:DI 0 "gpc_reg_operand")]
5989 rtx tmp_df = gen_reg_rtx (DFmode);
5991 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5992 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
5995 rtx src_df = gen_reg_rtx (DFmode);
5997 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5998 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5999 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6003 rtx tmp_rn = gen_reg_rtx (DImode);
6004 rtx tmp_di = gen_reg_rtx (DImode);
6006 /* Extract new DRN mode from operand. */
6007 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6008 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6010 /* Insert new RN mode into FSCPR. */
6011 emit_insn (gen_rs6000_mffs (tmp_df));
6012 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6013 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6014 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6016 /* Need to write to field 7. The fields are [0:15]. The equation to
6017 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6018 i to 0x1 to get field 7 where i selects the field. */
6019 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6020 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6025 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6026 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6027 ;; because the first makes it clear that operand 0 is not live
6028 ;; before the instruction.
6029 (define_insn "fctiwz_<mode>"
6030 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6032 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6038 [(set_attr "type" "fp")])
6040 (define_insn "fctiwuz_<mode>"
6041 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6042 (unspec:DI [(unsigned_fix:SI
6043 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6045 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6049 [(set_attr "type" "fp")])
6051 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6052 ;; since the friz instruction does not truncate the value if the floating
6053 ;; point value is < LONG_MIN or > LONG_MAX.
6054 (define_insn "*friz"
6055 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6056 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6057 "TARGET_HARD_FLOAT && TARGET_FPRND
6058 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6062 [(set_attr "type" "fp")])
6064 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6065 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6066 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6067 ;; extend it, store it back on the stack from the GPR, load it back into the
6068 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6069 ;; disable using store and load to sign/zero extend the value.
6070 (define_insn_and_split "*round32<mode>2_fprs"
6071 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6073 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6074 (clobber (match_scratch:DI 2 "=d"))
6075 (clobber (match_scratch:DI 3 "=d"))]
6077 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6078 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6083 rtx dest = operands[0];
6084 rtx src = operands[1];
6085 rtx tmp1 = operands[2];
6086 rtx tmp2 = operands[3];
6087 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6089 if (GET_CODE (tmp1) == SCRATCH)
6090 tmp1 = gen_reg_rtx (DImode);
6091 if (GET_CODE (tmp2) == SCRATCH)
6092 tmp2 = gen_reg_rtx (DImode);
6094 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6095 emit_insn (gen_stfiwx (stack, tmp1));
6096 emit_insn (gen_lfiwax (tmp2, stack));
6097 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6100 [(set_attr "type" "fpload")
6101 (set_attr "length" "16")])
6103 (define_insn_and_split "*roundu32<mode>2_fprs"
6104 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6105 (unsigned_float:SFDF
6106 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6107 (clobber (match_scratch:DI 2 "=d"))
6108 (clobber (match_scratch:DI 3 "=d"))]
6110 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6111 && can_create_pseudo_p ()"
6116 rtx dest = operands[0];
6117 rtx src = operands[1];
6118 rtx tmp1 = operands[2];
6119 rtx tmp2 = operands[3];
6120 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6122 if (GET_CODE (tmp1) == SCRATCH)
6123 tmp1 = gen_reg_rtx (DImode);
6124 if (GET_CODE (tmp2) == SCRATCH)
6125 tmp2 = gen_reg_rtx (DImode);
6127 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6128 emit_insn (gen_stfiwx (stack, tmp1));
6129 emit_insn (gen_lfiwzx (tmp2, stack));
6130 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6133 [(set_attr "type" "fpload")
6134 (set_attr "length" "16")])
6136 ;; No VSX equivalent to fctid
6137 (define_insn "lrint<mode>di2"
6138 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6139 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6141 "TARGET_HARD_FLOAT && TARGET_FPRND"
6143 [(set_attr "type" "fp")])
6145 (define_insn "btrunc<mode>2"
6146 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6147 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6149 "TARGET_HARD_FLOAT && TARGET_FPRND"
6153 [(set_attr "type" "fp")])
6155 (define_insn "ceil<mode>2"
6156 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6157 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6159 "TARGET_HARD_FLOAT && TARGET_FPRND"
6163 [(set_attr "type" "fp")])
6165 (define_insn "floor<mode>2"
6166 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6167 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6169 "TARGET_HARD_FLOAT && TARGET_FPRND"
6173 [(set_attr "type" "fp")])
6175 ;; No VSX equivalent to frin
6176 (define_insn "round<mode>2"
6177 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6178 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6180 "TARGET_HARD_FLOAT && TARGET_FPRND"
6182 [(set_attr "type" "fp")])
6184 (define_insn "*xsrdpi<mode>2"
6185 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6186 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6188 "TARGET_HARD_FLOAT && TARGET_VSX"
6190 [(set_attr "type" "fp")])
6192 (define_expand "lround<mode>di2"
6194 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6196 (set (match_operand:DI 0 "gpc_reg_operand")
6197 (unspec:DI [(match_dup 2)]
6199 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6201 operands[2] = gen_reg_rtx (<MODE>mode);
6204 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6205 (define_insn "stfiwx"
6206 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6207 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6213 [(set_attr "type" "fpstore")
6214 (set_attr "isa" "*,p8v")])
6216 ;; If we don't have a direct conversion to single precision, don't enable this
6217 ;; conversion for 32-bit without fast math, because we don't have the insn to
6218 ;; generate the fixup swizzle to avoid double rounding problems.
6219 (define_expand "floatsisf2"
6220 [(set (match_operand:SF 0 "gpc_reg_operand")
6221 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6223 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6225 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6227 if (TARGET_FCFIDS && TARGET_LFIWAX)
6229 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6232 else if (TARGET_FCFID && TARGET_LFIWAX)
6234 rtx dfreg = gen_reg_rtx (DFmode);
6235 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6236 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6241 rtx dreg = operands[1];
6243 dreg = force_reg (SImode, dreg);
6244 dreg = convert_to_mode (DImode, dreg, false);
6245 emit_insn (gen_floatdisf2 (operands[0], dreg));
6250 (define_insn "floatdidf2"
6251 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6252 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6253 "TARGET_FCFID && TARGET_HARD_FLOAT"
6257 [(set_attr "type" "fp")])
6259 ; Allow the combiner to merge source memory operands to the conversion so that
6260 ; the optimizer/register allocator doesn't try to load the value too early in a
6261 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6262 ; hit. We will split after reload to avoid the trip through the GPRs
6264 (define_insn_and_split "*floatdidf2_mem"
6265 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6266 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6267 (clobber (match_scratch:DI 2 "=d,wa"))]
6268 "TARGET_HARD_FLOAT && TARGET_FCFID"
6270 "&& reload_completed"
6271 [(set (match_dup 2) (match_dup 1))
6272 (set (match_dup 0) (float:DF (match_dup 2)))]
6274 [(set_attr "length" "8")
6275 (set_attr "type" "fpload")])
6277 (define_expand "floatunsdidf2"
6278 [(set (match_operand:DF 0 "gpc_reg_operand")
6280 (match_operand:DI 1 "gpc_reg_operand")))]
6281 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6284 (define_insn "*floatunsdidf2_fcfidu"
6285 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6286 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6287 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6291 [(set_attr "type" "fp")])
6293 (define_insn_and_split "*floatunsdidf2_mem"
6294 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6295 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6296 (clobber (match_scratch:DI 2 "=d,wa"))]
6297 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6299 "&& reload_completed"
6300 [(set (match_dup 2) (match_dup 1))
6301 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6303 [(set_attr "length" "8")
6304 (set_attr "type" "fpload")])
6306 (define_expand "floatdisf2"
6307 [(set (match_operand:SF 0 "gpc_reg_operand")
6308 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6309 "TARGET_FCFID && TARGET_HARD_FLOAT
6310 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6314 rtx val = operands[1];
6315 if (!flag_unsafe_math_optimizations)
6317 rtx label = gen_label_rtx ();
6318 val = gen_reg_rtx (DImode);
6319 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6322 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6327 (define_insn "floatdisf2_fcfids"
6328 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6329 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6330 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6334 [(set_attr "type" "fp")
6335 (set_attr "isa" "*,p8v")])
6337 (define_insn_and_split "*floatdisf2_mem"
6338 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6339 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6340 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6341 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6343 "&& reload_completed"
6346 emit_move_insn (operands[2], operands[1]);
6347 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6350 [(set_attr "length" "8")
6351 (set_attr "isa" "*,p8v,p8v")])
6353 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6354 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6355 ;; from double rounding.
6356 ;; Instead of creating a new cpu type for two FP operations, just use fp
6357 (define_insn_and_split "floatdisf2_internal1"
6358 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6359 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6360 (clobber (match_scratch:DF 2 "=d"))]
6361 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6363 "&& reload_completed"
6365 (float:DF (match_dup 1)))
6367 (float_truncate:SF (match_dup 2)))]
6369 [(set_attr "length" "8")
6370 (set_attr "type" "fp")])
6372 ;; Twiddles bits to avoid double rounding.
6373 ;; Bits that might be truncated when converting to DFmode are replaced
6374 ;; by a bit that won't be lost at that stage, but is below the SFmode
6375 ;; rounding position.
6376 (define_expand "floatdisf2_internal2"
6377 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6379 (clobber (reg:DI CA_REGNO))])
6380 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6382 (set (match_dup 3) (plus:DI (match_dup 3)
6384 (set (match_dup 0) (plus:DI (match_dup 0)
6386 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6388 (set (match_dup 0) (ior:DI (match_dup 0)
6390 (set (match_dup 0) (and:DI (match_dup 0)
6392 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6393 (label_ref (match_operand:DI 2 ""))
6395 (set (match_dup 0) (match_dup 1))]
6396 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6398 operands[3] = gen_reg_rtx (DImode);
6399 operands[4] = gen_reg_rtx (CCUNSmode);
6402 (define_expand "floatunsdisf2"
6403 [(set (match_operand:SF 0 "gpc_reg_operand")
6404 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6405 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6408 (define_insn "floatunsdisf2_fcfidus"
6409 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6410 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6411 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6415 [(set_attr "type" "fp")
6416 (set_attr "isa" "*,p8v")])
6418 (define_insn_and_split "*floatunsdisf2_mem"
6419 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6420 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6421 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6422 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6424 "&& reload_completed"
6427 emit_move_insn (operands[2], operands[1]);
6428 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6431 [(set_attr "type" "fpload")
6432 (set_attr "length" "8")
6433 (set_attr "isa" "*,p8v,p8v")])
6435 ;; Define the TImode operations that can be done in a small number
6436 ;; of instructions. The & constraints are to prevent the register
6437 ;; allocator from allocating registers that overlap with the inputs
6438 ;; (for example, having an input in 7,8 and an output in 6,7). We
6439 ;; also allow for the output being the same as one of the inputs.
6441 (define_expand "addti3"
6442 [(set (match_operand:TI 0 "gpc_reg_operand")
6443 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6444 (match_operand:TI 2 "reg_or_short_operand")))]
6447 rtx lo0 = gen_lowpart (DImode, operands[0]);
6448 rtx lo1 = gen_lowpart (DImode, operands[1]);
6449 rtx lo2 = gen_lowpart (DImode, operands[2]);
6450 rtx hi0 = gen_highpart (DImode, operands[0]);
6451 rtx hi1 = gen_highpart (DImode, operands[1]);
6452 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6454 if (!reg_or_short_operand (lo2, DImode))
6455 lo2 = force_reg (DImode, lo2);
6456 if (!adde_operand (hi2, DImode))
6457 hi2 = force_reg (DImode, hi2);
6459 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6460 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6464 (define_expand "subti3"
6465 [(set (match_operand:TI 0 "gpc_reg_operand")
6466 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6467 (match_operand:TI 2 "gpc_reg_operand")))]
6470 rtx lo0 = gen_lowpart (DImode, operands[0]);
6471 rtx lo1 = gen_lowpart (DImode, operands[1]);
6472 rtx lo2 = gen_lowpart (DImode, operands[2]);
6473 rtx hi0 = gen_highpart (DImode, operands[0]);
6474 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6475 rtx hi2 = gen_highpart (DImode, operands[2]);
6477 if (!reg_or_short_operand (lo1, DImode))
6478 lo1 = force_reg (DImode, lo1);
6479 if (!adde_operand (hi1, DImode))
6480 hi1 = force_reg (DImode, hi1);
6482 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6483 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6487 ;; 128-bit logical operations expanders
6489 (define_expand "and<mode>3"
6490 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6491 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6492 (match_operand:BOOL_128 2 "vlogical_operand")))]
6496 (define_expand "ior<mode>3"
6497 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6498 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6499 (match_operand:BOOL_128 2 "vlogical_operand")))]
6503 (define_expand "xor<mode>3"
6504 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6505 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6506 (match_operand:BOOL_128 2 "vlogical_operand")))]
6510 (define_expand "nor<mode>3"
6511 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6513 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6514 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6518 (define_expand "andc<mode>3"
6519 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6521 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6522 (match_operand:BOOL_128 1 "vlogical_operand")))]
6526 ;; Power8 vector logical instructions.
6527 (define_expand "eqv<mode>3"
6528 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6530 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6531 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6532 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6535 ;; Rewrite nand into canonical form
6536 (define_expand "nand<mode>3"
6537 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6539 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6540 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6541 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6544 ;; The canonical form is to have the negated element first, so we need to
6545 ;; reverse arguments.
6546 (define_expand "orc<mode>3"
6547 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6549 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6550 (match_operand:BOOL_128 1 "vlogical_operand")))]
6551 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6554 ;; 128-bit logical operations insns and split operations
6555 (define_insn_and_split "*and<mode>3_internal"
6556 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6558 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6559 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6562 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6563 return "xxland %x0,%x1,%x2";
6565 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6566 return "vand %0,%1,%2";
6570 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6573 rs6000_split_logical (operands, AND, false, false, false);
6578 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6579 (const_string "veclogical")
6580 (const_string "integer")))
6581 (set (attr "length")
6583 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6586 (match_test "TARGET_POWERPC64")
6588 (const_string "16"))))])
6591 (define_insn_and_split "*bool<mode>3_internal"
6592 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6593 (match_operator:BOOL_128 3 "boolean_or_operator"
6594 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6595 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6598 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6599 return "xxl%q3 %x0,%x1,%x2";
6601 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6602 return "v%q3 %0,%1,%2";
6606 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6609 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6614 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6615 (const_string "veclogical")
6616 (const_string "integer")))
6617 (set (attr "length")
6619 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6622 (match_test "TARGET_POWERPC64")
6624 (const_string "16"))))])
6627 (define_insn_and_split "*boolc<mode>3_internal1"
6628 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6629 (match_operator:BOOL_128 3 "boolean_operator"
6631 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6632 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6633 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6635 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6636 return "xxl%q3 %x0,%x1,%x2";
6638 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6639 return "v%q3 %0,%1,%2";
6643 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6644 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6647 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6652 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6653 (const_string "veclogical")
6654 (const_string "integer")))
6655 (set (attr "length")
6657 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6660 (match_test "TARGET_POWERPC64")
6662 (const_string "16"))))])
6664 (define_insn_and_split "*boolc<mode>3_internal2"
6665 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6666 (match_operator:TI2 3 "boolean_operator"
6668 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6669 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6670 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6672 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6675 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6678 [(set_attr "type" "integer")
6679 (set (attr "length")
6681 (match_test "TARGET_POWERPC64")
6683 (const_string "16")))])
6686 (define_insn_and_split "*boolcc<mode>3_internal1"
6687 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6688 (match_operator:BOOL_128 3 "boolean_operator"
6690 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6692 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6693 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6695 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6696 return "xxl%q3 %x0,%x1,%x2";
6698 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6699 return "v%q3 %0,%1,%2";
6703 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6704 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6707 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
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"))))])
6724 (define_insn_and_split "*boolcc<mode>3_internal2"
6725 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6726 (match_operator:TI2 3 "boolean_operator"
6728 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6730 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6731 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6733 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6736 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6739 [(set_attr "type" "integer")
6740 (set (attr "length")
6742 (match_test "TARGET_POWERPC64")
6744 (const_string "16")))])
6748 (define_insn_and_split "*eqv<mode>3_internal1"
6749 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6752 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6753 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6756 if (vsx_register_operand (operands[0], <MODE>mode))
6757 return "xxleqv %x0,%x1,%x2";
6761 "TARGET_P8_VECTOR && reload_completed
6762 && int_reg_operand (operands[0], <MODE>mode)"
6765 rs6000_split_logical (operands, XOR, true, false, false);
6770 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6771 (const_string "veclogical")
6772 (const_string "integer")))
6773 (set (attr "length")
6775 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6778 (match_test "TARGET_POWERPC64")
6780 (const_string "16"))))])
6782 (define_insn_and_split "*eqv<mode>3_internal2"
6783 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6786 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6787 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6790 "reload_completed && !TARGET_P8_VECTOR"
6793 rs6000_split_logical (operands, XOR, true, false, false);
6796 [(set_attr "type" "integer")
6797 (set (attr "length")
6799 (match_test "TARGET_POWERPC64")
6801 (const_string "16")))])
6803 ;; 128-bit one's complement
6804 (define_insn_and_split "one_cmpl<mode>2"
6805 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6807 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6810 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6811 return "xxlnor %x0,%x1,%x1";
6813 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6814 return "vnor %0,%1,%1";
6818 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6821 rs6000_split_logical (operands, NOT, false, false, false);
6826 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6827 (const_string "veclogical")
6828 (const_string "integer")))
6829 (set (attr "length")
6831 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6834 (match_test "TARGET_POWERPC64")
6836 (const_string "16"))))])
6839 ;; Now define ways of moving data around.
6841 ;; Set up a register with a value from the GOT table
6843 (define_expand "movsi_got"
6844 [(set (match_operand:SI 0 "gpc_reg_operand")
6845 (unspec:SI [(match_operand:SI 1 "got_operand")
6846 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6847 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6849 if (GET_CODE (operands[1]) == CONST)
6851 rtx offset = const0_rtx;
6852 HOST_WIDE_INT value;
6854 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6855 value = INTVAL (offset);
6858 rtx tmp = (!can_create_pseudo_p ()
6860 : gen_reg_rtx (Pmode));
6861 emit_insn (gen_movsi_got (tmp, operands[1]));
6862 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6867 operands[2] = rs6000_got_register (operands[1]);
6870 (define_insn "*movsi_got_internal"
6871 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6872 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6873 (match_operand:SI 2 "gpc_reg_operand" "b")]
6875 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6876 "lwz %0,%a1@got(%2)"
6877 [(set_attr "type" "load")])
6879 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6880 ;; didn't get allocated to a hard register.
6882 [(set (match_operand:SI 0 "gpc_reg_operand")
6883 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6884 (match_operand:SI 2 "memory_operand")]
6886 "DEFAULT_ABI == ABI_V4
6888 && reload_completed"
6889 [(set (match_dup 0) (match_dup 2))
6890 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6895 ;; LWZ LFIWZX LXSIWZX
6896 ;; STW STFIWX STXSIWX
6898 ;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6899 ;; XXLXOR 0 XXLORC -1 P9 const
6903 (define_insn "*movsi_internal1"
6904 [(set (match_operand:SI 0 "nonimmediate_operand"
6913 (match_operand:SI 1 "input_operand"
6922 "gpc_reg_operand (operands[0], SImode)
6923 || gpc_reg_operand (operands[1], SImode)"
6951 load, fpload, fpload,
6952 store, fpstore, fpstore,
6954 veclogical, vecsimple, vecsimple, vecsimple,
6955 veclogical, veclogical, vecsimple,
6977 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6978 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6980 ;; Because SF values are actually stored as DF values within the vector
6981 ;; registers, we need to convert the value to the vector SF format when
6982 ;; we need to use the bits in a union or similar cases. We only need
6983 ;; to do this transformation when the value is a vector register. Loads,
6984 ;; stores, and transfers within GPRs are assumed to be safe.
6986 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6987 ;; no alternatives, because the call is created as part of secondary_reload,
6988 ;; and operand #2's register class is used to allocate the temporary register.
6989 ;; This function is called before reload, and it creates the temporary as
6992 ;; MR LWZ LFIWZX LXSIWZX STW
6993 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6996 (define_insn_and_split "movsi_from_sf"
6997 [(set (match_operand:SI 0 "nonimmediate_operand"
6998 "=r, r, ?*d, ?*v, m,
7001 (unspec:SI [(match_operand:SF 1 "input_operand"
7006 (clobber (match_scratch:V4SF 2
7010 "TARGET_NO_SF_SUBREG
7011 && (register_operand (operands[0], SImode)
7012 || register_operand (operands[1], SFmode))"
7025 "&& reload_completed
7026 && int_reg_operand (operands[0], SImode)
7027 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7030 rtx op0 = operands[0];
7031 rtx op1 = operands[1];
7032 rtx op2 = operands[2];
7033 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7034 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7036 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7037 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7041 "*, load, fpload, fpload, store,
7042 fpstore, fpstore, fpstore, mftgpr, fp,
7050 *, p9v, p8v, p8v, p8v,
7053 ;; movsi_from_sf with zero extension
7055 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7058 (define_insn_and_split "*movdi_from_sf_zero_ext"
7059 [(set (match_operand:DI 0 "gpc_reg_operand"
7060 "=r, r, ?*d, ?*v, r,
7063 (unspec:SI [(match_operand:SF 1 "input_operand"
7066 UNSPEC_SI_FROM_SF)))
7067 (clobber (match_scratch:V4SF 2
7070 "TARGET_DIRECT_MOVE_64BIT
7071 && (register_operand (operands[0], DImode)
7072 || register_operand (operands[1], SImode))"
7081 "&& reload_completed
7082 && register_operand (operands[0], DImode)
7083 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7086 rtx op0 = operands[0];
7087 rtx op1 = operands[1];
7088 rtx op2 = operands[2];
7089 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7091 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7092 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7096 "*, load, fpload, fpload, two,
7102 "*, *, p8v, p8v, p8v,
7105 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7106 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7107 ;; conversion explicitly since that doesn't work in most cases if the input
7108 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7109 ;; former handles cases where the input will not fit in a SFmode, and the
7110 ;; latter assumes the value has already been rounded.
7111 (define_insn "*movsi_from_df"
7112 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7113 (unspec:SI [(float_truncate:SF
7114 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7115 UNSPEC_SI_FROM_SF))]
7116 "TARGET_NO_SF_SUBREG"
7118 [(set_attr "type" "fp")])
7120 ;; Split a load of a large constant into the appropriate two-insn
7124 [(set (match_operand:SI 0 "gpc_reg_operand")
7125 (match_operand:SI 1 "const_int_operand"))]
7126 "num_insns_constant (operands[1], SImode) > 1"
7130 (ior:SI (match_dup 0)
7133 if (rs6000_emit_set_const (operands[0], operands[1]))
7139 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7141 [(set (match_operand:DI 0 "altivec_register_operand")
7142 (match_operand:DI 1 "xxspltib_constant_split"))]
7143 "TARGET_P9_VECTOR && reload_completed"
7146 rtx op0 = operands[0];
7147 rtx op1 = operands[1];
7148 int r = REGNO (op0);
7149 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7151 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7152 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7156 (define_insn "*mov<mode>_internal2"
7157 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7158 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7160 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7166 [(set_attr "type" "cmp,logical,cmp")
7167 (set_attr "dot" "yes")
7168 (set_attr "length" "4,4,8")])
7171 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7172 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7174 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7176 [(set (match_dup 0) (match_dup 1))
7178 (compare:CC (match_dup 0)
7182 (define_expand "mov<mode>"
7183 [(set (match_operand:INT 0 "general_operand")
7184 (match_operand:INT 1 "any_operand"))]
7187 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7191 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7192 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7193 ;; MTVSRWZ MF%1 MT%1 NOP
7194 (define_insn "*mov<mode>_internal"
7195 [(set (match_operand:QHI 0 "nonimmediate_operand"
7196 "=r, r, wa, m, Z, r,
7197 wa, wa, wa, v, ?v, r,
7199 (match_operand:QHI 1 "input_operand"
7201 wa, O, wM, wB, wS, wa,
7203 "gpc_reg_operand (operands[0], <MODE>mode)
7204 || gpc_reg_operand (operands[1], <MODE>mode)"
7223 "*, load, fpload, store, fpstore, *,
7224 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7225 mffgpr, mfjmpr, mtjmpr, *")
7231 "*, *, p9v, *, p9v, *,
7232 p9v, p9v, p9v, p9v, p9v, p9v,
7236 ;; Here is how to move condition codes around. When we store CC data in
7237 ;; an integer register or memory, we store just the high-order 4 bits.
7238 ;; This lets us not shift in the most common case of CR0.
7239 (define_expand "movcc"
7240 [(set (match_operand:CC 0 "nonimmediate_operand")
7241 (match_operand:CC 1 "nonimmediate_operand"))]
7245 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7247 (define_insn "*movcc_<mode>"
7248 [(set (match_operand:CC_any 0 "nonimmediate_operand"
7249 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7250 (match_operand:CC_any 1 "general_operand"
7251 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7252 "register_operand (operands[0], <MODE>mode)
7253 || register_operand (operands[1], <MODE>mode)"
7257 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7260 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7267 [(set_attr_alternative "type"
7268 [(const_string "cr_logical")
7269 (const_string "mtcr")
7270 (const_string "mtcr")
7271 (const_string "cr_logical")
7272 (if_then_else (match_test "TARGET_MFCRF")
7273 (const_string "mfcrf") (const_string "mfcr"))
7274 (if_then_else (match_test "TARGET_MFCRF")
7275 (const_string "mfcrf") (const_string "mfcr"))
7276 (const_string "integer")
7277 (const_string "integer")
7278 (const_string "mfjmpr")
7279 (const_string "mtjmpr")
7280 (const_string "load")
7281 (const_string "store")])
7282 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7284 ;; For floating-point, we normally deal with the floating-point registers
7285 ;; unless -msoft-float is used. The sole exception is that parameter passing
7286 ;; can produce floating-point values in fixed-point registers. Unless the
7287 ;; value is a simple constant or already in memory, we deal with this by
7288 ;; allocating memory and copying the value explicitly via that memory location.
7290 ;; Move 32-bit binary/decimal floating point
7291 (define_expand "mov<mode>"
7292 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7293 (match_operand:FMOVE32 1 "any_operand"))]
7296 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7301 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7302 (match_operand:FMOVE32 1 "const_double_operand"))]
7304 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7305 || (SUBREG_P (operands[0])
7306 && REG_P (SUBREG_REG (operands[0]))
7307 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7308 [(set (match_dup 2) (match_dup 3))]
7312 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7314 if (! TARGET_POWERPC64)
7315 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7317 operands[2] = gen_lowpart (SImode, operands[0]);
7319 operands[3] = gen_int_mode (l, SImode);
7322 ;; Originally, we tried to keep movsf and movsd common, but the differences
7323 ;; addressing was making it rather difficult to hide with mode attributes. In
7324 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7325 ;; before the VSX stores meant that the register allocator would tend to do a
7326 ;; direct move to the GPR (which involves conversion from scalar to
7327 ;; vector/memory formats) to save values in the traditional Altivec registers,
7328 ;; while SDmode had problems on power6 if the GPR store was not first due to
7329 ;; the power6 not having an integer store operation.
7331 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7332 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7333 ;; MR MT<x> MF<x> NOP
7335 (define_insn "movsf_hardfloat"
7336 [(set (match_operand:SF 0 "nonimmediate_operand"
7337 "=!r, f, v, wa, m, wY,
7338 Z, m, wa, !r, f, wa,
7340 (match_operand:SF 1 "input_operand"
7344 "(register_operand (operands[0], SFmode)
7345 || register_operand (operands[1], SFmode))
7346 && TARGET_HARD_FLOAT
7347 && (TARGET_ALLOW_SF_SUBREG
7348 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7361 xscpsgndp %x0,%x1,%x1
7367 "load, fpload, fpload, fpload, fpstore, fpstore,
7368 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7369 *, mtjmpr, mfjmpr, *")
7371 "*, *, p9v, p8v, *, p9v,
7375 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7376 ;; FMR MR MT%0 MF%1 NOP
7377 (define_insn "movsd_hardfloat"
7378 [(set (match_operand:SD 0 "nonimmediate_operand"
7379 "=!r, d, m, Z, ?d, ?r,
7380 f, !r, *c*l, !r, *h")
7381 (match_operand:SD 1 "input_operand"
7384 "(register_operand (operands[0], SDmode)
7385 || register_operand (operands[1], SDmode))
7386 && TARGET_HARD_FLOAT"
7400 "load, fpload, store, fpstore, mffgpr, mftgpr,
7401 fpsimple, *, mtjmpr, mfjmpr, *")
7403 "*, p7, *, *, p8v, p8v,
7406 ;; MR MT%0 MF%0 LWZ STW LI
7407 ;; LIS G-const. F/n-const NOP
7408 (define_insn "*mov<mode>_softfloat"
7409 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7410 "=r, *c*l, r, r, m, r,
7413 (match_operand:FMOVE32 1 "input_operand"
7417 "(gpc_reg_operand (operands[0], <MODE>mode)
7418 || gpc_reg_operand (operands[1], <MODE>mode))
7419 && TARGET_SOFT_FLOAT"
7432 "*, mtjmpr, mfjmpr, load, store, *,
7439 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7440 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7442 ;; Because SF values are actually stored as DF values within the vector
7443 ;; registers, we need to convert the value to the vector SF format when
7444 ;; we need to use the bits in a union or similar cases. We only need
7445 ;; to do this transformation when the value is a vector register. Loads,
7446 ;; stores, and transfers within GPRs are assumed to be safe.
7448 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7449 ;; no alternatives, because the call is created as part of secondary_reload,
7450 ;; and operand #2's register class is used to allocate the temporary register.
7451 ;; This function is called before reload, and it creates the temporary as
7454 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7455 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7456 (define_insn_and_split "movsf_from_si"
7457 [(set (match_operand:SF 0 "nonimmediate_operand"
7458 "=!r, f, v, wa, m, Z,
7460 (unspec:SF [(match_operand:SI 1 "input_operand"
7464 (clobber (match_scratch:DI 2
7467 "TARGET_NO_SF_SUBREG
7468 && (register_operand (operands[0], SFmode)
7469 || register_operand (operands[1], SImode))"
7482 "&& reload_completed
7483 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7484 && int_reg_operand_not_pseudo (operands[1], SImode)"
7487 rtx op0 = operands[0];
7488 rtx op1 = operands[1];
7489 rtx op2 = operands[2];
7490 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7492 /* Move SF value to upper 32-bits for xscvspdpn. */
7493 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7494 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7495 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7502 "load, fpload, fpload, fpload, store, fpstore,
7503 fpstore, vecfloat, mffgpr, *")
7505 "*, *, p9v, p8v, *, *,
7506 p8v, p8v, p8v, *")])
7509 ;; Move 64-bit binary/decimal floating point
7510 (define_expand "mov<mode>"
7511 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7512 (match_operand:FMOVE64 1 "any_operand"))]
7515 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7520 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7521 (match_operand:FMOVE64 1 "const_int_operand"))]
7522 "! TARGET_POWERPC64 && reload_completed
7523 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7524 || (SUBREG_P (operands[0])
7525 && REG_P (SUBREG_REG (operands[0]))
7526 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7527 [(set (match_dup 2) (match_dup 4))
7528 (set (match_dup 3) (match_dup 1))]
7530 int endian = (WORDS_BIG_ENDIAN == 0);
7531 HOST_WIDE_INT value = INTVAL (operands[1]);
7533 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7534 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7535 operands[4] = GEN_INT (value >> 32);
7536 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7540 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7541 (match_operand:FMOVE64 1 "const_double_operand"))]
7542 "! TARGET_POWERPC64 && reload_completed
7543 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7544 || (SUBREG_P (operands[0])
7545 && REG_P (SUBREG_REG (operands[0]))
7546 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7547 [(set (match_dup 2) (match_dup 4))
7548 (set (match_dup 3) (match_dup 5))]
7550 int endian = (WORDS_BIG_ENDIAN == 0);
7553 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7555 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7556 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7557 operands[4] = gen_int_mode (l[endian], SImode);
7558 operands[5] = gen_int_mode (l[1 - endian], SImode);
7562 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7563 (match_operand:FMOVE64 1 "const_double_operand"))]
7564 "TARGET_POWERPC64 && reload_completed
7565 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7566 || (SUBREG_P (operands[0])
7567 && REG_P (SUBREG_REG (operands[0]))
7568 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7569 [(set (match_dup 2) (match_dup 3))]
7571 int endian = (WORDS_BIG_ENDIAN == 0);
7575 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7577 operands[2] = gen_lowpart (DImode, operands[0]);
7578 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7579 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7580 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7582 operands[3] = gen_int_mode (val, DImode);
7585 ;; Don't have reload use general registers to load a constant. It is
7586 ;; less efficient than loading the constant into an FP register, since
7587 ;; it will probably be used there.
7589 ;; The move constraints are ordered to prefer floating point registers before
7590 ;; general purpose registers to avoid doing a store and a load to get the value
7591 ;; into a floating point register when it is needed for a floating point
7592 ;; operation. Prefer traditional floating point registers over VSX registers,
7593 ;; since the D-form version of the memory instructions does not need a GPR for
7594 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7597 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7598 ;; except for 0.0 which can be created on VSX with an xor instruction.
7600 ;; STFD LFD FMR LXSD STXSD
7601 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7605 (define_insn "*mov<mode>_hardfloat32"
7606 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7607 "=m, d, d, <f64_p9>, wY,
7608 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7610 (match_operand:FMOVE64 1 "input_operand"
7611 "d, m, d, wY, <f64_p9>,
7612 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7614 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7615 && (gpc_reg_operand (operands[0], <MODE>mode)
7616 || gpc_reg_operand (operands[1], <MODE>mode))"
7632 "fpstore, fpload, fpsimple, fpload, fpstore,
7633 fpload, fpstore, veclogical, veclogical, two,
7635 (set_attr "size" "64")
7645 ;; STW LWZ MR G-const H-const F-const
7647 (define_insn "*mov<mode>_softfloat32"
7648 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7649 "=Y, r, r, r, r, r")
7651 (match_operand:FMOVE64 1 "input_operand"
7652 "r, Y, r, G, H, F"))]
7655 && (gpc_reg_operand (operands[0], <MODE>mode)
7656 || gpc_reg_operand (operands[1], <MODE>mode))"
7659 "store, load, two, *, *, *")
7662 "8, 8, 8, 8, 12, 16")])
7664 ; ld/std require word-aligned displacements -> 'Y' constraint.
7665 ; List Y->r and r->Y before r->r for reload.
7667 ;; STFD LFD FMR LXSD STXSD
7668 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7669 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7670 ;; NOP MFVSRD MTVSRD
7672 (define_insn "*mov<mode>_hardfloat64"
7673 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7674 "=m, d, d, <f64_p9>, wY,
7675 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7676 YZ, r, !r, *c*l, !r,
7678 (match_operand:FMOVE64 1 "input_operand"
7679 "d, m, d, wY, <f64_p9>,
7680 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7683 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7684 && (gpc_reg_operand (operands[0], <MODE>mode)
7685 || gpc_reg_operand (operands[1], <MODE>mode))"
7706 "fpstore, fpload, fpsimple, fpload, fpstore,
7707 fpload, fpstore, veclogical, veclogical, integer,
7708 store, load, *, mtjmpr, mfjmpr,
7710 (set_attr "size" "64")
7717 ;; STD LD MR MT<SPR> MF<SPR> G-const
7718 ;; H-const F-const Special
7720 (define_insn "*mov<mode>_softfloat64"
7721 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7722 "=Y, r, r, *c*l, r, r,
7725 (match_operand:FMOVE64 1 "input_operand"
7729 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7730 && (gpc_reg_operand (operands[0], <MODE>mode)
7731 || gpc_reg_operand (operands[1], <MODE>mode))"
7743 "store, load, *, mtjmpr, mfjmpr, *,
7750 (define_expand "mov<mode>"
7751 [(set (match_operand:FMOVE128 0 "general_operand")
7752 (match_operand:FMOVE128 1 "any_operand"))]
7755 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7759 ;; It's important to list Y->r and r->Y before r->r because otherwise
7760 ;; reload, given m->r, will try to pick r->r and reload it, which
7761 ;; doesn't make progress.
7763 ;; We can't split little endian direct moves of TDmode, because the words are
7764 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7765 ;; problematical. Don't allow direct move for this case.
7767 ;; FPR load FPR store FPR move FPR zero GPR load
7768 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
7770 (define_insn_and_split "*mov<mode>_64bit_dm"
7771 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7775 (match_operand:FMOVE128_FPR 1 "input_operand"
7776 "d, m, d, <zero_fp>, r,
7777 <zero_fp>, Y, r, d, r"))]
7779 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7780 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7781 && (gpc_reg_operand (operands[0], <MODE>mode)
7782 || gpc_reg_operand (operands[1], <MODE>mode))"
7784 "&& reload_completed"
7787 rs6000_split_multireg_move (operands[0], operands[1]);
7790 [(set_attr "length" "8")
7791 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7792 (set_attr "max_prefixed_insns" "2")
7793 (set_attr "num_insns" "2")])
7795 (define_insn_and_split "*movtd_64bit_nodm"
7796 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7797 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7798 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7799 && (gpc_reg_operand (operands[0], TDmode)
7800 || gpc_reg_operand (operands[1], TDmode))"
7802 "&& reload_completed"
7805 rs6000_split_multireg_move (operands[0], operands[1]);
7808 [(set_attr "length" "8,8,8,12,12,8")
7809 (set_attr "max_prefixed_insns" "2")
7810 (set_attr "num_insns" "2,2,2,3,3,2")])
7812 (define_insn_and_split "*mov<mode>_32bit"
7813 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7814 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7815 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7816 && (FLOAT128_2REG_P (<MODE>mode)
7817 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7818 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7819 && (gpc_reg_operand (operands[0], <MODE>mode)
7820 || gpc_reg_operand (operands[1], <MODE>mode))"
7822 "&& reload_completed"
7825 rs6000_split_multireg_move (operands[0], operands[1]);
7828 [(set_attr "length" "8,8,8,8,20,20,16")])
7830 (define_insn_and_split "*mov<mode>_softfloat"
7831 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7832 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7834 && (gpc_reg_operand (operands[0], <MODE>mode)
7835 || gpc_reg_operand (operands[1], <MODE>mode))"
7837 "&& reload_completed"
7840 rs6000_split_multireg_move (operands[0], operands[1]);
7843 [(set_attr_alternative "length"
7844 [(if_then_else (match_test "TARGET_POWERPC64")
7846 (const_string "16"))
7847 (if_then_else (match_test "TARGET_POWERPC64")
7849 (const_string "16"))
7850 (if_then_else (match_test "TARGET_POWERPC64")
7852 (const_string "32"))
7853 (if_then_else (match_test "TARGET_POWERPC64")
7855 (const_string "16"))])])
7857 (define_expand "@extenddf<mode>2"
7858 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7859 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7860 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7862 if (FLOAT128_IEEE_P (<MODE>mode))
7863 rs6000_expand_float128_convert (operands[0], operands[1], false);
7864 else if (TARGET_VSX)
7865 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7868 rtx zero = gen_reg_rtx (DFmode);
7869 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7871 emit_insn (gen_extenddf2_fprs (<MODE>mode,
7872 operands[0], operands[1], zero));
7877 ;; Allow memory operands for the source to be created by the combiner.
7878 (define_insn_and_split "@extenddf<mode>2_fprs"
7879 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7880 (float_extend:IBM128
7881 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7882 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7883 "!TARGET_VSX && TARGET_HARD_FLOAT
7884 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7886 "&& reload_completed"
7887 [(set (match_dup 3) (match_dup 1))
7888 (set (match_dup 4) (match_dup 2))]
7890 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7891 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7893 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7894 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7897 (define_insn_and_split "@extenddf<mode>2_vsx"
7898 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7899 (float_extend:IBM128
7900 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7901 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7903 "&& reload_completed"
7904 [(set (match_dup 2) (match_dup 1))
7905 (set (match_dup 3) (match_dup 4))]
7907 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7908 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7910 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7911 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7912 operands[4] = CONST0_RTX (DFmode);
7915 (define_expand "extendsf<mode>2"
7916 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7917 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7918 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7920 if (FLOAT128_IEEE_P (<MODE>mode))
7921 rs6000_expand_float128_convert (operands[0], operands[1], false);
7924 rtx tmp = gen_reg_rtx (DFmode);
7925 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7926 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7931 (define_expand "trunc<mode>df2"
7932 [(set (match_operand:DF 0 "gpc_reg_operand")
7933 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7934 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7936 if (FLOAT128_IEEE_P (<MODE>mode))
7938 rs6000_expand_float128_convert (operands[0], operands[1], false);
7943 (define_insn_and_split "trunc<mode>df2_internal1"
7944 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7946 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7947 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7948 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7952 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7955 emit_note (NOTE_INSN_DELETED);
7958 [(set_attr "type" "fpsimple")])
7960 (define_insn "trunc<mode>df2_internal2"
7961 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7962 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7963 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7964 && TARGET_LONG_DOUBLE_128"
7966 [(set_attr "type" "fp")])
7968 (define_expand "trunc<mode>sf2"
7969 [(set (match_operand:SF 0 "gpc_reg_operand")
7970 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7971 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7973 if (FLOAT128_IEEE_P (<MODE>mode))
7974 rs6000_expand_float128_convert (operands[0], operands[1], false);
7977 rtx tmp = gen_reg_rtx (DFmode);
7978 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7979 emit_insn (gen_truncdfsf2 (operands[0], tmp));
7984 (define_expand "floatsi<mode>2"
7985 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7986 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7987 (clobber (match_scratch:DI 2))])]
7988 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7990 rtx op0 = operands[0];
7991 rtx op1 = operands[1];
7993 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7995 else if (FLOAT128_IEEE_P (<MODE>mode))
7997 rs6000_expand_float128_convert (op0, op1, false);
8002 rtx tmp = gen_reg_rtx (DFmode);
8003 expand_float (tmp, op1, false);
8004 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8009 ; fadd, but rounding towards zero.
8010 ; This is probably not the optimal code sequence.
8011 (define_insn "fix_trunc_helper<mode>"
8012 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8013 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8014 UNSPEC_FIX_TRUNC_TF))
8015 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8016 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8017 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8018 [(set_attr "type" "fp")
8019 (set_attr "length" "20")])
8021 (define_expand "fix_trunc<mode>si2"
8022 [(set (match_operand:SI 0 "gpc_reg_operand")
8023 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8024 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8026 rtx op0 = operands[0];
8027 rtx op1 = operands[1];
8029 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8033 if (FLOAT128_IEEE_P (<MODE>mode))
8034 rs6000_expand_float128_convert (op0, op1, false);
8036 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8041 (define_expand "@fix_trunc<mode>si2_fprs"
8042 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8043 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8044 (clobber (match_dup 2))
8045 (clobber (match_dup 3))
8046 (clobber (match_dup 4))
8047 (clobber (match_dup 5))])]
8048 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8050 operands[2] = gen_reg_rtx (DFmode);
8051 operands[3] = gen_reg_rtx (DFmode);
8052 operands[4] = gen_reg_rtx (DImode);
8053 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8056 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8057 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8058 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8059 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8060 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8061 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8062 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8063 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8069 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8072 gcc_assert (MEM_P (operands[5]));
8073 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8075 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8076 emit_move_insn (operands[5], operands[4]);
8077 emit_move_insn (operands[0], lowword);
8081 (define_expand "fix_trunc<mode>di2"
8082 [(set (match_operand:DI 0 "gpc_reg_operand")
8083 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8084 "TARGET_FLOAT128_TYPE"
8086 if (!TARGET_FLOAT128_HW)
8088 rs6000_expand_float128_convert (operands[0], operands[1], false);
8093 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8094 [(set (match_operand:SDI 0 "gpc_reg_operand")
8095 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8096 "TARGET_FLOAT128_TYPE"
8098 rs6000_expand_float128_convert (operands[0], operands[1], true);
8102 (define_expand "floatdi<mode>2"
8103 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8104 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8105 "TARGET_FLOAT128_TYPE"
8107 if (!TARGET_FLOAT128_HW)
8109 rs6000_expand_float128_convert (operands[0], operands[1], false);
8114 (define_expand "floatunsdi<IEEE128:mode>2"
8115 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8116 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8117 "TARGET_FLOAT128_TYPE"
8119 if (!TARGET_FLOAT128_HW)
8121 rs6000_expand_float128_convert (operands[0], operands[1], true);
8126 (define_expand "floatuns<IEEE128:mode>2"
8127 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8128 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8129 "TARGET_FLOAT128_TYPE"
8131 rtx op0 = operands[0];
8132 rtx op1 = operands[1];
8134 if (TARGET_FLOAT128_HW)
8135 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8137 rs6000_expand_float128_convert (op0, op1, true);
8141 (define_expand "neg<mode>2"
8142 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8143 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8144 "FLOAT128_IEEE_P (<MODE>mode)
8145 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8147 if (FLOAT128_IEEE_P (<MODE>mode))
8149 if (TARGET_FLOAT128_HW)
8150 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8151 else if (TARGET_FLOAT128_TYPE)
8152 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8153 operands[0], operands[1]));
8156 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8157 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8159 operands[1], <MODE>mode);
8161 if (target && !rtx_equal_p (target, operands[0]))
8162 emit_move_insn (operands[0], target);
8168 (define_insn "neg<mode>2_internal"
8169 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8170 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8171 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8173 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8174 return "fneg %L0,%L1\;fneg %0,%1";
8176 return "fneg %0,%1\;fneg %L0,%L1";
8178 [(set_attr "type" "fpsimple")
8179 (set_attr "length" "8")])
8181 (define_expand "abs<mode>2"
8182 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8183 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8184 "FLOAT128_IEEE_P (<MODE>mode)
8185 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8189 if (FLOAT128_IEEE_P (<MODE>mode))
8191 if (TARGET_FLOAT128_HW)
8193 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8196 else if (TARGET_FLOAT128_TYPE)
8198 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8199 operands[0], operands[1]));
8206 label = gen_label_rtx ();
8207 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8212 (define_expand "@abs<mode>2_internal"
8213 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8214 (match_operand:IBM128 1 "gpc_reg_operand"))
8215 (set (match_dup 3) (match_dup 5))
8216 (set (match_dup 5) (abs:DF (match_dup 5)))
8217 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8218 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8219 (label_ref (match_operand 2 ""))
8221 (set (match_dup 6) (neg:DF (match_dup 6)))]
8222 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8224 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8225 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8226 operands[3] = gen_reg_rtx (DFmode);
8227 operands[4] = gen_reg_rtx (CCFPmode);
8228 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8229 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8233 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8236 (define_expand "ieee_128bit_negative_zero"
8237 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8238 "TARGET_FLOAT128_TYPE"
8240 rtvec v = rtvec_alloc (16);
8243 for (i = 0; i < 16; i++)
8244 RTVEC_ELT (v, i) = const0_rtx;
8246 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8247 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8249 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8253 ;; IEEE 128-bit negate
8255 ;; We have 2 insns here for negate and absolute value. The first uses
8256 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8257 ;; insns, and second insn after the first split pass loads up the bit to
8258 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8259 ;; neg/abs to create the constant just once.
8261 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8262 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8263 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8264 (clobber (match_scratch:V16QI 2 "=v"))]
8265 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8268 [(parallel [(set (match_dup 0)
8269 (neg:IEEE128 (match_dup 1)))
8270 (use (match_dup 2))])]
8272 if (GET_CODE (operands[2]) == SCRATCH)
8273 operands[2] = gen_reg_rtx (V16QImode);
8275 operands[3] = gen_reg_rtx (V16QImode);
8276 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8278 [(set_attr "length" "8")
8279 (set_attr "type" "vecsimple")])
8281 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8282 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8283 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8284 (use (match_operand:V16QI 2 "register_operand" "v"))]
8285 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8286 "xxlxor %x0,%x1,%x2"
8287 [(set_attr "type" "veclogical")])
8289 ;; IEEE 128-bit absolute value
8290 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8291 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8292 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8293 (clobber (match_scratch:V16QI 2 "=v"))]
8294 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8297 [(parallel [(set (match_dup 0)
8298 (abs:IEEE128 (match_dup 1)))
8299 (use (match_dup 2))])]
8301 if (GET_CODE (operands[2]) == SCRATCH)
8302 operands[2] = gen_reg_rtx (V16QImode);
8304 operands[3] = gen_reg_rtx (V16QImode);
8305 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8307 [(set_attr "length" "8")
8308 (set_attr "type" "vecsimple")])
8310 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8311 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8312 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8313 (use (match_operand:V16QI 2 "register_operand" "v"))]
8314 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8315 "xxlandc %x0,%x1,%x2"
8316 [(set_attr "type" "veclogical")])
8318 ;; IEEE 128-bit negative absolute value
8319 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8320 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8323 (match_operand:IEEE128 1 "register_operand" "wa"))))
8324 (clobber (match_scratch:V16QI 2 "=v"))]
8325 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8326 && FLOAT128_IEEE_P (<MODE>mode)"
8329 [(parallel [(set (match_dup 0)
8330 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8331 (use (match_dup 2))])]
8333 if (GET_CODE (operands[2]) == SCRATCH)
8334 operands[2] = gen_reg_rtx (V16QImode);
8336 operands[3] = gen_reg_rtx (V16QImode);
8337 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8339 [(set_attr "length" "8")
8340 (set_attr "type" "vecsimple")])
8342 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8343 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8346 (match_operand:IEEE128 1 "register_operand" "wa"))))
8347 (use (match_operand:V16QI 2 "register_operand" "v"))]
8348 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8350 [(set_attr "type" "veclogical")])
8352 ;; Float128 conversion functions. These expand to library function calls.
8353 ;; We use expand to convert from IBM double double to IEEE 128-bit
8354 ;; and trunc for the opposite.
8355 (define_expand "extendiftf2"
8356 [(set (match_operand:TF 0 "gpc_reg_operand")
8357 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8358 "TARGET_FLOAT128_TYPE"
8360 rs6000_expand_float128_convert (operands[0], operands[1], false);
8364 (define_expand "extendifkf2"
8365 [(set (match_operand:KF 0 "gpc_reg_operand")
8366 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8367 "TARGET_FLOAT128_TYPE"
8369 rs6000_expand_float128_convert (operands[0], operands[1], false);
8373 (define_expand "extendtfkf2"
8374 [(set (match_operand:KF 0 "gpc_reg_operand")
8375 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8376 "TARGET_FLOAT128_TYPE"
8378 rs6000_expand_float128_convert (operands[0], operands[1], false);
8382 (define_expand "extendtfif2"
8383 [(set (match_operand:IF 0 "gpc_reg_operand")
8384 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8385 "TARGET_FLOAT128_TYPE"
8387 rs6000_expand_float128_convert (operands[0], operands[1], false);
8391 (define_expand "trunciftf2"
8392 [(set (match_operand:TF 0 "gpc_reg_operand")
8393 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8394 "TARGET_FLOAT128_TYPE"
8396 rs6000_expand_float128_convert (operands[0], operands[1], false);
8400 (define_expand "truncifkf2"
8401 [(set (match_operand:KF 0 "gpc_reg_operand")
8402 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8403 "TARGET_FLOAT128_TYPE"
8405 rs6000_expand_float128_convert (operands[0], operands[1], false);
8409 (define_expand "trunckftf2"
8410 [(set (match_operand:TF 0 "gpc_reg_operand")
8411 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8412 "TARGET_FLOAT128_TYPE"
8414 rs6000_expand_float128_convert (operands[0], operands[1], false);
8418 (define_expand "trunctfif2"
8419 [(set (match_operand:IF 0 "gpc_reg_operand")
8420 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8421 "TARGET_FLOAT128_TYPE"
8423 rs6000_expand_float128_convert (operands[0], operands[1], false);
8427 (define_insn_and_split "*extend<mode>tf2_internal"
8428 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8430 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8431 "TARGET_FLOAT128_TYPE
8432 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8434 "&& reload_completed"
8435 [(set (match_dup 0) (match_dup 2))]
8437 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8440 (define_insn_and_split "*extendtf<mode>2_internal"
8441 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8443 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8444 "TARGET_FLOAT128_TYPE
8445 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8447 "&& reload_completed"
8448 [(set (match_dup 0) (match_dup 2))]
8450 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8454 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8455 ;; must have 3 arguments, and scratch register constraint must be a single
8458 ;; Reload patterns to support gpr load/store with misaligned mem.
8459 ;; and multiple gpr load/store at offset >= 0xfffc
8460 (define_expand "reload_<mode>_store"
8461 [(parallel [(match_operand 0 "memory_operand" "=m")
8462 (match_operand 1 "gpc_reg_operand" "r")
8463 (match_operand:GPR 2 "register_operand" "=&b")])]
8466 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8470 (define_expand "reload_<mode>_load"
8471 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8472 (match_operand 1 "memory_operand" "m")
8473 (match_operand:GPR 2 "register_operand" "=b")])]
8476 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8481 ;; Reload patterns for various types using the vector registers. We may need
8482 ;; an additional base register to convert the reg+offset addressing to reg+reg
8483 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8484 ;; index register for gpr registers.
8485 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8486 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8487 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8488 (match_operand:P 2 "register_operand" "=b")])]
8491 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8495 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8496 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8497 (match_operand:RELOAD 1 "memory_operand" "m")
8498 (match_operand:P 2 "register_operand" "=b")])]
8501 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8506 ;; Reload sometimes tries to move the address to a GPR, and can generate
8507 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8508 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8510 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8511 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8512 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8513 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8515 "TARGET_ALTIVEC && reload_completed"
8517 "&& reload_completed"
8519 (plus:P (match_dup 1)
8522 (and:P (match_dup 0)
8525 ;; Power8 merge instructions to allow direct move to/from floating point
8526 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8527 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8528 ;; value, since it is allocated in reload and not all of the flow information
8529 ;; is setup for it. We have two patterns to do the two moves between gprs and
8530 ;; fprs. There isn't a dependancy between the two, but we could potentially
8531 ;; schedule other instructions between the two instructions.
8533 (define_insn "p8_fmrgow_<mode>"
8534 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8536 (match_operand:DF 1 "register_operand" "d")
8537 (match_operand:DF 2 "register_operand" "d")]
8538 UNSPEC_P8V_FMRGOW))]
8539 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8541 [(set_attr "type" "fpsimple")])
8543 (define_insn "p8_mtvsrwz"
8544 [(set (match_operand:DF 0 "register_operand" "=d")
8545 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8546 UNSPEC_P8V_MTVSRWZ))]
8547 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8549 [(set_attr "type" "mftgpr")])
8551 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8552 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8553 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8554 UNSPEC_P8V_RELOAD_FROM_GPR))
8555 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8556 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8558 "&& reload_completed"
8561 rtx dest = operands[0];
8562 rtx src = operands[1];
8563 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8564 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8565 rtx gpr_hi_reg = gen_highpart (SImode, src);
8566 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8568 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8569 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8570 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8573 [(set_attr "length" "12")
8574 (set_attr "type" "three")])
8576 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8577 (define_insn "p8_mtvsrd_df"
8578 [(set (match_operand:DF 0 "register_operand" "=wa")
8579 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8580 UNSPEC_P8V_MTVSRD))]
8581 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8583 [(set_attr "type" "mftgpr")])
8585 (define_insn "p8_xxpermdi_<mode>"
8586 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8587 (unspec:FMOVE128_GPR [
8588 (match_operand:DF 1 "register_operand" "wa")
8589 (match_operand:DF 2 "register_operand" "wa")]
8590 UNSPEC_P8V_XXPERMDI))]
8591 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8592 "xxpermdi %x0,%x1,%x2,0"
8593 [(set_attr "type" "vecperm")])
8595 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8596 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8597 (unspec:FMOVE128_GPR
8598 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8599 UNSPEC_P8V_RELOAD_FROM_GPR))
8600 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8601 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8603 "&& reload_completed"
8606 rtx dest = operands[0];
8607 rtx src = operands[1];
8608 /* You might think that we could use op0 as one temp and a DF clobber
8609 as op2, but you'd be wrong. Secondary reload move patterns don't
8610 check for overlap of the clobber and the destination. */
8611 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8612 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8613 rtx gpr_hi_reg = gen_highpart (DImode, src);
8614 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8616 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8617 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8618 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8621 [(set_attr "length" "12")
8622 (set_attr "type" "three")])
8625 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8626 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8628 && (int_reg_operand (operands[0], <MODE>mode)
8629 || int_reg_operand (operands[1], <MODE>mode))
8630 && (!TARGET_DIRECT_MOVE_128
8631 || (!vsx_register_operand (operands[0], <MODE>mode)
8632 && !vsx_register_operand (operands[1], <MODE>mode)))"
8635 rs6000_split_multireg_move (operands[0], operands[1]);
8639 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8640 ;; type is stored internally as double precision in the VSX registers, we have
8641 ;; to convert it from the vector format.
8642 (define_insn "p8_mtvsrd_sf"
8643 [(set (match_operand:SF 0 "register_operand" "=wa")
8644 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8645 UNSPEC_P8V_MTVSRD))]
8646 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8648 [(set_attr "type" "mftgpr")])
8650 (define_insn_and_split "reload_vsx_from_gprsf"
8651 [(set (match_operand:SF 0 "register_operand" "=wa")
8652 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8653 UNSPEC_P8V_RELOAD_FROM_GPR))
8654 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8655 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8657 "&& reload_completed"
8660 rtx op0 = operands[0];
8661 rtx op1 = operands[1];
8662 rtx op2 = operands[2];
8663 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8665 /* Move SF value to upper 32-bits for xscvspdpn. */
8666 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8667 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8668 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8671 [(set_attr "length" "8")
8672 (set_attr "type" "two")])
8674 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8675 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8676 ;; and then doing a move of that.
8677 (define_insn "p8_mfvsrd_3_<mode>"
8678 [(set (match_operand:DF 0 "register_operand" "=r")
8679 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8680 UNSPEC_P8V_RELOAD_FROM_VSX))]
8681 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8683 [(set_attr "type" "mftgpr")])
8685 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8686 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8687 (unspec:FMOVE128_GPR
8688 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8689 UNSPEC_P8V_RELOAD_FROM_VSX))
8690 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8691 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8693 "&& reload_completed"
8696 rtx dest = operands[0];
8697 rtx src = operands[1];
8698 rtx tmp = operands[2];
8699 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8700 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8702 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8703 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8704 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8707 [(set_attr "length" "12")
8708 (set_attr "type" "three")])
8710 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8711 ;; type is stored internally as double precision, we have to convert it to the
8714 (define_insn_and_split "reload_gpr_from_vsxsf"
8715 [(set (match_operand:SF 0 "register_operand" "=r")
8716 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8717 UNSPEC_P8V_RELOAD_FROM_VSX))
8718 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8719 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8721 "&& reload_completed"
8724 rtx op0 = operands[0];
8725 rtx op1 = operands[1];
8726 rtx op2 = operands[2];
8727 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8728 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8730 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8731 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8734 [(set_attr "length" "8")
8735 (set_attr "type" "two")
8736 (set_attr "isa" "p8v")])
8738 ;; Next come the multi-word integer load and store and the load and store
8741 ;; List r->r after r->Y, otherwise reload will try to reload a
8742 ;; non-offsettable address by using r->r which won't make progress.
8743 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8744 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8746 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8747 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8748 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8751 (define_insn "*movdi_internal32"
8752 [(set (match_operand:DI 0 "nonimmediate_operand"
8753 "=Y, r, r, m, ^d, ^d,
8754 r, wY, Z, ^v, $v, ^wa,
8755 wa, wa, v, wa, *i, v,
8757 (match_operand:DI 1 "input_operand"
8758 "r, Y, r, ^d, m, ^d,
8759 IJKnF, ^v, $v, wY, Z, ^wa,
8760 Oj, wM, OjwM, Oj, wM, wS,
8763 && (gpc_reg_operand (operands[0], DImode)
8764 || gpc_reg_operand (operands[1], DImode))"
8786 "store, load, *, fpstore, fpload, fpsimple,
8787 *, fpstore, fpstore, fpload, fpload, veclogical,
8788 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8790 (set_attr "size" "64")
8798 *, p9v, p7v, p9v, p7v, *,
8799 p9v, p9v, p7v, *, *, p7v,
8803 [(set (match_operand:DI 0 "gpc_reg_operand")
8804 (match_operand:DI 1 "const_int_operand"))]
8805 "! TARGET_POWERPC64 && reload_completed
8806 && gpr_or_gpr_p (operands[0], operands[1])
8807 && !direct_move_p (operands[0], operands[1])"
8808 [(set (match_dup 2) (match_dup 4))
8809 (set (match_dup 3) (match_dup 1))]
8811 HOST_WIDE_INT value = INTVAL (operands[1]);
8812 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8814 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8816 operands[4] = GEN_INT (value >> 32);
8817 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8821 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8822 (match_operand:DIFD 1 "input_operand"))]
8823 "reload_completed && !TARGET_POWERPC64
8824 && gpr_or_gpr_p (operands[0], operands[1])
8825 && !direct_move_p (operands[0], operands[1])"
8828 rs6000_split_multireg_move (operands[0], operands[1]);
8832 ;; GPR store GPR load GPR move
8833 ;; GPR li GPR lis GPR pli GPR #
8834 ;; FPR store FPR load FPR move
8835 ;; AVX store AVX store AVX load AVX load VSX move
8836 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1
8837 ;; P9 const AVX const
8838 ;; From SPR To SPR SPR<->SPR
8839 ;; VSX->GPR GPR->VSX
8840 (define_insn "*movdi_internal64"
8841 [(set (match_operand:DI 0 "nonimmediate_operand"
8850 (match_operand:DI 1 "input_operand"
8855 Oj, wM, OjwM, Oj, wM,
8860 && (gpc_reg_operand (operands[0], DImode)
8861 || gpc_reg_operand (operands[1], DImode))"
8893 fpstore, fpload, fpsimple,
8894 fpstore, fpstore, fpload, fpload, veclogical,
8895 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
8896 vecsimple, vecsimple,
8899 (set_attr "size" "64")
8913 p9v, p7v, p9v, p7v, *,
8914 p9v, p9v, p7v, *, *,
8919 ; Some DImode loads are best done as a load of -1 followed by a mask
8922 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8923 (match_operand:DI 1 "const_int_operand"))]
8925 && num_insns_constant (operands[1], DImode) > 1
8926 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8927 && rs6000_is_valid_and_mask (operands[1], DImode)"
8931 (and:DI (match_dup 0)
8935 ;; Split a load of a large constant into the appropriate five-instruction
8936 ;; sequence. Handle anything in a constant number of insns.
8937 ;; When non-easy constants can go in the TOC, this should use
8938 ;; easy_fp_constant predicate.
8940 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8941 (match_operand:DI 1 "const_int_operand"))]
8942 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8943 [(set (match_dup 0) (match_dup 2))
8944 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8946 if (rs6000_emit_set_const (operands[0], operands[1]))
8953 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8954 (match_operand:DI 1 "const_scalar_int_operand"))]
8955 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8956 [(set (match_dup 0) (match_dup 2))
8957 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8959 if (rs6000_emit_set_const (operands[0], operands[1]))
8966 [(set (match_operand:DI 0 "altivec_register_operand")
8967 (match_operand:DI 1 "s5bit_cint_operand"))]
8968 "TARGET_VSX && reload_completed"
8971 rtx op0 = operands[0];
8972 rtx op1 = operands[1];
8973 int r = REGNO (op0);
8974 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8976 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8977 if (op1 != const0_rtx && op1 != constm1_rtx)
8979 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8980 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8985 ;; Split integer constants that can be loaded with XXSPLTIB and a
8986 ;; sign extend operation.
8988 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8989 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8990 "TARGET_P9_VECTOR && reload_completed"
8993 rtx op0 = operands[0];
8994 rtx op1 = operands[1];
8995 int r = REGNO (op0);
8996 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8998 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8999 if (<MODE>mode == DImode)
9000 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9001 else if (<MODE>mode == SImode)
9002 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9003 else if (<MODE>mode == HImode)
9005 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9006 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9012 ;; TImode/PTImode is similar, except that we usually want to compute the
9013 ;; address into a register and use lsi/stsi (the exception is during reload).
9015 (define_insn "*mov<mode>_string"
9016 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9017 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9019 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9020 && (gpc_reg_operand (operands[0], <MODE>mode)
9021 || gpc_reg_operand (operands[1], <MODE>mode))"
9023 [(set_attr "type" "store,store,load,load,*,*")
9024 (set_attr "update" "yes")
9025 (set_attr "indexed" "yes")
9026 (set_attr "cell_micro" "conditional")])
9028 (define_insn "*mov<mode>_ppc64"
9029 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9030 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9031 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9032 && (gpc_reg_operand (operands[0], <MODE>mode)
9033 || gpc_reg_operand (operands[1], <MODE>mode)))"
9035 return rs6000_output_move_128bit (operands);
9037 [(set_attr "type" "store,store,load,load,*,*")
9038 (set_attr "length" "8")
9039 (set_attr "max_prefixed_insns" "2")])
9042 [(set (match_operand:TI2 0 "int_reg_operand")
9043 (match_operand:TI2 1 "const_scalar_int_operand"))]
9045 && (VECTOR_MEM_NONE_P (<MODE>mode)
9046 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9047 [(set (match_dup 2) (match_dup 4))
9048 (set (match_dup 3) (match_dup 5))]
9050 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9052 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9054 if (CONST_WIDE_INT_P (operands[1]))
9056 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9057 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9059 else if (CONST_INT_P (operands[1]))
9061 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9062 operands[5] = operands[1];
9069 [(set (match_operand:TI2 0 "nonimmediate_operand")
9070 (match_operand:TI2 1 "input_operand"))]
9072 && gpr_or_gpr_p (operands[0], operands[1])
9073 && !direct_move_p (operands[0], operands[1])
9074 && !quad_load_store_p (operands[0], operands[1])"
9077 rs6000_split_multireg_move (operands[0], operands[1]);
9081 (define_expand "setmemsi"
9082 [(parallel [(set (match_operand:BLK 0 "")
9083 (match_operand 2 "const_int_operand"))
9084 (use (match_operand:SI 1 ""))
9085 (use (match_operand:SI 3 ""))])]
9088 /* If value to set is not zero, use the library routine. */
9089 if (operands[2] != const0_rtx)
9092 if (expand_block_clear (operands))
9098 ;; String compare N insn.
9099 ;; Argument 0 is the target (result)
9100 ;; Argument 1 is the destination
9101 ;; Argument 2 is the source
9102 ;; Argument 3 is the length
9103 ;; Argument 4 is the alignment
9105 (define_expand "cmpstrnsi"
9106 [(parallel [(set (match_operand:SI 0)
9107 (compare:SI (match_operand:BLK 1)
9108 (match_operand:BLK 2)))
9109 (use (match_operand:SI 3))
9110 (use (match_operand:SI 4))])]
9111 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9113 if (optimize_insn_for_size_p ())
9116 if (expand_strn_compare (operands, 0))
9122 ;; String compare insn.
9123 ;; Argument 0 is the target (result)
9124 ;; Argument 1 is the destination
9125 ;; Argument 2 is the source
9126 ;; Argument 3 is the alignment
9128 (define_expand "cmpstrsi"
9129 [(parallel [(set (match_operand:SI 0)
9130 (compare:SI (match_operand:BLK 1)
9131 (match_operand:BLK 2)))
9132 (use (match_operand:SI 3))])]
9133 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9135 if (optimize_insn_for_size_p ())
9138 if (expand_strn_compare (operands, 1))
9144 ;; Block compare insn.
9145 ;; Argument 0 is the target (result)
9146 ;; Argument 1 is the destination
9147 ;; Argument 2 is the source
9148 ;; Argument 3 is the length
9149 ;; Argument 4 is the alignment
9151 (define_expand "cmpmemsi"
9152 [(parallel [(set (match_operand:SI 0)
9153 (compare:SI (match_operand:BLK 1)
9154 (match_operand:BLK 2)))
9155 (use (match_operand:SI 3))
9156 (use (match_operand:SI 4))])]
9159 if (expand_block_compare (operands))
9165 ;; String/block copy insn (source and destination must not overlap).
9166 ;; Argument 0 is the destination
9167 ;; Argument 1 is the source
9168 ;; Argument 2 is the length
9169 ;; Argument 3 is the alignment
9171 (define_expand "cpymemsi"
9172 [(parallel [(set (match_operand:BLK 0 "")
9173 (match_operand:BLK 1 ""))
9174 (use (match_operand:SI 2 ""))
9175 (use (match_operand:SI 3 ""))])]
9178 if (expand_block_move (operands, false))
9184 ;; String/block move insn (source and destination may overlap).
9185 ;; Argument 0 is the destination
9186 ;; Argument 1 is the source
9187 ;; Argument 2 is the length
9188 ;; Argument 3 is the alignment
9190 (define_expand "movmemsi"
9191 [(parallel [(set (match_operand:BLK 0 "")
9192 (match_operand:BLK 1 ""))
9193 (use (match_operand:SI 2 ""))
9194 (use (match_operand:SI 3 ""))])]
9197 if (expand_block_move (operands, true))
9204 ;; Define insns that do load or store with update. Some of these we can
9205 ;; get by using pre-decrement or pre-increment, but the hardware can also
9206 ;; do cases where the increment is not the size of the object.
9208 ;; In all these cases, we use operands 0 and 1 for the register being
9209 ;; incremented because those are the operands that local-alloc will
9210 ;; tie and these are the pair most likely to be tieable (and the ones
9211 ;; that will benefit the most).
9213 (define_insn "*movdi_update1"
9214 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9215 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9216 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9217 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9218 (plus:P (match_dup 1) (match_dup 2)))]
9219 "TARGET_POWERPC64 && TARGET_UPDATE
9220 && (!avoiding_indexed_address_p (DImode)
9221 || !gpc_reg_operand (operands[2], Pmode))"
9225 [(set_attr "type" "load")
9226 (set_attr "update" "yes")
9227 (set_attr "indexed" "yes,no")])
9229 (define_insn "movdi_<mode>_update"
9230 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9231 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9232 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9233 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9234 (plus:P (match_dup 1) (match_dup 2)))]
9235 "TARGET_POWERPC64 && TARGET_UPDATE
9236 && (!avoiding_indexed_address_p (DImode)
9237 || !gpc_reg_operand (operands[2], Pmode)
9238 || (REG_P (operands[0])
9239 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9243 [(set_attr "type" "store")
9244 (set_attr "update" "yes")
9245 (set_attr "indexed" "yes,no")])
9247 ;; This pattern is only conditional on TARGET_64BIT, as it is
9248 ;; needed for stack allocation, even if the user passes -mno-update.
9249 (define_insn "movdi_update_stack"
9250 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9251 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9252 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9253 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9254 (plus:DI (match_dup 1) (match_dup 2)))]
9259 [(set_attr "type" "store")
9260 (set_attr "update" "yes")
9261 (set_attr "indexed" "yes,no")])
9263 (define_insn "*movsi_update1"
9264 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9265 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9266 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9267 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9268 (plus:P (match_dup 1) (match_dup 2)))]
9270 && (!avoiding_indexed_address_p (SImode)
9271 || !gpc_reg_operand (operands[2], Pmode))"
9275 [(set_attr "type" "load")
9276 (set_attr "update" "yes")
9277 (set_attr "indexed" "yes,no")])
9279 (define_insn "*movsi_update2"
9280 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9282 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9283 (match_operand:P 2 "gpc_reg_operand" "r")))))
9284 (set (match_operand:P 0 "gpc_reg_operand" "=b")
9285 (plus:P (match_dup 1) (match_dup 2)))]
9286 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9288 [(set_attr "type" "load")
9289 (set_attr "sign_extend" "yes")
9290 (set_attr "update" "yes")
9291 (set_attr "indexed" "yes")])
9293 (define_insn "movsi_<mode>_update"
9294 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9295 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9296 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9297 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9298 (plus:P (match_dup 1) (match_dup 2)))]
9300 && (!avoiding_indexed_address_p (SImode)
9301 || !gpc_reg_operand (operands[2], Pmode)
9302 || (REG_P (operands[0])
9303 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9307 [(set_attr "type" "store")
9308 (set_attr "update" "yes")
9309 (set_attr "indexed" "yes,no")])
9311 ;; This is an unconditional pattern; needed for stack allocation, even
9312 ;; if the user passes -mno-update.
9313 (define_insn "movsi_update_stack"
9314 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9315 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9316 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9317 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9318 (plus:SI (match_dup 1) (match_dup 2)))]
9323 [(set_attr "type" "store")
9324 (set_attr "update" "yes")
9325 (set_attr "indexed" "yes,no")])
9327 (define_insn "*movhi_update1"
9328 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9329 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9330 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9331 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9332 (plus:P (match_dup 1) (match_dup 2)))]
9334 && (!avoiding_indexed_address_p (HImode)
9335 || !gpc_reg_operand (operands[2], SImode))"
9339 [(set_attr "type" "load")
9340 (set_attr "update" "yes")
9341 (set_attr "indexed" "yes,no")])
9343 (define_insn "*movhi_update2"
9344 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9346 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9347 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9348 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9349 (plus:P (match_dup 1) (match_dup 2)))]
9351 && (!avoiding_indexed_address_p (HImode)
9352 || !gpc_reg_operand (operands[2], Pmode))"
9356 [(set_attr "type" "load")
9357 (set_attr "update" "yes")
9358 (set_attr "indexed" "yes,no")])
9360 (define_insn "*movhi_update3"
9361 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9363 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9364 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9365 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9366 (plus:P (match_dup 1) (match_dup 2)))]
9368 && !(avoiding_indexed_address_p (HImode)
9369 && gpc_reg_operand (operands[2], Pmode))"
9373 [(set_attr "type" "load")
9374 (set_attr "sign_extend" "yes")
9375 (set_attr "update" "yes")
9376 (set_attr "indexed" "yes,no")])
9378 (define_insn "*movhi_update4"
9379 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9380 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9381 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9382 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9383 (plus:P (match_dup 1) (match_dup 2)))]
9385 && (!avoiding_indexed_address_p (HImode)
9386 || !gpc_reg_operand (operands[2], Pmode))"
9390 [(set_attr "type" "store")
9391 (set_attr "update" "yes")
9392 (set_attr "indexed" "yes,no")])
9394 (define_insn "*movqi_update1"
9395 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9396 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9397 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9398 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9399 (plus:P (match_dup 1) (match_dup 2)))]
9401 && (!avoiding_indexed_address_p (QImode)
9402 || !gpc_reg_operand (operands[2], Pmode))"
9406 [(set_attr "type" "load")
9407 (set_attr "update" "yes")
9408 (set_attr "indexed" "yes,no")])
9410 (define_insn "*movqi_update2"
9411 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9413 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9414 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9415 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9416 (plus:P (match_dup 1) (match_dup 2)))]
9418 && (!avoiding_indexed_address_p (QImode)
9419 || !gpc_reg_operand (operands[2], Pmode))"
9423 [(set_attr "type" "load")
9424 (set_attr "update" "yes")
9425 (set_attr "indexed" "yes,no")])
9427 (define_insn "*movqi_update3"
9428 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9429 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9430 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9431 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9432 (plus:P (match_dup 1) (match_dup 2)))]
9434 && (!avoiding_indexed_address_p (QImode)
9435 || !gpc_reg_operand (operands[2], Pmode))"
9439 [(set_attr "type" "store")
9440 (set_attr "update" "yes")
9441 (set_attr "indexed" "yes,no")])
9443 (define_insn "*mov<SFDF:mode>_update1"
9444 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9445 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9446 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9447 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9448 (plus:P (match_dup 1) (match_dup 2)))]
9449 "TARGET_HARD_FLOAT && TARGET_UPDATE
9450 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9451 || !gpc_reg_operand (operands[2], Pmode))"
9455 [(set_attr "type" "fpload")
9456 (set_attr "update" "yes")
9457 (set_attr "indexed" "yes,no")
9458 (set_attr "size" "<SFDF:bits>")])
9460 (define_insn "*mov<SFDF:mode>_update2"
9461 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9462 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9463 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9464 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9465 (plus:P (match_dup 1) (match_dup 2)))]
9466 "TARGET_HARD_FLOAT && TARGET_UPDATE
9467 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9468 || !gpc_reg_operand (operands[2], Pmode))"
9472 [(set_attr "type" "fpstore")
9473 (set_attr "update" "yes")
9474 (set_attr "indexed" "yes,no")
9475 (set_attr "size" "<SFDF:bits>")])
9477 (define_insn "*movsf_update3"
9478 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9479 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9480 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9481 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9482 (plus:P (match_dup 1) (match_dup 2)))]
9483 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9484 && (!avoiding_indexed_address_p (SFmode)
9485 || !gpc_reg_operand (operands[2], Pmode))"
9489 [(set_attr "type" "load")
9490 (set_attr "update" "yes")
9491 (set_attr "indexed" "yes,no")])
9493 (define_insn "*movsf_update4"
9494 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9495 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9496 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9497 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9498 (plus:P (match_dup 1) (match_dup 2)))]
9499 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9500 && (!avoiding_indexed_address_p (SFmode)
9501 || !gpc_reg_operand (operands[2], Pmode))"
9505 [(set_attr "type" "store")
9506 (set_attr "update" "yes")
9507 (set_attr "indexed" "yes,no")])
9510 ;; After inserting conditional returns we can sometimes have
9511 ;; unnecessary register moves. Unfortunately we cannot have a
9512 ;; modeless peephole here, because some single SImode sets have early
9513 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9514 ;; sequences, using get_attr_length here will smash the operands
9515 ;; array. Neither is there an early_cobbler_p predicate.
9516 ;; Also this optimization interferes with scalars going into
9517 ;; altivec registers (the code does reloading through the FPRs).
9519 [(set (match_operand:DF 0 "gpc_reg_operand")
9520 (match_operand:DF 1 "any_operand"))
9521 (set (match_operand:DF 2 "gpc_reg_operand")
9524 && peep2_reg_dead_p (2, operands[0])"
9525 [(set (match_dup 2) (match_dup 1))])
9528 [(set (match_operand:SF 0 "gpc_reg_operand")
9529 (match_operand:SF 1 "any_operand"))
9530 (set (match_operand:SF 2 "gpc_reg_operand")
9533 && peep2_reg_dead_p (2, operands[0])"
9534 [(set (match_dup 2) (match_dup 1))])
9539 (define_insn "*tls_gd_pcrel<bits>"
9540 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9541 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9544 "HAVE_AS_TLS && TARGET_ELF"
9545 "la %0,%1@got@tlsgd@pcrel"
9546 [(set_attr "prefixed" "yes")])
9548 (define_insn_and_split "*tls_gd<bits>"
9549 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9550 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9551 (match_operand:P 2 "gpc_reg_operand" "b")]
9553 "HAVE_AS_TLS && TARGET_ELF"
9554 "addi %0,%2,%1@got@tlsgd"
9555 "&& TARGET_CMODEL != CMODEL_SMALL"
9558 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9560 (lo_sum:P (match_dup 3)
9561 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9563 operands[3] = gen_reg_rtx (<MODE>mode);
9565 [(set (attr "length")
9566 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9570 (define_insn "*tls_gd_high<bits>"
9571 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9573 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9574 (match_operand:P 2 "gpc_reg_operand" "b")]
9576 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9577 "addis %0,%2,%1@got@tlsgd@ha")
9579 (define_insn "*tls_gd_low<bits>"
9580 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9581 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9582 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9583 (match_operand:P 3 "gpc_reg_operand" "b")]
9585 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9586 "addi %0,%1,%2@got@tlsgd@l")
9588 (define_insn "*tls_ld_pcrel<bits>"
9589 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9590 (unspec:P [(const_int 0)]
9592 "HAVE_AS_TLS && TARGET_ELF"
9593 "la %0,%&@got@tlsld@pcrel"
9594 [(set_attr "prefixed" "yes")])
9596 (define_insn_and_split "*tls_ld<bits>"
9597 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9598 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9600 "HAVE_AS_TLS && TARGET_ELF"
9601 "addi %0,%1,%&@got@tlsld"
9602 "&& TARGET_CMODEL != CMODEL_SMALL"
9605 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9607 (lo_sum:P (match_dup 2)
9608 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9610 operands[2] = gen_reg_rtx (<MODE>mode);
9612 [(set (attr "length")
9613 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9617 (define_insn "*tls_ld_high<bits>"
9618 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9620 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9622 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9623 "addis %0,%1,%&@got@tlsld@ha")
9625 (define_insn "*tls_ld_low<bits>"
9626 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9627 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9628 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9630 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9631 "addi %0,%1,%&@got@tlsld@l")
9633 (define_insn "tls_dtprel_<bits>"
9634 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9635 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9636 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9639 "addi %0,%1,%2@dtprel"
9640 [(set (attr "prefixed")
9641 (if_then_else (match_test "rs6000_tls_size == 16")
9643 (const_string "yes")))])
9645 (define_insn "tls_dtprel_ha_<bits>"
9646 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9647 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9648 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9649 UNSPEC_TLSDTPRELHA))]
9651 "addis %0,%1,%2@dtprel@ha")
9653 (define_insn "tls_dtprel_lo_<bits>"
9654 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9655 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9656 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9657 UNSPEC_TLSDTPRELLO))]
9659 "addi %0,%1,%2@dtprel@l")
9661 (define_insn_and_split "tls_got_dtprel_<bits>"
9662 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9663 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9664 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9665 UNSPEC_TLSGOTDTPREL))]
9667 "<ptrload> %0,%2@got@dtprel(%1)"
9668 "&& TARGET_CMODEL != CMODEL_SMALL"
9671 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9673 (lo_sum:P (match_dup 3)
9674 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9676 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9678 [(set (attr "length")
9679 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9683 (define_insn "*tls_got_dtprel_high<bits>"
9684 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9686 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9687 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9688 UNSPEC_TLSGOTDTPREL)))]
9689 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9690 "addis %0,%1,%2@got@dtprel@ha")
9692 (define_insn "*tls_got_dtprel_low<bits>"
9693 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9694 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9695 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9696 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9697 UNSPEC_TLSGOTDTPREL)))]
9698 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9699 "<ptrload> %0,%2@got@dtprel@l(%1)")
9701 (define_insn "tls_tprel_<bits>"
9702 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9703 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9704 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9707 "addi %0,%1,%2@tprel"
9708 [(set (attr "prefixed")
9709 (if_then_else (match_test "rs6000_tls_size == 16")
9711 (const_string "yes")))])
9713 (define_insn "tls_tprel_ha_<bits>"
9714 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9715 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9716 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9717 UNSPEC_TLSTPRELHA))]
9719 "addis %0,%1,%2@tprel@ha")
9721 (define_insn "tls_tprel_lo_<bits>"
9722 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9723 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9724 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9725 UNSPEC_TLSTPRELLO))]
9727 "addi %0,%1,%2@tprel@l")
9729 (define_insn "*tls_got_tprel_pcrel_<bits>"
9730 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9731 (unspec:P [(const_int 0)
9732 (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9733 UNSPEC_TLSGOTTPREL))]
9735 "<ptrload> %0,%1@got@tprel@pcrel"
9736 [(set_attr "prefixed" "yes")])
9738 ;; "b" output constraint here and on tls_tls input to support linker tls
9739 ;; optimization. The linker may edit the instructions emitted by a
9740 ;; tls_got_tprel/tls_tls pair to addis,addi.
9741 (define_insn_and_split "tls_got_tprel_<bits>"
9742 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9743 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9744 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9745 UNSPEC_TLSGOTTPREL))]
9747 "<ptrload> %0,%2@got@tprel(%1)"
9748 "&& TARGET_CMODEL != CMODEL_SMALL"
9751 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9753 (lo_sum:P (match_dup 3)
9754 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9756 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9758 [(set (attr "length")
9759 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9763 (define_insn "*tls_got_tprel_high<bits>"
9764 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9766 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9767 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9768 UNSPEC_TLSGOTTPREL)))]
9769 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9770 "addis %0,%1,%2@got@tprel@ha")
9772 (define_insn "*tls_got_tprel_low<bits>"
9773 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9774 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9775 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9776 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9777 UNSPEC_TLSGOTTPREL)))]
9778 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9779 "<ptrload> %0,%2@got@tprel@l(%1)")
9781 (define_insn "tls_tls_pcrel_<bits>"
9782 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9783 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9784 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9785 UNSPEC_TLSTLS_PCREL))]
9786 "TARGET_ELF && HAVE_AS_TLS"
9787 "add %0,%1,%2@tls@pcrel")
9789 (define_insn "tls_tls_<bits>"
9790 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9791 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9792 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9794 "TARGET_ELF && HAVE_AS_TLS"
9797 (define_expand "tls_get_tpointer"
9798 [(set (match_operand:SI 0 "gpc_reg_operand")
9799 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9800 "TARGET_XCOFF && HAVE_AS_TLS"
9802 emit_insn (gen_tls_get_tpointer_internal ());
9803 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9807 (define_insn "tls_get_tpointer_internal"
9809 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9810 (clobber (reg:SI LR_REGNO))]
9811 "TARGET_XCOFF && HAVE_AS_TLS"
9812 "bla __get_tpointer")
9814 (define_expand "tls_get_addr<mode>"
9815 [(set (match_operand:P 0 "gpc_reg_operand")
9816 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9817 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9818 "TARGET_XCOFF && HAVE_AS_TLS"
9820 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9821 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9822 emit_insn (gen_tls_get_addr_internal<mode> ());
9823 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9827 (define_insn "tls_get_addr_internal<mode>"
9829 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9833 (clobber (reg:P 11))
9834 (clobber (reg:CC CR0_REGNO))
9835 (clobber (reg:P LR_REGNO))]
9836 "TARGET_XCOFF && HAVE_AS_TLS"
9837 "bla __tls_get_addr")
9839 ;; Next come insns related to the calling sequence.
9841 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9842 ;; We move the back-chain and decrement the stack pointer.
9844 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9845 ;; constant alloca, using that predicate will force the generic code to put
9846 ;; the constant size into a register before calling the expander.
9848 ;; As a result the expander would not have the constant size information
9849 ;; in those cases and would have to generate less efficient code.
9851 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9852 ;; the constant size. The value is forced into a register if necessary.
9854 (define_expand "allocate_stack"
9855 [(set (match_operand 0 "gpc_reg_operand")
9856 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9858 (minus (reg 1) (match_dup 1)))]
9861 rtx chain = gen_reg_rtx (Pmode);
9862 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9864 rtx insn, par, set, mem;
9866 /* By allowing reg_or_cint_operand as the predicate we can get
9867 better code for stack-clash-protection because we do not lose
9868 size information. But the rest of the code expects the operand
9869 to be reg_or_short_operand. If it isn't, then force it into
9871 rtx orig_op1 = operands[1];
9872 if (!reg_or_short_operand (operands[1], Pmode))
9873 operands[1] = force_reg (Pmode, operands[1]);
9875 emit_move_insn (chain, stack_bot);
9877 /* Check stack bounds if necessary. */
9878 if (crtl->limit_stack)
9881 available = expand_binop (Pmode, sub_optab,
9882 stack_pointer_rtx, stack_limit_rtx,
9883 NULL_RTX, 1, OPTAB_WIDEN);
9884 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9887 /* Allocate and probe if requested.
9888 This may look similar to the loop we use for prologue allocations,
9889 but it is critically different. For the former we know the loop
9890 will iterate, but do not know that generally here. The former
9891 uses that knowledge to rotate the loop. Combining them would be
9892 possible with some performance cost. */
9893 if (flag_stack_clash_protection)
9895 rtx rounded_size, last_addr, residual;
9896 HOST_WIDE_INT probe_interval;
9897 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9898 &residual, &probe_interval,
9901 /* We do occasionally get in here with constant sizes, we might
9902 as well do a reasonable job when we obviously can. */
9903 if (rounded_size != const0_rtx)
9905 rtx loop_lab, end_loop;
9906 bool rotated = CONST_INT_P (rounded_size);
9907 rtx update = GEN_INT (-probe_interval);
9908 if (probe_interval > 32768)
9909 update = force_reg (Pmode, update);
9911 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9912 last_addr, rotated);
9915 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9919 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9922 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9923 last_addr, rotated);
9926 /* Now handle residuals. We just have to set operands[1] correctly
9927 and let the rest of the expander run. */
9928 operands[1] = residual;
9931 if (!(CONST_INT_P (operands[1])
9932 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9934 operands[1] = force_reg (Pmode, operands[1]);
9935 neg_op0 = gen_reg_rtx (Pmode);
9936 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9939 neg_op0 = GEN_INT (-INTVAL (operands[1]));
9941 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9942 : gen_movdi_update_stack))
9943 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9945 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9946 it now and set the alias set/attributes. The above gen_*_update
9947 calls will generate a PARALLEL with the MEM set being the first
9949 par = PATTERN (insn);
9950 gcc_assert (GET_CODE (par) == PARALLEL);
9951 set = XVECEXP (par, 0, 0);
9952 gcc_assert (GET_CODE (set) == SET);
9953 mem = SET_DEST (set);
9954 gcc_assert (MEM_P (mem));
9955 MEM_NOTRAP_P (mem) = 1;
9956 set_mem_alias_set (mem, get_frame_alias_set ());
9958 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9962 ;; These patterns say how to save and restore the stack pointer. We need not
9963 ;; save the stack pointer at function level since we are careful to
9964 ;; preserve the backchain. At block level, we have to restore the backchain
9965 ;; when we restore the stack pointer.
9967 ;; For nonlocal gotos, we must save both the stack pointer and its
9968 ;; backchain and restore both. Note that in the nonlocal case, the
9969 ;; save area is a memory location.
9971 (define_expand "save_stack_function"
9972 [(match_operand 0 "any_operand")
9973 (match_operand 1 "any_operand")]
9977 (define_expand "restore_stack_function"
9978 [(match_operand 0 "any_operand")
9979 (match_operand 1 "any_operand")]
9983 ;; Adjust stack pointer (op0) to a new value (op1).
9984 ;; First copy old stack backchain to new location, and ensure that the
9985 ;; scheduler won't reorder the sp assignment before the backchain write.
9986 (define_expand "restore_stack_block"
9987 [(set (match_dup 2) (match_dup 3))
9988 (set (match_dup 4) (match_dup 2))
9990 (set (match_operand 0 "register_operand")
9991 (match_operand 1 "register_operand"))]
9996 operands[1] = force_reg (Pmode, operands[1]);
9997 operands[2] = gen_reg_rtx (Pmode);
9998 operands[3] = gen_frame_mem (Pmode, operands[0]);
9999 operands[4] = gen_frame_mem (Pmode, operands[1]);
10000 p = rtvec_alloc (1);
10001 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10003 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10006 (define_expand "save_stack_nonlocal"
10007 [(set (match_dup 3) (match_dup 4))
10008 (set (match_operand 0 "memory_operand") (match_dup 3))
10009 (set (match_dup 2) (match_operand 1 "register_operand"))]
10012 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10014 /* Copy the backchain to the first word, sp to the second. */
10015 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10016 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10017 operands[3] = gen_reg_rtx (Pmode);
10018 operands[4] = gen_frame_mem (Pmode, operands[1]);
10021 (define_expand "restore_stack_nonlocal"
10022 [(set (match_dup 2) (match_operand 1 "memory_operand"))
10023 (set (match_dup 3) (match_dup 4))
10024 (set (match_dup 5) (match_dup 2))
10026 (set (match_operand 0 "register_operand") (match_dup 3))]
10029 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10032 /* Restore the backchain from the first word, sp from the second. */
10033 operands[2] = gen_reg_rtx (Pmode);
10034 operands[3] = gen_reg_rtx (Pmode);
10035 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10036 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10037 operands[5] = gen_frame_mem (Pmode, operands[3]);
10038 p = rtvec_alloc (1);
10039 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10041 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10044 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10045 ;; to the symbol or label.
10046 (define_insn "*pcrel_local_addr"
10047 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10048 (match_operand:DI 1 "pcrel_local_address"))]
10051 [(set_attr "prefixed" "yes")])
10053 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10054 ;; program are both defined in the main program, the linker will optimize this
10055 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10056 ;; the dynamic linker and loaded up. Print_operand_address will append a
10057 ;; @got@pcrel to the symbol.
10058 (define_insn "*pcrel_extern_addr"
10059 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10060 (match_operand:DI 1 "pcrel_external_address"))]
10063 [(set_attr "prefixed" "yes")
10064 (set_attr "type" "load")])
10066 ;; TOC register handling.
10068 ;; Code to initialize the TOC register...
10070 (define_insn "load_toc_aix_si"
10071 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10072 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10073 (use (reg:SI 2))])]
10074 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10077 extern int need_toc_init;
10079 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10080 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10081 operands[2] = gen_rtx_REG (Pmode, 2);
10082 return "lwz %0,%1(%2)";
10084 [(set_attr "type" "load")
10085 (set_attr "update" "no")
10086 (set_attr "indexed" "no")])
10088 (define_insn "load_toc_aix_di"
10089 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10090 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10091 (use (reg:DI 2))])]
10092 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10095 extern int need_toc_init;
10097 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10098 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10100 strcat (buf, "@toc");
10101 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10102 operands[2] = gen_rtx_REG (Pmode, 2);
10103 return "ld %0,%1(%2)";
10105 [(set_attr "type" "load")
10106 (set_attr "update" "no")
10107 (set_attr "indexed" "no")])
10109 (define_insn "load_toc_v4_pic_si"
10110 [(set (reg:SI LR_REGNO)
10111 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10112 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10113 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10114 [(set_attr "type" "branch")])
10116 (define_expand "load_toc_v4_PIC_1"
10117 [(parallel [(set (reg:SI LR_REGNO)
10118 (match_operand:SI 0 "immediate_operand" "s"))
10119 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10120 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10121 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10124 (define_insn "load_toc_v4_PIC_1_normal"
10125 [(set (reg:SI LR_REGNO)
10126 (match_operand:SI 0 "immediate_operand" "s"))
10127 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10128 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10129 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10130 "bcl 20,31,%0\n%0:"
10131 [(set_attr "type" "branch")
10132 (set_attr "cannot_copy" "yes")])
10134 (define_insn "load_toc_v4_PIC_1_476"
10135 [(set (reg:SI LR_REGNO)
10136 (match_operand:SI 0 "immediate_operand" "s"))
10137 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10138 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10139 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10142 static char templ[32];
10144 get_ppc476_thunk_name (name);
10145 sprintf (templ, "bl %s\n%%0:", name);
10148 [(set_attr "type" "branch")
10149 (set_attr "cannot_copy" "yes")])
10151 (define_expand "load_toc_v4_PIC_1b"
10152 [(parallel [(set (reg:SI LR_REGNO)
10153 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10154 (label_ref (match_operand 1 ""))]
10157 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10160 (define_insn "load_toc_v4_PIC_1b_normal"
10161 [(set (reg:SI LR_REGNO)
10162 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10163 (label_ref (match_operand 1 "" ""))]
10166 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10167 "bcl 20,31,$+8\;.long %0-$"
10168 [(set_attr "type" "branch")
10169 (set_attr "length" "8")])
10171 (define_insn "load_toc_v4_PIC_1b_476"
10172 [(set (reg:SI LR_REGNO)
10173 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10174 (label_ref (match_operand 1 "" ""))]
10177 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10180 static char templ[32];
10182 get_ppc476_thunk_name (name);
10183 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10186 [(set_attr "type" "branch")
10187 (set_attr "length" "16")])
10189 (define_insn "load_toc_v4_PIC_2"
10190 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10192 (match_operand:SI 1 "gpc_reg_operand" "b")
10194 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10195 (match_operand:SI 3 "immediate_operand" "s"))))))]
10196 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10198 [(set_attr "type" "load")])
10200 (define_insn "load_toc_v4_PIC_3b"
10201 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10203 (match_operand:SI 1 "gpc_reg_operand" "b")
10206 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10207 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10208 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10209 "addis %0,%1,%2-%3@ha")
10211 (define_insn "load_toc_v4_PIC_3c"
10212 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10214 (match_operand:SI 1 "gpc_reg_operand" "b")
10216 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10217 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10218 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10219 "addi %0,%1,%2-%3@l")
10221 ;; If the TOC is shared over a translation unit, as happens with all
10222 ;; the kinds of PIC that we support, we need to restore the TOC
10223 ;; pointer only when jumping over units of translation.
10224 ;; On Darwin, we need to reload the picbase.
10226 (define_expand "builtin_setjmp_receiver"
10227 [(use (label_ref (match_operand 0 "")))]
10228 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10229 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10230 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10233 if (DEFAULT_ABI == ABI_DARWIN)
10235 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10236 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10240 crtl->uses_pic_offset_table = 1;
10241 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10242 CODE_LABEL_NUMBER (operands[0]));
10243 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10245 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10246 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10247 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10248 picrtx, tmplabrtx));
10252 rs6000_emit_load_toc_table (FALSE);
10256 ;; Largetoc support
10257 (define_insn "*largetoc_high"
10258 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10260 (unspec [(match_operand:DI 1 "" "")
10261 (match_operand:DI 2 "gpc_reg_operand" "b")]
10263 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10264 "addis %0,%2,%1@toc@ha")
10266 (define_insn "*largetoc_high_aix<mode>"
10267 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10269 (unspec [(match_operand:P 1 "" "")
10270 (match_operand:P 2 "gpc_reg_operand" "b")]
10272 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10273 "addis %0,%1@u(%2)")
10275 (define_insn "*largetoc_high_plus"
10276 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10279 (unspec [(match_operand:DI 1 "" "")
10280 (match_operand:DI 2 "gpc_reg_operand" "b")]
10282 (match_operand:DI 3 "add_cint_operand" "n"))))]
10283 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10284 "addis %0,%2,%1+%3@toc@ha")
10286 (define_insn "*largetoc_high_plus_aix<mode>"
10287 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10290 (unspec [(match_operand:P 1 "" "")
10291 (match_operand:P 2 "gpc_reg_operand" "b")]
10293 (match_operand:P 3 "add_cint_operand" "n"))))]
10294 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10295 "addis %0,%1+%3@u(%2)")
10297 (define_insn "*largetoc_low"
10298 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10299 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10300 (match_operand:DI 2 "" "")))]
10301 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10304 (define_insn "*largetoc_low_aix<mode>"
10305 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10306 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10307 (match_operand:P 2 "" "")))]
10308 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10311 (define_insn_and_split "*tocref<mode>"
10312 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10313 (match_operand:P 1 "small_toc_ref" "R"))]
10315 && legitimate_constant_pool_address_p (operands[1], QImode, false)"
10317 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10318 [(set (match_dup 0) (high:P (match_dup 1)))
10319 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10321 ;; Elf specific ways of loading addresses for non-PIC code.
10322 ;; The output of this could be r0, but we make a very strong
10323 ;; preference for a base register because it will usually
10324 ;; be needed there.
10325 (define_insn "elf_high"
10326 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10327 (high:SI (match_operand 1 "" "")))]
10328 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10331 (define_insn "elf_low"
10332 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10333 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10334 (match_operand 2 "" "")))]
10335 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10338 (define_insn "*pltseq_tocsave_<mode>"
10339 [(set (match_operand:P 0 "memory_operand" "=m")
10340 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10341 (match_operand:P 2 "symbol_ref_operand" "s")
10342 (match_operand:P 3 "" "")]
10345 && DEFAULT_ABI == ABI_ELFv2"
10347 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10350 (define_insn "*pltseq_plt16_ha_<mode>"
10351 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10352 (unspec:P [(match_operand:P 1 "" "")
10353 (match_operand:P 2 "symbol_ref_operand" "s")
10354 (match_operand:P 3 "" "")]
10358 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10361 (define_insn "*pltseq_plt16_lo_<mode>"
10362 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10363 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
10364 (match_operand:P 2 "symbol_ref_operand" "s")
10365 (match_operand:P 3 "" "")]
10366 UNSPECV_PLT16_LO))]
10369 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10371 [(set_attr "type" "load")])
10373 (define_insn "*pltseq_mtctr_<mode>"
10374 [(set (match_operand:P 0 "register_operand" "=c")
10375 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10376 (match_operand:P 2 "symbol_ref_operand" "s")
10377 (match_operand:P 3 "" "")]
10381 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10384 (define_insn "*pltseq_plt_pcrel<mode>"
10385 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10386 (unspec_volatile:P [(match_operand:P 1 "" "")
10387 (match_operand:P 2 "symbol_ref_operand" "s")
10388 (match_operand:P 3 "" "")]
10389 UNSPECV_PLT_PCREL))]
10390 "HAVE_AS_PLTSEQ && TARGET_ELF
10391 && rs6000_pcrel_p (cfun)"
10393 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10395 [(set_attr "type" "load")
10396 (set_attr "length" "12")])
10398 ;; Call and call_value insns
10399 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10400 (define_expand "call"
10401 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10402 (match_operand 1 ""))
10403 (use (match_operand 2 ""))
10404 (clobber (reg:SI LR_REGNO))])]
10408 if (MACHOPIC_INDIRECT)
10409 operands[0] = machopic_indirect_call_target (operands[0]);
10412 gcc_assert (MEM_P (operands[0]));
10414 operands[0] = XEXP (operands[0], 0);
10416 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10417 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10418 else if (DEFAULT_ABI == ABI_V4)
10419 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10420 else if (DEFAULT_ABI == ABI_DARWIN)
10421 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10423 gcc_unreachable ();
10428 (define_expand "call_value"
10429 [(parallel [(set (match_operand 0 "")
10430 (call (mem:SI (match_operand 1 "address_operand"))
10431 (match_operand 2 "")))
10432 (use (match_operand 3 ""))
10433 (clobber (reg:SI LR_REGNO))])]
10437 if (MACHOPIC_INDIRECT)
10438 operands[1] = machopic_indirect_call_target (operands[1]);
10441 gcc_assert (MEM_P (operands[1]));
10443 operands[1] = XEXP (operands[1], 0);
10445 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10446 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10447 else if (DEFAULT_ABI == ABI_V4)
10448 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10449 else if (DEFAULT_ABI == ABI_DARWIN)
10450 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10452 gcc_unreachable ();
10457 ;; Call to function in current module. No TOC pointer reload needed.
10458 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10459 ;; either the function was not prototyped, or it was prototyped as a
10460 ;; variable argument function. It is > 0 if FP registers were passed
10461 ;; and < 0 if they were not.
10463 (define_insn "*call_local<mode>"
10464 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
10466 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10467 (clobber (reg:P LR_REGNO))]
10468 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10470 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10471 output_asm_insn ("crxor 6,6,6", operands);
10473 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10474 output_asm_insn ("creqv 6,6,6", operands);
10476 if (rs6000_pcrel_p (cfun))
10477 return "bl %z0@notoc";
10478 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10480 [(set_attr "type" "branch")
10481 (set_attr "length" "4,8")])
10483 (define_insn "*call_value_local<mode>"
10484 [(set (match_operand 0 "" "")
10485 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
10486 (match_operand 2)))
10487 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10488 (clobber (reg:P LR_REGNO))]
10489 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10491 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10492 output_asm_insn ("crxor 6,6,6", operands);
10494 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10495 output_asm_insn ("creqv 6,6,6", operands);
10497 if (rs6000_pcrel_p (cfun))
10498 return "bl %z1@notoc";
10499 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10501 [(set_attr "type" "branch")
10502 (set_attr "length" "4,8")])
10505 ;; A function pointer under System V is just a normal pointer
10506 ;; operands[0] is the function pointer
10507 ;; operands[1] is the tls call arg
10508 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10509 ;; which indicates how to set cr1
10511 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10512 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10514 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10515 (clobber (reg:P LR_REGNO))]
10516 "DEFAULT_ABI == ABI_V4
10517 || DEFAULT_ABI == ABI_DARWIN"
10519 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10520 output_asm_insn ("crxor 6,6,6", operands);
10522 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10523 output_asm_insn ("creqv 6,6,6", operands);
10525 return rs6000_indirect_call_template (operands, 0);
10527 [(set_attr "type" "jmpreg")
10528 (set (attr "length")
10529 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10530 (match_test "which_alternative != 1"))
10531 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10532 (const_string "12")
10533 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10534 (match_test "which_alternative != 1"))
10535 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10536 (const_string "8")]
10537 (const_string "4")))])
10539 (define_insn "*call_nonlocal_sysv<mode>"
10540 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10542 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10543 (clobber (reg:P LR_REGNO))]
10544 "(DEFAULT_ABI == ABI_DARWIN
10545 || (DEFAULT_ABI == ABI_V4
10546 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10548 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10549 output_asm_insn ("crxor 6,6,6", operands);
10551 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10552 output_asm_insn ("creqv 6,6,6", operands);
10554 return rs6000_call_template (operands, 0);
10556 [(set_attr "type" "branch,branch")
10557 (set_attr "length" "4,8")])
10559 (define_insn "*call_nonlocal_sysv_secure<mode>"
10560 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10562 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10563 (use (match_operand:SI 3 "register_operand" "r,r"))
10564 (clobber (reg:P LR_REGNO))]
10565 "(DEFAULT_ABI == ABI_V4
10566 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10567 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10569 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10570 output_asm_insn ("crxor 6,6,6", operands);
10572 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10573 output_asm_insn ("creqv 6,6,6", operands);
10575 return rs6000_call_template (operands, 0);
10577 [(set_attr "type" "branch,branch")
10578 (set_attr "length" "4,8")])
10580 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10581 [(set (match_operand 0 "" "")
10582 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10583 (match_operand:P 2 "unspec_tls" "")))
10584 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10585 (clobber (reg:P LR_REGNO))]
10586 "DEFAULT_ABI == ABI_V4
10587 || DEFAULT_ABI == ABI_DARWIN"
10589 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10590 output_asm_insn ("crxor 6,6,6", operands);
10592 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10593 output_asm_insn ("creqv 6,6,6", operands);
10595 return rs6000_indirect_call_template (operands, 1);
10597 [(set_attr "type" "jmpreg")
10598 (set (attr "length")
10600 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10603 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10604 (match_test "which_alternative != 1"))
10608 (define_insn "*call_value_nonlocal_sysv<mode>"
10609 [(set (match_operand 0 "" "")
10610 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10611 (match_operand:P 2 "unspec_tls" "")))
10612 (use (match_operand:SI 3 "immediate_operand" "n"))
10613 (clobber (reg:P LR_REGNO))]
10614 "(DEFAULT_ABI == ABI_DARWIN
10615 || (DEFAULT_ABI == ABI_V4
10616 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10618 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10619 output_asm_insn ("crxor 6,6,6", operands);
10621 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10622 output_asm_insn ("creqv 6,6,6", operands);
10624 return rs6000_call_template (operands, 1);
10626 [(set_attr "type" "branch")
10627 (set (attr "length")
10628 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10632 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10633 [(set (match_operand 0 "" "")
10634 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10635 (match_operand:P 2 "unspec_tls" "")))
10636 (use (match_operand:SI 3 "immediate_operand" "n"))
10637 (use (match_operand:SI 4 "register_operand" "r"))
10638 (clobber (reg:P LR_REGNO))]
10639 "(DEFAULT_ABI == ABI_V4
10640 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10641 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10643 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10644 output_asm_insn ("crxor 6,6,6", operands);
10646 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10647 output_asm_insn ("creqv 6,6,6", operands);
10649 return rs6000_call_template (operands, 1);
10651 [(set_attr "type" "branch")
10652 (set (attr "length")
10653 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10657 ;; Call to AIX abi function which may be in another module.
10658 ;; Restore the TOC pointer (r2) after the call.
10660 (define_insn "*call_nonlocal_aix<mode>"
10661 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10663 (use (match_operand:SI 2 "immediate_operand" "n"))
10664 (clobber (reg:P LR_REGNO))]
10665 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10666 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10668 return rs6000_call_template (operands, 0);
10670 [(set_attr "type" "branch")
10671 (set (attr "length")
10672 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10676 (define_insn "*call_value_nonlocal_aix<mode>"
10677 [(set (match_operand 0 "" "")
10678 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10679 (match_operand:P 2 "unspec_tls" "")))
10680 (use (match_operand:SI 3 "immediate_operand" "n"))
10681 (clobber (reg:P LR_REGNO))]
10682 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10683 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10685 return rs6000_call_template (operands, 1);
10687 [(set_attr "type" "branch")
10688 (set (attr "length")
10689 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10693 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10694 ;; Operand0 is the addresss of the function to call
10695 ;; Operand3 is the location in the function descriptor to load r2 from
10696 ;; Operand4 is the offset of the stack location holding the current TOC pointer
10698 (define_insn "*call_indirect_aix<mode>"
10699 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10701 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10702 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10703 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10704 (clobber (reg:P LR_REGNO))]
10705 "DEFAULT_ABI == ABI_AIX"
10707 return rs6000_indirect_call_template (operands, 0);
10709 [(set_attr "type" "jmpreg")
10710 (set (attr "length")
10711 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10712 (match_test "which_alternative != 1"))
10713 (const_string "16")
10714 (const_string "12")))])
10716 (define_insn "*call_value_indirect_aix<mode>"
10717 [(set (match_operand 0 "" "")
10718 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10719 (match_operand:P 2 "unspec_tls" "")))
10720 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10721 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10722 (set (reg:P TOC_REGNUM)
10723 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
10725 (clobber (reg:P LR_REGNO))]
10726 "DEFAULT_ABI == ABI_AIX"
10728 return rs6000_indirect_call_template (operands, 1);
10730 [(set_attr "type" "jmpreg")
10731 (set (attr "length")
10732 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10733 (match_test "which_alternative != 1"))
10734 (const_string "16")
10735 (const_string "12")))])
10737 ;; Call to indirect functions with the ELFv2 ABI.
10738 ;; Operand0 is the addresss of the function to call
10739 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10741 (define_insn "*call_indirect_elfv2<mode>"
10742 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10744 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10745 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10746 (clobber (reg:P LR_REGNO))]
10747 "DEFAULT_ABI == ABI_ELFv2"
10749 return rs6000_indirect_call_template (operands, 0);
10751 [(set_attr "type" "jmpreg")
10752 (set (attr "length")
10753 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10754 (match_test "which_alternative != 1"))
10755 (const_string "12")
10756 (const_string "8")))])
10758 (define_insn "*call_indirect_pcrel<mode>"
10759 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10761 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10762 (clobber (reg:P LR_REGNO))]
10763 "rs6000_pcrel_p (cfun)"
10765 return rs6000_indirect_call_template (operands, 0);
10767 [(set_attr "type" "jmpreg")
10768 (set (attr "length")
10769 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10770 (match_test "which_alternative != 1"))
10772 (const_string "4")))])
10774 (define_insn "*call_value_indirect_elfv2<mode>"
10775 [(set (match_operand 0 "" "")
10776 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10777 (match_operand:P 2 "unspec_tls" "")))
10778 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10779 (set (reg:P TOC_REGNUM)
10780 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10782 (clobber (reg:P LR_REGNO))]
10783 "DEFAULT_ABI == ABI_ELFv2"
10785 return rs6000_indirect_call_template (operands, 1);
10787 [(set_attr "type" "jmpreg")
10788 (set (attr "length")
10789 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10790 (match_test "which_alternative != 1"))
10791 (const_string "12")
10792 (const_string "8")))])
10794 (define_insn "*call_value_indirect_pcrel<mode>"
10795 [(set (match_operand 0 "" "")
10796 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10797 (match_operand:P 2 "unspec_tls" "")))
10798 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10799 (clobber (reg:P LR_REGNO))]
10800 "rs6000_pcrel_p (cfun)"
10802 return rs6000_indirect_call_template (operands, 1);
10804 [(set_attr "type" "jmpreg")
10805 (set (attr "length")
10806 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10807 (match_test "which_alternative != 1"))
10809 (const_string "4")))])
10811 ;; Call subroutine returning any type.
10812 (define_expand "untyped_call"
10813 [(parallel [(call (match_operand 0 "")
10815 (match_operand 1 "")
10816 (match_operand 2 "")])]
10821 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10823 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10824 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
10825 emit_insn (gen_blockage ());
10827 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10829 rtx set = XVECEXP (operands[2], 0, i);
10830 emit_move_insn (SET_DEST (set), SET_SRC (set));
10833 /* The optimizer does not know that the call sets the function value
10834 registers we stored in the result block. We avoid problems by
10835 claiming that all hard registers are used and clobbered at this
10837 emit_insn (gen_blockage ());
10842 ;; sibling call patterns
10843 (define_expand "sibcall"
10844 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10845 (match_operand 1 ""))
10846 (use (match_operand 2 ""))
10851 if (MACHOPIC_INDIRECT)
10852 operands[0] = machopic_indirect_call_target (operands[0]);
10855 gcc_assert (MEM_P (operands[0]));
10856 gcc_assert (CONST_INT_P (operands[1]));
10858 operands[0] = XEXP (operands[0], 0);
10860 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10861 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10862 else if (DEFAULT_ABI == ABI_V4)
10863 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10864 else if (DEFAULT_ABI == ABI_DARWIN)
10865 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10867 gcc_unreachable ();
10872 (define_expand "sibcall_value"
10873 [(parallel [(set (match_operand 0 "register_operand")
10874 (call (mem:SI (match_operand 1 "address_operand"))
10875 (match_operand 2 "")))
10876 (use (match_operand 3 ""))
10881 if (MACHOPIC_INDIRECT)
10882 operands[1] = machopic_indirect_call_target (operands[1]);
10885 gcc_assert (MEM_P (operands[1]));
10886 gcc_assert (CONST_INT_P (operands[2]));
10888 operands[1] = XEXP (operands[1], 0);
10890 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10891 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10892 else if (DEFAULT_ABI == ABI_V4)
10893 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10894 else if (DEFAULT_ABI == ABI_DARWIN)
10895 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10897 gcc_unreachable ();
10902 (define_insn "*sibcall_local32"
10903 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10905 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10907 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10909 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10910 output_asm_insn ("crxor 6,6,6", operands);
10912 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10913 output_asm_insn ("creqv 6,6,6", operands);
10915 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10917 [(set_attr "type" "branch")
10918 (set_attr "length" "4,8")])
10920 (define_insn "*sibcall_local64"
10921 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10923 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10925 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10927 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10928 output_asm_insn ("crxor 6,6,6", operands);
10930 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10931 output_asm_insn ("creqv 6,6,6", operands);
10933 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10935 [(set_attr "type" "branch")
10936 (set_attr "length" "4,8")])
10938 (define_insn "*sibcall_value_local32"
10939 [(set (match_operand 0 "" "")
10940 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10941 (match_operand 2)))
10942 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10944 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10946 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10947 output_asm_insn ("crxor 6,6,6", operands);
10949 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10950 output_asm_insn ("creqv 6,6,6", operands);
10952 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10954 [(set_attr "type" "branch")
10955 (set_attr "length" "4,8")])
10957 (define_insn "*sibcall_value_local64"
10958 [(set (match_operand 0 "" "")
10959 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10960 (match_operand 2)))
10961 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10963 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10965 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10966 output_asm_insn ("crxor 6,6,6", operands);
10968 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10969 output_asm_insn ("creqv 6,6,6", operands);
10971 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10973 [(set_attr "type" "branch")
10974 (set_attr "length" "4,8")])
10976 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10977 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10979 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10981 "DEFAULT_ABI == ABI_V4
10982 || DEFAULT_ABI == ABI_DARWIN"
10984 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10985 output_asm_insn ("crxor 6,6,6", operands);
10987 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10988 output_asm_insn ("creqv 6,6,6", operands);
10990 return rs6000_indirect_sibcall_template (operands, 0);
10992 [(set_attr "type" "jmpreg")
10993 (set (attr "length")
10994 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10995 (match_test "which_alternative != 1"))
10996 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10997 (const_string "12")
10998 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10999 (match_test "which_alternative != 1"))
11000 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11001 (const_string "8")]
11002 (const_string "4")))])
11004 (define_insn "*sibcall_nonlocal_sysv<mode>"
11005 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11007 (use (match_operand 2 "immediate_operand" "O,n"))
11009 "(DEFAULT_ABI == ABI_DARWIN
11010 || DEFAULT_ABI == ABI_V4)
11011 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11013 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11014 output_asm_insn ("crxor 6,6,6", operands);
11016 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11017 output_asm_insn ("creqv 6,6,6", operands);
11019 return rs6000_sibcall_template (operands, 0);
11021 [(set_attr "type" "branch")
11022 (set_attr "length" "4,8")])
11024 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11025 [(set (match_operand 0 "" "")
11026 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11027 (match_operand 2)))
11028 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11030 "DEFAULT_ABI == ABI_V4
11031 || DEFAULT_ABI == ABI_DARWIN"
11033 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11034 output_asm_insn ("crxor 6,6,6", operands);
11036 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11037 output_asm_insn ("creqv 6,6,6", operands);
11039 return rs6000_indirect_sibcall_template (operands, 1);
11041 [(set_attr "type" "jmpreg")
11042 (set (attr "length")
11043 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11044 (match_test "which_alternative != 1"))
11045 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11046 (const_string "12")
11047 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11048 (match_test "which_alternative != 1"))
11049 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11050 (const_string "8")]
11051 (const_string "4")))])
11053 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11054 [(set (match_operand 0 "" "")
11055 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11056 (match_operand 2)))
11057 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11059 "(DEFAULT_ABI == ABI_DARWIN
11060 || DEFAULT_ABI == ABI_V4)
11061 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11063 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11064 output_asm_insn ("crxor 6,6,6", operands);
11066 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11067 output_asm_insn ("creqv 6,6,6", operands);
11069 return rs6000_sibcall_template (operands, 1);
11071 [(set_attr "type" "branch")
11072 (set_attr "length" "4,8")])
11074 ;; AIX ABI sibling call patterns.
11076 (define_insn "*sibcall_aix<mode>"
11077 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11080 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11082 if (which_alternative == 0)
11083 return rs6000_sibcall_template (operands, 0);
11087 [(set_attr "type" "branch")])
11089 (define_insn "*sibcall_value_aix<mode>"
11090 [(set (match_operand 0 "" "")
11091 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11092 (match_operand 2)))
11094 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11096 if (which_alternative == 0)
11097 return rs6000_sibcall_template (operands, 1);
11101 [(set_attr "type" "branch")])
11103 (define_expand "sibcall_epilogue"
11104 [(use (const_int 0))]
11107 if (!TARGET_SCHED_PROLOG)
11108 emit_insn (gen_blockage ());
11109 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11113 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11114 ;; all of memory. This blocks insns from being moved across this point.
11116 (define_insn "blockage"
11117 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11120 [(set_attr "length" "0")])
11122 (define_expand "probe_stack_address"
11123 [(use (match_operand 0 "address_operand"))]
11126 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11127 MEM_VOLATILE_P (operands[0]) = 1;
11130 emit_insn (gen_probe_stack_di (operands[0]));
11132 emit_insn (gen_probe_stack_si (operands[0]));
11136 (define_insn "probe_stack_<mode>"
11137 [(set (match_operand:P 0 "memory_operand" "=m")
11138 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11141 operands[1] = gen_rtx_REG (Pmode, 0);
11142 return "st<wd>%U0%X0 %1,%0";
11144 [(set_attr "type" "store")
11145 (set (attr "update")
11146 (if_then_else (match_operand 0 "update_address_mem")
11147 (const_string "yes")
11148 (const_string "no")))
11149 (set (attr "indexed")
11150 (if_then_else (match_operand 0 "indexed_address_mem")
11151 (const_string "yes")
11152 (const_string "no")))])
11154 (define_insn "probe_stack_range<P:mode>"
11155 [(set (match_operand:P 0 "register_operand" "=&r")
11156 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11157 (match_operand:P 2 "register_operand" "r")
11158 (match_operand:P 3 "register_operand" "r")]
11159 UNSPECV_PROBE_STACK_RANGE))]
11161 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11162 [(set_attr "type" "three")])
11164 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11165 ;; signed & unsigned, and one type of branch.
11167 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11168 ;; insns, and branches.
11170 (define_expand "cbranch<mode>4"
11171 [(use (match_operator 0 "comparison_operator"
11172 [(match_operand:GPR 1 "gpc_reg_operand")
11173 (match_operand:GPR 2 "reg_or_short_operand")]))
11174 (use (match_operand 3))]
11177 /* Take care of the possibility that operands[2] might be negative but
11178 this might be a logical operation. That insn doesn't exist. */
11179 if (CONST_INT_P (operands[2])
11180 && INTVAL (operands[2]) < 0)
11182 operands[2] = force_reg (<MODE>mode, operands[2]);
11183 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11184 GET_MODE (operands[0]),
11185 operands[1], operands[2]);
11188 rs6000_emit_cbranch (<MODE>mode, operands);
11192 (define_expand "cbranch<mode>4"
11193 [(use (match_operator 0 "comparison_operator"
11194 [(match_operand:FP 1 "gpc_reg_operand")
11195 (match_operand:FP 2 "gpc_reg_operand")]))
11196 (use (match_operand 3))]
11199 rs6000_emit_cbranch (<MODE>mode, operands);
11203 (define_expand "cstore<mode>4_signed"
11204 [(use (match_operator 1 "signed_comparison_operator"
11205 [(match_operand:P 2 "gpc_reg_operand")
11206 (match_operand:P 3 "gpc_reg_operand")]))
11207 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11210 enum rtx_code cond_code = GET_CODE (operands[1]);
11212 rtx op0 = operands[0];
11213 rtx op1 = operands[2];
11214 rtx op2 = operands[3];
11216 if (cond_code == GE || cond_code == LT)
11218 cond_code = swap_condition (cond_code);
11219 std::swap (op1, op2);
11222 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11223 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11224 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11226 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11227 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11228 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11230 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11232 if (cond_code == LE)
11233 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11236 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11237 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11238 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11244 (define_expand "cstore<mode>4_unsigned"
11245 [(use (match_operator 1 "unsigned_comparison_operator"
11246 [(match_operand:P 2 "gpc_reg_operand")
11247 (match_operand:P 3 "reg_or_short_operand")]))
11248 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11251 enum rtx_code cond_code = GET_CODE (operands[1]);
11253 rtx op0 = operands[0];
11254 rtx op1 = operands[2];
11255 rtx op2 = operands[3];
11257 if (cond_code == GEU || cond_code == LTU)
11259 cond_code = swap_condition (cond_code);
11260 std::swap (op1, op2);
11263 if (!gpc_reg_operand (op1, <MODE>mode))
11264 op1 = force_reg (<MODE>mode, op1);
11265 if (!reg_or_short_operand (op2, <MODE>mode))
11266 op2 = force_reg (<MODE>mode, op2);
11268 rtx tmp = gen_reg_rtx (<MODE>mode);
11269 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11271 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11272 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11274 if (cond_code == LEU)
11275 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11277 emit_insn (gen_neg<mode>2 (op0, tmp2));
11282 (define_expand "cstore_si_as_di"
11283 [(use (match_operator 1 "unsigned_comparison_operator"
11284 [(match_operand:SI 2 "gpc_reg_operand")
11285 (match_operand:SI 3 "reg_or_short_operand")]))
11286 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11289 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11290 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11292 operands[2] = force_reg (SImode, operands[2]);
11293 operands[3] = force_reg (SImode, operands[3]);
11294 rtx op1 = gen_reg_rtx (DImode);
11295 rtx op2 = gen_reg_rtx (DImode);
11296 convert_move (op1, operands[2], uns_flag);
11297 convert_move (op2, operands[3], uns_flag);
11299 if (cond_code == GT || cond_code == LE)
11301 cond_code = swap_condition (cond_code);
11302 std::swap (op1, op2);
11305 rtx tmp = gen_reg_rtx (DImode);
11306 rtx tmp2 = gen_reg_rtx (DImode);
11307 emit_insn (gen_subdi3 (tmp, op1, op2));
11308 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11314 gcc_unreachable ();
11319 tmp3 = gen_reg_rtx (DImode);
11320 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11324 convert_move (operands[0], tmp3, 1);
11329 (define_expand "cstore<mode>4_signed_imm"
11330 [(use (match_operator 1 "signed_comparison_operator"
11331 [(match_operand:GPR 2 "gpc_reg_operand")
11332 (match_operand:GPR 3 "immediate_operand")]))
11333 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11336 bool invert = false;
11338 enum rtx_code cond_code = GET_CODE (operands[1]);
11340 rtx op0 = operands[0];
11341 rtx op1 = operands[2];
11342 HOST_WIDE_INT val = INTVAL (operands[3]);
11344 if (cond_code == GE || cond_code == GT)
11346 cond_code = reverse_condition (cond_code);
11350 if (cond_code == LE)
11353 rtx tmp = gen_reg_rtx (<MODE>mode);
11354 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11355 rtx x = gen_reg_rtx (<MODE>mode);
11357 emit_insn (gen_and<mode>3 (x, op1, tmp));
11359 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11363 rtx tmp = gen_reg_rtx (<MODE>mode);
11364 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11368 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11369 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11374 (define_expand "cstore<mode>4_unsigned_imm"
11375 [(use (match_operator 1 "unsigned_comparison_operator"
11376 [(match_operand:GPR 2 "gpc_reg_operand")
11377 (match_operand:GPR 3 "immediate_operand")]))
11378 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11381 bool invert = false;
11383 enum rtx_code cond_code = GET_CODE (operands[1]);
11385 rtx op0 = operands[0];
11386 rtx op1 = operands[2];
11387 HOST_WIDE_INT val = INTVAL (operands[3]);
11389 if (cond_code == GEU || cond_code == GTU)
11391 cond_code = reverse_condition (cond_code);
11395 if (cond_code == LEU)
11398 rtx tmp = gen_reg_rtx (<MODE>mode);
11399 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11400 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11401 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11402 rtx x = gen_reg_rtx (<MODE>mode);
11404 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11406 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11410 rtx tmp = gen_reg_rtx (<MODE>mode);
11411 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11415 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11416 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11421 (define_expand "cstore<mode>4"
11422 [(use (match_operator 1 "comparison_operator"
11423 [(match_operand:GPR 2 "gpc_reg_operand")
11424 (match_operand:GPR 3 "reg_or_short_operand")]))
11425 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11428 /* Expanding EQ and NE directly to some machine instructions does not help
11429 but does hurt combine. So don't. */
11430 if (GET_CODE (operands[1]) == EQ)
11431 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11432 else if (<MODE>mode == Pmode
11433 && GET_CODE (operands[1]) == NE)
11434 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11435 else if (GET_CODE (operands[1]) == NE)
11437 rtx tmp = gen_reg_rtx (<MODE>mode);
11438 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11439 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11442 /* If ISEL is fast, expand to it. */
11443 else if (TARGET_ISEL)
11444 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11446 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11447 etc. combinations magically work out just right. */
11448 else if (<MODE>mode == Pmode
11449 && unsigned_comparison_operator (operands[1], VOIDmode))
11450 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11451 operands[2], operands[3]));
11453 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11454 else if (<MODE>mode == SImode && Pmode == DImode)
11455 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11456 operands[2], operands[3]));
11458 /* For signed comparisons against a constant, we can do some simple
11460 else if (signed_comparison_operator (operands[1], VOIDmode)
11461 && CONST_INT_P (operands[3]))
11462 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11463 operands[2], operands[3]));
11465 /* And similarly for unsigned comparisons. */
11466 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11467 && CONST_INT_P (operands[3]))
11468 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11469 operands[2], operands[3]));
11471 /* We also do not want to use mfcr for signed comparisons. */
11472 else if (<MODE>mode == Pmode
11473 && signed_comparison_operator (operands[1], VOIDmode))
11474 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11475 operands[2], operands[3]));
11477 /* Everything else, use the mfcr brute force. */
11479 rs6000_emit_sCOND (<MODE>mode, operands);
11484 (define_expand "cstore<mode>4"
11485 [(use (match_operator 1 "comparison_operator"
11486 [(match_operand:FP 2 "gpc_reg_operand")
11487 (match_operand:FP 3 "gpc_reg_operand")]))
11488 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11491 rs6000_emit_sCOND (<MODE>mode, operands);
11496 (define_expand "stack_protect_set"
11497 [(match_operand 0 "memory_operand")
11498 (match_operand 1 "memory_operand")]
11501 if (rs6000_stack_protector_guard == SSP_TLS)
11503 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11504 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11505 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11506 operands[1] = gen_rtx_MEM (Pmode, addr);
11510 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11512 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11517 (define_insn "stack_protect_setsi"
11518 [(set (match_operand:SI 0 "memory_operand" "=m")
11519 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11520 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11522 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11523 [(set_attr "type" "three")
11524 (set_attr "length" "12")])
11526 ;; We can't use the prefixed attribute here because there are two memory
11527 ;; instructions. We can't split the insn due to the fact that this operation
11528 ;; needs to be done in one piece.
11529 (define_insn "stack_protect_setdi"
11530 [(set (match_operand:DI 0 "memory_operand" "=Y")
11531 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11532 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11535 if (prefixed_memory (operands[1], DImode))
11536 output_asm_insn ("pld %2,%1", operands);
11538 output_asm_insn ("ld%U1%X1 %2,%1", operands);
11540 if (prefixed_memory (operands[0], DImode))
11541 output_asm_insn ("pstd %2,%0", operands);
11543 output_asm_insn ("std%U0%X0 %2,%0", operands);
11547 [(set_attr "type" "three")
11549 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11550 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
11551 ;; the LI 0 at the end.
11552 (set_attr "prefixed" "no")
11553 (set_attr "num_insns" "3")
11554 (set (attr "length")
11555 (cond [(and (match_operand 0 "prefixed_memory")
11556 (match_operand 1 "prefixed_memory"))
11559 (ior (match_operand 0 "prefixed_memory")
11560 (match_operand 1 "prefixed_memory"))
11565 (define_expand "stack_protect_test"
11566 [(match_operand 0 "memory_operand")
11567 (match_operand 1 "memory_operand")
11568 (match_operand 2 "")]
11571 rtx guard = operands[1];
11573 if (rs6000_stack_protector_guard == SSP_TLS)
11575 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11576 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11577 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11578 guard = gen_rtx_MEM (Pmode, addr);
11581 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11582 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11583 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11584 emit_jump_insn (jump);
11589 (define_insn "stack_protect_testsi"
11590 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11591 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11592 (match_operand:SI 2 "memory_operand" "m,m")]
11594 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11595 (clobber (match_scratch:SI 3 "=&r,&r"))]
11598 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11599 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11600 [(set_attr "length" "16,20")])
11602 ;; We can't use the prefixed attribute here because there are two memory
11603 ;; instructions. We can't split the insn due to the fact that this operation
11604 ;; needs to be done in one piece.
11605 (define_insn "stack_protect_testdi"
11606 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11607 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11608 (match_operand:DI 2 "memory_operand" "Y,Y")]
11610 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11611 (clobber (match_scratch:DI 3 "=&r,&r"))]
11614 if (prefixed_memory (operands[1], DImode))
11615 output_asm_insn ("pld %3,%1", operands);
11617 output_asm_insn ("ld%U1%X1 %3,%1", operands);
11619 if (prefixed_memory (operands[2], DImode))
11620 output_asm_insn ("pld %4,%2", operands);
11622 output_asm_insn ("ld%U2%X2 %4,%2", operands);
11624 if (which_alternative == 0)
11625 output_asm_insn ("xor. %3,%3,%4", operands);
11627 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11631 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11632 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
11633 ;; 8 bytes to do the test.
11634 [(set_attr "prefixed" "no")
11635 (set_attr "num_insns" "4,5")
11636 (set (attr "length")
11637 (cond [(and (match_operand 1 "prefixed_memory")
11638 (match_operand 2 "prefixed_memory"))
11639 (if_then_else (eq_attr "alternative" "0")
11643 (ior (match_operand 1 "prefixed_memory")
11644 (match_operand 2 "prefixed_memory"))
11645 (if_then_else (eq_attr "alternative" "0")
11649 (if_then_else (eq_attr "alternative" "0")
11651 (const_int 20))))])
11654 ;; Here are the actual compare insns.
11655 (define_insn "*cmp<mode>_signed"
11656 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11657 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11658 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11660 "cmp<wd>%I2 %0,%1,%2"
11661 [(set_attr "type" "cmp")])
11663 (define_insn "*cmp<mode>_unsigned"
11664 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11665 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11666 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11668 "cmpl<wd>%I2 %0,%1,%2"
11669 [(set_attr "type" "cmp")])
11671 ;; If we are comparing a register for equality with a large constant,
11672 ;; we can do this with an XOR followed by a compare. But this is profitable
11673 ;; only if the large constant is only used for the comparison (and in this
11674 ;; case we already have a register to reuse as scratch).
11676 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11677 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11680 [(set (match_operand:SI 0 "register_operand")
11681 (match_operand:SI 1 "logical_const_operand"))
11682 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11684 (match_operand:SI 2 "logical_const_operand")]))
11685 (set (match_operand:CC 4 "cc_reg_operand")
11686 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11689 (if_then_else (match_operator 6 "equality_operator"
11690 [(match_dup 4) (const_int 0)])
11691 (match_operand 7 "")
11692 (match_operand 8 "")))]
11693 "peep2_reg_dead_p (3, operands[0])
11694 && peep2_reg_dead_p (4, operands[4])
11695 && REGNO (operands[0]) != REGNO (operands[5])"
11696 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11697 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11698 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11701 /* Get the constant we are comparing against, and see what it looks like
11702 when sign-extended from 16 to 32 bits. Then see what constant we could
11703 XOR with SEXTC to get the sign-extended value. */
11704 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11706 operands[1], operands[2]);
11707 HOST_WIDE_INT c = INTVAL (cnst);
11708 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11709 HOST_WIDE_INT xorv = c ^ sextc;
11711 operands[9] = GEN_INT (xorv);
11712 operands[10] = GEN_INT (sextc);
11715 ;; Only need to compare second words if first words equal
11716 (define_insn "*cmp<mode>_internal1"
11717 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11718 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11719 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11720 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11721 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11722 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11723 [(set_attr "type" "fpcompare")
11724 (set_attr "length" "12")])
11726 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11727 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11728 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11729 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11730 (clobber (match_scratch:DF 3 "=d"))
11731 (clobber (match_scratch:DF 4 "=d"))
11732 (clobber (match_scratch:DF 5 "=d"))
11733 (clobber (match_scratch:DF 6 "=d"))
11734 (clobber (match_scratch:DF 7 "=d"))
11735 (clobber (match_scratch:DF 8 "=d"))
11736 (clobber (match_scratch:DF 9 "=d"))
11737 (clobber (match_scratch:DF 10 "=d"))
11738 (clobber (match_scratch:GPR 11 "=b"))]
11739 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11740 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11742 "&& reload_completed"
11743 [(set (match_dup 3) (match_dup 14))
11744 (set (match_dup 4) (match_dup 15))
11745 (set (match_dup 9) (abs:DF (match_dup 5)))
11746 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11747 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11748 (label_ref (match_dup 12))
11750 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11751 (set (pc) (label_ref (match_dup 13)))
11753 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11754 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11755 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11756 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11759 REAL_VALUE_TYPE rv;
11760 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11761 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11763 operands[5] = simplify_gen_subreg (DFmode, operands[1],
11764 <IBM128:MODE>mode, hi_word);
11765 operands[6] = simplify_gen_subreg (DFmode, operands[1],
11766 <IBM128:MODE>mode, lo_word);
11767 operands[7] = simplify_gen_subreg (DFmode, operands[2],
11768 <IBM128:MODE>mode, hi_word);
11769 operands[8] = simplify_gen_subreg (DFmode, operands[2],
11770 <IBM128:MODE>mode, lo_word);
11771 operands[12] = gen_label_rtx ();
11772 operands[13] = gen_label_rtx ();
11774 operands[14] = force_const_mem (DFmode,
11775 const_double_from_real_value (rv, DFmode));
11776 operands[15] = force_const_mem (DFmode,
11777 const_double_from_real_value (dconst0,
11782 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11783 operands[14] = gen_const_mem (DFmode, tocref);
11784 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11785 operands[15] = gen_const_mem (DFmode, tocref);
11786 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11787 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11791 ;; Now we have the scc insns. We can do some combinations because of the
11792 ;; way the machine works.
11794 ;; Note that this is probably faster if we can put an insn between the
11795 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11796 ;; cases the insns below which don't use an intermediate CR field will
11797 ;; be used instead.
11798 (define_insn "set<mode>_cc"
11799 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11800 (match_operator:GPR 1 "scc_comparison_operator"
11801 [(match_operand 2 "cc_reg_operand" "y")
11804 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11805 [(set (attr "type")
11806 (cond [(match_test "TARGET_MFCRF")
11807 (const_string "mfcrf")
11809 (const_string "mfcr")))
11810 (set_attr "length" "8")])
11813 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11814 (define_code_attr UNS [(eq "CC")
11816 (lt "CC") (ltu "CCUNS")
11817 (gt "CC") (gtu "CCUNS")
11818 (le "CC") (leu "CCUNS")
11819 (ge "CC") (geu "CCUNS")])
11820 (define_code_attr UNSu_ [(eq "")
11825 (ge "") (geu "u_")])
11826 (define_code_attr UNSIK [(eq "I")
11831 (ge "I") (geu "K")])
11833 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11834 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11835 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11836 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11837 (clobber (match_scratch:GPR 3 "=r"))
11838 (clobber (match_scratch:GPR 4 "=r"))
11839 (clobber (match_scratch:<UNS> 5 "=y"))]
11841 && !(<CODE> == EQ && operands[2] == const0_rtx)
11842 && !(<CODE> == NE && operands[2] == const0_rtx
11843 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11848 rtx_code code = <CODE>;
11849 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11851 HOST_WIDE_INT val = INTVAL (operands[2]);
11852 if (code == LT && val != -0x8000)
11857 if (code == GT && val != 0x7fff)
11862 if (code == LTU && val != 0)
11867 if (code == GTU && val != 0xffff)
11872 operands[2] = GEN_INT (val);
11875 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11876 operands[3] = const0_rtx;
11879 if (GET_CODE (operands[3]) == SCRATCH)
11880 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11881 emit_move_insn (operands[3], const0_rtx);
11884 if (GET_CODE (operands[4]) == SCRATCH)
11885 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11886 emit_move_insn (operands[4], const1_rtx);
11888 if (GET_CODE (operands[5]) == SCRATCH)
11889 operands[5] = gen_reg_rtx (<UNS>mode);
11891 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11892 emit_insn (gen_rtx_SET (operands[5], c1));
11894 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11895 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11896 emit_move_insn (operands[0], x);
11900 [(set (attr "cost")
11901 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11903 || <CODE> == LE || <CODE> == GE
11904 || <CODE> == LEU || <CODE> == GEU")
11906 (const_string "10")))])
11908 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11911 (define_expand "eq<mode>3"
11913 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11914 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11915 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11916 (clobber (match_scratch:GPR 3 "=r"))
11917 (clobber (match_scratch:GPR 4 "=r"))])]
11920 if (TARGET_ISEL && operands[2] != const0_rtx)
11922 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11928 (define_insn_and_split "*eq<mode>3"
11929 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11930 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11931 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11932 (clobber (match_scratch:GPR 3 "=r"))
11933 (clobber (match_scratch:GPR 4 "=r"))]
11934 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11937 [(set (match_dup 4)
11938 (clz:GPR (match_dup 3)))
11940 (lshiftrt:GPR (match_dup 4)
11943 operands[3] = rs6000_emit_eqne (<MODE>mode,
11944 operands[1], operands[2], operands[3]);
11946 if (GET_CODE (operands[4]) == SCRATCH)
11947 operands[4] = gen_reg_rtx (<MODE>mode);
11949 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11951 [(set (attr "length")
11952 (if_then_else (match_test "operands[2] == const0_rtx")
11954 (const_string "12")))])
11956 (define_expand "ne<mode>3"
11958 (set (match_operand:P 0 "gpc_reg_operand" "=r")
11959 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11960 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11961 (clobber (match_scratch:P 3 "=r"))
11962 (clobber (match_scratch:P 4 "=r"))
11963 (clobber (reg:P CA_REGNO))])]
11966 if (TARGET_ISEL && operands[2] != const0_rtx)
11968 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11974 (define_insn_and_split "*ne<mode>3"
11975 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11976 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11977 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11978 (clobber (match_scratch:P 3 "=r"))
11979 (clobber (match_scratch:P 4 "=r"))
11980 (clobber (reg:P CA_REGNO))]
11981 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11984 [(parallel [(set (match_dup 4)
11985 (plus:P (match_dup 3)
11987 (set (reg:P CA_REGNO)
11988 (ne:P (match_dup 3)
11990 (parallel [(set (match_dup 0)
11991 (plus:P (plus:P (not:P (match_dup 4))
11994 (clobber (reg:P CA_REGNO))])]
11996 operands[3] = rs6000_emit_eqne (<MODE>mode,
11997 operands[1], operands[2], operands[3]);
11999 if (GET_CODE (operands[4]) == SCRATCH)
12000 operands[4] = gen_reg_rtx (<MODE>mode);
12002 [(set (attr "length")
12003 (if_then_else (match_test "operands[2] == const0_rtx")
12005 (const_string "12")))])
12007 (define_insn_and_split "*neg_eq_<mode>"
12008 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12009 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12010 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12011 (clobber (match_scratch:P 3 "=r"))
12012 (clobber (match_scratch:P 4 "=r"))
12013 (clobber (reg:P CA_REGNO))]
12017 [(parallel [(set (match_dup 4)
12018 (plus:P (match_dup 3)
12020 (set (reg:P CA_REGNO)
12021 (ne:P (match_dup 3)
12023 (parallel [(set (match_dup 0)
12024 (plus:P (reg:P CA_REGNO)
12026 (clobber (reg:P CA_REGNO))])]
12028 operands[3] = rs6000_emit_eqne (<MODE>mode,
12029 operands[1], operands[2], operands[3]);
12031 if (GET_CODE (operands[4]) == SCRATCH)
12032 operands[4] = gen_reg_rtx (<MODE>mode);
12034 [(set (attr "length")
12035 (if_then_else (match_test "operands[2] == const0_rtx")
12037 (const_string "12")))])
12039 (define_insn_and_split "*neg_ne_<mode>"
12040 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12041 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12042 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12043 (clobber (match_scratch:P 3 "=r"))
12044 (clobber (match_scratch:P 4 "=r"))
12045 (clobber (reg:P CA_REGNO))]
12049 [(parallel [(set (match_dup 4)
12050 (neg:P (match_dup 3)))
12051 (set (reg:P CA_REGNO)
12052 (eq:P (match_dup 3)
12054 (parallel [(set (match_dup 0)
12055 (plus:P (reg:P CA_REGNO)
12057 (clobber (reg:P CA_REGNO))])]
12059 operands[3] = rs6000_emit_eqne (<MODE>mode,
12060 operands[1], operands[2], operands[3]);
12062 if (GET_CODE (operands[4]) == SCRATCH)
12063 operands[4] = gen_reg_rtx (<MODE>mode);
12065 [(set (attr "length")
12066 (if_then_else (match_test "operands[2] == const0_rtx")
12068 (const_string "12")))])
12070 (define_insn_and_split "*plus_eq_<mode>"
12071 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12072 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12073 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12074 (match_operand:P 3 "gpc_reg_operand" "r")))
12075 (clobber (match_scratch:P 4 "=r"))
12076 (clobber (match_scratch:P 5 "=r"))
12077 (clobber (reg:P CA_REGNO))]
12081 [(parallel [(set (match_dup 5)
12082 (neg:P (match_dup 4)))
12083 (set (reg:P CA_REGNO)
12084 (eq:P (match_dup 4)
12086 (parallel [(set (match_dup 0)
12087 (plus:P (match_dup 3)
12089 (clobber (reg:P CA_REGNO))])]
12091 operands[4] = rs6000_emit_eqne (<MODE>mode,
12092 operands[1], operands[2], operands[4]);
12094 if (GET_CODE (operands[5]) == SCRATCH)
12095 operands[5] = gen_reg_rtx (<MODE>mode);
12097 [(set (attr "length")
12098 (if_then_else (match_test "operands[2] == const0_rtx")
12100 (const_string "12")))])
12102 (define_insn_and_split "*plus_ne_<mode>"
12103 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12104 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12105 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12106 (match_operand:P 3 "gpc_reg_operand" "r")))
12107 (clobber (match_scratch:P 4 "=r"))
12108 (clobber (match_scratch:P 5 "=r"))
12109 (clobber (reg:P CA_REGNO))]
12113 [(parallel [(set (match_dup 5)
12114 (plus:P (match_dup 4)
12116 (set (reg:P CA_REGNO)
12117 (ne:P (match_dup 4)
12119 (parallel [(set (match_dup 0)
12120 (plus:P (match_dup 3)
12122 (clobber (reg:P CA_REGNO))])]
12124 operands[4] = rs6000_emit_eqne (<MODE>mode,
12125 operands[1], operands[2], operands[4]);
12127 if (GET_CODE (operands[5]) == SCRATCH)
12128 operands[5] = gen_reg_rtx (<MODE>mode);
12130 [(set (attr "length")
12131 (if_then_else (match_test "operands[2] == const0_rtx")
12133 (const_string "12")))])
12135 (define_insn_and_split "*minus_eq_<mode>"
12136 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12137 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12138 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12139 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12140 (clobber (match_scratch:P 4 "=r"))
12141 (clobber (match_scratch:P 5 "=r"))
12142 (clobber (reg:P CA_REGNO))]
12146 [(parallel [(set (match_dup 5)
12147 (plus:P (match_dup 4)
12149 (set (reg:P CA_REGNO)
12150 (ne:P (match_dup 4)
12152 (parallel [(set (match_dup 0)
12153 (plus:P (plus:P (match_dup 3)
12156 (clobber (reg:P CA_REGNO))])]
12158 operands[4] = rs6000_emit_eqne (<MODE>mode,
12159 operands[1], operands[2], operands[4]);
12161 if (GET_CODE (operands[5]) == SCRATCH)
12162 operands[5] = gen_reg_rtx (<MODE>mode);
12164 [(set (attr "length")
12165 (if_then_else (match_test "operands[2] == const0_rtx")
12167 (const_string "12")))])
12169 (define_insn_and_split "*minus_ne_<mode>"
12170 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12171 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12172 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12173 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12174 (clobber (match_scratch:P 4 "=r"))
12175 (clobber (match_scratch:P 5 "=r"))
12176 (clobber (reg:P CA_REGNO))]
12180 [(parallel [(set (match_dup 5)
12181 (neg:P (match_dup 4)))
12182 (set (reg:P CA_REGNO)
12183 (eq:P (match_dup 4)
12185 (parallel [(set (match_dup 0)
12186 (plus:P (plus:P (match_dup 3)
12189 (clobber (reg:P CA_REGNO))])]
12191 operands[4] = rs6000_emit_eqne (<MODE>mode,
12192 operands[1], operands[2], operands[4]);
12194 if (GET_CODE (operands[5]) == SCRATCH)
12195 operands[5] = gen_reg_rtx (<MODE>mode);
12197 [(set (attr "length")
12198 (if_then_else (match_test "operands[2] == const0_rtx")
12200 (const_string "12")))])
12202 (define_insn_and_split "*eqsi3_ext<mode>"
12203 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12204 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12205 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12206 (clobber (match_scratch:SI 3 "=r"))
12207 (clobber (match_scratch:SI 4 "=r"))]
12211 [(set (match_dup 4)
12212 (clz:SI (match_dup 3)))
12215 (lshiftrt:SI (match_dup 4)
12218 operands[3] = rs6000_emit_eqne (SImode,
12219 operands[1], operands[2], operands[3]);
12221 if (GET_CODE (operands[4]) == SCRATCH)
12222 operands[4] = gen_reg_rtx (SImode);
12224 [(set (attr "length")
12225 (if_then_else (match_test "operands[2] == const0_rtx")
12227 (const_string "12")))])
12229 (define_insn_and_split "*nesi3_ext<mode>"
12230 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12231 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12232 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12233 (clobber (match_scratch:SI 3 "=r"))
12234 (clobber (match_scratch:SI 4 "=r"))
12235 (clobber (match_scratch:EXTSI 5 "=r"))]
12239 [(set (match_dup 4)
12240 (clz:SI (match_dup 3)))
12243 (lshiftrt:SI (match_dup 4)
12246 (xor:EXTSI (match_dup 5)
12249 operands[3] = rs6000_emit_eqne (SImode,
12250 operands[1], operands[2], operands[3]);
12252 if (GET_CODE (operands[4]) == SCRATCH)
12253 operands[4] = gen_reg_rtx (SImode);
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")
12259 (const_string "12")
12260 (const_string "16")))])
12263 (define_code_iterator fp_rev [ordered ne unle unge])
12264 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12266 (define_insn_and_split "*<code><mode>_cc"
12267 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12268 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12270 "!flag_finite_math_only"
12275 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12276 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
12277 rtx tmp = gen_reg_rtx (<MODE>mode);
12278 emit_move_insn (tmp, eq);
12279 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12282 [(set_attr "length" "12")])
12284 (define_insn_and_split "*<code><mode>_cc"
12285 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12286 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12288 "!flag_finite_math_only"
12293 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
12295 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12298 [(set_attr "length" "12")])
12300 ;; Conditional branches.
12301 ;; These either are a single bc insn, or a bc around a b.
12303 (define_insn "*cbranch"
12305 (if_then_else (match_operator 1 "branch_comparison_operator"
12306 [(match_operand 2 "cc_reg_operand" "y")
12308 (label_ref (match_operand 0))
12312 return output_cbranch (operands[1], "%l0", 0, insn);
12314 [(set_attr "type" "branch")
12315 (set (attr "length")
12316 (if_then_else (and (ge (minus (match_dup 0) (pc))
12317 (const_int -32768))
12318 (lt (minus (match_dup 0) (pc))
12319 (const_int 32764)))
12323 (define_insn_and_split "*cbranch_2insn"
12325 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
12326 [(match_operand 2 "cc_reg_operand" "y")
12328 (label_ref (match_operand 0))
12330 "!flag_finite_math_only"
12335 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
12337 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
12339 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
12340 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12341 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12342 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12346 profile_probability prob
12347 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
12349 add_reg_br_prob_note (get_last_insn (), prob);
12354 [(set_attr "type" "branch")
12355 (set (attr "length")
12356 (if_then_else (and (ge (minus (match_dup 0) (pc))
12357 (const_int -32764))
12358 (lt (minus (match_dup 0) (pc))
12359 (const_int 32760)))
12363 ;; Conditional return.
12364 (define_insn "*creturn"
12366 (if_then_else (match_operator 0 "branch_comparison_operator"
12367 [(match_operand 1 "cc_reg_operand" "y")
12373 return output_cbranch (operands[0], NULL, 0, insn);
12375 [(set_attr "type" "jmpreg")])
12377 ;; Logic on condition register values.
12379 ; This pattern matches things like
12380 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12381 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12383 ; which are generated by the branch logic.
12384 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12386 (define_insn "@cceq_ior_compare_<mode>"
12387 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12388 (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
12389 [(match_operator:GPR 2
12390 "branch_positive_comparison_operator"
12392 "cc_reg_operand" "y,y")
12394 (match_operator:GPR 4
12395 "branch_positive_comparison_operator"
12397 "cc_reg_operand" "0,y")
12401 "cr%q1 %E0,%j2,%j4"
12402 [(set_attr "type" "cr_logical")
12403 (set_attr "cr_logical_3op" "no,yes")])
12405 ; Why is the constant -1 here, but 1 in the previous pattern?
12406 ; Because ~1 has all but the low bit set.
12407 (define_insn "cceq_ior_compare_complement"
12408 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12409 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12410 [(not:SI (match_operator:SI 2
12411 "branch_positive_comparison_operator"
12413 "cc_reg_operand" "y,y")
12415 (match_operator:SI 4
12416 "branch_positive_comparison_operator"
12418 "cc_reg_operand" "0,y")
12422 "cr%q1 %E0,%j2,%j4"
12423 [(set_attr "type" "cr_logical")
12424 (set_attr "cr_logical_3op" "no,yes")])
12426 (define_insn "@cceq_rev_compare_<mode>"
12427 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12428 (compare:CCEQ (match_operator:GPR 1
12429 "branch_positive_comparison_operator"
12431 "cc_reg_operand" "0,y")
12436 [(set_attr "type" "cr_logical")
12437 (set_attr "cr_logical_3op" "no,yes")])
12439 ;; If we are comparing the result of two comparisons, this can be done
12440 ;; using creqv or crxor.
12442 (define_insn_and_split ""
12443 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12444 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12445 [(match_operand 2 "cc_reg_operand" "y")
12447 (match_operator 3 "branch_comparison_operator"
12448 [(match_operand 4 "cc_reg_operand" "y")
12453 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12456 int positive_1, positive_2;
12458 positive_1 = branch_positive_comparison_operator (operands[1],
12459 GET_MODE (operands[1]));
12460 positive_2 = branch_positive_comparison_operator (operands[3],
12461 GET_MODE (operands[3]));
12464 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12465 GET_CODE (operands[1])),
12467 operands[2], const0_rtx);
12468 else if (GET_MODE (operands[1]) != SImode)
12469 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12470 operands[2], const0_rtx);
12473 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12474 GET_CODE (operands[3])),
12476 operands[4], const0_rtx);
12477 else if (GET_MODE (operands[3]) != SImode)
12478 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12479 operands[4], const0_rtx);
12481 if (positive_1 == positive_2)
12483 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12484 operands[5] = constm1_rtx;
12488 operands[5] = const1_rtx;
12492 ;; Unconditional branch and return.
12494 (define_insn "jump"
12496 (label_ref (match_operand 0)))]
12499 [(set_attr "type" "branch")])
12501 (define_insn "<return_str>return"
12505 [(set_attr "type" "jmpreg")])
12507 (define_expand "indirect_jump"
12508 [(set (pc) (match_operand 0 "register_operand"))]
12511 if (!rs6000_speculate_indirect_jumps) {
12512 rtx ccreg = gen_reg_rtx (CCmode);
12513 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12518 (define_insn "*indirect_jump<mode>"
12520 (match_operand:P 0 "register_operand" "c,*l"))]
12521 "rs6000_speculate_indirect_jumps"
12523 [(set_attr "type" "jmpreg")])
12525 (define_insn "@indirect_jump<mode>_nospec"
12526 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12527 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12528 "!rs6000_speculate_indirect_jumps"
12529 "crset %E1\;beq%T0- %1\;b $"
12530 [(set_attr "type" "jmpreg")
12531 (set_attr "length" "12")])
12533 ;; Table jump for switch statements:
12534 (define_expand "tablejump"
12535 [(use (match_operand 0))
12536 (use (label_ref (match_operand 1)))]
12539 if (rs6000_speculate_indirect_jumps)
12542 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12544 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12548 rtx ccreg = gen_reg_rtx (CCmode);
12551 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12553 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12554 emit_jump_insn (jump);
12559 (define_expand "tablejumpsi"
12560 [(set (match_dup 3)
12561 (plus:SI (match_operand:SI 0)
12563 (parallel [(set (pc)
12565 (use (label_ref (match_operand 1)))])]
12566 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12568 operands[0] = force_reg (SImode, operands[0]);
12569 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12570 operands[3] = gen_reg_rtx (SImode);
12573 (define_expand "tablejumpsi_nospec"
12574 [(set (match_dup 4)
12575 (plus:SI (match_operand:SI 0)
12577 (parallel [(set (pc)
12579 (use (label_ref (match_operand 1)))
12580 (clobber (match_operand 2))])]
12581 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12583 operands[0] = force_reg (SImode, operands[0]);
12584 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12585 operands[4] = gen_reg_rtx (SImode);
12588 (define_expand "tablejumpdi"
12589 [(set (match_dup 4)
12590 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12592 (plus:DI (match_dup 4)
12594 (parallel [(set (pc)
12596 (use (label_ref (match_operand 1)))])]
12597 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12599 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12600 operands[3] = gen_reg_rtx (DImode);
12601 operands[4] = gen_reg_rtx (DImode);
12604 (define_expand "tablejumpdi_nospec"
12605 [(set (match_dup 5)
12606 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12608 (plus:DI (match_dup 5)
12610 (parallel [(set (pc)
12612 (use (label_ref (match_operand 1)))
12613 (clobber (match_operand 2))])]
12614 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12616 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12617 operands[4] = gen_reg_rtx (DImode);
12618 operands[5] = gen_reg_rtx (DImode);
12621 (define_insn "*tablejump<mode>_internal1"
12623 (match_operand:P 0 "register_operand" "c,*l"))
12624 (use (label_ref (match_operand 1)))]
12625 "rs6000_speculate_indirect_jumps"
12627 [(set_attr "type" "jmpreg")])
12629 (define_insn "*tablejump<mode>_internal1_nospec"
12631 (match_operand:P 0 "register_operand" "c,*l"))
12632 (use (label_ref (match_operand 1)))
12633 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12634 "!rs6000_speculate_indirect_jumps"
12635 "crset %E2\;beq%T0- %2\;b $"
12636 [(set_attr "type" "jmpreg")
12637 (set_attr "length" "12")])
12640 [(unspec [(const_int 0)] UNSPEC_NOP)]
12644 (define_insn "group_ending_nop"
12645 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12648 operands[0] = gen_rtx_REG (Pmode,
12649 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12650 return "ori %0,%0,0";
12653 (define_insn "speculation_barrier"
12654 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12657 operands[0] = gen_rtx_REG (Pmode, 31);
12658 return "ori %0,%0,0";
12661 ;; Define the subtract-one-and-jump insns, starting with the template
12662 ;; so loop.c knows what to generate.
12664 (define_expand "doloop_end"
12665 [(use (match_operand 0)) ; loop pseudo
12666 (use (match_operand 1))] ; label
12669 if (GET_MODE (operands[0]) != Pmode)
12672 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12676 (define_expand "@ctr<mode>"
12677 [(parallel [(set (pc)
12678 (if_then_else (ne (match_operand:P 0 "register_operand")
12680 (label_ref (match_operand 1))
12683 (plus:P (match_dup 0)
12685 (clobber (match_scratch:CC 2))
12686 (clobber (match_scratch:P 3))])]
12690 ;; We need to be able to do this for any operand, including MEM, or we
12691 ;; will cause reload to blow up since we don't allow output reloads on
12693 ;; For the length attribute to be calculated correctly, the
12694 ;; label MUST be operand 0.
12695 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12696 ;; the ctr<mode> insns.
12698 (define_code_iterator eqne [eq ne])
12699 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12700 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12702 (define_insn "<bd>_<mode>"
12704 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12706 (label_ref (match_operand 0))
12708 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12709 (plus:P (match_dup 1)
12711 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12712 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12715 if (which_alternative != 0)
12717 else if (get_attr_length (insn) == 4)
12720 return "<bd_neg> $+8\;b %l0";
12722 [(set_attr "type" "branch")
12723 (set_attr_alternative "length"
12724 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12725 (const_int -32768))
12726 (lt (minus (match_dup 0) (pc))
12727 (const_int 32764)))
12730 (const_string "16")
12731 (const_string "20")
12732 (const_string "20")])])
12734 ;; Now the splitter if we could not allocate the CTR register
12737 (if_then_else (match_operator 2 "comparison_operator"
12738 [(match_operand:P 1 "gpc_reg_operand")
12741 (match_operand 6)))
12742 (set (match_operand:P 0 "nonimmediate_operand")
12743 (plus:P (match_dup 1)
12745 (clobber (match_scratch:CC 3))
12746 (clobber (match_scratch:P 4))]
12749 (if_then_else (match_dup 7)
12753 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12755 emit_insn (gen_rtx_SET (operands[3],
12756 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12757 if (int_reg_operand (operands[0], <MODE>mode))
12758 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12761 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12762 emit_move_insn (operands[0], operands[4]);
12764 /* No DONE so branch comes from the pattern. */
12767 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12768 ;; Note that in the case of long branches we have to decompose this into
12769 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12770 ;; and the CR bit, which means there is no way to conveniently invert the
12771 ;; comparison as is done with plain bdnz/bdz.
12773 (define_insn "<bd>tf_<mode>"
12777 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12779 (match_operator 3 "branch_comparison_operator"
12780 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12782 (label_ref (match_operand 0))
12784 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12785 (plus:P (match_dup 1)
12787 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12788 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12789 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12792 if (which_alternative != 0)
12794 else if (get_attr_length (insn) == 4)
12796 if (branch_positive_comparison_operator (operands[3],
12797 GET_MODE (operands[3])))
12798 return "<bd>t %j3,%l0";
12800 return "<bd>f %j3,%l0";
12804 static char seq[96];
12805 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12806 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12810 [(set_attr "type" "branch")
12811 (set_attr_alternative "length"
12812 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12813 (const_int -32768))
12814 (lt (minus (match_dup 0) (pc))
12815 (const_int 32764)))
12818 (const_string "16")
12819 (const_string "20")
12820 (const_string "20")])])
12822 ;; Now the splitter if we could not allocate the CTR register
12827 (match_operator 1 "comparison_operator"
12828 [(match_operand:P 0 "gpc_reg_operand")
12830 (match_operator 3 "branch_comparison_operator"
12831 [(match_operand 2 "cc_reg_operand")
12834 (match_operand 5)))
12835 (set (match_operand:P 6 "nonimmediate_operand")
12836 (plus:P (match_dup 0)
12838 (clobber (match_scratch:P 7))
12839 (clobber (match_scratch:CC 8))
12840 (clobber (match_scratch:CCEQ 9))]
12844 rtx ctr = operands[0];
12845 rtx ctrcmp = operands[1];
12846 rtx ccin = operands[2];
12847 rtx cccmp = operands[3];
12848 rtx dst1 = operands[4];
12849 rtx dst2 = operands[5];
12850 rtx ctrout = operands[6];
12851 rtx ctrtmp = operands[7];
12852 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12853 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12855 cmpcode = reverse_condition (cmpcode);
12856 /* Generate crand/crandc here. */
12857 emit_insn (gen_rtx_SET (operands[8],
12858 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12859 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12861 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12863 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
12864 operands[8], cccmp, ccin));
12866 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12867 operands[8], cccmp, ccin));
12868 if (int_reg_operand (ctrout, <MODE>mode))
12869 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12872 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12873 emit_move_insn (ctrout, ctrtmp);
12875 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12876 emit_jump_insn (gen_rtx_SET (pc_rtx,
12877 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12883 (define_insn "trap"
12884 [(trap_if (const_int 1) (const_int 0))]
12887 [(set_attr "type" "trap")])
12889 (define_expand "ctrap<mode>4"
12890 [(trap_if (match_operator 0 "ordered_comparison_operator"
12891 [(match_operand:GPR 1 "register_operand")
12892 (match_operand:GPR 2 "reg_or_short_operand")])
12893 (match_operand 3 "zero_constant" ""))]
12898 [(trap_if (match_operator 0 "ordered_comparison_operator"
12899 [(match_operand:GPR 1 "register_operand" "r")
12900 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12903 "t<wd>%V0%I2 %1,%2"
12904 [(set_attr "type" "trap")])
12906 ;; Insns related to generating the function prologue and epilogue.
12908 (define_expand "prologue"
12909 [(use (const_int 0))]
12912 rs6000_emit_prologue ();
12913 if (!TARGET_SCHED_PROLOG)
12914 emit_insn (gen_blockage ());
12918 (define_insn "*movesi_from_cr_one"
12919 [(match_parallel 0 "mfcr_operation"
12920 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12921 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12922 (match_operand 3 "immediate_operand" "n")]
12923 UNSPEC_MOVESI_FROM_CR))])]
12928 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12930 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12931 operands[4] = GEN_INT (mask);
12932 output_asm_insn ("mfcr %1,%4", operands);
12936 [(set_attr "type" "mfcrf")])
12938 ;; Don't include the volatile CRs since their values are not used wrt CR save
12939 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12940 ;; prologue past an insn (early exit test) that defines a register used in the
12942 (define_insn "prologue_movesi_from_cr"
12943 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12944 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12945 (reg:CC CR4_REGNO)]
12946 UNSPEC_MOVESI_FROM_CR))]
12949 [(set_attr "type" "mfcr")])
12951 (define_insn "*crsave"
12952 [(match_parallel 0 "crsave_operation"
12953 [(set (match_operand:SI 1 "memory_operand" "=m")
12954 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12957 [(set_attr "type" "store")])
12959 (define_insn "*stmw"
12960 [(match_parallel 0 "stmw_operation"
12961 [(set (match_operand:SI 1 "memory_operand" "=m")
12962 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12965 [(set_attr "type" "store")
12966 (set_attr "update" "yes")
12967 (set_attr "indexed" "yes")])
12969 ; The following comment applies to:
12973 ; return_and_restore_gpregs*
12974 ; return_and_restore_fpregs*
12975 ; return_and_restore_fpregs_aix*
12977 ; The out-of-line save / restore functions expects one input argument.
12978 ; Since those are not standard call_insn's, we must avoid using
12979 ; MATCH_OPERAND for that argument. That way the register rename
12980 ; optimization will not try to rename this register.
12981 ; Each pattern is repeated for each possible register number used in
12982 ; various ABIs (r11, r1, and for some functions r12)
12984 (define_insn "*save_gpregs_<mode>_r11"
12985 [(match_parallel 0 "any_parallel_operand"
12986 [(clobber (reg:P LR_REGNO))
12987 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12989 (set (match_operand:P 2 "memory_operand" "=m")
12990 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12993 [(set_attr "type" "branch")])
12995 (define_insn "*save_gpregs_<mode>_r12"
12996 [(match_parallel 0 "any_parallel_operand"
12997 [(clobber (reg:P LR_REGNO))
12998 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13000 (set (match_operand:P 2 "memory_operand" "=m")
13001 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13004 [(set_attr "type" "branch")])
13006 (define_insn "*save_gpregs_<mode>_r1"
13007 [(match_parallel 0 "any_parallel_operand"
13008 [(clobber (reg:P LR_REGNO))
13009 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13011 (set (match_operand:P 2 "memory_operand" "=m")
13012 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13015 [(set_attr "type" "branch")])
13017 (define_insn "*save_fpregs_<mode>_r11"
13018 [(match_parallel 0 "any_parallel_operand"
13019 [(clobber (reg:P LR_REGNO))
13020 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13022 (set (match_operand:DF 2 "memory_operand" "=m")
13023 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13026 [(set_attr "type" "branch")])
13028 (define_insn "*save_fpregs_<mode>_r12"
13029 [(match_parallel 0 "any_parallel_operand"
13030 [(clobber (reg:P LR_REGNO))
13031 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13033 (set (match_operand:DF 2 "memory_operand" "=m")
13034 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13037 [(set_attr "type" "branch")])
13039 (define_insn "*save_fpregs_<mode>_r1"
13040 [(match_parallel 0 "any_parallel_operand"
13041 [(clobber (reg:P LR_REGNO))
13042 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13044 (set (match_operand:DF 2 "memory_operand" "=m")
13045 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13048 [(set_attr "type" "branch")])
13050 ; This is to explain that changes to the stack pointer should
13051 ; not be moved over loads from or stores to stack memory.
13052 (define_insn "stack_tie"
13053 [(match_parallel 0 "tie_operand"
13054 [(set (mem:BLK (reg 1)) (const_int 0))])]
13057 [(set_attr "length" "0")])
13059 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13060 ; stay behind all restores from the stack, it cannot be reordered to before
13061 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13062 (define_insn "stack_restore_tie"
13063 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13064 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13065 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13066 (set (mem:BLK (scratch)) (const_int 0))]
13071 [(set_attr "type" "*,add")])
13073 (define_expand "epilogue"
13074 [(use (const_int 0))]
13077 if (!TARGET_SCHED_PROLOG)
13078 emit_insn (gen_blockage ());
13079 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13083 ; On some processors, doing the mtcrf one CC register at a time is
13084 ; faster (like on the 604e). On others, doing them all at once is
13085 ; faster; for instance, on the 601 and 750.
13087 (define_expand "movsi_to_cr_one"
13088 [(set (match_operand:CC 0 "cc_reg_operand")
13089 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13090 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13092 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13094 (define_insn "*movsi_to_cr"
13095 [(match_parallel 0 "mtcrf_operation"
13096 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13097 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13098 (match_operand 3 "immediate_operand" "n")]
13099 UNSPEC_MOVESI_TO_CR))])]
13104 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13105 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13106 operands[4] = GEN_INT (mask);
13107 return "mtcrf %4,%2";
13109 [(set_attr "type" "mtcr")])
13111 (define_insn "*mtcrfsi"
13112 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13113 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13114 (match_operand 2 "immediate_operand" "n")]
13115 UNSPEC_MOVESI_TO_CR))]
13116 "REG_P (operands[0])
13117 && CR_REGNO_P (REGNO (operands[0]))
13118 && CONST_INT_P (operands[2])
13119 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13121 [(set_attr "type" "mtcr")])
13123 ; The load-multiple instructions have similar properties.
13124 ; Note that "load_multiple" is a name known to the machine-independent
13125 ; code that actually corresponds to the PowerPC load-string.
13127 (define_insn "*lmw"
13128 [(match_parallel 0 "lmw_operation"
13129 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13130 (match_operand:SI 2 "memory_operand" "m"))])]
13133 [(set_attr "type" "load")
13134 (set_attr "update" "yes")
13135 (set_attr "indexed" "yes")
13136 (set_attr "cell_micro" "always")])
13138 ; FIXME: "any_parallel_operand" is a bit flexible...
13140 ; The following comment applies to:
13144 ; return_and_restore_gpregs*
13145 ; return_and_restore_fpregs*
13146 ; return_and_restore_fpregs_aix*
13148 ; The out-of-line save / restore functions expects one input argument.
13149 ; Since those are not standard call_insn's, we must avoid using
13150 ; MATCH_OPERAND for that argument. That way the register rename
13151 ; optimization will not try to rename this register.
13152 ; Each pattern is repeated for each possible register number used in
13153 ; various ABIs (r11, r1, and for some functions r12)
13155 (define_insn "*restore_gpregs_<mode>_r11"
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 "gpc_reg_operand" "=r")
13161 (match_operand:P 3 "memory_operand" "m"))])]
13164 [(set_attr "type" "branch")])
13166 (define_insn "*restore_gpregs_<mode>_r12"
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 "gpc_reg_operand" "=r")
13172 (match_operand:P 3 "memory_operand" "m"))])]
13175 [(set_attr "type" "branch")])
13177 (define_insn "*restore_gpregs_<mode>_r1"
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:P 2 "gpc_reg_operand" "=r")
13183 (match_operand:P 3 "memory_operand" "m"))])]
13186 [(set_attr "type" "branch")])
13188 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13189 [(match_parallel 0 "any_parallel_operand"
13191 (clobber (reg:P LR_REGNO))
13192 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13194 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13195 (match_operand:P 3 "memory_operand" "m"))])]
13198 [(set_attr "type" "branch")])
13200 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13201 [(match_parallel 0 "any_parallel_operand"
13203 (clobber (reg:P LR_REGNO))
13204 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13206 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13207 (match_operand:P 3 "memory_operand" "m"))])]
13210 [(set_attr "type" "branch")])
13212 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13213 [(match_parallel 0 "any_parallel_operand"
13215 (clobber (reg:P LR_REGNO))
13216 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13218 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13219 (match_operand:P 3 "memory_operand" "m"))])]
13222 [(set_attr "type" "branch")])
13224 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13225 [(match_parallel 0 "any_parallel_operand"
13227 (clobber (reg:P LR_REGNO))
13228 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13230 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13231 (match_operand:DF 3 "memory_operand" "m"))])]
13234 [(set_attr "type" "branch")])
13236 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13237 [(match_parallel 0 "any_parallel_operand"
13239 (clobber (reg:P LR_REGNO))
13240 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13242 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13243 (match_operand:DF 3 "memory_operand" "m"))])]
13246 [(set_attr "type" "branch")])
13248 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13249 [(match_parallel 0 "any_parallel_operand"
13251 (clobber (reg:P LR_REGNO))
13252 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13254 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13255 (match_operand:DF 3 "memory_operand" "m"))])]
13258 [(set_attr "type" "branch")])
13260 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13261 [(match_parallel 0 "any_parallel_operand"
13263 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13265 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13266 (match_operand:DF 3 "memory_operand" "m"))])]
13269 [(set_attr "type" "branch")])
13271 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13272 [(match_parallel 0 "any_parallel_operand"
13274 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13276 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13277 (match_operand:DF 3 "memory_operand" "m"))])]
13280 [(set_attr "type" "branch")])
13282 ; This is used in compiling the unwind routines.
13283 (define_expand "eh_return"
13284 [(use (match_operand 0 "general_operand"))]
13287 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13291 ; We can't expand this before we know where the link register is stored.
13292 (define_insn_and_split "@eh_set_lr_<mode>"
13293 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13294 (clobber (match_scratch:P 1 "=&b"))]
13300 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13304 (define_insn "prefetch"
13305 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13306 (match_operand:SI 1 "const_int_operand" "n")
13307 (match_operand:SI 2 "const_int_operand" "n"))]
13312 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13313 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13314 The AIX assembler does not support the three operand form of dcbt
13315 and dcbtst on Power 7 (-mpwr7). */
13316 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13318 if (REG_P (operands[0]))
13320 if (INTVAL (operands[1]) == 0)
13321 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13323 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13327 if (INTVAL (operands[1]) == 0)
13328 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13330 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13333 [(set_attr "type" "load")])
13335 ;; Handle -fsplit-stack.
13337 (define_expand "split_stack_prologue"
13341 rs6000_expand_split_stack_prologue ();
13345 (define_expand "load_split_stack_limit"
13346 [(set (match_operand 0)
13347 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13350 emit_insn (gen_rtx_SET (operands[0],
13351 gen_rtx_UNSPEC (Pmode,
13352 gen_rtvec (1, const0_rtx),
13353 UNSPEC_STACK_CHECK)));
13357 (define_insn "load_split_stack_limit_di"
13358 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13359 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13361 "ld %0,-0x7040(13)"
13362 [(set_attr "type" "load")
13363 (set_attr "update" "no")
13364 (set_attr "indexed" "no")])
13366 (define_insn "load_split_stack_limit_si"
13367 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13368 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13370 "lwz %0,-0x7020(2)"
13371 [(set_attr "type" "load")
13372 (set_attr "update" "no")
13373 (set_attr "indexed" "no")])
13375 ;; A return instruction which the middle-end doesn't see.
13376 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13377 ;; after the call to __morestack.
13378 (define_insn "split_stack_return"
13379 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13382 [(set_attr "type" "jmpreg")])
13384 ;; If there are operand 0 bytes available on the stack, jump to
13386 (define_expand "split_stack_space_check"
13387 [(set (match_dup 2)
13388 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13390 (minus (reg STACK_POINTER_REGNUM)
13391 (match_operand 0)))
13392 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13393 (set (pc) (if_then_else
13394 (geu (match_dup 4) (const_int 0))
13395 (label_ref (match_operand 1))
13399 rs6000_split_stack_space_check (operands[0], operands[1]);
13403 (define_insn "bpermd_<mode>"
13404 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13405 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13406 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13409 [(set_attr "type" "popcnt")])
13412 ;; Builtin fma support. Handle
13413 ;; Note that the conditions for expansion are in the FMA_F iterator.
13415 (define_expand "fma<mode>4"
13416 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13418 (match_operand:FMA_F 1 "gpc_reg_operand")
13419 (match_operand:FMA_F 2 "gpc_reg_operand")
13420 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13424 (define_insn "*fma<mode>4_fpr"
13425 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13427 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13428 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13429 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13430 "TARGET_HARD_FLOAT"
13432 fmadd<s> %0,%1,%2,%3
13433 xsmadda<sd>p %x0,%x1,%x2
13434 xsmaddm<sd>p %x0,%x1,%x3"
13435 [(set_attr "type" "fp")
13436 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13438 ; Altivec only has fma and nfms.
13439 (define_expand "fms<mode>4"
13440 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13442 (match_operand:FMA_F 1 "gpc_reg_operand")
13443 (match_operand:FMA_F 2 "gpc_reg_operand")
13444 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13445 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13448 (define_insn "*fms<mode>4_fpr"
13449 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13451 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13452 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13453 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13454 "TARGET_HARD_FLOAT"
13456 fmsub<s> %0,%1,%2,%3
13457 xsmsuba<sd>p %x0,%x1,%x2
13458 xsmsubm<sd>p %x0,%x1,%x3"
13459 [(set_attr "type" "fp")
13460 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13462 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13463 (define_expand "fnma<mode>4"
13464 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13467 (match_operand:FMA_F 1 "gpc_reg_operand")
13468 (match_operand:FMA_F 2 "gpc_reg_operand")
13469 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13470 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13473 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13474 (define_expand "fnms<mode>4"
13475 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13478 (match_operand:FMA_F 1 "gpc_reg_operand")
13479 (match_operand:FMA_F 2 "gpc_reg_operand")
13480 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13481 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13484 ; Not an official optab name, but used from builtins.
13485 (define_expand "nfma<mode>4"
13486 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13489 (match_operand:FMA_F 1 "gpc_reg_operand")
13490 (match_operand:FMA_F 2 "gpc_reg_operand")
13491 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13492 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13495 (define_insn "*nfma<mode>4_fpr"
13496 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13499 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13500 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13501 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13502 "TARGET_HARD_FLOAT"
13504 fnmadd<s> %0,%1,%2,%3
13505 xsnmadda<sd>p %x0,%x1,%x2
13506 xsnmaddm<sd>p %x0,%x1,%x3"
13507 [(set_attr "type" "fp")
13508 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13510 ; Not an official optab name, but used from builtins.
13511 (define_expand "nfms<mode>4"
13512 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13515 (match_operand:FMA_F 1 "gpc_reg_operand")
13516 (match_operand:FMA_F 2 "gpc_reg_operand")
13517 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13521 (define_insn "*nfmssf4_fpr"
13522 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13525 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13526 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13528 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13529 "TARGET_HARD_FLOAT"
13531 fnmsub<s> %0,%1,%2,%3
13532 xsnmsuba<sd>p %x0,%x1,%x2
13533 xsnmsubm<sd>p %x0,%x1,%x3"
13534 [(set_attr "type" "fp")
13535 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13537 (define_expand "rs6000_get_timebase"
13538 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13541 if (TARGET_POWERPC64)
13542 emit_insn (gen_rs6000_mftb_di (operands[0]));
13544 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13548 (define_insn "rs6000_get_timebase_ppc32"
13549 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13550 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13551 (clobber (match_scratch:SI 1 "=r"))
13552 (clobber (match_scratch:CC 2 "=y"))]
13553 "!TARGET_POWERPC64"
13555 if (WORDS_BIG_ENDIAN)
13558 return "mfspr %0,269\;"
13566 return "mftbu %0\;"
13575 return "mfspr %L0,269\;"
13583 return "mftbu %L0\;"
13590 [(set_attr "length" "20")])
13592 (define_insn "rs6000_mftb_<mode>"
13593 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13594 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13598 return "mfspr %0,268";
13604 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13605 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13606 (define_insn "rs6000_mffsl_hw"
13607 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13608 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13609 "TARGET_HARD_FLOAT"
13612 (define_expand "rs6000_mffsl"
13613 [(set (match_operand:DF 0 "gpc_reg_operand")
13614 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13615 "TARGET_HARD_FLOAT"
13617 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13618 otherwise fall back to the older mffs instruction to emulate the mffsl
13621 if (!TARGET_P9_MISC)
13623 rtx tmp1 = gen_reg_rtx (DFmode);
13625 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13626 instruction using the mffs instruction and masking the result. */
13627 emit_insn (gen_rs6000_mffs (tmp1));
13629 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
13630 rtx tmp2 = gen_reg_rtx (DImode);
13631 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
13633 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
13634 emit_move_insn (operands[0], tmp2df);
13638 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13642 (define_insn "rs6000_mffs"
13643 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13644 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13645 "TARGET_HARD_FLOAT"
13648 (define_insn "rs6000_mtfsf"
13649 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13650 (match_operand:DF 1 "gpc_reg_operand" "d")]
13652 "TARGET_HARD_FLOAT"
13655 (define_insn "rs6000_mtfsf_hi"
13656 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13657 (match_operand:DF 1 "gpc_reg_operand" "d")]
13659 "TARGET_HARD_FLOAT"
13663 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13664 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13665 ;; register that is being loaded. The fused ops must be physically adjacent.
13667 ;; On Power8 GPR loads, we try to use the register that is being load. The
13668 ;; peephole2 then gathers any other fused possibilities that it can find after
13669 ;; register allocation. If power9 fusion is selected, we also fuse floating
13670 ;; point loads/stores.
13672 ;; Find cases where the addis that feeds into a load instruction is either used
13673 ;; once or is the same as the target register, and replace it with the fusion
13677 [(set (match_operand:P 0 "base_reg_operand")
13678 (match_operand:P 1 "fusion_gpr_addis"))
13679 (set (match_operand:INT1 2 "base_reg_operand")
13680 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13682 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13686 expand_fusion_gpr_load (operands);
13690 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13693 (define_insn "*fusion_gpr_load_<mode>"
13694 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13695 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13696 UNSPEC_FUSION_GPR))]
13699 return emit_fusion_gpr_load (operands[0], operands[1]);
13701 [(set_attr "type" "load")
13702 (set_attr "length" "8")])
13705 ;; Optimize cases where we want to do a D-form load (register+offset) on
13706 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13711 ;; and we change this to:
13716 [(match_scratch:P 0 "b")
13717 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13718 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13719 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13721 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13722 [(set (match_dup 0)
13727 rtx tmp_reg = operands[0];
13728 rtx mem = operands[2];
13729 rtx addr = XEXP (mem, 0);
13730 rtx add_op0, add_op1, new_addr;
13732 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13733 add_op0 = XEXP (addr, 0);
13734 add_op1 = XEXP (addr, 1);
13735 gcc_assert (REG_P (add_op0));
13736 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13738 operands[4] = add_op1;
13739 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13742 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13743 ;; Altivec register, and the register allocator has generated:
13747 ;; and we change this to:
13752 [(match_scratch:P 0 "b")
13753 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13754 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13755 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13757 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13758 [(set (match_dup 0)
13763 rtx tmp_reg = operands[0];
13764 rtx mem = operands[3];
13765 rtx addr = XEXP (mem, 0);
13766 rtx add_op0, add_op1, new_addr;
13768 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13769 add_op0 = XEXP (addr, 0);
13770 add_op1 = XEXP (addr, 1);
13771 gcc_assert (REG_P (add_op0));
13772 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13774 operands[4] = add_op1;
13775 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13779 ;; Miscellaneous ISA 2.06 (power7) instructions
13780 (define_insn "addg6s"
13781 [(set (match_operand:SI 0 "register_operand" "=r")
13782 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13783 (match_operand:SI 2 "register_operand" "r")]
13787 [(set_attr "type" "integer")])
13789 (define_insn "cdtbcd"
13790 [(set (match_operand:SI 0 "register_operand" "=r")
13791 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13795 [(set_attr "type" "integer")])
13797 (define_insn "cbcdtd"
13798 [(set (match_operand:SI 0 "register_operand" "=r")
13799 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13803 [(set_attr "type" "integer")])
13805 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13808 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13809 (UNSPEC_DIVEU "eu")])
13811 (define_insn "div<div_extend>_<mode>"
13812 [(set (match_operand:GPR 0 "register_operand" "=r")
13813 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13814 (match_operand:GPR 2 "register_operand" "r")]
13815 UNSPEC_DIV_EXTEND))]
13817 "div<wd><div_extend> %0,%1,%2"
13818 [(set_attr "type" "div")
13819 (set_attr "size" "<bits>")])
13822 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13824 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13825 (define_mode_attr FP128_64 [(TF "DF")
13830 (define_expand "unpack<mode>"
13831 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13833 [(match_operand:FMOVE128 1 "register_operand")
13834 (match_operand:QI 2 "const_0_to_1_operand")]
13835 UNSPEC_UNPACK_128BIT))]
13836 "FLOAT128_2REG_P (<MODE>mode)"
13839 (define_insn_and_split "unpack<mode>_dm"
13840 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13842 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13843 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13844 UNSPEC_UNPACK_128BIT))]
13845 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13847 "&& reload_completed"
13848 [(set (match_dup 0) (match_dup 3))]
13850 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13852 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13854 emit_note (NOTE_INSN_DELETED);
13858 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13860 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13862 (define_insn_and_split "unpack<mode>_nodm"
13863 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13865 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13866 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13867 UNSPEC_UNPACK_128BIT))]
13868 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13870 "&& reload_completed"
13871 [(set (match_dup 0) (match_dup 3))]
13873 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13875 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13877 emit_note (NOTE_INSN_DELETED);
13881 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13883 [(set_attr "type" "fp,fpstore")])
13885 (define_insn_and_split "pack<mode>"
13886 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13888 [(match_operand:<FP128_64> 1 "register_operand" "d")
13889 (match_operand:<FP128_64> 2 "register_operand" "d")]
13890 UNSPEC_PACK_128BIT))]
13891 "FLOAT128_2REG_P (<MODE>mode)"
13893 "&& reload_completed"
13894 [(set (match_dup 3) (match_dup 1))
13895 (set (match_dup 4) (match_dup 2))]
13897 unsigned dest_hi = REGNO (operands[0]);
13898 unsigned dest_lo = dest_hi + 1;
13900 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13901 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13903 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13904 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13906 [(set_attr "type" "fp")
13907 (set_attr "length" "8")])
13909 (define_insn "unpack<mode>"
13910 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13911 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13912 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13913 UNSPEC_UNPACK_128BIT))]
13914 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13916 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13917 return ASM_COMMENT_START " xxpermdi to same register";
13919 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13920 return "xxpermdi %x0,%x1,%x1,%3";
13922 [(set_attr "type" "vecperm")])
13924 (define_insn "pack<mode>"
13925 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13926 (unspec:FMOVE128_VSX
13927 [(match_operand:DI 1 "register_operand" "wa")
13928 (match_operand:DI 2 "register_operand" "wa")]
13929 UNSPEC_PACK_128BIT))]
13931 "xxpermdi %x0,%x1,%x2,0"
13932 [(set_attr "type" "vecperm")])
13936 ;; ISA 2.08 IEEE 128-bit floating point support.
13938 (define_insn "add<mode>3"
13939 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13941 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13942 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13943 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13945 [(set_attr "type" "vecfloat")
13946 (set_attr "size" "128")])
13948 (define_insn "sub<mode>3"
13949 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13951 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13952 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13953 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13955 [(set_attr "type" "vecfloat")
13956 (set_attr "size" "128")])
13958 (define_insn "mul<mode>3"
13959 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13961 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13962 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13963 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13965 [(set_attr "type" "qmul")
13966 (set_attr "size" "128")])
13968 (define_insn "div<mode>3"
13969 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13971 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13972 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13973 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13975 [(set_attr "type" "vecdiv")
13976 (set_attr "size" "128")])
13978 (define_insn "sqrt<mode>2"
13979 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13981 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13982 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13984 [(set_attr "type" "vecdiv")
13985 (set_attr "size" "128")])
13987 (define_expand "copysign<mode>3"
13988 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13989 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13990 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13991 "FLOAT128_IEEE_P (<MODE>mode)"
13993 if (TARGET_FLOAT128_HW)
13994 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13997 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14002 (define_insn "copysign<mode>3_hard"
14003 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14005 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14006 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14008 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14009 "xscpsgnqp %0,%2,%1"
14010 [(set_attr "type" "vecmove")
14011 (set_attr "size" "128")])
14013 (define_insn "copysign<mode>3_soft"
14014 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14016 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14017 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14019 (clobber (match_scratch:IEEE128 3 "=&v"))]
14020 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14021 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14022 [(set_attr "type" "veccomplex")
14023 (set_attr "length" "8")])
14025 (define_insn "@neg<mode>2_hw"
14026 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14028 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14029 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14031 [(set_attr "type" "vecmove")
14032 (set_attr "size" "128")])
14035 (define_insn "@abs<mode>2_hw"
14036 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14038 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14039 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14041 [(set_attr "type" "vecmove")
14042 (set_attr "size" "128")])
14045 (define_insn "*nabs<mode>2_hw"
14046 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14049 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14050 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14052 [(set_attr "type" "vecmove")
14053 (set_attr "size" "128")])
14055 ;; Initially don't worry about doing fusion
14056 (define_insn "fma<mode>4_hw"
14057 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14059 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14060 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14061 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14062 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14063 "xsmaddqp %0,%1,%2"
14064 [(set_attr "type" "qmul")
14065 (set_attr "size" "128")])
14067 (define_insn "*fms<mode>4_hw"
14068 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14070 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14071 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14073 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14074 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14075 "xsmsubqp %0,%1,%2"
14076 [(set_attr "type" "qmul")
14077 (set_attr "size" "128")])
14079 (define_insn "*nfma<mode>4_hw"
14080 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14083 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14084 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14085 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14086 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14087 "xsnmaddqp %0,%1,%2"
14088 [(set_attr "type" "qmul")
14089 (set_attr "size" "128")])
14091 (define_insn "*nfms<mode>4_hw"
14092 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14095 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14096 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14098 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14099 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14100 "xsnmsubqp %0,%1,%2"
14101 [(set_attr "type" "qmul")
14102 (set_attr "size" "128")])
14104 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14105 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14106 (float_extend:IEEE128
14107 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14108 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14110 [(set_attr "type" "vecfloat")
14111 (set_attr "size" "128")])
14113 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14114 ;; point is a simple copy.
14115 (define_insn_and_split "extendkftf2"
14116 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14117 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14118 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14122 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14125 emit_note (NOTE_INSN_DELETED);
14128 [(set_attr "type" "*,veclogical")
14129 (set_attr "length" "0,4")])
14131 (define_insn_and_split "trunctfkf2"
14132 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14133 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14134 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14138 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14141 emit_note (NOTE_INSN_DELETED);
14144 [(set_attr "type" "*,veclogical")
14145 (set_attr "length" "0,4")])
14147 (define_insn "trunc<mode>df2_hw"
14148 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14150 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14151 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14153 [(set_attr "type" "vecfloat")
14154 (set_attr "size" "128")])
14156 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14157 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14159 (define_insn_and_split "trunc<mode>sf2_hw"
14160 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14162 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14163 (clobber (match_scratch:DF 2 "=v"))]
14164 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14167 [(set (match_dup 2)
14168 (unspec:DF [(match_dup 1)]
14169 UNSPEC_TRUNC_ROUND_TO_ODD))
14171 (float_truncate:SF (match_dup 2)))]
14173 if (GET_CODE (operands[2]) == SCRATCH)
14174 operands[2] = gen_reg_rtx (DFmode);
14176 [(set_attr "type" "vecfloat")
14177 (set_attr "length" "8")
14178 (set_attr "isa" "p8v")])
14180 ;; Conversion between IEEE 128-bit and integer types
14182 ;; The fix function for DImode and SImode was declared earlier as a
14183 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14184 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14185 ;; unless we have the IEEE 128-bit hardware.
14187 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14188 ;; to provide a GPR target that used direct move and a conversion in the GPR
14189 ;; which works around QImode/HImode not being allowed in vector registers in
14190 ;; ISA 2.07 (power8).
14191 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14192 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14193 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14194 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14195 "xscvqp<su><wd>z %0,%1"
14196 [(set_attr "type" "vecfloat")
14197 (set_attr "size" "128")])
14199 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14200 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14202 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14203 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14204 "xscvqp<su>wz %0,%1"
14205 [(set_attr "type" "vecfloat")
14206 (set_attr "size" "128")])
14208 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14209 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14210 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14211 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14213 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14214 (clobber (match_scratch:QHSI 2 "=v"))]
14215 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14217 "&& reload_completed"
14218 [(set (match_dup 2)
14219 (any_fix:QHSI (match_dup 1)))
14223 (define_insn "float_<mode>di2_hw"
14224 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14225 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14226 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14228 [(set_attr "type" "vecfloat")
14229 (set_attr "size" "128")])
14231 (define_insn_and_split "float_<mode>si2_hw"
14232 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14233 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14234 (clobber (match_scratch:DI 2 "=v"))]
14235 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14238 [(set (match_dup 2)
14239 (sign_extend:DI (match_dup 1)))
14241 (float:IEEE128 (match_dup 2)))]
14243 if (GET_CODE (operands[2]) == SCRATCH)
14244 operands[2] = gen_reg_rtx (DImode);
14246 if (MEM_P (operands[1]))
14247 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14250 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14251 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14252 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14253 (clobber (match_scratch:DI 2 "=X,r,X"))]
14254 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14256 "&& reload_completed"
14259 rtx dest = operands[0];
14260 rtx src = operands[1];
14261 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14263 if (altivec_register_operand (src, <QHI:MODE>mode))
14264 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14265 else if (int_reg_operand (src, <QHI:MODE>mode))
14267 rtx ext_di = operands[2];
14268 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14269 emit_move_insn (dest_di, ext_di);
14271 else if (MEM_P (src))
14273 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14274 emit_move_insn (dest_qhi, src);
14275 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14278 gcc_unreachable ();
14280 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14283 [(set_attr "length" "8,12,12")
14284 (set_attr "type" "vecfloat")
14285 (set_attr "size" "128")])
14287 (define_insn "floatuns_<mode>di2_hw"
14288 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14289 (unsigned_float:IEEE128
14290 (match_operand:DI 1 "altivec_register_operand" "v")))]
14291 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14293 [(set_attr "type" "vecfloat")
14294 (set_attr "size" "128")])
14296 (define_insn_and_split "floatuns_<mode>si2_hw"
14297 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14298 (unsigned_float:IEEE128
14299 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14300 (clobber (match_scratch:DI 2 "=v"))]
14301 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14304 [(set (match_dup 2)
14305 (zero_extend:DI (match_dup 1)))
14307 (float:IEEE128 (match_dup 2)))]
14309 if (GET_CODE (operands[2]) == SCRATCH)
14310 operands[2] = gen_reg_rtx (DImode);
14312 if (MEM_P (operands[1]))
14313 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14316 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14317 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14318 (unsigned_float:IEEE128
14319 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14320 (clobber (match_scratch:DI 2 "=X,r,X"))]
14321 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14323 "&& reload_completed"
14326 rtx dest = operands[0];
14327 rtx src = operands[1];
14328 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14330 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14331 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14332 else if (int_reg_operand (src, <QHI:MODE>mode))
14334 rtx ext_di = operands[2];
14335 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14336 emit_move_insn (dest_di, ext_di);
14339 gcc_unreachable ();
14341 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14344 [(set_attr "length" "8,12,8")
14345 (set_attr "type" "vecfloat")
14346 (set_attr "size" "128")])
14348 ;; IEEE 128-bit round to integer built-in functions
14349 (define_insn "floor<mode>2"
14350 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14352 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14354 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14356 [(set_attr "type" "vecfloat")
14357 (set_attr "size" "128")])
14359 (define_insn "ceil<mode>2"
14360 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14362 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14364 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14366 [(set_attr "type" "vecfloat")
14367 (set_attr "size" "128")])
14369 (define_insn "btrunc<mode>2"
14370 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14372 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14374 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14376 [(set_attr "type" "vecfloat")
14377 (set_attr "size" "128")])
14379 (define_insn "round<mode>2"
14380 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14382 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14384 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14386 [(set_attr "type" "vecfloat")
14387 (set_attr "size" "128")])
14389 ;; IEEE 128-bit instructions with round to odd semantics
14390 (define_insn "add<mode>3_odd"
14391 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14393 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14394 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14395 UNSPEC_ADD_ROUND_TO_ODD))]
14396 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14397 "xsaddqpo %0,%1,%2"
14398 [(set_attr "type" "vecfloat")
14399 (set_attr "size" "128")])
14401 (define_insn "sub<mode>3_odd"
14402 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14404 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14405 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14406 UNSPEC_SUB_ROUND_TO_ODD))]
14407 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14408 "xssubqpo %0,%1,%2"
14409 [(set_attr "type" "vecfloat")
14410 (set_attr "size" "128")])
14412 (define_insn "mul<mode>3_odd"
14413 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14415 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14416 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14417 UNSPEC_MUL_ROUND_TO_ODD))]
14418 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14419 "xsmulqpo %0,%1,%2"
14420 [(set_attr "type" "qmul")
14421 (set_attr "size" "128")])
14423 (define_insn "div<mode>3_odd"
14424 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14426 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14427 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14428 UNSPEC_DIV_ROUND_TO_ODD))]
14429 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14430 "xsdivqpo %0,%1,%2"
14431 [(set_attr "type" "vecdiv")
14432 (set_attr "size" "128")])
14434 (define_insn "sqrt<mode>2_odd"
14435 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14437 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14438 UNSPEC_SQRT_ROUND_TO_ODD))]
14439 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14441 [(set_attr "type" "vecdiv")
14442 (set_attr "size" "128")])
14444 (define_insn "fma<mode>4_odd"
14445 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14447 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14448 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14449 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14450 UNSPEC_FMA_ROUND_TO_ODD))]
14451 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14452 "xsmaddqpo %0,%1,%2"
14453 [(set_attr "type" "qmul")
14454 (set_attr "size" "128")])
14456 (define_insn "*fms<mode>4_odd"
14457 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14459 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14460 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14462 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14463 UNSPEC_FMA_ROUND_TO_ODD))]
14464 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14465 "xsmsubqpo %0,%1,%2"
14466 [(set_attr "type" "qmul")
14467 (set_attr "size" "128")])
14469 (define_insn "*nfma<mode>4_odd"
14470 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14473 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14474 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14475 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14476 UNSPEC_FMA_ROUND_TO_ODD)))]
14477 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14478 "xsnmaddqpo %0,%1,%2"
14479 [(set_attr "type" "qmul")
14480 (set_attr "size" "128")])
14482 (define_insn "*nfms<mode>4_odd"
14483 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14486 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14487 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14489 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14490 UNSPEC_FMA_ROUND_TO_ODD)))]
14491 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14492 "xsnmsubqpo %0,%1,%2"
14493 [(set_attr "type" "qmul")
14494 (set_attr "size" "128")])
14496 (define_insn "trunc<mode>df2_odd"
14497 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14498 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14499 UNSPEC_TRUNC_ROUND_TO_ODD))]
14500 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14502 [(set_attr "type" "vecfloat")
14503 (set_attr "size" "128")])
14505 ;; IEEE 128-bit comparisons
14506 (define_insn "*cmp<mode>_hw"
14507 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14508 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14509 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14510 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14511 "xscmpuqp %0,%1,%2"
14512 [(set_attr "type" "veccmp")
14513 (set_attr "size" "128")])
14515 ;; Miscellaneous ISA 3.0 (power9) instructions
14517 (define_insn "darn_32"
14518 [(set (match_operand:SI 0 "register_operand" "=r")
14519 (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14522 [(set_attr "type" "integer")])
14524 (define_insn "darn_raw"
14525 [(set (match_operand:DI 0 "register_operand" "=r")
14526 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14527 "TARGET_P9_MISC && TARGET_64BIT"
14529 [(set_attr "type" "integer")])
14531 (define_insn "darn"
14532 [(set (match_operand:DI 0 "register_operand" "=r")
14533 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14534 "TARGET_P9_MISC && TARGET_64BIT"
14536 [(set_attr "type" "integer")])
14538 ;; Test byte within range.
14540 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14541 ;; represents a byte whose value is ignored in this context and
14542 ;; vv, the least significant byte, holds the byte value that is to
14543 ;; be tested for membership within the range specified by operand 2.
14544 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14546 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14547 ;; vv <= hi. Otherwise, set register operand 0 to 0.
14549 ;; Though the instructions to which this expansion maps operate on
14550 ;; 64-bit registers, the current implementation only operates on
14551 ;; SI-mode operands as the high-order bits provide no information
14552 ;; that is not already available in the low-order bits. To avoid the
14553 ;; costs of data widening operations, future enhancements might allow
14554 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14555 (define_expand "cmprb"
14556 [(set (match_dup 3)
14557 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14558 (match_operand:SI 2 "gpc_reg_operand" "r")]
14560 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14561 (if_then_else:SI (lt (match_dup 3)
14564 (if_then_else (gt (match_dup 3)
14570 operands[3] = gen_reg_rtx (CCmode);
14573 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14574 ;; represents a byte whose value is ignored in this context and
14575 ;; vv, the least significant byte, holds the byte value that is to
14576 ;; be tested for membership within the range specified by operand 2.
14577 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14579 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14580 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
14581 ;; 3 bits of the target CR register are all set to 0.
14582 (define_insn "*cmprb_internal"
14583 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14584 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14585 (match_operand:SI 2 "gpc_reg_operand" "r")]
14589 [(set_attr "type" "logical")])
14591 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14592 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
14593 ;; if the GT bit (0x4) of condition register operand 1 is on.
14594 ;; Otherwise, set operand 0 to 0. Note that the result stored into
14595 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14596 ;; within condition register operand 1.
14597 (define_insn "setb_signed"
14598 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14599 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14602 (if_then_else (gt (match_dup 1)
14608 [(set_attr "type" "logical")])
14610 (define_insn "setb_unsigned"
14611 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14612 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14615 (if_then_else (gtu (match_dup 1)
14621 [(set_attr "type" "logical")])
14623 ;; Test byte within two ranges.
14625 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14626 ;; represents a byte whose value is ignored in this context and
14627 ;; vv, the least significant byte, holds the byte value that is to
14628 ;; be tested for membership within the range specified by operand 2.
14629 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14631 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14632 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
14635 ;; Though the instructions to which this expansion maps operate on
14636 ;; 64-bit registers, the current implementation only operates on
14637 ;; SI-mode operands as the high-order bits provide no information
14638 ;; that is not already available in the low-order bits. To avoid the
14639 ;; costs of data widening operations, future enhancements might allow
14640 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14641 (define_expand "cmprb2"
14642 [(set (match_dup 3)
14643 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14644 (match_operand:SI 2 "gpc_reg_operand" "r")]
14646 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14647 (if_then_else:SI (lt (match_dup 3)
14650 (if_then_else (gt (match_dup 3)
14656 operands[3] = gen_reg_rtx (CCmode);
14659 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14660 ;; represents a byte whose value is ignored in this context and
14661 ;; vv, the least significant byte, holds the byte value that is to
14662 ;; be tested for membership within the ranges specified by operand 2.
14663 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14665 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14666 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14667 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
14668 ;; CR register are all set to 0.
14669 (define_insn "*cmprb2_internal"
14670 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14671 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14672 (match_operand:SI 2 "gpc_reg_operand" "r")]
14676 [(set_attr "type" "logical")])
14678 ;; Test byte membership within set of 8 bytes.
14680 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14681 ;; represents a byte whose value is ignored in this context and
14682 ;; vv, the least significant byte, holds the byte value that is to
14683 ;; be tested for membership within the set specified by operand 2.
14684 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14686 ;; Return in target register operand 0 a value of 1 if vv equals one
14687 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
14688 ;; register operand 0 to 0. Note that the 8 byte values held within
14689 ;; operand 2 need not be unique.
14691 ;; Though the instructions to which this expansion maps operate on
14692 ;; 64-bit registers, the current implementation requires that operands
14693 ;; 0 and 1 have mode SI as the high-order bits provide no information
14694 ;; that is not already available in the low-order bits. To avoid the
14695 ;; costs of data widening operations, future enhancements might allow
14696 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14697 (define_expand "cmpeqb"
14698 [(set (match_dup 3)
14699 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14700 (match_operand:DI 2 "gpc_reg_operand" "r")]
14702 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14703 (if_then_else:SI (lt (match_dup 3)
14706 (if_then_else (gt (match_dup 3)
14710 "TARGET_P9_MISC && TARGET_64BIT"
14712 operands[3] = gen_reg_rtx (CCmode);
14715 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14716 ;; represents a byte whose value is ignored in this context and
14717 ;; vv, the least significant byte, holds the byte value that is to
14718 ;; be tested for membership within the set specified by operand 2.
14719 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14721 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14722 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
14723 ;; set the GT bit to zero. The other 3 bits of the target CR register
14724 ;; are all set to 0.
14725 (define_insn "*cmpeqb_internal"
14726 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14727 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14728 (match_operand:DI 2 "gpc_reg_operand" "r")]
14730 "TARGET_P9_MISC && TARGET_64BIT"
14732 [(set_attr "type" "logical")])
14735 (include "sync.md")
14736 (include "vector.md")
14738 (include "altivec.md")
14740 (include "crypto.md")