1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2019 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
89 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
107 UNSPEC_MACHOPIC_OFFSET
121 UNSPEC_P8V_RELOAD_FROM_GPR
124 UNSPEC_P8V_RELOAD_FROM_VSX
138 UNSPEC_ADD_ROUND_TO_ODD
139 UNSPEC_SUB_ROUND_TO_ODD
140 UNSPEC_MUL_ROUND_TO_ODD
141 UNSPEC_DIV_ROUND_TO_ODD
142 UNSPEC_FMA_ROUND_TO_ODD
143 UNSPEC_SQRT_ROUND_TO_ODD
144 UNSPEC_TRUNC_ROUND_TO_ODD
155 ;; UNSPEC_VOLATILE usage
158 (define_c_enum "unspecv"
160 UNSPECV_LL ; load-locked
161 UNSPECV_SC ; store-conditional
162 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
163 UNSPECV_EH_RR ; eh_reg_restore
164 UNSPECV_ISYNC ; isync instruction
165 UNSPECV_MFTB ; move from time base
166 UNSPECV_DARN ; darn 1 (deliver a random number)
167 UNSPECV_DARN_32 ; darn 2
168 UNSPECV_DARN_RAW ; darn 0
169 UNSPECV_NLGR ; non-local goto receiver
170 UNSPECV_MFFS ; Move from FPSCR
171 UNSPECV_MFFSL ; Move from FPSCR light instruction version
172 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
173 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
174 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
175 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
176 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
177 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
178 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
179 UNSPECV_SPEC_BARRIER ; Speculation barrier
182 ; The three different kinds of epilogue.
183 (define_enum "epilogue_type" [normal sibcall eh_return])
185 ;; Define an insn type attribute. This is used in function unit delay
189 add,logical,shift,insert,
191 exts,cntlz,popcnt,isel,
192 load,store,fpload,fpstore,vecload,vecstore,
194 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
195 cr_logical,mfcr,mfcrf,mtcr,
196 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
197 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
198 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
199 veclogical,veccmpfx,vecexts,vecmove,
201 (const_string "integer"))
203 ;; What data size does this instruction work on?
204 ;; This is used for insert, mul and others as necessary.
205 (define_attr "size" "8,16,32,64,128" (const_string "32"))
207 ;; What is the insn_cost for this insn? The target hook can still override
208 ;; this. For optimizing for size the "length" attribute is used instead.
209 (define_attr "cost" "" (const_int 0))
211 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
212 ;; This is used for add, logical, shift, exts, mul.
213 (define_attr "dot" "no,yes" (const_string "no"))
215 ;; Does this instruction sign-extend its result?
216 ;; This is used for load insns.
217 (define_attr "sign_extend" "no,yes" (const_string "no"))
219 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
220 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
222 ;; Does this instruction use indexed (that is, reg+reg) addressing?
223 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
224 ;; it is automatically set based on that. If a load or store instruction
225 ;; has fewer than two operands it needs to set this attribute manually
226 ;; or the compiler will crash.
227 (define_attr "indexed" "no,yes"
228 (if_then_else (ior (match_operand 0 "indexed_address_mem")
229 (match_operand 1 "indexed_address_mem"))
231 (const_string "no")))
233 ;; Does this instruction use update addressing?
234 ;; This is used for load and store insns. See the comments for "indexed".
235 (define_attr "update" "no,yes"
236 (if_then_else (ior (match_operand 0 "update_address_mem")
237 (match_operand 1 "update_address_mem"))
239 (const_string "no")))
241 ;; Is this instruction using operands[2] as shift amount, and can that be a
243 ;; This is used for shift insns.
244 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
246 ;; Is this instruction using a shift amount from a register?
247 ;; This is used for shift insns.
248 (define_attr "var_shift" "no,yes"
249 (if_then_else (and (eq_attr "type" "shift")
250 (eq_attr "maybe_var_shift" "yes"))
251 (if_then_else (match_operand 2 "gpc_reg_operand")
254 (const_string "no")))
256 ;; Is copying of this instruction disallowed?
257 (define_attr "cannot_copy" "no,yes" (const_string "no"))
260 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
261 ;; before the instruction. A prefixed instruction has a prefix instruction
262 ;; word that extends the immediate value of the instructions from 12-16 bits to
263 ;; 34 bits. The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
264 ;; insns. The default "length" attribute will also be adjusted by default to
266 (define_attr "prefixed" "no,yes"
267 (cond [(ior (match_test "!TARGET_PREFIXED_ADDR")
268 (match_test "!NONJUMP_INSN_P (insn)"))
271 (eq_attr "type" "load,fpload,vecload")
272 (if_then_else (match_test "prefixed_load_p (insn)")
276 (eq_attr "type" "store,fpstore,vecstore")
277 (if_then_else (match_test "prefixed_store_p (insn)")
281 (eq_attr "type" "integer,add")
282 (if_then_else (match_test "prefixed_paddi_p (insn)")
284 (const_string "no"))]
286 (const_string "no")))
288 ;; Return the number of real hardware instructions in a combined insn. If it
289 ;; is 0, just use the length / 4.
290 (define_attr "num_insns" "" (const_int 0))
292 ;; If an insn is prefixed, return the maximum number of prefixed instructions
293 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
295 (define_attr "max_prefixed_insns" "" (const_int 1))
297 ;; Length of the instruction (in bytes). This length does not consider the
298 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
299 ;; the length if there are prefixed instructions.
301 ;; While it might be tempting to use num_insns to calculate the length, it can
302 ;; be problematical unless all insn lengths are adjusted to use num_insns
303 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
304 ;; num_insns and recurse).
305 (define_attr "length" "" (const_int 4))
307 ;; Processor type -- this attribute must exactly match the processor_type
308 ;; enumeration in rs6000-opts.h.
310 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
311 ppc750,ppc7400,ppc7450,
312 ppc403,ppc405,ppc440,ppc476,
313 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
314 power4,power5,power6,power7,power8,power9,future,
315 rs64a,mpccore,cell,ppca2,titan"
316 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
318 ;; The ISA we implement.
319 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,fut"
320 (const_string "any"))
322 ;; Is this alternative enabled for the current CPU/ISA/etc.?
323 (define_attr "enabled" ""
325 [(eq_attr "isa" "any")
328 (and (eq_attr "isa" "p5")
329 (match_test "TARGET_POPCNTB"))
332 (and (eq_attr "isa" "p6")
333 (match_test "TARGET_CMPB"))
336 (and (eq_attr "isa" "p7")
337 (match_test "TARGET_POPCNTD"))
340 (and (eq_attr "isa" "p7v")
341 (match_test "TARGET_VSX"))
344 (and (eq_attr "isa" "p8v")
345 (match_test "TARGET_P8_VECTOR"))
348 (and (eq_attr "isa" "p9v")
349 (match_test "TARGET_P9_VECTOR"))
352 (and (eq_attr "isa" "p9kf")
353 (match_test "TARGET_FLOAT128_TYPE"))
356 (and (eq_attr "isa" "p9tf")
357 (match_test "FLOAT128_VECTOR_P (TFmode)"))
360 (and (eq_attr "isa" "fut")
361 (match_test "TARGET_FUTURE"))
365 ;; If this instruction is microcoded on the CELL processor
366 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
367 (define_attr "cell_micro" "not,conditional,always"
368 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
369 (eq_attr "dot" "yes"))
370 (and (eq_attr "type" "load")
371 (eq_attr "sign_extend" "yes"))
372 (and (eq_attr "type" "shift")
373 (eq_attr "var_shift" "yes")))
374 (const_string "always")
375 (const_string "not")))
377 (automata_option "ndfa")
390 (include "e300c2c3.md")
391 (include "e500mc.md")
392 (include "e500mc64.md")
395 (include "power4.md")
396 (include "power5.md")
397 (include "power6.md")
398 (include "power7.md")
399 (include "power8.md")
400 (include "power9.md")
401 (include "future.md")
406 (include "predicates.md")
407 (include "constraints.md")
412 ; This mode iterator allows :GPR to be used to indicate the allowable size
413 ; of whole values in GPRs.
414 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
416 ; And again, for patterns that need two (potentially) different integer modes.
417 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
419 ; Any supported integer mode.
420 (define_mode_iterator INT [QI HI SI DI TI PTI])
422 ; Any supported integer mode that fits in one register.
423 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
425 ; Integer modes supported in VSX registers with ISA 3.0 instructions
426 (define_mode_iterator INT_ISA3 [QI HI SI DI])
428 ; Everything we can extend QImode to.
429 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
431 ; Everything we can extend HImode to.
432 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
434 ; Everything we can extend SImode to.
435 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
437 ; QImode or HImode for small integer moves and small atomic ops
438 (define_mode_iterator QHI [QI HI])
440 ; QImode, HImode, SImode for fused ops only for GPR loads
441 (define_mode_iterator QHSI [QI HI SI])
443 ; HImode or SImode for sign extended fusion ops
444 (define_mode_iterator HSI [HI SI])
446 ; SImode or DImode, even if DImode doesn't fit in GPRs.
447 (define_mode_iterator SDI [SI DI])
449 ; The size of a pointer. Also, the size of the value that a record-condition
450 ; (one with a '.') will compare; and the size used for arithmetic carries.
451 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
453 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
454 ; PTImode is GPR only)
455 (define_mode_iterator TI2 [TI PTI])
457 ; Any hardware-supported floating-point mode
458 (define_mode_iterator FP [
459 (SF "TARGET_HARD_FLOAT")
460 (DF "TARGET_HARD_FLOAT")
461 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
462 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
463 (KF "TARGET_FLOAT128_TYPE")
467 ; Any fma capable floating-point mode.
468 (define_mode_iterator FMA_F [
469 (SF "TARGET_HARD_FLOAT")
470 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
471 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
472 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
473 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
474 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
477 ; Floating point move iterators to combine binary and decimal moves
478 (define_mode_iterator FMOVE32 [SF SD])
479 (define_mode_iterator FMOVE64 [DF DD])
480 (define_mode_iterator FMOVE64X [DI DF DD])
481 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
482 (IF "FLOAT128_IBM_P (IFmode)")
483 (TD "TARGET_HARD_FLOAT")])
485 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
486 (IF "FLOAT128_2REG_P (IFmode)")
487 (TD "TARGET_HARD_FLOAT")])
489 ; Iterators for 128 bit types for direct move
490 (define_mode_iterator FMOVE128_GPR [TI
498 (KF "FLOAT128_VECTOR_P (KFmode)")
499 (TF "FLOAT128_VECTOR_P (TFmode)")])
501 ; Iterator for 128-bit VSX types for pack/unpack
502 (define_mode_iterator FMOVE128_VSX [V1TI KF])
504 ; Iterators for converting to/from TFmode
505 (define_mode_iterator IFKF [IF KF])
507 ; Constraints for moving IF/KFmode.
508 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
510 ; Whether a floating point move is ok, don't allow SD without hardware FP
511 (define_mode_attr fmove_ok [(SF "")
513 (SD "TARGET_HARD_FLOAT")
516 ; Convert REAL_VALUE to the appropriate bits
517 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
518 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
519 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
520 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
522 ; Whether 0.0 has an all-zero bit pattern
523 (define_mode_attr zero_fp [(SF "j")
532 ; Definitions for 64-bit VSX
533 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
535 ; Definitions for 64-bit direct move
536 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
538 ; Definitions for 64-bit use of altivec registers
539 (define_mode_attr f64_av [(DF "v") (DD "wn")])
541 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
542 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
544 ; These modes do not fit in integer registers in 32-bit mode.
545 (define_mode_iterator DIFD [DI DF DD])
547 ; Iterator for reciprocal estimate instructions
548 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
551 (define_mode_iterator SFDF [SF DF])
553 ; And again, for when we need two FP modes in a pattern.
554 (define_mode_iterator SFDF2 [SF DF])
556 ; A generic s/d attribute, for sp/dp for example.
557 (define_mode_attr sd [(SF "s") (DF "d")
558 (V4SF "s") (V2DF "d")])
560 ; "s" or nothing, for fmuls/fmul for example.
561 (define_mode_attr s [(SF "s") (DF "")])
563 ; Iterator for 128-bit floating point that uses the IBM double-double format
564 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
565 (TF "FLOAT128_IBM_P (TFmode)")])
567 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
568 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
569 (TF "FLOAT128_IEEE_P (TFmode)")])
571 ; Iterator for 128-bit floating point
572 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
573 (IF "TARGET_FLOAT128_TYPE")
574 (TF "TARGET_LONG_DOUBLE_128")])
576 ; Iterator for signbit on 64-bit machines with direct move
577 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
578 (TF "FLOAT128_VECTOR_P (TFmode)")])
580 ; Iterator for ISA 3.0 supported floating point types
581 (define_mode_iterator FP_ISA3 [SF DF])
583 ; SF/DF constraint for arithmetic on traditional floating point registers
584 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
586 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
587 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
588 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
590 (define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")])
592 ; Which isa is needed for those float instructions?
593 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
596 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
598 ; Conditional returns.
599 (define_code_iterator any_return [return simple_return])
600 (define_code_attr return_pred [(return "direct_return ()")
601 (simple_return "1")])
602 (define_code_attr return_str [(return "") (simple_return "simple_")])
605 (define_code_iterator iorxor [ior xor])
606 (define_code_iterator and_ior_xor [and ior xor])
608 ; Signed/unsigned variants of ops.
609 (define_code_iterator any_extend [sign_extend zero_extend])
610 (define_code_iterator any_fix [fix unsigned_fix])
611 (define_code_iterator any_float [float unsigned_float])
613 (define_code_attr u [(sign_extend "")
618 (define_code_attr su [(sign_extend "s")
623 (unsigned_float "u")])
625 (define_code_attr az [(sign_extend "a")
630 (unsigned_float "z")])
632 (define_code_attr uns [(fix "")
635 (unsigned_float "uns")])
637 ; Various instructions that come in SI and DI forms.
638 ; A generic w/d attribute, for things like cmpw/cmpd.
639 (define_mode_attr wd [(QI "b")
650 ;; How many bits in this mode?
651 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
652 (SF "32") (DF "64")])
655 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
657 ;; Bitmask for shift instructions
658 (define_mode_attr hH [(SI "h") (DI "H")])
660 ;; A mode twice the size of the given mode
661 (define_mode_attr dmode [(SI "di") (DI "ti")])
662 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
664 ;; Suffix for reload patterns
665 (define_mode_attr ptrsize [(SI "32bit")
668 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
669 (DI "TARGET_64BIT")])
671 (define_mode_attr mptrsize [(SI "si")
674 (define_mode_attr ptrload [(SI "lwz")
677 (define_mode_attr ptrm [(SI "m")
680 (define_mode_attr rreg [(SF "f")
687 (define_mode_attr rreg2 [(SF "f")
690 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
691 (DF "TARGET_FCFID")])
693 ;; Mode iterator for logical operations on 128-bit types
694 (define_mode_iterator BOOL_128 [TI
696 (V16QI "TARGET_ALTIVEC")
697 (V8HI "TARGET_ALTIVEC")
698 (V4SI "TARGET_ALTIVEC")
699 (V4SF "TARGET_ALTIVEC")
700 (V2DI "TARGET_ALTIVEC")
701 (V2DF "TARGET_ALTIVEC")
702 (V1TI "TARGET_ALTIVEC")])
704 ;; For the GPRs we use 3 constraints for register outputs, two that are the
705 ;; same as the output register, and a third where the output register is an
706 ;; early clobber, so we don't have to deal with register overlaps. For the
707 ;; vector types, we prefer to use the vector registers. For TI mode, allow
710 ;; Mode attribute for boolean operation register constraints for output
711 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
713 (V16QI "wa,v,&?r,?r,?r")
714 (V8HI "wa,v,&?r,?r,?r")
715 (V4SI "wa,v,&?r,?r,?r")
716 (V4SF "wa,v,&?r,?r,?r")
717 (V2DI "wa,v,&?r,?r,?r")
718 (V2DF "wa,v,&?r,?r,?r")
719 (V1TI "wa,v,&?r,?r,?r")])
721 ;; Mode attribute for boolean operation register constraints for operand1
722 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
730 (V1TI "wa,v,r,0,r")])
732 ;; Mode attribute for boolean operation register constraints for operand2
733 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
741 (V1TI "wa,v,r,r,0")])
743 ;; Mode attribute for boolean operation register constraints for operand1
744 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
745 ;; is used for operand1 or operand2
746 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
754 (V1TI "wa,v,r,0,0")])
756 ;; Reload iterator for creating the function to allocate a base register to
757 ;; supplement addressing modes.
758 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
759 SF SD SI DF DD DI TI PTI KF IF TF])
761 ;; Iterate over smin, smax
762 (define_code_iterator fp_minmax [smin smax])
764 (define_code_attr minmax [(smin "min")
767 (define_code_attr SMINMAX [(smin "SMIN")
770 ;; Iterator to optimize the following cases:
771 ;; D-form load to FPR register & move to Altivec register
772 ;; Move Altivec register to FPR register and store
773 (define_mode_iterator ALTIVEC_DFORM [DF
774 (SF "TARGET_P8_VECTOR")
775 (DI "TARGET_POWERPC64")])
777 (include "darwin.md")
779 ;; Start with fixed-point load and store insns. Here we put only the more
780 ;; complex forms. Basic data transfer is done later.
782 (define_insn "zero_extendqi<mode>2"
783 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
784 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
791 [(set_attr "type" "load,shift,fpload,vecperm")
792 (set_attr "isa" "*,*,p9v,p9v")])
794 (define_insn_and_split "*zero_extendqi<mode>2_dot"
795 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
796 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
798 (clobber (match_scratch:EXTQI 0 "=r,r"))]
803 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
805 (zero_extend:EXTQI (match_dup 1)))
807 (compare:CC (match_dup 0)
810 [(set_attr "type" "logical")
811 (set_attr "dot" "yes")
812 (set_attr "length" "4,8")])
814 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
815 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
816 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
818 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
819 (zero_extend:EXTQI (match_dup 1)))]
824 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
826 (zero_extend:EXTQI (match_dup 1)))
828 (compare:CC (match_dup 0)
831 [(set_attr "type" "logical")
832 (set_attr "dot" "yes")
833 (set_attr "length" "4,8")])
836 (define_insn "zero_extendhi<mode>2"
837 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
838 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
842 rlwinm %0,%1,0,0xffff
845 [(set_attr "type" "load,shift,fpload,vecperm")
846 (set_attr "isa" "*,*,p9v,p9v")])
848 (define_insn_and_split "*zero_extendhi<mode>2_dot"
849 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
850 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
852 (clobber (match_scratch:EXTHI 0 "=r,r"))]
857 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
859 (zero_extend:EXTHI (match_dup 1)))
861 (compare:CC (match_dup 0)
864 [(set_attr "type" "logical")
865 (set_attr "dot" "yes")
866 (set_attr "length" "4,8")])
868 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
869 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
870 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
872 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
873 (zero_extend:EXTHI (match_dup 1)))]
878 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
880 (zero_extend:EXTHI (match_dup 1)))
882 (compare:CC (match_dup 0)
885 [(set_attr "type" "logical")
886 (set_attr "dot" "yes")
887 (set_attr "length" "4,8")])
890 (define_insn "zero_extendsi<mode>2"
891 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
892 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
901 xxextractuw %x0,%x1,4"
902 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
903 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
905 (define_insn_and_split "*zero_extendsi<mode>2_dot"
906 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
907 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
909 (clobber (match_scratch:EXTSI 0 "=r,r"))]
914 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
916 (zero_extend:DI (match_dup 1)))
918 (compare:CC (match_dup 0)
921 [(set_attr "type" "shift")
922 (set_attr "dot" "yes")
923 (set_attr "length" "4,8")])
925 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
926 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
927 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
929 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
930 (zero_extend:EXTSI (match_dup 1)))]
935 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
937 (zero_extend:EXTSI (match_dup 1)))
939 (compare:CC (match_dup 0)
942 [(set_attr "type" "shift")
943 (set_attr "dot" "yes")
944 (set_attr "length" "4,8")])
947 (define_insn "extendqi<mode>2"
948 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
949 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
954 [(set_attr "type" "exts,vecperm")
955 (set_attr "isa" "*,p9v")])
957 (define_insn_and_split "*extendqi<mode>2_dot"
958 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
959 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
961 (clobber (match_scratch:EXTQI 0 "=r,r"))]
966 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
968 (sign_extend:EXTQI (match_dup 1)))
970 (compare:CC (match_dup 0)
973 [(set_attr "type" "exts")
974 (set_attr "dot" "yes")
975 (set_attr "length" "4,8")])
977 (define_insn_and_split "*extendqi<mode>2_dot2"
978 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
979 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
981 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
982 (sign_extend:EXTQI (match_dup 1)))]
987 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
989 (sign_extend:EXTQI (match_dup 1)))
991 (compare:CC (match_dup 0)
994 [(set_attr "type" "exts")
995 (set_attr "dot" "yes")
996 (set_attr "length" "4,8")])
999 (define_expand "extendhi<mode>2"
1000 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1001 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1005 (define_insn "*extendhi<mode>2"
1006 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1007 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1014 [(set_attr "type" "load,exts,fpload,vecperm")
1015 (set_attr "sign_extend" "yes")
1016 (set_attr "length" "*,*,8,*")
1017 (set_attr "isa" "*,*,p9v,p9v")])
1020 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1022 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1023 "TARGET_P9_VECTOR && reload_completed"
1027 (sign_extend:EXTHI (match_dup 2)))]
1029 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1032 (define_insn_and_split "*extendhi<mode>2_dot"
1033 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1034 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1036 (clobber (match_scratch:EXTHI 0 "=r,r"))]
1041 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1043 (sign_extend:EXTHI (match_dup 1)))
1045 (compare:CC (match_dup 0)
1048 [(set_attr "type" "exts")
1049 (set_attr "dot" "yes")
1050 (set_attr "length" "4,8")])
1052 (define_insn_and_split "*extendhi<mode>2_dot2"
1053 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1054 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1056 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1057 (sign_extend:EXTHI (match_dup 1)))]
1062 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1064 (sign_extend:EXTHI (match_dup 1)))
1066 (compare:CC (match_dup 0)
1069 [(set_attr "type" "exts")
1070 (set_attr "dot" "yes")
1071 (set_attr "length" "4,8")])
1074 (define_insn "extendsi<mode>2"
1075 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1076 "=r, r, d, wa, wa, v, v, wr")
1077 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1078 "YZ, r, Z, Z, r, v, v, ?wa")))]
1089 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1090 (set_attr "sign_extend" "yes")
1091 (set_attr "length" "*,*,*,*,*,*,8,8")
1092 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1095 [(set (match_operand:EXTSI 0 "int_reg_operand")
1096 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1097 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1101 (sign_extend:DI (match_dup 2)))]
1103 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1107 [(set (match_operand:DI 0 "altivec_register_operand")
1108 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1109 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1112 rtx dest = operands[0];
1113 rtx src = operands[1];
1114 int dest_regno = REGNO (dest);
1115 int src_regno = REGNO (src);
1116 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1117 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1119 if (BYTES_BIG_ENDIAN)
1121 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1122 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1126 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1127 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1132 (define_insn_and_split "*extendsi<mode>2_dot"
1133 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1134 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1136 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1141 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1143 (sign_extend:EXTSI (match_dup 1)))
1145 (compare:CC (match_dup 0)
1148 [(set_attr "type" "exts")
1149 (set_attr "dot" "yes")
1150 (set_attr "length" "4,8")])
1152 (define_insn_and_split "*extendsi<mode>2_dot2"
1153 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1154 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1156 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1157 (sign_extend:EXTSI (match_dup 1)))]
1162 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1164 (sign_extend:EXTSI (match_dup 1)))
1166 (compare:CC (match_dup 0)
1169 [(set_attr "type" "exts")
1170 (set_attr "dot" "yes")
1171 (set_attr "length" "4,8")])
1173 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1175 (define_insn "*macchwc"
1176 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1177 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1178 (match_operand:SI 2 "gpc_reg_operand" "r")
1181 (match_operand:HI 1 "gpc_reg_operand" "r")))
1182 (match_operand:SI 4 "gpc_reg_operand" "0"))
1184 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1185 (plus:SI (mult:SI (ashiftrt:SI
1193 [(set_attr "type" "halfmul")])
1195 (define_insn "*macchw"
1196 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1197 (plus:SI (mult:SI (ashiftrt:SI
1198 (match_operand:SI 2 "gpc_reg_operand" "r")
1201 (match_operand:HI 1 "gpc_reg_operand" "r")))
1202 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1205 [(set_attr "type" "halfmul")])
1207 (define_insn "*macchwuc"
1208 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1209 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1210 (match_operand:SI 2 "gpc_reg_operand" "r")
1213 (match_operand:HI 1 "gpc_reg_operand" "r")))
1214 (match_operand:SI 4 "gpc_reg_operand" "0"))
1216 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1217 (plus:SI (mult:SI (lshiftrt:SI
1225 [(set_attr "type" "halfmul")])
1227 (define_insn "*macchwu"
1228 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1229 (plus:SI (mult:SI (lshiftrt:SI
1230 (match_operand:SI 2 "gpc_reg_operand" "r")
1233 (match_operand:HI 1 "gpc_reg_operand" "r")))
1234 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1237 [(set_attr "type" "halfmul")])
1239 (define_insn "*machhwc"
1240 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1241 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1242 (match_operand:SI 1 "gpc_reg_operand" "%r")
1245 (match_operand:SI 2 "gpc_reg_operand" "r")
1247 (match_operand:SI 4 "gpc_reg_operand" "0"))
1249 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1250 (plus:SI (mult:SI (ashiftrt:SI
1259 [(set_attr "type" "halfmul")])
1261 (define_insn "*machhw"
1262 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1263 (plus:SI (mult:SI (ashiftrt:SI
1264 (match_operand:SI 1 "gpc_reg_operand" "%r")
1267 (match_operand:SI 2 "gpc_reg_operand" "r")
1269 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1272 [(set_attr "type" "halfmul")])
1274 (define_insn "*machhwuc"
1275 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1276 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1277 (match_operand:SI 1 "gpc_reg_operand" "%r")
1280 (match_operand:SI 2 "gpc_reg_operand" "r")
1282 (match_operand:SI 4 "gpc_reg_operand" "0"))
1284 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1285 (plus:SI (mult:SI (lshiftrt:SI
1294 [(set_attr "type" "halfmul")])
1296 (define_insn "*machhwu"
1297 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1298 (plus:SI (mult:SI (lshiftrt:SI
1299 (match_operand:SI 1 "gpc_reg_operand" "%r")
1302 (match_operand:SI 2 "gpc_reg_operand" "r")
1304 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1307 [(set_attr "type" "halfmul")])
1309 (define_insn "*maclhwc"
1310 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1311 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1312 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1314 (match_operand:HI 2 "gpc_reg_operand" "r")))
1315 (match_operand:SI 4 "gpc_reg_operand" "0"))
1317 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1318 (plus:SI (mult:SI (sign_extend:SI
1325 [(set_attr "type" "halfmul")])
1327 (define_insn "*maclhw"
1328 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1329 (plus:SI (mult:SI (sign_extend:SI
1330 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1332 (match_operand:HI 2 "gpc_reg_operand" "r")))
1333 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1336 [(set_attr "type" "halfmul")])
1338 (define_insn "*maclhwuc"
1339 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1340 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1341 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1343 (match_operand:HI 2 "gpc_reg_operand" "r")))
1344 (match_operand:SI 4 "gpc_reg_operand" "0"))
1346 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347 (plus:SI (mult:SI (zero_extend:SI
1354 [(set_attr "type" "halfmul")])
1356 (define_insn "*maclhwu"
1357 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1358 (plus:SI (mult:SI (zero_extend:SI
1359 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1361 (match_operand:HI 2 "gpc_reg_operand" "r")))
1362 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1365 [(set_attr "type" "halfmul")])
1367 (define_insn "*nmacchwc"
1368 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1369 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1370 (mult:SI (ashiftrt:SI
1371 (match_operand:SI 2 "gpc_reg_operand" "r")
1374 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1376 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1377 (minus:SI (match_dup 4)
1378 (mult:SI (ashiftrt:SI
1385 [(set_attr "type" "halfmul")])
1387 (define_insn "*nmacchw"
1388 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1390 (mult:SI (ashiftrt:SI
1391 (match_operand:SI 2 "gpc_reg_operand" "r")
1394 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1397 [(set_attr "type" "halfmul")])
1399 (define_insn "*nmachhwc"
1400 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1401 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1402 (mult:SI (ashiftrt:SI
1403 (match_operand:SI 1 "gpc_reg_operand" "%r")
1406 (match_operand:SI 2 "gpc_reg_operand" "r")
1409 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1410 (minus:SI (match_dup 4)
1411 (mult:SI (ashiftrt:SI
1419 [(set_attr "type" "halfmul")])
1421 (define_insn "*nmachhw"
1422 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1423 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1424 (mult:SI (ashiftrt:SI
1425 (match_operand:SI 1 "gpc_reg_operand" "%r")
1428 (match_operand:SI 2 "gpc_reg_operand" "r")
1432 [(set_attr "type" "halfmul")])
1434 (define_insn "*nmaclhwc"
1435 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1436 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1437 (mult:SI (sign_extend:SI
1438 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1440 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1442 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1443 (minus:SI (match_dup 4)
1444 (mult:SI (sign_extend:SI
1450 [(set_attr "type" "halfmul")])
1452 (define_insn "*nmaclhw"
1453 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1454 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1455 (mult:SI (sign_extend:SI
1456 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1458 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1461 [(set_attr "type" "halfmul")])
1463 (define_insn "*mulchwc"
1464 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1465 (compare:CC (mult:SI (ashiftrt:SI
1466 (match_operand:SI 2 "gpc_reg_operand" "r")
1469 (match_operand:HI 1 "gpc_reg_operand" "r")))
1471 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1472 (mult:SI (ashiftrt:SI
1479 [(set_attr "type" "halfmul")])
1481 (define_insn "*mulchw"
1482 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1483 (mult:SI (ashiftrt:SI
1484 (match_operand:SI 2 "gpc_reg_operand" "r")
1487 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1490 [(set_attr "type" "halfmul")])
1492 (define_insn "*mulchwuc"
1493 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1494 (compare:CC (mult:SI (lshiftrt:SI
1495 (match_operand:SI 2 "gpc_reg_operand" "r")
1498 (match_operand:HI 1 "gpc_reg_operand" "r")))
1500 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1501 (mult:SI (lshiftrt:SI
1508 [(set_attr "type" "halfmul")])
1510 (define_insn "*mulchwu"
1511 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1512 (mult:SI (lshiftrt:SI
1513 (match_operand:SI 2 "gpc_reg_operand" "r")
1516 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1519 [(set_attr "type" "halfmul")])
1521 (define_insn "*mulhhwc"
1522 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1523 (compare:CC (mult:SI (ashiftrt:SI
1524 (match_operand:SI 1 "gpc_reg_operand" "%r")
1527 (match_operand:SI 2 "gpc_reg_operand" "r")
1530 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1531 (mult:SI (ashiftrt:SI
1539 [(set_attr "type" "halfmul")])
1541 (define_insn "*mulhhw"
1542 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1543 (mult:SI (ashiftrt:SI
1544 (match_operand:SI 1 "gpc_reg_operand" "%r")
1547 (match_operand:SI 2 "gpc_reg_operand" "r")
1551 [(set_attr "type" "halfmul")])
1553 (define_insn "*mulhhwuc"
1554 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1555 (compare:CC (mult:SI (lshiftrt:SI
1556 (match_operand:SI 1 "gpc_reg_operand" "%r")
1559 (match_operand:SI 2 "gpc_reg_operand" "r")
1562 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1563 (mult:SI (lshiftrt:SI
1571 [(set_attr "type" "halfmul")])
1573 (define_insn "*mulhhwu"
1574 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1575 (mult:SI (lshiftrt:SI
1576 (match_operand:SI 1 "gpc_reg_operand" "%r")
1579 (match_operand:SI 2 "gpc_reg_operand" "r")
1583 [(set_attr "type" "halfmul")])
1585 (define_insn "*mullhwc"
1586 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1587 (compare:CC (mult:SI (sign_extend:SI
1588 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1590 (match_operand:HI 2 "gpc_reg_operand" "r")))
1592 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1593 (mult:SI (sign_extend:SI
1599 [(set_attr "type" "halfmul")])
1601 (define_insn "*mullhw"
1602 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1603 (mult:SI (sign_extend:SI
1604 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1606 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1609 [(set_attr "type" "halfmul")])
1611 (define_insn "*mullhwuc"
1612 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1613 (compare:CC (mult:SI (zero_extend:SI
1614 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1616 (match_operand:HI 2 "gpc_reg_operand" "r")))
1618 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1619 (mult:SI (zero_extend:SI
1625 [(set_attr "type" "halfmul")])
1627 (define_insn "*mullhwu"
1628 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1629 (mult:SI (zero_extend:SI
1630 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1632 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1635 [(set_attr "type" "halfmul")])
1637 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1638 (define_insn "dlmzb"
1639 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1640 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1641 (match_operand:SI 2 "gpc_reg_operand" "r")]
1643 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1644 (unspec:SI [(match_dup 1)
1650 (define_expand "strlensi"
1651 [(set (match_operand:SI 0 "gpc_reg_operand")
1652 (unspec:SI [(match_operand:BLK 1 "general_operand")
1653 (match_operand:QI 2 "const_int_operand")
1654 (match_operand 3 "const_int_operand")]
1655 UNSPEC_DLMZB_STRLEN))
1656 (clobber (match_scratch:CC 4))]
1657 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1659 rtx result = operands[0];
1660 rtx src = operands[1];
1661 rtx search_char = operands[2];
1662 rtx align = operands[3];
1663 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1664 rtx loop_label, end_label, mem, cr0, cond;
1665 if (search_char != const0_rtx
1666 || !CONST_INT_P (align)
1667 || INTVAL (align) < 8)
1669 word1 = gen_reg_rtx (SImode);
1670 word2 = gen_reg_rtx (SImode);
1671 scratch_dlmzb = gen_reg_rtx (SImode);
1672 scratch_string = gen_reg_rtx (Pmode);
1673 loop_label = gen_label_rtx ();
1674 end_label = gen_label_rtx ();
1675 addr = force_reg (Pmode, XEXP (src, 0));
1676 emit_move_insn (scratch_string, addr);
1677 emit_label (loop_label);
1678 mem = change_address (src, SImode, scratch_string);
1679 emit_move_insn (word1, mem);
1680 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1681 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1682 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1683 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1684 emit_jump_insn (gen_rtx_SET (pc_rtx,
1685 gen_rtx_IF_THEN_ELSE (VOIDmode,
1691 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1692 emit_jump_insn (gen_rtx_SET (pc_rtx,
1693 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1695 emit_label (end_label);
1696 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1697 emit_insn (gen_subsi3 (result, scratch_string, addr));
1698 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1702 ;; Fixed-point arithmetic insns.
1704 (define_expand "add<mode>3"
1705 [(set (match_operand:SDI 0 "gpc_reg_operand")
1706 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1707 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1710 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1712 rtx lo0 = gen_lowpart (SImode, operands[0]);
1713 rtx lo1 = gen_lowpart (SImode, operands[1]);
1714 rtx lo2 = gen_lowpart (SImode, operands[2]);
1715 rtx hi0 = gen_highpart (SImode, operands[0]);
1716 rtx hi1 = gen_highpart (SImode, operands[1]);
1717 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1719 if (!reg_or_short_operand (lo2, SImode))
1720 lo2 = force_reg (SImode, lo2);
1721 if (!adde_operand (hi2, SImode))
1722 hi2 = force_reg (SImode, hi2);
1724 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1725 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1729 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1731 rtx tmp = ((!can_create_pseudo_p ()
1732 || rtx_equal_p (operands[0], operands[1]))
1733 ? operands[0] : gen_reg_rtx (<MODE>mode));
1735 /* Adding a constant to r0 is not a valid insn, so use a different
1736 strategy in that case. */
1737 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1739 if (operands[0] == operands[1])
1741 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1742 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1746 HOST_WIDE_INT val = INTVAL (operands[2]);
1747 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1748 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1750 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1753 /* The ordering here is important for the prolog expander.
1754 When space is allocated from the stack, adding 'low' first may
1755 produce a temporary deallocation (which would be bad). */
1756 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1757 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1762 (define_insn "*add<mode>3"
1763 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1764 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1765 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1771 [(set_attr "type" "add")])
1773 (define_insn "*addsi3_high"
1774 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1775 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1776 (high:SI (match_operand 2 "" ""))))]
1777 "TARGET_MACHO && !TARGET_64BIT"
1778 "addis %0,%1,ha16(%2)"
1779 [(set_attr "type" "add")])
1781 (define_insn_and_split "*add<mode>3_dot"
1782 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1783 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1784 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1786 (clobber (match_scratch:GPR 0 "=r,r"))]
1787 "<MODE>mode == Pmode"
1791 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1793 (plus:GPR (match_dup 1)
1796 (compare:CC (match_dup 0)
1799 [(set_attr "type" "add")
1800 (set_attr "dot" "yes")
1801 (set_attr "length" "4,8")])
1803 (define_insn_and_split "*add<mode>3_dot2"
1804 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1805 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1806 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1808 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1809 (plus:GPR (match_dup 1)
1811 "<MODE>mode == Pmode"
1815 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1817 (plus:GPR (match_dup 1)
1820 (compare:CC (match_dup 0)
1823 [(set_attr "type" "add")
1824 (set_attr "dot" "yes")
1825 (set_attr "length" "4,8")])
1827 (define_insn_and_split "*add<mode>3_imm_dot"
1828 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1829 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1830 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1832 (clobber (match_scratch:GPR 0 "=r,r"))
1833 (clobber (reg:GPR CA_REGNO))]
1834 "<MODE>mode == Pmode"
1838 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1840 (plus:GPR (match_dup 1)
1843 (compare:CC (match_dup 0)
1846 [(set_attr "type" "add")
1847 (set_attr "dot" "yes")
1848 (set_attr "length" "4,8")])
1850 (define_insn_and_split "*add<mode>3_imm_dot2"
1851 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1852 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1853 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1855 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1856 (plus:GPR (match_dup 1)
1858 (clobber (reg:GPR CA_REGNO))]
1859 "<MODE>mode == Pmode"
1863 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1865 (plus:GPR (match_dup 1)
1868 (compare:CC (match_dup 0)
1871 [(set_attr "type" "add")
1872 (set_attr "dot" "yes")
1873 (set_attr "length" "4,8")])
1875 ;; Split an add that we can't do in one insn into two insns, each of which
1876 ;; does one 16-bit part. This is used by combine. Note that the low-order
1877 ;; add should be last in case the result gets used in an address.
1880 [(set (match_operand:GPR 0 "gpc_reg_operand")
1881 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1882 (match_operand:GPR 2 "non_add_cint_operand")))]
1884 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1885 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1887 HOST_WIDE_INT val = INTVAL (operands[2]);
1888 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1889 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1891 operands[4] = GEN_INT (low);
1892 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1893 operands[3] = GEN_INT (rest);
1894 else if (can_create_pseudo_p ())
1896 operands[3] = gen_reg_rtx (DImode);
1897 emit_move_insn (operands[3], operands[2]);
1898 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1906 (define_insn "add<mode>3_carry"
1907 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1908 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1909 (match_operand:P 2 "reg_or_short_operand" "rI")))
1910 (set (reg:P CA_REGNO)
1911 (ltu:P (plus:P (match_dup 1)
1916 [(set_attr "type" "add")])
1918 (define_insn "*add<mode>3_imm_carry_pos"
1919 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1920 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1921 (match_operand:P 2 "short_cint_operand" "n")))
1922 (set (reg:P CA_REGNO)
1923 (geu:P (match_dup 1)
1924 (match_operand:P 3 "const_int_operand" "n")))]
1925 "INTVAL (operands[2]) > 0
1926 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1928 [(set_attr "type" "add")])
1930 (define_insn "*add<mode>3_imm_carry_0"
1931 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1932 (match_operand:P 1 "gpc_reg_operand" "r"))
1933 (set (reg:P CA_REGNO)
1937 [(set_attr "type" "add")])
1939 (define_insn "*add<mode>3_imm_carry_m1"
1940 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1941 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1943 (set (reg:P CA_REGNO)
1948 [(set_attr "type" "add")])
1950 (define_insn "*add<mode>3_imm_carry_neg"
1951 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1952 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1953 (match_operand:P 2 "short_cint_operand" "n")))
1954 (set (reg:P CA_REGNO)
1955 (gtu:P (match_dup 1)
1956 (match_operand:P 3 "const_int_operand" "n")))]
1957 "INTVAL (operands[2]) < 0
1958 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1960 [(set_attr "type" "add")])
1963 (define_expand "add<mode>3_carry_in"
1965 (set (match_operand:GPR 0 "gpc_reg_operand")
1966 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1967 (match_operand:GPR 2 "adde_operand"))
1968 (reg:GPR CA_REGNO)))
1969 (clobber (reg:GPR CA_REGNO))])]
1972 if (operands[2] == const0_rtx)
1974 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1977 if (operands[2] == constm1_rtx)
1979 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1984 (define_insn "*add<mode>3_carry_in_internal"
1985 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1986 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1987 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1988 (reg:GPR CA_REGNO)))
1989 (clobber (reg:GPR CA_REGNO))]
1992 [(set_attr "type" "add")])
1994 (define_insn "*add<mode>3_carry_in_internal2"
1995 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1996 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1998 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1999 (clobber (reg:GPR CA_REGNO))]
2002 [(set_attr "type" "add")])
2004 (define_insn "add<mode>3_carry_in_0"
2005 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2006 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2007 (reg:GPR CA_REGNO)))
2008 (clobber (reg:GPR CA_REGNO))]
2011 [(set_attr "type" "add")])
2013 (define_insn "add<mode>3_carry_in_m1"
2014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2015 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2018 (clobber (reg:GPR CA_REGNO))]
2021 [(set_attr "type" "add")])
2024 (define_expand "one_cmpl<mode>2"
2025 [(set (match_operand:SDI 0 "gpc_reg_operand")
2026 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2029 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2031 rs6000_split_logical (operands, NOT, false, false, false);
2036 (define_insn "*one_cmpl<mode>2"
2037 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2038 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2042 (define_insn_and_split "*one_cmpl<mode>2_dot"
2043 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2044 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2046 (clobber (match_scratch:GPR 0 "=r,r"))]
2047 "<MODE>mode == Pmode"
2051 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2053 (not:GPR (match_dup 1)))
2055 (compare:CC (match_dup 0)
2058 [(set_attr "type" "logical")
2059 (set_attr "dot" "yes")
2060 (set_attr "length" "4,8")])
2062 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2063 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2064 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2066 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2067 (not:GPR (match_dup 1)))]
2068 "<MODE>mode == Pmode"
2072 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2074 (not:GPR (match_dup 1)))
2076 (compare:CC (match_dup 0)
2079 [(set_attr "type" "logical")
2080 (set_attr "dot" "yes")
2081 (set_attr "length" "4,8")])
2084 (define_expand "sub<mode>3"
2085 [(set (match_operand:SDI 0 "gpc_reg_operand")
2086 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2087 (match_operand:SDI 2 "gpc_reg_operand")))]
2090 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2092 rtx lo0 = gen_lowpart (SImode, operands[0]);
2093 rtx lo1 = gen_lowpart (SImode, operands[1]);
2094 rtx lo2 = gen_lowpart (SImode, operands[2]);
2095 rtx hi0 = gen_highpart (SImode, operands[0]);
2096 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2097 rtx hi2 = gen_highpart (SImode, operands[2]);
2099 if (!reg_or_short_operand (lo1, SImode))
2100 lo1 = force_reg (SImode, lo1);
2101 if (!adde_operand (hi1, SImode))
2102 hi1 = force_reg (SImode, hi1);
2104 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2105 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2109 if (short_cint_operand (operands[1], <MODE>mode))
2111 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2116 (define_insn "*subf<mode>3"
2117 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2118 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2119 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2122 [(set_attr "type" "add")])
2124 (define_insn_and_split "*subf<mode>3_dot"
2125 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2126 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2127 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2129 (clobber (match_scratch:GPR 0 "=r,r"))]
2130 "<MODE>mode == Pmode"
2134 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2136 (minus:GPR (match_dup 2)
2139 (compare:CC (match_dup 0)
2142 [(set_attr "type" "add")
2143 (set_attr "dot" "yes")
2144 (set_attr "length" "4,8")])
2146 (define_insn_and_split "*subf<mode>3_dot2"
2147 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2148 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2149 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2151 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2152 (minus:GPR (match_dup 2)
2154 "<MODE>mode == Pmode"
2158 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2160 (minus:GPR (match_dup 2)
2163 (compare:CC (match_dup 0)
2166 [(set_attr "type" "add")
2167 (set_attr "dot" "yes")
2168 (set_attr "length" "4,8")])
2170 (define_insn "subf<mode>3_imm"
2171 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2172 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2173 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2174 (clobber (reg:GPR CA_REGNO))]
2177 [(set_attr "type" "add")])
2179 (define_insn_and_split "subf<mode>3_carry_dot2"
2180 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2181 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2182 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2184 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2185 (minus:P (match_dup 2)
2187 (set (reg:P CA_REGNO)
2188 (leu:P (match_dup 1)
2190 "<MODE>mode == Pmode"
2194 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2195 [(parallel [(set (match_dup 0)
2196 (minus:P (match_dup 2)
2198 (set (reg:P CA_REGNO)
2199 (leu:P (match_dup 1)
2202 (compare:CC (match_dup 0)
2205 [(set_attr "type" "add")
2206 (set_attr "dot" "yes")
2207 (set_attr "length" "4,8")])
2209 (define_insn "subf<mode>3_carry"
2210 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2211 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2212 (match_operand:P 1 "gpc_reg_operand" "r")))
2213 (set (reg:P CA_REGNO)
2214 (leu:P (match_dup 1)
2218 [(set_attr "type" "add")])
2220 (define_insn "*subf<mode>3_imm_carry_0"
2221 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2222 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2223 (set (reg:P CA_REGNO)
2228 [(set_attr "type" "add")])
2230 (define_insn "*subf<mode>3_imm_carry_m1"
2231 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2232 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2233 (set (reg:P CA_REGNO)
2237 [(set_attr "type" "add")])
2240 (define_expand "subf<mode>3_carry_in"
2242 (set (match_operand:GPR 0 "gpc_reg_operand")
2243 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2245 (match_operand:GPR 2 "adde_operand")))
2246 (clobber (reg:GPR CA_REGNO))])]
2249 if (operands[2] == const0_rtx)
2251 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2254 if (operands[2] == constm1_rtx)
2256 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2261 (define_insn "*subf<mode>3_carry_in_internal"
2262 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2263 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2265 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2266 (clobber (reg:GPR CA_REGNO))]
2269 [(set_attr "type" "add")])
2271 (define_insn "subf<mode>3_carry_in_0"
2272 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2273 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2274 (reg:GPR CA_REGNO)))
2275 (clobber (reg:GPR CA_REGNO))]
2278 [(set_attr "type" "add")])
2280 (define_insn "subf<mode>3_carry_in_m1"
2281 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2282 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2283 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2285 (clobber (reg:GPR CA_REGNO))]
2288 [(set_attr "type" "add")])
2290 (define_insn "subf<mode>3_carry_in_xx"
2291 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2292 (plus:GPR (reg:GPR CA_REGNO)
2294 (clobber (reg:GPR CA_REGNO))]
2297 [(set_attr "type" "add")])
2300 (define_insn "@neg<mode>2"
2301 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2302 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2305 [(set_attr "type" "add")])
2307 (define_insn_and_split "*neg<mode>2_dot"
2308 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2309 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2311 (clobber (match_scratch:GPR 0 "=r,r"))]
2312 "<MODE>mode == Pmode"
2316 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2318 (neg:GPR (match_dup 1)))
2320 (compare:CC (match_dup 0)
2323 [(set_attr "type" "add")
2324 (set_attr "dot" "yes")
2325 (set_attr "length" "4,8")])
2327 (define_insn_and_split "*neg<mode>2_dot2"
2328 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2329 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2331 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2332 (neg:GPR (match_dup 1)))]
2333 "<MODE>mode == Pmode"
2337 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2339 (neg:GPR (match_dup 1)))
2341 (compare:CC (match_dup 0)
2344 [(set_attr "type" "add")
2345 (set_attr "dot" "yes")
2346 (set_attr "length" "4,8")])
2349 (define_insn "clz<mode>2"
2350 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2351 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2354 [(set_attr "type" "cntlz")])
2356 (define_expand "ctz<mode>2"
2357 [(set (match_operand:GPR 0 "gpc_reg_operand")
2358 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2363 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2367 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2368 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2369 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2373 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2374 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2375 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2376 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2380 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2381 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2382 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2383 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2389 (define_insn "ctz<mode>2_hw"
2390 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2391 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2394 [(set_attr "type" "cntlz")])
2396 (define_expand "ffs<mode>2"
2397 [(set (match_operand:GPR 0 "gpc_reg_operand")
2398 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2401 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2402 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2403 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2404 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2405 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2406 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2407 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2412 (define_expand "popcount<mode>2"
2413 [(set (match_operand:GPR 0 "gpc_reg_operand")
2414 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2415 "TARGET_POPCNTB || TARGET_POPCNTD"
2417 rs6000_emit_popcount (operands[0], operands[1]);
2421 (define_insn "popcntb<mode>2"
2422 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2423 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2427 [(set_attr "type" "popcnt")])
2429 (define_insn "popcntd<mode>2"
2430 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2431 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2434 [(set_attr "type" "popcnt")])
2437 (define_expand "parity<mode>2"
2438 [(set (match_operand:GPR 0 "gpc_reg_operand")
2439 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2442 rs6000_emit_parity (operands[0], operands[1]);
2446 (define_insn "parity<mode>2_cmpb"
2447 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2448 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2449 "TARGET_CMPB && TARGET_POPCNTB"
2451 [(set_attr "type" "popcnt")])
2453 (define_insn "cmpb<mode>3"
2454 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2455 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2456 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2459 [(set_attr "type" "cmp")])
2461 ;; Since the hardware zeros the upper part of the register, save generating the
2462 ;; AND immediate if we are converting to unsigned
2463 (define_insn "*bswap<mode>2_extenddi"
2464 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2466 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2469 [(set_attr "type" "load")])
2471 (define_insn "*bswaphi2_extendsi"
2472 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2474 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2477 [(set_attr "type" "load")])
2479 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2480 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2481 ;; load with byte swap, which can be slower than doing it in the registers. It
2482 ;; also prevents certain failures with the RELOAD register allocator.
2484 (define_expand "bswap<mode>2"
2485 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2486 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2489 rtx dest = operands[0];
2490 rtx src = operands[1];
2492 if (!REG_P (dest) && !REG_P (src))
2493 src = force_reg (<MODE>mode, src);
2497 src = rs6000_force_indexed_or_indirect_mem (src);
2498 emit_insn (gen_bswap<mode>2_load (dest, src));
2500 else if (MEM_P (dest))
2502 dest = rs6000_force_indexed_or_indirect_mem (dest);
2503 emit_insn (gen_bswap<mode>2_store (dest, src));
2506 emit_insn (gen_bswap<mode>2_reg (dest, src));
2510 (define_insn "bswap<mode>2_load"
2511 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2512 (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2515 [(set_attr "type" "load")])
2517 (define_insn "bswap<mode>2_store"
2518 [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2519 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2522 [(set_attr "type" "store")])
2524 (define_insn_and_split "bswaphi2_reg"
2525 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2527 (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2528 (clobber (match_scratch:SI 2 "=&r,X"))]
2533 "reload_completed && int_reg_operand (operands[0], HImode)"
2535 (and:SI (lshiftrt:SI (match_dup 4)
2539 (and:SI (ashift:SI (match_dup 4)
2541 (const_int 65280))) ;; 0xff00
2543 (ior:SI (match_dup 3)
2546 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2547 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2549 [(set_attr "length" "12,4")
2550 (set_attr "type" "*,vecperm")
2551 (set_attr "isa" "*,p9v")])
2553 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2554 ;; zero_extract insns do not change for -mlittle.
2555 (define_insn_and_split "bswapsi2_reg"
2556 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2558 (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2563 "reload_completed && int_reg_operand (operands[0], SImode)"
2564 [(set (match_dup 0) ; DABC
2565 (rotate:SI (match_dup 1)
2567 (set (match_dup 0) ; DCBC
2568 (ior:SI (and:SI (ashift:SI (match_dup 1)
2570 (const_int 16711680))
2571 (and:SI (match_dup 0)
2572 (const_int -16711681))))
2573 (set (match_dup 0) ; DCBA
2574 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2577 (and:SI (match_dup 0)
2578 (const_int -256))))]
2580 [(set_attr "length" "12,4")
2581 (set_attr "type" "*,vecperm")
2582 (set_attr "isa" "*,p9v")])
2584 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2585 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2588 (define_expand "bswapdi2"
2589 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2591 (match_operand:DI 1 "reg_or_mem_operand")))
2592 (clobber (match_scratch:DI 2))
2593 (clobber (match_scratch:DI 3))])]
2596 rtx dest = operands[0];
2597 rtx src = operands[1];
2599 if (!REG_P (dest) && !REG_P (src))
2600 operands[1] = src = force_reg (DImode, src);
2602 if (TARGET_POWERPC64 && TARGET_LDBRX)
2606 src = rs6000_force_indexed_or_indirect_mem (src);
2607 emit_insn (gen_bswapdi2_load (dest, src));
2609 else if (MEM_P (dest))
2611 dest = rs6000_force_indexed_or_indirect_mem (dest);
2612 emit_insn (gen_bswapdi2_store (dest, src));
2614 else if (TARGET_P9_VECTOR)
2615 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2617 emit_insn (gen_bswapdi2_reg (dest, src));
2621 if (!TARGET_POWERPC64)
2623 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2624 that uses 64-bit registers needs the same scratch registers as 64-bit
2626 emit_insn (gen_bswapdi2_32bit (dest, src));
2631 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2632 (define_insn "bswapdi2_load"
2633 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2634 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2635 "TARGET_POWERPC64 && TARGET_LDBRX"
2637 [(set_attr "type" "load")])
2639 (define_insn "bswapdi2_store"
2640 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2641 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2642 "TARGET_POWERPC64 && TARGET_LDBRX"
2644 [(set_attr "type" "store")])
2646 (define_insn "bswapdi2_xxbrd"
2647 [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2648 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2651 [(set_attr "type" "vecperm")
2652 (set_attr "isa" "p9v")])
2654 (define_insn "bswapdi2_reg"
2655 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2656 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2657 (clobber (match_scratch:DI 2 "=&r"))
2658 (clobber (match_scratch:DI 3 "=&r"))]
2659 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2661 [(set_attr "length" "36")])
2663 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2664 (define_insn "*bswapdi2_64bit"
2665 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2666 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2667 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2668 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2669 "TARGET_POWERPC64 && !TARGET_LDBRX
2670 && (REG_P (operands[0]) || REG_P (operands[1]))
2671 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2672 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2674 [(set_attr "length" "16,12,36")])
2677 [(set (match_operand:DI 0 "gpc_reg_operand")
2678 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2679 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2680 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2681 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2684 rtx dest = operands[0];
2685 rtx src = operands[1];
2686 rtx op2 = operands[2];
2687 rtx op3 = operands[3];
2688 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2689 BYTES_BIG_ENDIAN ? 4 : 0);
2690 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2691 BYTES_BIG_ENDIAN ? 4 : 0);
2697 addr1 = XEXP (src, 0);
2698 if (GET_CODE (addr1) == PLUS)
2700 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2701 if (TARGET_AVOID_XFORM)
2703 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2707 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2709 else if (TARGET_AVOID_XFORM)
2711 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2716 emit_move_insn (op2, GEN_INT (4));
2717 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2720 word1 = change_address (src, SImode, addr1);
2721 word2 = change_address (src, SImode, addr2);
2723 if (BYTES_BIG_ENDIAN)
2725 emit_insn (gen_bswapsi2 (op3_32, word2));
2726 emit_insn (gen_bswapsi2 (dest_32, word1));
2730 emit_insn (gen_bswapsi2 (op3_32, word1));
2731 emit_insn (gen_bswapsi2 (dest_32, word2));
2734 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2735 emit_insn (gen_iordi3 (dest, dest, op3));
2740 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2741 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2742 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2743 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2744 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2747 rtx dest = operands[0];
2748 rtx src = operands[1];
2749 rtx op2 = operands[2];
2750 rtx op3 = operands[3];
2751 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2752 BYTES_BIG_ENDIAN ? 4 : 0);
2753 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2754 BYTES_BIG_ENDIAN ? 4 : 0);
2760 addr1 = XEXP (dest, 0);
2761 if (GET_CODE (addr1) == PLUS)
2763 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2764 if (TARGET_AVOID_XFORM)
2766 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2770 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2772 else if (TARGET_AVOID_XFORM)
2774 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2779 emit_move_insn (op2, GEN_INT (4));
2780 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2783 word1 = change_address (dest, SImode, addr1);
2784 word2 = change_address (dest, SImode, addr2);
2786 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2788 if (BYTES_BIG_ENDIAN)
2790 emit_insn (gen_bswapsi2 (word1, src_si));
2791 emit_insn (gen_bswapsi2 (word2, op3_si));
2795 emit_insn (gen_bswapsi2 (word2, src_si));
2796 emit_insn (gen_bswapsi2 (word1, op3_si));
2802 [(set (match_operand:DI 0 "gpc_reg_operand")
2803 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2804 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2805 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2806 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2809 rtx dest = operands[0];
2810 rtx src = operands[1];
2811 rtx op2 = operands[2];
2812 rtx op3 = operands[3];
2813 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2814 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2815 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2816 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2817 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2819 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2820 emit_insn (gen_bswapsi2 (dest_si, src_si));
2821 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2822 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2823 emit_insn (gen_iordi3 (dest, dest, op3));
2827 (define_insn "bswapdi2_32bit"
2828 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2829 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2830 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2831 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2833 [(set_attr "length" "16,12,36")])
2836 [(set (match_operand:DI 0 "gpc_reg_operand")
2837 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2838 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2839 "!TARGET_POWERPC64 && reload_completed"
2842 rtx dest = operands[0];
2843 rtx src = operands[1];
2844 rtx op2 = operands[2];
2845 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2846 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2852 addr1 = XEXP (src, 0);
2853 if (GET_CODE (addr1) == PLUS)
2855 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2856 if (TARGET_AVOID_XFORM
2857 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2859 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2863 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2865 else if (TARGET_AVOID_XFORM
2866 || REGNO (addr1) == REGNO (dest2))
2868 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2873 emit_move_insn (op2, GEN_INT (4));
2874 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2877 word1 = change_address (src, SImode, addr1);
2878 word2 = change_address (src, SImode, addr2);
2880 emit_insn (gen_bswapsi2 (dest2, word1));
2881 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2882 thus allowing us to omit an early clobber on the output. */
2883 emit_insn (gen_bswapsi2 (dest1, word2));
2888 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2889 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2890 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2891 "!TARGET_POWERPC64 && reload_completed"
2894 rtx dest = operands[0];
2895 rtx src = operands[1];
2896 rtx op2 = operands[2];
2897 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2898 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2904 addr1 = XEXP (dest, 0);
2905 if (GET_CODE (addr1) == PLUS)
2907 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2908 if (TARGET_AVOID_XFORM)
2910 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2914 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2916 else if (TARGET_AVOID_XFORM)
2918 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2923 emit_move_insn (op2, GEN_INT (4));
2924 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2927 word1 = change_address (dest, SImode, addr1);
2928 word2 = change_address (dest, SImode, addr2);
2930 emit_insn (gen_bswapsi2 (word2, src1));
2931 emit_insn (gen_bswapsi2 (word1, src2));
2936 [(set (match_operand:DI 0 "gpc_reg_operand")
2937 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2938 (clobber (match_operand:SI 2 ""))]
2939 "!TARGET_POWERPC64 && reload_completed"
2942 rtx dest = operands[0];
2943 rtx src = operands[1];
2944 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2945 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2946 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2947 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2949 emit_insn (gen_bswapsi2 (dest1, src2));
2950 emit_insn (gen_bswapsi2 (dest2, src1));
2955 (define_insn "mul<mode>3"
2956 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2957 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2958 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2963 [(set_attr "type" "mul")
2965 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2967 (match_operand:GPR 2 "short_cint_operand")
2968 (const_string "16")]
2969 (const_string "<bits>")))])
2971 (define_insn_and_split "*mul<mode>3_dot"
2972 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2973 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2974 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2976 (clobber (match_scratch:GPR 0 "=r,r"))]
2977 "<MODE>mode == Pmode"
2981 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2983 (mult:GPR (match_dup 1)
2986 (compare:CC (match_dup 0)
2989 [(set_attr "type" "mul")
2990 (set_attr "size" "<bits>")
2991 (set_attr "dot" "yes")
2992 (set_attr "length" "4,8")])
2994 (define_insn_and_split "*mul<mode>3_dot2"
2995 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2996 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2997 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2999 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3000 (mult:GPR (match_dup 1)
3002 "<MODE>mode == Pmode"
3006 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3008 (mult:GPR (match_dup 1)
3011 (compare:CC (match_dup 0)
3014 [(set_attr "type" "mul")
3015 (set_attr "size" "<bits>")
3016 (set_attr "dot" "yes")
3017 (set_attr "length" "4,8")])
3020 (define_expand "<su>mul<mode>3_highpart"
3021 [(set (match_operand:GPR 0 "gpc_reg_operand")
3023 (mult:<DMODE> (any_extend:<DMODE>
3024 (match_operand:GPR 1 "gpc_reg_operand"))
3026 (match_operand:GPR 2 "gpc_reg_operand")))
3030 if (<MODE>mode == SImode && TARGET_POWERPC64)
3032 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3037 if (!WORDS_BIG_ENDIAN)
3039 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3045 (define_insn "*<su>mul<mode>3_highpart"
3046 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3048 (mult:<DMODE> (any_extend:<DMODE>
3049 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3051 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3053 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3054 "mulh<wd><u> %0,%1,%2"
3055 [(set_attr "type" "mul")
3056 (set_attr "size" "<bits>")])
3058 (define_insn "<su>mulsi3_highpart_le"
3059 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3061 (mult:DI (any_extend:DI
3062 (match_operand:SI 1 "gpc_reg_operand" "r"))
3064 (match_operand:SI 2 "gpc_reg_operand" "r")))
3066 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3068 [(set_attr "type" "mul")])
3070 (define_insn "<su>muldi3_highpart_le"
3071 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3073 (mult:TI (any_extend:TI
3074 (match_operand:DI 1 "gpc_reg_operand" "r"))
3076 (match_operand:DI 2 "gpc_reg_operand" "r")))
3078 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3080 [(set_attr "type" "mul")
3081 (set_attr "size" "64")])
3083 (define_insn "<su>mulsi3_highpart_64"
3084 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3087 (mult:DI (any_extend:DI
3088 (match_operand:SI 1 "gpc_reg_operand" "r"))
3090 (match_operand:SI 2 "gpc_reg_operand" "r")))
3094 [(set_attr "type" "mul")])
3096 (define_expand "<u>mul<mode><dmode>3"
3097 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3098 (mult:<DMODE> (any_extend:<DMODE>
3099 (match_operand:GPR 1 "gpc_reg_operand"))
3101 (match_operand:GPR 2 "gpc_reg_operand"))))]
3102 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3104 rtx l = gen_reg_rtx (<MODE>mode);
3105 rtx h = gen_reg_rtx (<MODE>mode);
3106 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3107 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3108 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3109 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3113 (define_insn "*maddld<mode>4"
3114 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3115 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3116 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3117 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3119 "maddld %0,%1,%2,%3"
3120 [(set_attr "type" "mul")])
3122 (define_insn "udiv<mode>3"
3123 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3124 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3125 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3128 [(set_attr "type" "div")
3129 (set_attr "size" "<bits>")])
3132 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3133 ;; modulus. If it isn't a power of two, force operands into register and do
3135 (define_expand "div<mode>3"
3136 [(set (match_operand:GPR 0 "gpc_reg_operand")
3137 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3138 (match_operand:GPR 2 "reg_or_cint_operand")))]
3141 if (CONST_INT_P (operands[2])
3142 && INTVAL (operands[2]) > 0
3143 && exact_log2 (INTVAL (operands[2])) >= 0)
3145 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3149 operands[2] = force_reg (<MODE>mode, operands[2]);
3152 (define_insn "*div<mode>3"
3153 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3154 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3155 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3158 [(set_attr "type" "div")
3159 (set_attr "size" "<bits>")])
3161 (define_insn "div<mode>3_sra"
3162 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3163 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3164 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3165 (clobber (reg:GPR CA_REGNO))]
3167 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3168 [(set_attr "type" "two")
3169 (set_attr "length" "8")])
3171 (define_insn_and_split "*div<mode>3_sra_dot"
3172 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3173 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3174 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3176 (clobber (match_scratch:GPR 0 "=r,r"))
3177 (clobber (reg:GPR CA_REGNO))]
3178 "<MODE>mode == Pmode"
3180 sra<wd>i %0,%1,%p2\;addze. %0,%0
3182 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3183 [(parallel [(set (match_dup 0)
3184 (div:GPR (match_dup 1)
3186 (clobber (reg:GPR CA_REGNO))])
3188 (compare:CC (match_dup 0)
3191 [(set_attr "type" "two")
3192 (set_attr "length" "8,12")
3193 (set_attr "cell_micro" "not")])
3195 (define_insn_and_split "*div<mode>3_sra_dot2"
3196 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3197 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3198 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3200 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3201 (div:GPR (match_dup 1)
3203 (clobber (reg:GPR CA_REGNO))]
3204 "<MODE>mode == Pmode"
3206 sra<wd>i %0,%1,%p2\;addze. %0,%0
3208 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3209 [(parallel [(set (match_dup 0)
3210 (div:GPR (match_dup 1)
3212 (clobber (reg:GPR CA_REGNO))])
3214 (compare:CC (match_dup 0)
3217 [(set_attr "type" "two")
3218 (set_attr "length" "8,12")
3219 (set_attr "cell_micro" "not")])
3221 (define_expand "mod<mode>3"
3222 [(set (match_operand:GPR 0 "gpc_reg_operand")
3223 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3224 (match_operand:GPR 2 "reg_or_cint_operand")))]
3231 if (!CONST_INT_P (operands[2])
3232 || INTVAL (operands[2]) <= 0
3233 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3238 operands[2] = force_reg (<MODE>mode, operands[2]);
3242 temp1 = gen_reg_rtx (<MODE>mode);
3243 temp2 = gen_reg_rtx (<MODE>mode);
3245 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3246 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3247 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3252 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3253 ;; mod, prefer putting the result of mod into a different register
3254 (define_insn "*mod<mode>3"
3255 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3256 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3257 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3260 [(set_attr "type" "div")
3261 (set_attr "size" "<bits>")])
3264 (define_insn "umod<mode>3"
3265 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3266 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3267 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3270 [(set_attr "type" "div")
3271 (set_attr "size" "<bits>")])
3273 ;; On machines with modulo support, do a combined div/mod the old fashioned
3274 ;; method, since the multiply/subtract is faster than doing the mod instruction
3278 [(set (match_operand:GPR 0 "gpc_reg_operand")
3279 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3280 (match_operand:GPR 2 "gpc_reg_operand")))
3281 (set (match_operand:GPR 3 "gpc_reg_operand")
3282 (mod:GPR (match_dup 1)
3285 && ! reg_mentioned_p (operands[0], operands[1])
3286 && ! reg_mentioned_p (operands[0], operands[2])
3287 && ! reg_mentioned_p (operands[3], operands[1])
3288 && ! reg_mentioned_p (operands[3], operands[2])"
3290 (div:GPR (match_dup 1)
3293 (mult:GPR (match_dup 0)
3296 (minus:GPR (match_dup 1)
3300 [(set (match_operand:GPR 0 "gpc_reg_operand")
3301 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3302 (match_operand:GPR 2 "gpc_reg_operand")))
3303 (set (match_operand:GPR 3 "gpc_reg_operand")
3304 (umod:GPR (match_dup 1)
3307 && ! reg_mentioned_p (operands[0], operands[1])
3308 && ! reg_mentioned_p (operands[0], operands[2])
3309 && ! reg_mentioned_p (operands[3], operands[1])
3310 && ! reg_mentioned_p (operands[3], operands[2])"
3312 (udiv:GPR (match_dup 1)
3315 (mult:GPR (match_dup 0)
3318 (minus:GPR (match_dup 1)
3322 ;; Logical instructions
3323 ;; The logical instructions are mostly combined by using match_operator,
3324 ;; but the plain AND insns are somewhat different because there is no
3325 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3326 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3328 (define_expand "and<mode>3"
3329 [(set (match_operand:SDI 0 "gpc_reg_operand")
3330 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3331 (match_operand:SDI 2 "reg_or_cint_operand")))]
3334 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3336 rs6000_split_logical (operands, AND, false, false, false);
3340 if (CONST_INT_P (operands[2]))
3342 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3344 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3348 if (logical_const_operand (operands[2], <MODE>mode))
3350 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3354 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3356 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3360 operands[2] = force_reg (<MODE>mode, operands[2]);
3365 (define_insn "and<mode>3_imm"
3366 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3367 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3368 (match_operand:GPR 2 "logical_const_operand" "n")))
3369 (clobber (match_scratch:CC 3 "=x"))]
3370 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3371 "andi%e2. %0,%1,%u2"
3372 [(set_attr "type" "logical")
3373 (set_attr "dot" "yes")])
3375 (define_insn_and_split "*and<mode>3_imm_dot"
3376 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3377 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3378 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3380 (clobber (match_scratch:GPR 0 "=r,r"))
3381 (clobber (match_scratch:CC 4 "=X,x"))]
3382 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3383 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3387 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3388 [(parallel [(set (match_dup 0)
3389 (and:GPR (match_dup 1)
3391 (clobber (match_dup 4))])
3393 (compare:CC (match_dup 0)
3396 [(set_attr "type" "logical")
3397 (set_attr "dot" "yes")
3398 (set_attr "length" "4,8")])
3400 (define_insn_and_split "*and<mode>3_imm_dot2"
3401 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3402 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3403 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3405 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3406 (and:GPR (match_dup 1)
3408 (clobber (match_scratch:CC 4 "=X,x"))]
3409 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3410 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3414 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3415 [(parallel [(set (match_dup 0)
3416 (and:GPR (match_dup 1)
3418 (clobber (match_dup 4))])
3420 (compare:CC (match_dup 0)
3423 [(set_attr "type" "logical")
3424 (set_attr "dot" "yes")
3425 (set_attr "length" "4,8")])
3427 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3428 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3429 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3430 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3432 (clobber (match_scratch:GPR 0 "=r,r"))]
3433 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3434 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3438 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3440 (and:GPR (match_dup 1)
3443 (compare:CC (match_dup 0)
3446 [(set_attr "type" "logical")
3447 (set_attr "dot" "yes")
3448 (set_attr "length" "4,8")])
3450 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3451 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3452 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3453 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3455 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3456 (and:GPR (match_dup 1)
3458 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3459 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3463 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3465 (and:GPR (match_dup 1)
3468 (compare:CC (match_dup 0)
3471 [(set_attr "type" "logical")
3472 (set_attr "dot" "yes")
3473 (set_attr "length" "4,8")])
3475 (define_insn "*and<mode>3_imm_dot_shifted"
3476 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3479 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3480 (match_operand:SI 4 "const_int_operand" "n"))
3481 (match_operand:GPR 2 "const_int_operand" "n"))
3483 (clobber (match_scratch:GPR 0 "=r"))]
3484 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3485 << INTVAL (operands[4])),
3487 && (<MODE>mode == Pmode
3488 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3490 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3491 return "andi%e2. %0,%1,%u2";
3493 [(set_attr "type" "logical")
3494 (set_attr "dot" "yes")])
3497 (define_insn "and<mode>3_mask"
3498 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3499 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3500 (match_operand:GPR 2 "const_int_operand" "n")))]
3501 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3503 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3505 [(set_attr "type" "shift")])
3507 (define_insn_and_split "*and<mode>3_mask_dot"
3508 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3509 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3510 (match_operand:GPR 2 "const_int_operand" "n,n"))
3512 (clobber (match_scratch:GPR 0 "=r,r"))]
3513 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3514 && !logical_const_operand (operands[2], <MODE>mode)
3515 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3517 if (which_alternative == 0)
3518 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3522 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3524 (and:GPR (match_dup 1)
3527 (compare:CC (match_dup 0)
3530 [(set_attr "type" "shift")
3531 (set_attr "dot" "yes")
3532 (set_attr "length" "4,8")])
3534 (define_insn_and_split "*and<mode>3_mask_dot2"
3535 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3536 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3537 (match_operand:GPR 2 "const_int_operand" "n,n"))
3539 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3540 (and:GPR (match_dup 1)
3542 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3543 && !logical_const_operand (operands[2], <MODE>mode)
3544 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3546 if (which_alternative == 0)
3547 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3551 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3553 (and:GPR (match_dup 1)
3556 (compare:CC (match_dup 0)
3559 [(set_attr "type" "shift")
3560 (set_attr "dot" "yes")
3561 (set_attr "length" "4,8")])
3564 (define_insn_and_split "*and<mode>3_2insn"
3565 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3566 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3567 (match_operand:GPR 2 "const_int_operand" "n")))]
3568 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3569 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3570 || logical_const_operand (operands[2], <MODE>mode))"
3575 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3578 [(set_attr "type" "shift")
3579 (set_attr "length" "8")])
3581 (define_insn_and_split "*and<mode>3_2insn_dot"
3582 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3583 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3584 (match_operand:GPR 2 "const_int_operand" "n,n"))
3586 (clobber (match_scratch:GPR 0 "=r,r"))]
3587 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3588 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3589 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3590 || logical_const_operand (operands[2], <MODE>mode))"
3592 "&& reload_completed"
3595 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3598 [(set_attr "type" "shift")
3599 (set_attr "dot" "yes")
3600 (set_attr "length" "8,12")])
3602 (define_insn_and_split "*and<mode>3_2insn_dot2"
3603 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3604 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3605 (match_operand:GPR 2 "const_int_operand" "n,n"))
3607 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3608 (and:GPR (match_dup 1)
3610 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3611 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3612 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3613 || logical_const_operand (operands[2], <MODE>mode))"
3615 "&& reload_completed"
3618 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3621 [(set_attr "type" "shift")
3622 (set_attr "dot" "yes")
3623 (set_attr "length" "8,12")])
3626 (define_expand "<code><mode>3"
3627 [(set (match_operand:SDI 0 "gpc_reg_operand")
3628 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3629 (match_operand:SDI 2 "reg_or_cint_operand")))]
3632 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3634 rs6000_split_logical (operands, <CODE>, false, false, false);
3638 if (non_logical_cint_operand (operands[2], <MODE>mode))
3640 rtx tmp = ((!can_create_pseudo_p ()
3641 || rtx_equal_p (operands[0], operands[1]))
3642 ? operands[0] : gen_reg_rtx (<MODE>mode));
3644 HOST_WIDE_INT value = INTVAL (operands[2]);
3645 HOST_WIDE_INT lo = value & 0xffff;
3646 HOST_WIDE_INT hi = value - lo;
3648 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3649 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3653 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3654 operands[2] = force_reg (<MODE>mode, operands[2]);
3658 [(set (match_operand:GPR 0 "gpc_reg_operand")
3659 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3660 (match_operand:GPR 2 "non_logical_cint_operand")))]
3663 (iorxor:GPR (match_dup 1)
3666 (iorxor:GPR (match_dup 3)
3669 operands[3] = ((!can_create_pseudo_p ()
3670 || rtx_equal_p (operands[0], operands[1]))
3671 ? operands[0] : gen_reg_rtx (<MODE>mode));
3673 HOST_WIDE_INT value = INTVAL (operands[2]);
3674 HOST_WIDE_INT lo = value & 0xffff;
3675 HOST_WIDE_INT hi = value - lo;
3677 operands[4] = GEN_INT (hi);
3678 operands[5] = GEN_INT (lo);
3681 (define_insn "*bool<mode>3_imm"
3682 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3683 (match_operator:GPR 3 "boolean_or_operator"
3684 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3685 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3688 [(set_attr "type" "logical")])
3690 (define_insn "*bool<mode>3"
3691 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3692 (match_operator:GPR 3 "boolean_operator"
3693 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3694 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3697 [(set_attr "type" "logical")])
3699 (define_insn_and_split "*bool<mode>3_dot"
3700 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3701 (compare:CC (match_operator:GPR 3 "boolean_operator"
3702 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3703 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3705 (clobber (match_scratch:GPR 0 "=r,r"))]
3706 "<MODE>mode == Pmode"
3710 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3714 (compare:CC (match_dup 0)
3717 [(set_attr "type" "logical")
3718 (set_attr "dot" "yes")
3719 (set_attr "length" "4,8")])
3721 (define_insn_and_split "*bool<mode>3_dot2"
3722 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3723 (compare:CC (match_operator:GPR 3 "boolean_operator"
3724 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3725 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3727 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3729 "<MODE>mode == Pmode"
3733 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3737 (compare:CC (match_dup 0)
3740 [(set_attr "type" "logical")
3741 (set_attr "dot" "yes")
3742 (set_attr "length" "4,8")])
3745 (define_insn "*boolc<mode>3"
3746 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3747 (match_operator:GPR 3 "boolean_operator"
3748 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3749 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3752 [(set_attr "type" "logical")])
3754 (define_insn_and_split "*boolc<mode>3_dot"
3755 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3756 (compare:CC (match_operator:GPR 3 "boolean_operator"
3757 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3758 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3760 (clobber (match_scratch:GPR 0 "=r,r"))]
3761 "<MODE>mode == Pmode"
3765 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3769 (compare:CC (match_dup 0)
3772 [(set_attr "type" "logical")
3773 (set_attr "dot" "yes")
3774 (set_attr "length" "4,8")])
3776 (define_insn_and_split "*boolc<mode>3_dot2"
3777 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3778 (compare:CC (match_operator:GPR 3 "boolean_operator"
3779 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3780 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3782 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3784 "<MODE>mode == Pmode"
3788 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3792 (compare:CC (match_dup 0)
3795 [(set_attr "type" "logical")
3796 (set_attr "dot" "yes")
3797 (set_attr "length" "4,8")])
3800 (define_insn "*boolcc<mode>3"
3801 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3802 (match_operator:GPR 3 "boolean_operator"
3803 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3804 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3807 [(set_attr "type" "logical")])
3809 (define_insn_and_split "*boolcc<mode>3_dot"
3810 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3811 (compare:CC (match_operator:GPR 3 "boolean_operator"
3812 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3813 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3815 (clobber (match_scratch:GPR 0 "=r,r"))]
3816 "<MODE>mode == Pmode"
3820 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3824 (compare:CC (match_dup 0)
3827 [(set_attr "type" "logical")
3828 (set_attr "dot" "yes")
3829 (set_attr "length" "4,8")])
3831 (define_insn_and_split "*boolcc<mode>3_dot2"
3832 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3833 (compare:CC (match_operator:GPR 3 "boolean_operator"
3834 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3835 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3837 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3839 "<MODE>mode == Pmode"
3843 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3847 (compare:CC (match_dup 0)
3850 [(set_attr "type" "logical")
3851 (set_attr "dot" "yes")
3852 (set_attr "length" "4,8")])
3855 ;; TODO: Should have dots of this as well.
3856 (define_insn "*eqv<mode>3"
3857 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3858 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3859 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3862 [(set_attr "type" "logical")])
3864 ;; Rotate-and-mask and insert.
3866 (define_insn "*rotl<mode>3_mask"
3867 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3868 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3869 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3870 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3871 (match_operand:GPR 3 "const_int_operand" "n")))]
3872 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3874 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3876 [(set_attr "type" "shift")
3877 (set_attr "maybe_var_shift" "yes")])
3879 (define_insn_and_split "*rotl<mode>3_mask_dot"
3880 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3882 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3883 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3884 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3885 (match_operand:GPR 3 "const_int_operand" "n,n"))
3887 (clobber (match_scratch:GPR 0 "=r,r"))]
3888 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3889 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3891 if (which_alternative == 0)
3892 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3896 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3898 (and:GPR (match_dup 4)
3901 (compare:CC (match_dup 0)
3904 [(set_attr "type" "shift")
3905 (set_attr "maybe_var_shift" "yes")
3906 (set_attr "dot" "yes")
3907 (set_attr "length" "4,8")])
3909 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3910 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3912 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3913 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3914 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3915 (match_operand:GPR 3 "const_int_operand" "n,n"))
3917 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3918 (and:GPR (match_dup 4)
3920 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3921 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3923 if (which_alternative == 0)
3924 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3928 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3930 (and:GPR (match_dup 4)
3933 (compare:CC (match_dup 0)
3936 [(set_attr "type" "shift")
3937 (set_attr "maybe_var_shift" "yes")
3938 (set_attr "dot" "yes")
3939 (set_attr "length" "4,8")])
3941 ; Special case for less-than-0. We can do it with just one machine
3942 ; instruction, but the generic optimizers do not realise it is cheap.
3943 (define_insn "*lt0_<mode>di"
3944 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3945 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3949 [(set_attr "type" "shift")])
3951 (define_insn "*lt0_<mode>si"
3952 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3953 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3956 "rlwinm %0,%1,1,31,31"
3957 [(set_attr "type" "shift")])
3961 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3962 ; both are an AND so are the same precedence).
3963 (define_insn "*rotl<mode>3_insert"
3964 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3965 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3966 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3967 (match_operand:SI 2 "const_int_operand" "n")])
3968 (match_operand:GPR 3 "const_int_operand" "n"))
3969 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3970 (match_operand:GPR 6 "const_int_operand" "n"))))]
3971 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3972 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3974 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3976 [(set_attr "type" "insert")])
3977 ; FIXME: this needs an attr "size", so that the scheduler can see the
3978 ; difference between rlwimi and rldimi. We also might want dot forms,
3979 ; but not for rlwimi on POWER4 and similar processors.
3981 (define_insn "*rotl<mode>3_insert_2"
3982 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3983 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3984 (match_operand:GPR 6 "const_int_operand" "n"))
3985 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3986 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3987 (match_operand:SI 2 "const_int_operand" "n")])
3988 (match_operand:GPR 3 "const_int_operand" "n"))))]
3989 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3990 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3992 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3994 [(set_attr "type" "insert")])
3996 ; There are also some forms without one of the ANDs.
3997 (define_insn "*rotl<mode>3_insert_3"
3998 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3999 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4000 (match_operand:GPR 4 "const_int_operand" "n"))
4001 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4002 (match_operand:SI 2 "const_int_operand" "n"))))]
4003 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4005 if (<MODE>mode == SImode)
4006 return "rlwimi %0,%1,%h2,0,31-%h2";
4008 return "rldimi %0,%1,%H2,0";
4010 [(set_attr "type" "insert")])
4012 (define_insn "*rotl<mode>3_insert_4"
4013 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4014 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4015 (match_operand:GPR 4 "const_int_operand" "n"))
4016 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4017 (match_operand:SI 2 "const_int_operand" "n"))))]
4018 "<MODE>mode == SImode &&
4019 GET_MODE_PRECISION (<MODE>mode)
4020 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4022 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4023 - INTVAL (operands[2]));
4024 if (<MODE>mode == SImode)
4025 return "rlwimi %0,%1,%h2,32-%h2,31";
4027 return "rldimi %0,%1,%H2,64-%H2";
4029 [(set_attr "type" "insert")])
4031 (define_insn "*rotlsi3_insert_5"
4032 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4033 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4034 (match_operand:SI 2 "const_int_operand" "n,n"))
4035 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4036 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4037 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4038 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4039 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4043 [(set_attr "type" "insert")])
4045 (define_insn "*rotldi3_insert_6"
4046 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4047 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4048 (match_operand:DI 2 "const_int_operand" "n"))
4049 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4050 (match_operand:DI 4 "const_int_operand" "n"))))]
4051 "exact_log2 (-UINTVAL (operands[2])) > 0
4052 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4054 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4055 return "rldimi %0,%3,0,%5";
4057 [(set_attr "type" "insert")
4058 (set_attr "size" "64")])
4060 (define_insn "*rotldi3_insert_7"
4061 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4062 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4063 (match_operand:DI 4 "const_int_operand" "n"))
4064 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4065 (match_operand:DI 2 "const_int_operand" "n"))))]
4066 "exact_log2 (-UINTVAL (operands[2])) > 0
4067 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4069 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4070 return "rldimi %0,%3,0,%5";
4072 [(set_attr "type" "insert")
4073 (set_attr "size" "64")])
4076 ; This handles the important case of multiple-precision shifts. There is
4077 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4079 [(set (match_operand:GPR 0 "gpc_reg_operand")
4080 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4081 (match_operand:SI 3 "const_int_operand"))
4082 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4083 (match_operand:SI 4 "const_int_operand"))))]
4084 "can_create_pseudo_p ()
4085 && INTVAL (operands[3]) + INTVAL (operands[4])
4086 >= GET_MODE_PRECISION (<MODE>mode)"
4088 (lshiftrt:GPR (match_dup 2)
4091 (ior:GPR (and:GPR (match_dup 5)
4093 (ashift:GPR (match_dup 1)
4096 unsigned HOST_WIDE_INT mask = 1;
4097 mask = (mask << INTVAL (operands[3])) - 1;
4098 operands[5] = gen_reg_rtx (<MODE>mode);
4099 operands[6] = GEN_INT (mask);
4103 [(set (match_operand:GPR 0 "gpc_reg_operand")
4104 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4105 (match_operand:SI 4 "const_int_operand"))
4106 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4107 (match_operand:SI 3 "const_int_operand"))))]
4108 "can_create_pseudo_p ()
4109 && INTVAL (operands[3]) + INTVAL (operands[4])
4110 >= GET_MODE_PRECISION (<MODE>mode)"
4112 (lshiftrt:GPR (match_dup 2)
4115 (ior:GPR (and:GPR (match_dup 5)
4117 (ashift:GPR (match_dup 1)
4120 unsigned HOST_WIDE_INT mask = 1;
4121 mask = (mask << INTVAL (operands[3])) - 1;
4122 operands[5] = gen_reg_rtx (<MODE>mode);
4123 operands[6] = GEN_INT (mask);
4127 ; Another important case is setting some bits to 1; we can do that with
4128 ; an insert instruction, in many cases.
4129 (define_insn_and_split "*ior<mode>_mask"
4130 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4131 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4132 (match_operand:GPR 2 "const_int_operand" "n")))
4133 (clobber (match_scratch:GPR 3 "=r"))]
4134 "!logical_const_operand (operands[2], <MODE>mode)
4135 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4141 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4144 (and:GPR (match_dup 1)
4148 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4149 if (GET_CODE (operands[3]) == SCRATCH)
4150 operands[3] = gen_reg_rtx (<MODE>mode);
4151 operands[4] = GEN_INT (ne);
4152 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4154 [(set_attr "type" "two")
4155 (set_attr "length" "8")])
4158 ; Yet another case is an rldimi with the second value coming from memory.
4159 ; The zero_extend that should become part of the rldimi is merged into the
4160 ; load from memory instead. Split things properly again.
4162 [(set (match_operand:DI 0 "gpc_reg_operand")
4163 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4164 (match_operand:SI 2 "const_int_operand"))
4165 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4166 "INTVAL (operands[2]) == <bits>"
4168 (zero_extend:DI (match_dup 3)))
4170 (ior:DI (and:DI (match_dup 4)
4172 (ashift:DI (match_dup 1)
4175 operands[4] = gen_reg_rtx (DImode);
4176 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4181 [(set (match_operand:SI 0 "gpc_reg_operand")
4182 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4183 (match_operand:SI 2 "const_int_operand"))
4184 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4185 "INTVAL (operands[2]) == <bits>"
4187 (zero_extend:SI (match_dup 3)))
4189 (ior:SI (and:SI (match_dup 4)
4191 (ashift:SI (match_dup 1)
4194 operands[4] = gen_reg_rtx (SImode);
4195 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4199 ;; Now the simple shifts.
4201 (define_insn "rotl<mode>3"
4202 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4203 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4204 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4206 "rotl<wd>%I2 %0,%1,%<hH>2"
4207 [(set_attr "type" "shift")
4208 (set_attr "maybe_var_shift" "yes")])
4210 (define_insn "*rotlsi3_64"
4211 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4213 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4214 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4216 "rotlw%I2 %0,%1,%h2"
4217 [(set_attr "type" "shift")
4218 (set_attr "maybe_var_shift" "yes")])
4220 (define_insn_and_split "*rotl<mode>3_dot"
4221 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4222 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4223 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4225 (clobber (match_scratch:GPR 0 "=r,r"))]
4226 "<MODE>mode == Pmode"
4228 rotl<wd>%I2. %0,%1,%<hH>2
4230 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4232 (rotate:GPR (match_dup 1)
4235 (compare:CC (match_dup 0)
4238 [(set_attr "type" "shift")
4239 (set_attr "maybe_var_shift" "yes")
4240 (set_attr "dot" "yes")
4241 (set_attr "length" "4,8")])
4243 (define_insn_and_split "*rotl<mode>3_dot2"
4244 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4245 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4246 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4248 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4249 (rotate:GPR (match_dup 1)
4251 "<MODE>mode == Pmode"
4253 rotl<wd>%I2. %0,%1,%<hH>2
4255 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4257 (rotate:GPR (match_dup 1)
4260 (compare:CC (match_dup 0)
4263 [(set_attr "type" "shift")
4264 (set_attr "maybe_var_shift" "yes")
4265 (set_attr "dot" "yes")
4266 (set_attr "length" "4,8")])
4269 (define_insn "ashl<mode>3"
4270 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4271 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4272 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4274 "sl<wd>%I2 %0,%1,%<hH>2"
4275 [(set_attr "type" "shift")
4276 (set_attr "maybe_var_shift" "yes")])
4278 (define_insn "*ashlsi3_64"
4279 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4281 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4282 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4285 [(set_attr "type" "shift")
4286 (set_attr "maybe_var_shift" "yes")])
4288 (define_insn_and_split "*ashl<mode>3_dot"
4289 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4290 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4291 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4293 (clobber (match_scratch:GPR 0 "=r,r"))]
4294 "<MODE>mode == Pmode"
4296 sl<wd>%I2. %0,%1,%<hH>2
4298 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4300 (ashift:GPR (match_dup 1)
4303 (compare:CC (match_dup 0)
4306 [(set_attr "type" "shift")
4307 (set_attr "maybe_var_shift" "yes")
4308 (set_attr "dot" "yes")
4309 (set_attr "length" "4,8")])
4311 (define_insn_and_split "*ashl<mode>3_dot2"
4312 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4313 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4314 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4316 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4317 (ashift:GPR (match_dup 1)
4319 "<MODE>mode == Pmode"
4321 sl<wd>%I2. %0,%1,%<hH>2
4323 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4325 (ashift:GPR (match_dup 1)
4328 (compare:CC (match_dup 0)
4331 [(set_attr "type" "shift")
4332 (set_attr "maybe_var_shift" "yes")
4333 (set_attr "dot" "yes")
4334 (set_attr "length" "4,8")])
4336 ;; Pretend we have a memory form of extswsli until register allocation is done
4337 ;; so that we use LWZ to load the value from memory, instead of LWA.
4338 (define_insn_and_split "ashdi3_extswsli"
4339 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4341 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4342 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4347 "&& reload_completed && MEM_P (operands[1])"
4351 (ashift:DI (sign_extend:DI (match_dup 3))
4354 operands[3] = gen_lowpart (SImode, operands[0]);
4356 [(set_attr "type" "shift")
4357 (set_attr "maybe_var_shift" "no")])
4360 (define_insn_and_split "ashdi3_extswsli_dot"
4361 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4364 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4365 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4367 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4374 "&& reload_completed
4375 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4376 || memory_operand (operands[1], SImode))"
4379 rtx dest = operands[0];
4380 rtx src = operands[1];
4381 rtx shift = operands[2];
4382 rtx cr = operands[3];
4389 src2 = gen_lowpart (SImode, dest);
4390 emit_move_insn (src2, src);
4393 if (REGNO (cr) == CR0_REGNO)
4395 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4399 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4400 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4403 [(set_attr "type" "shift")
4404 (set_attr "maybe_var_shift" "no")
4405 (set_attr "dot" "yes")
4406 (set_attr "length" "4,8,8,12")])
4408 (define_insn_and_split "ashdi3_extswsli_dot2"
4409 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4412 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4413 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4415 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4416 (ashift:DI (sign_extend:DI (match_dup 1))
4424 "&& reload_completed
4425 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4426 || memory_operand (operands[1], SImode))"
4429 rtx dest = operands[0];
4430 rtx src = operands[1];
4431 rtx shift = operands[2];
4432 rtx cr = operands[3];
4439 src2 = gen_lowpart (SImode, dest);
4440 emit_move_insn (src2, src);
4443 if (REGNO (cr) == CR0_REGNO)
4445 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4449 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4450 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4453 [(set_attr "type" "shift")
4454 (set_attr "maybe_var_shift" "no")
4455 (set_attr "dot" "yes")
4456 (set_attr "length" "4,8,8,12")])
4458 (define_insn "lshr<mode>3"
4459 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4460 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4461 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4463 "sr<wd>%I2 %0,%1,%<hH>2"
4464 [(set_attr "type" "shift")
4465 (set_attr "maybe_var_shift" "yes")])
4467 (define_insn "*lshrsi3_64"
4468 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4470 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4471 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4474 [(set_attr "type" "shift")
4475 (set_attr "maybe_var_shift" "yes")])
4477 (define_insn_and_split "*lshr<mode>3_dot"
4478 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4479 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4480 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4482 (clobber (match_scratch:GPR 0 "=r,r"))]
4483 "<MODE>mode == Pmode"
4485 sr<wd>%I2. %0,%1,%<hH>2
4487 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4489 (lshiftrt:GPR (match_dup 1)
4492 (compare:CC (match_dup 0)
4495 [(set_attr "type" "shift")
4496 (set_attr "maybe_var_shift" "yes")
4497 (set_attr "dot" "yes")
4498 (set_attr "length" "4,8")])
4500 (define_insn_and_split "*lshr<mode>3_dot2"
4501 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4502 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4503 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4505 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4506 (lshiftrt:GPR (match_dup 1)
4508 "<MODE>mode == Pmode"
4510 sr<wd>%I2. %0,%1,%<hH>2
4512 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4514 (lshiftrt:GPR (match_dup 1)
4517 (compare:CC (match_dup 0)
4520 [(set_attr "type" "shift")
4521 (set_attr "maybe_var_shift" "yes")
4522 (set_attr "dot" "yes")
4523 (set_attr "length" "4,8")])
4526 (define_insn "ashr<mode>3"
4527 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4528 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4529 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4530 (clobber (reg:GPR CA_REGNO))]
4532 "sra<wd>%I2 %0,%1,%<hH>2"
4533 [(set_attr "type" "shift")
4534 (set_attr "maybe_var_shift" "yes")])
4536 (define_insn "*ashrsi3_64"
4537 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4539 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4540 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4541 (clobber (reg:SI CA_REGNO))]
4544 [(set_attr "type" "shift")
4545 (set_attr "maybe_var_shift" "yes")])
4547 (define_insn_and_split "*ashr<mode>3_dot"
4548 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4549 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4550 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4552 (clobber (match_scratch:GPR 0 "=r,r"))
4553 (clobber (reg:GPR CA_REGNO))]
4554 "<MODE>mode == Pmode"
4556 sra<wd>%I2. %0,%1,%<hH>2
4558 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4559 [(parallel [(set (match_dup 0)
4560 (ashiftrt:GPR (match_dup 1)
4562 (clobber (reg:GPR CA_REGNO))])
4564 (compare:CC (match_dup 0)
4567 [(set_attr "type" "shift")
4568 (set_attr "maybe_var_shift" "yes")
4569 (set_attr "dot" "yes")
4570 (set_attr "length" "4,8")])
4572 (define_insn_and_split "*ashr<mode>3_dot2"
4573 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4574 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4575 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4577 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4578 (ashiftrt:GPR (match_dup 1)
4580 (clobber (reg:GPR CA_REGNO))]
4581 "<MODE>mode == Pmode"
4583 sra<wd>%I2. %0,%1,%<hH>2
4585 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4586 [(parallel [(set (match_dup 0)
4587 (ashiftrt:GPR (match_dup 1)
4589 (clobber (reg:GPR CA_REGNO))])
4591 (compare:CC (match_dup 0)
4594 [(set_attr "type" "shift")
4595 (set_attr "maybe_var_shift" "yes")
4596 (set_attr "dot" "yes")
4597 (set_attr "length" "4,8")])
4599 ;; Builtins to replace a division to generate FRE reciprocal estimate
4600 ;; instructions and the necessary fixup instructions
4601 (define_expand "recip<mode>3"
4602 [(match_operand:RECIPF 0 "gpc_reg_operand")
4603 (match_operand:RECIPF 1 "gpc_reg_operand")
4604 (match_operand:RECIPF 2 "gpc_reg_operand")]
4605 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4607 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4611 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4612 ;; hardware division. This is only done before register allocation and with
4613 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4614 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4615 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4617 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4618 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4619 (match_operand 2 "gpc_reg_operand")))]
4620 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4621 && can_create_pseudo_p () && flag_finite_math_only
4622 && !flag_trapping_math && flag_reciprocal_math"
4625 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4629 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4630 ;; appropriate fixup.
4631 (define_expand "rsqrt<mode>2"
4632 [(match_operand:RECIPF 0 "gpc_reg_operand")
4633 (match_operand:RECIPF 1 "gpc_reg_operand")]
4634 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4636 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4640 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4641 ;; modes here, and also add in conditional vsx/power8-vector support to access
4642 ;; values in the traditional Altivec registers if the appropriate
4643 ;; -mupper-regs-{df,sf} option is enabled.
4645 (define_expand "abs<mode>2"
4646 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4647 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4651 (define_insn "*abs<mode>2_fpr"
4652 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4653 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4658 [(set_attr "type" "fpsimple")])
4660 (define_insn "*nabs<mode>2_fpr"
4661 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4664 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4669 [(set_attr "type" "fpsimple")])
4671 (define_expand "neg<mode>2"
4672 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4673 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4677 (define_insn "*neg<mode>2_fpr"
4678 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4679 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4684 [(set_attr "type" "fpsimple")])
4686 (define_expand "add<mode>3"
4687 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4688 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4689 (match_operand:SFDF 2 "gpc_reg_operand")))]
4693 (define_insn "*add<mode>3_fpr"
4694 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4695 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4696 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4700 xsadd<sd>p %x0,%x1,%x2"
4701 [(set_attr "type" "fp")
4702 (set_attr "isa" "*,<Fisa>")])
4704 (define_expand "sub<mode>3"
4705 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4706 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4707 (match_operand:SFDF 2 "gpc_reg_operand")))]
4711 (define_insn "*sub<mode>3_fpr"
4712 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4713 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4714 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4718 xssub<sd>p %x0,%x1,%x2"
4719 [(set_attr "type" "fp")
4720 (set_attr "isa" "*,<Fisa>")])
4722 (define_expand "mul<mode>3"
4723 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4724 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4725 (match_operand:SFDF 2 "gpc_reg_operand")))]
4729 (define_insn "*mul<mode>3_fpr"
4730 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4731 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4732 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4736 xsmul<sd>p %x0,%x1,%x2"
4737 [(set_attr "type" "dmul")
4738 (set_attr "isa" "*,<Fisa>")])
4740 (define_expand "div<mode>3"
4741 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4742 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4743 (match_operand:SFDF 2 "gpc_reg_operand")))]
4746 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4747 && can_create_pseudo_p () && flag_finite_math_only
4748 && !flag_trapping_math && flag_reciprocal_math)
4750 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4755 (define_insn "*div<mode>3_fpr"
4756 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4757 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4758 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4762 xsdiv<sd>p %x0,%x1,%x2"
4763 [(set_attr "type" "<sd>div")
4764 (set_attr "isa" "*,<Fisa>")])
4766 (define_insn "*sqrt<mode>2_internal"
4767 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4768 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4769 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4772 xssqrt<sd>p %x0,%x1"
4773 [(set_attr "type" "<sd>sqrt")
4774 (set_attr "isa" "*,<Fisa>")])
4776 (define_expand "sqrt<mode>2"
4777 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4778 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4779 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4781 if (<MODE>mode == SFmode
4782 && TARGET_RECIP_PRECISION
4783 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4784 && !optimize_function_for_size_p (cfun)
4785 && flag_finite_math_only && !flag_trapping_math
4786 && flag_unsafe_math_optimizations)
4788 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4793 ;; Floating point reciprocal approximation
4794 (define_insn "fre<sd>"
4795 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4796 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4802 [(set_attr "type" "fp")
4803 (set_attr "isa" "*,<Fisa>")])
4805 (define_insn "*rsqrt<mode>2"
4806 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4807 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4809 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4812 xsrsqrte<sd>p %x0,%x1"
4813 [(set_attr "type" "fp")
4814 (set_attr "isa" "*,<Fisa>")])
4816 ;; Floating point comparisons
4817 (define_insn "*cmp<mode>_fpr"
4818 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4819 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4820 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4824 xscmpudp %0,%x1,%x2"
4825 [(set_attr "type" "fpcompare")
4826 (set_attr "isa" "*,<Fisa>")])
4828 ;; Floating point conversions
4829 (define_expand "extendsfdf2"
4830 [(set (match_operand:DF 0 "gpc_reg_operand")
4831 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4834 if (HONOR_SNANS (SFmode))
4835 operands[1] = force_reg (SFmode, operands[1]);
4838 (define_insn_and_split "*extendsfdf2_fpr"
4839 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4840 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4841 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4847 xscpsgndp %x0,%x1,%x1
4850 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4853 emit_note (NOTE_INSN_DELETED);
4856 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4857 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4859 (define_insn "*extendsfdf2_snan"
4860 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4861 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4862 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4866 [(set_attr "type" "fp")
4867 (set_attr "isa" "*,p8v")])
4869 (define_expand "truncdfsf2"
4870 [(set (match_operand:SF 0 "gpc_reg_operand")
4871 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4875 (define_insn "*truncdfsf2_fpr"
4876 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4877 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4882 [(set_attr "type" "fp")
4883 (set_attr "isa" "*,p8v")])
4885 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4886 ;; builtins.c and optabs.c that are not correct for IBM long double
4887 ;; when little-endian.
4888 (define_expand "signbit<mode>2"
4890 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4892 (subreg:DI (match_dup 2) 0))
4895 (set (match_operand:SI 0 "gpc_reg_operand")
4898 && (!FLOAT128_IEEE_P (<MODE>mode)
4899 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4901 if (FLOAT128_IEEE_P (<MODE>mode))
4903 rtx dest = operands[0];
4904 rtx src = operands[1];
4905 rtx tmp = gen_reg_rtx (DImode);
4906 rtx dest_di = gen_lowpart (DImode, dest);
4908 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4909 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4912 operands[2] = gen_reg_rtx (DFmode);
4913 operands[3] = gen_reg_rtx (DImode);
4914 if (TARGET_POWERPC64)
4916 operands[4] = gen_reg_rtx (DImode);
4917 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4918 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4919 WORDS_BIG_ENDIAN ? 4 : 0);
4923 operands[4] = gen_reg_rtx (SImode);
4924 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4925 WORDS_BIG_ENDIAN ? 0 : 4);
4926 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4930 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4931 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4932 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4933 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4935 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4936 ;; split allows the post reload phases to eliminate the move, and do the shift
4937 ;; directly with the register that contains the signbit.
4938 (define_insn_and_split "@signbit<mode>2_dm"
4939 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4940 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4942 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4946 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4950 operands[2] = gen_highpart (DImode, operands[1]);
4952 [(set_attr "type" "mftgpr,*")])
4954 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4955 ;; register and then doing a direct move if the value comes from memory. On
4956 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4957 (define_insn_and_split "*signbit<mode>2_dm_mem"
4958 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4959 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4961 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4967 rtx dest = operands[0];
4968 rtx src = operands[1];
4969 rtx addr = XEXP (src, 0);
4971 if (WORDS_BIG_ENDIAN)
4972 operands[2] = adjust_address (src, DImode, 0);
4974 else if (REG_P (addr) || SUBREG_P (addr))
4975 operands[2] = adjust_address (src, DImode, 8);
4977 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4978 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4979 operands[2] = adjust_address (src, DImode, 8);
4983 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4984 emit_insn (gen_rtx_SET (tmp, addr));
4985 operands[2] = change_address (src, DImode,
4986 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4990 (define_expand "copysign<mode>3"
4992 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4994 (neg:SFDF (abs:SFDF (match_dup 1))))
4995 (set (match_operand:SFDF 0 "gpc_reg_operand")
4996 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5001 && ((TARGET_PPC_GFXOPT
5002 && !HONOR_NANS (<MODE>mode)
5003 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5005 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5007 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5009 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5014 operands[3] = gen_reg_rtx (<MODE>mode);
5015 operands[4] = gen_reg_rtx (<MODE>mode);
5016 operands[5] = CONST0_RTX (<MODE>mode);
5019 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5020 ;; compiler from optimizing -0.0
5021 (define_insn "copysign<mode>3_fcpsgn"
5022 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5023 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5024 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5026 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5029 xscpsgndp %x0,%x2,%x1"
5030 [(set_attr "type" "fpsimple")])
5032 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5033 ;; fsel instruction and some auxiliary computations. Then we just have a
5034 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5036 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5037 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5038 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5039 ;; define_splits to make them if made by combine. On VSX machines we have the
5040 ;; min/max instructions.
5042 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5043 ;; to allow either DF/SF to use only traditional registers.
5045 (define_expand "s<minmax><mode>3"
5046 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5047 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5048 (match_operand:SFDF 2 "gpc_reg_operand")))]
5051 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5055 (define_insn "*s<minmax><mode>3_vsx"
5056 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5057 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5058 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5059 "TARGET_VSX && TARGET_HARD_FLOAT"
5061 return (TARGET_P9_MINMAX
5062 ? "xs<minmax>cdp %x0,%x1,%x2"
5063 : "xs<minmax>dp %x0,%x1,%x2");
5065 [(set_attr "type" "fp")])
5067 ;; The conditional move instructions allow us to perform max and min operations
5068 ;; even when we don't have the appropriate max/min instruction using the FSEL
5071 (define_insn_and_split "*s<minmax><mode>3_fpr"
5072 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5073 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5074 (match_operand:SFDF 2 "gpc_reg_operand")))]
5075 "!TARGET_VSX && TARGET_MINMAX"
5080 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5084 (define_expand "mov<mode>cc"
5085 [(set (match_operand:GPR 0 "gpc_reg_operand")
5086 (if_then_else:GPR (match_operand 1 "comparison_operator")
5087 (match_operand:GPR 2 "gpc_reg_operand")
5088 (match_operand:GPR 3 "gpc_reg_operand")))]
5091 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5097 ;; We use the BASE_REGS for the isel input operands because, if rA is
5098 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5099 ;; because we may switch the operands and rB may end up being rA.
5101 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5102 ;; leave out the mode in operand 4 and use one pattern, but reload can
5103 ;; change the mode underneath our feet and then gets confused trying
5104 ;; to reload the value.
5105 (define_mode_iterator CCEITHER [CC CCUNS])
5106 (define_mode_attr un [(CC "") (CCUNS "un")])
5107 (define_insn "isel_<un>signed_<GPR:mode>"
5108 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5110 (match_operator 1 "scc_comparison_operator"
5111 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5113 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5114 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5117 [(set_attr "type" "isel")])
5119 ;; These patterns can be useful for combine; they let combine know that
5120 ;; isel can handle reversed comparisons so long as the operands are
5123 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5124 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5126 (match_operator 1 "scc_rev_comparison_operator"
5127 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5129 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5130 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5133 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5134 return "isel %0,%3,%2,%j1";
5136 [(set_attr "type" "isel")])
5138 ;; Floating point conditional move
5139 (define_expand "mov<mode>cc"
5140 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5141 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5142 (match_operand:SFDF 2 "gpc_reg_operand")
5143 (match_operand:SFDF 3 "gpc_reg_operand")))]
5144 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5146 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5152 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5153 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5155 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5156 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5157 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5158 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5159 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5161 [(set_attr "type" "fp")])
5163 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5164 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5166 (match_operator:CCFP 1 "fpmask_comparison_operator"
5167 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5168 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5169 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5170 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5171 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5176 (if_then_else:V2DI (match_dup 1)
5180 (if_then_else:SFDF (ne (match_dup 6)
5185 if (GET_CODE (operands[6]) == SCRATCH)
5186 operands[6] = gen_reg_rtx (V2DImode);
5188 operands[7] = CONSTM1_RTX (V2DImode);
5189 operands[8] = CONST0_RTX (V2DImode);
5191 [(set_attr "length" "8")
5192 (set_attr "type" "vecperm")])
5194 ;; Handle inverting the fpmask comparisons.
5195 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5196 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5198 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5199 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5200 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5201 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5202 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5203 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5208 (if_then_else:V2DI (match_dup 9)
5212 (if_then_else:SFDF (ne (match_dup 6)
5217 rtx op1 = operands[1];
5218 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5220 if (GET_CODE (operands[6]) == SCRATCH)
5221 operands[6] = gen_reg_rtx (V2DImode);
5223 operands[7] = CONSTM1_RTX (V2DImode);
5224 operands[8] = CONST0_RTX (V2DImode);
5226 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5228 [(set_attr "length" "8")
5229 (set_attr "type" "vecperm")])
5231 (define_insn "*fpmask<mode>"
5232 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5234 (match_operator:CCFP 1 "fpmask_comparison_operator"
5235 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5236 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5237 (match_operand:V2DI 4 "all_ones_constant" "")
5238 (match_operand:V2DI 5 "zero_constant" "")))]
5240 "xscmp%V1dp %x0,%x2,%x3"
5241 [(set_attr "type" "fpcompare")])
5243 (define_insn "*xxsel<mode>"
5244 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5245 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5246 (match_operand:V2DI 2 "zero_constant" ""))
5247 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5248 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5250 "xxsel %x0,%x4,%x3,%x1"
5251 [(set_attr "type" "vecmove")])
5254 ;; Conversions to and from floating-point.
5256 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5257 ; don't want to support putting SImode in FPR registers.
5258 (define_insn "lfiwax"
5259 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5260 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5262 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5268 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5269 (set_attr "isa" "*,p8v,p8v,p9v")])
5271 ; This split must be run before register allocation because it allocates the
5272 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5273 ; it earlier to allow for the combiner to merge insns together where it might
5274 ; not be needed and also in case the insns are deleted as dead code.
5276 (define_insn_and_split "floatsi<mode>2_lfiwax"
5277 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5278 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5279 (clobber (match_scratch:DI 2 "=d,wa"))]
5280 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5281 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5286 rtx dest = operands[0];
5287 rtx src = operands[1];
5290 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5291 tmp = convert_to_mode (DImode, src, false);
5295 if (GET_CODE (tmp) == SCRATCH)
5296 tmp = gen_reg_rtx (DImode);
5299 src = rs6000_force_indexed_or_indirect_mem (src);
5300 emit_insn (gen_lfiwax (tmp, src));
5304 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5305 emit_move_insn (stack, src);
5306 emit_insn (gen_lfiwax (tmp, stack));
5309 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5312 [(set_attr "length" "12")
5313 (set_attr "type" "fpload")])
5315 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5316 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5319 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5320 (clobber (match_scratch:DI 2 "=d,wa"))]
5321 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5326 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5327 if (GET_CODE (operands[2]) == SCRATCH)
5328 operands[2] = gen_reg_rtx (DImode);
5329 if (TARGET_P8_VECTOR)
5330 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5332 emit_insn (gen_lfiwax (operands[2], operands[1]));
5333 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5336 [(set_attr "length" "8")
5337 (set_attr "type" "fpload")])
5339 (define_insn "lfiwzx"
5340 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5341 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5343 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5348 xxextractuw %x0,%x1,4"
5349 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5350 (set_attr "isa" "*,p8v,p8v,p9v")])
5352 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5353 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5354 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5355 (clobber (match_scratch:DI 2 "=d,wa"))]
5356 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5361 rtx dest = operands[0];
5362 rtx src = operands[1];
5365 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5366 tmp = convert_to_mode (DImode, src, true);
5370 if (GET_CODE (tmp) == SCRATCH)
5371 tmp = gen_reg_rtx (DImode);
5374 src = rs6000_force_indexed_or_indirect_mem (src);
5375 emit_insn (gen_lfiwzx (tmp, src));
5379 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5380 emit_move_insn (stack, src);
5381 emit_insn (gen_lfiwzx (tmp, stack));
5384 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5387 [(set_attr "length" "12")
5388 (set_attr "type" "fpload")])
5390 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5391 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5392 (unsigned_float:SFDF
5394 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5395 (clobber (match_scratch:DI 2 "=d,wa"))]
5396 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5401 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5402 if (GET_CODE (operands[2]) == SCRATCH)
5403 operands[2] = gen_reg_rtx (DImode);
5404 if (TARGET_P8_VECTOR)
5405 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5407 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5408 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5411 [(set_attr "length" "8")
5412 (set_attr "type" "fpload")])
5414 ; For each of these conversions, there is a define_expand, a define_insn
5415 ; with a '#' template, and a define_split (with C code). The idea is
5416 ; to allow constant folding with the template of the define_insn,
5417 ; then to have the insns split later (between sched1 and final).
5419 (define_expand "floatsidf2"
5420 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5421 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5424 (clobber (match_dup 4))
5425 (clobber (match_dup 5))
5426 (clobber (match_dup 6))])]
5429 if (TARGET_LFIWAX && TARGET_FCFID)
5431 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5434 else if (TARGET_FCFID)
5436 rtx dreg = operands[1];
5438 dreg = force_reg (SImode, dreg);
5439 dreg = convert_to_mode (DImode, dreg, false);
5440 emit_insn (gen_floatdidf2 (operands[0], dreg));
5444 if (!REG_P (operands[1]))
5445 operands[1] = force_reg (SImode, operands[1]);
5446 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5447 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5448 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5449 operands[5] = gen_reg_rtx (DFmode);
5450 operands[6] = gen_reg_rtx (SImode);
5453 (define_insn_and_split "*floatsidf2_internal"
5454 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5455 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5456 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5457 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5458 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5459 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5460 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5461 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5466 rtx lowword, highword;
5467 gcc_assert (MEM_P (operands[4]));
5468 highword = adjust_address (operands[4], SImode, 0);
5469 lowword = adjust_address (operands[4], SImode, 4);
5470 if (! WORDS_BIG_ENDIAN)
5471 std::swap (lowword, highword);
5473 emit_insn (gen_xorsi3 (operands[6], operands[1],
5474 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5475 emit_move_insn (lowword, operands[6]);
5476 emit_move_insn (highword, operands[2]);
5477 emit_move_insn (operands[5], operands[4]);
5478 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5481 [(set_attr "length" "24")
5482 (set_attr "type" "fp")])
5484 ;; If we don't have a direct conversion to single precision, don't enable this
5485 ;; conversion for 32-bit without fast math, because we don't have the insn to
5486 ;; generate the fixup swizzle to avoid double rounding problems.
5487 (define_expand "floatunssisf2"
5488 [(set (match_operand:SF 0 "gpc_reg_operand")
5489 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5491 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5493 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5495 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5497 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5502 rtx dreg = operands[1];
5504 dreg = force_reg (SImode, dreg);
5505 dreg = convert_to_mode (DImode, dreg, true);
5506 emit_insn (gen_floatdisf2 (operands[0], dreg));
5511 (define_expand "floatunssidf2"
5512 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5513 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5516 (clobber (match_dup 4))
5517 (clobber (match_dup 5))])]
5520 if (TARGET_LFIWZX && TARGET_FCFID)
5522 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5525 else if (TARGET_FCFID)
5527 rtx dreg = operands[1];
5529 dreg = force_reg (SImode, dreg);
5530 dreg = convert_to_mode (DImode, dreg, true);
5531 emit_insn (gen_floatdidf2 (operands[0], dreg));
5535 if (!REG_P (operands[1]))
5536 operands[1] = force_reg (SImode, operands[1]);
5537 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5538 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5539 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5540 operands[5] = gen_reg_rtx (DFmode);
5543 (define_insn_and_split "*floatunssidf2_internal"
5544 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5545 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5546 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5547 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5548 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5549 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5550 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5551 && !(TARGET_FCFID && TARGET_POWERPC64)"
5556 rtx lowword, highword;
5557 gcc_assert (MEM_P (operands[4]));
5558 highword = adjust_address (operands[4], SImode, 0);
5559 lowword = adjust_address (operands[4], SImode, 4);
5560 if (! WORDS_BIG_ENDIAN)
5561 std::swap (lowword, highword);
5563 emit_move_insn (lowword, operands[1]);
5564 emit_move_insn (highword, operands[2]);
5565 emit_move_insn (operands[5], operands[4]);
5566 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5569 [(set_attr "length" "20")
5570 (set_attr "type" "fp")])
5572 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5573 ;; vector registers. These insns favor doing the sign/zero extension in
5574 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5575 ;; extension and then a direct move.
5577 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5578 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5580 (match_operand:QHI 1 "input_operand")))
5581 (clobber (match_scratch:DI 2))
5582 (clobber (match_scratch:DI 3))
5583 (clobber (match_scratch:<QHI:MODE> 4))])]
5584 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5586 if (MEM_P (operands[1]))
5587 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5590 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5591 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5593 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5594 (clobber (match_scratch:DI 2 "=v,wa,v"))
5595 (clobber (match_scratch:DI 3 "=X,r,X"))
5596 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5597 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5599 "&& reload_completed"
5602 rtx result = operands[0];
5603 rtx input = operands[1];
5604 rtx di = operands[2];
5608 rtx tmp = operands[3];
5609 if (altivec_register_operand (input, <QHI:MODE>mode))
5610 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5611 else if (GET_CODE (tmp) == SCRATCH)
5612 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5615 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5616 emit_move_insn (di, tmp);
5621 rtx tmp = operands[4];
5622 emit_move_insn (tmp, input);
5623 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5626 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5629 [(set_attr "isa" "p9v,*,p9v")])
5631 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5632 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5633 (unsigned_float:FP_ISA3
5634 (match_operand:QHI 1 "input_operand")))
5635 (clobber (match_scratch:DI 2))
5636 (clobber (match_scratch:DI 3))])]
5637 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5639 if (MEM_P (operands[1]))
5640 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5643 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5644 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5645 (unsigned_float:FP_ISA3
5646 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5647 (clobber (match_scratch:DI 2 "=v,wa,wa"))
5648 (clobber (match_scratch:DI 3 "=X,r,X"))]
5649 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5651 "&& reload_completed"
5654 rtx result = operands[0];
5655 rtx input = operands[1];
5656 rtx di = operands[2];
5658 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5659 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5662 rtx tmp = operands[3];
5663 if (GET_CODE (tmp) == SCRATCH)
5664 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5667 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5668 emit_move_insn (di, tmp);
5672 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5675 [(set_attr "isa" "p9v,*,p9v")])
5677 (define_expand "fix_trunc<mode>si2"
5678 [(set (match_operand:SI 0 "gpc_reg_operand")
5679 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5682 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5684 rtx src = force_reg (<MODE>mode, operands[1]);
5687 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5690 rtx tmp = gen_reg_rtx (DImode);
5691 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5692 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5699 ; Like the convert to float patterns, this insn must be split before
5700 ; register allocation so that it can allocate the memory slot if it
5702 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5703 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5704 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5705 (clobber (match_scratch:DI 2 "=d"))]
5706 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5707 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5712 rtx dest = operands[0];
5713 rtx src = operands[1];
5714 rtx tmp = operands[2];
5716 if (GET_CODE (tmp) == SCRATCH)
5717 tmp = gen_reg_rtx (DImode);
5719 emit_insn (gen_fctiwz_<mode> (tmp, src));
5720 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5722 dest = rs6000_force_indexed_or_indirect_mem (dest);
5723 emit_insn (gen_stfiwx (dest, tmp));
5726 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5728 dest = gen_lowpart (DImode, dest);
5729 emit_move_insn (dest, tmp);
5734 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5735 emit_insn (gen_stfiwx (stack, tmp));
5736 emit_move_insn (dest, stack);
5740 [(set_attr "length" "12")
5741 (set_attr "type" "fp")])
5743 (define_insn_and_split "fix_trunc<mode>si2_internal"
5744 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5745 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5746 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5747 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5749 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5755 gcc_assert (MEM_P (operands[3]));
5756 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5758 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5759 emit_move_insn (operands[3], operands[2]);
5760 emit_move_insn (operands[0], lowword);
5763 [(set_attr "length" "16")
5764 (set_attr "type" "fp")])
5766 (define_expand "fix_trunc<mode>di2"
5767 [(set (match_operand:DI 0 "gpc_reg_operand")
5768 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5769 "TARGET_HARD_FLOAT && TARGET_FCFID"
5772 (define_insn "*fix_trunc<mode>di2_fctidz"
5773 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5774 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5775 "TARGET_HARD_FLOAT && TARGET_FCFID"
5779 [(set_attr "type" "fp")])
5781 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5782 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5783 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5784 ;; values can go in VSX registers. Keeping the direct move part through
5785 ;; register allocation prevents the register allocator from doing a direct move
5786 ;; of the SImode value to a GPR, and then a store/load.
5787 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5788 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5789 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5790 (clobber (match_scratch:SI 2 "=X,X,wa"))]
5791 "TARGET_DIRECT_MOVE"
5794 xscvdp<su>xws %x0,%x1
5796 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5798 (any_fix:SI (match_dup 1)))
5802 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5804 [(set_attr "type" "fp")
5805 (set_attr "length" "4,4,8")
5806 (set_attr "isa" "p9v,p9v,*")])
5808 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5809 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5810 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5811 "TARGET_DIRECT_MOVE"
5814 xscvdp<su>xws %x0,%x1"
5815 [(set_attr "type" "fp")])
5817 ;; Keep the convert and store together through register allocation to prevent
5818 ;; the register allocator from getting clever and doing a direct move to a GPR
5819 ;; and then store for reg+offset stores.
5820 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5821 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5822 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5823 (clobber (match_scratch:SI 2 "=wa"))]
5824 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5826 "&& reload_completed"
5828 (any_fix:SI (match_dup 1)))
5832 operands[3] = (<QHSI:MODE>mode == SImode
5834 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5837 (define_expand "fixuns_trunc<mode>si2"
5838 [(set (match_operand:SI 0 "gpc_reg_operand")
5839 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5840 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5842 if (!TARGET_P8_VECTOR)
5844 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5849 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5850 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5851 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5852 (clobber (match_scratch:DI 2 "=d"))]
5853 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5854 && TARGET_STFIWX && can_create_pseudo_p ()
5855 && !TARGET_P8_VECTOR"
5860 rtx dest = operands[0];
5861 rtx src = operands[1];
5862 rtx tmp = operands[2];
5864 if (GET_CODE (tmp) == SCRATCH)
5865 tmp = gen_reg_rtx (DImode);
5867 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5870 dest = rs6000_force_indexed_or_indirect_mem (dest);
5871 emit_insn (gen_stfiwx (dest, tmp));
5874 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5876 dest = gen_lowpart (DImode, dest);
5877 emit_move_insn (dest, tmp);
5882 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5883 emit_insn (gen_stfiwx (stack, tmp));
5884 emit_move_insn (dest, stack);
5888 [(set_attr "length" "12")
5889 (set_attr "type" "fp")])
5891 (define_insn "fixuns_trunc<mode>di2"
5892 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5893 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5894 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5898 [(set_attr "type" "fp")])
5900 (define_insn "rs6000_mtfsb0"
5901 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5905 [(set_attr "type" "fp")])
5907 (define_insn "rs6000_mtfsb1"
5908 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5912 [(set_attr "type" "fp")])
5914 (define_insn "rs6000_mffscrn"
5915 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5916 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5920 [(set_attr "type" "fp")])
5922 (define_insn "rs6000_mffscdrn"
5923 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5924 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5925 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5928 [(set_attr "type" "fp")])
5930 (define_expand "rs6000_set_fpscr_rn"
5931 [(match_operand:DI 0 "reg_or_cint_operand")]
5934 rtx tmp_df = gen_reg_rtx (DFmode);
5936 /* The floating point rounding control bits are FPSCR[62:63]. Put the
5937 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
5940 rtx src_df = force_reg (DImode, operands[0]);
5941 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5942 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5946 if (CONST_INT_P (operands[0]))
5948 if ((INTVAL (operands[0]) & 0x1) == 0x1)
5949 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5951 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5953 if ((INTVAL (operands[0]) & 0x2) == 0x2)
5954 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5956 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5960 rtx tmp_rn = gen_reg_rtx (DImode);
5961 rtx tmp_di = gen_reg_rtx (DImode);
5963 /* Extract new RN mode from operand. */
5964 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5966 /* Insert new RN mode into FSCPR. */
5967 emit_insn (gen_rs6000_mffs (tmp_df));
5968 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5969 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5970 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5972 /* Need to write to field k=15. The fields are [0:15]. Hence with
5973 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
5974 8-bit field[0:7]. Need to set the bit that corresponds to the
5975 value of i that you want [0:7]. */
5976 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5977 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5982 (define_expand "rs6000_set_fpscr_drn"
5983 [(match_operand:DI 0 "gpc_reg_operand")]
5986 rtx tmp_df = gen_reg_rtx (DFmode);
5988 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5989 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
5992 rtx src_df = gen_reg_rtx (DFmode);
5994 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5995 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5996 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6000 rtx tmp_rn = gen_reg_rtx (DImode);
6001 rtx tmp_di = gen_reg_rtx (DImode);
6003 /* Extract new DRN mode from operand. */
6004 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6005 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6007 /* Insert new RN mode into FSCPR. */
6008 emit_insn (gen_rs6000_mffs (tmp_df));
6009 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6010 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
6011 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6013 /* Need to write to field 7. The fields are [0:15]. The equation to
6014 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6015 i to 0x1 to get field 7 where i selects the field. */
6016 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6017 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6022 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6023 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6024 ;; because the first makes it clear that operand 0 is not live
6025 ;; before the instruction.
6026 (define_insn "fctiwz_<mode>"
6027 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6029 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6035 [(set_attr "type" "fp")])
6037 (define_insn "fctiwuz_<mode>"
6038 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6039 (unspec:DI [(unsigned_fix:SI
6040 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6042 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6046 [(set_attr "type" "fp")])
6048 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6049 ;; since the friz instruction does not truncate the value if the floating
6050 ;; point value is < LONG_MIN or > LONG_MAX.
6051 (define_insn "*friz"
6052 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6053 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6054 "TARGET_HARD_FLOAT && TARGET_FPRND
6055 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6059 [(set_attr "type" "fp")])
6061 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6062 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6063 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6064 ;; extend it, store it back on the stack from the GPR, load it back into the
6065 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6066 ;; disable using store and load to sign/zero extend the value.
6067 (define_insn_and_split "*round32<mode>2_fprs"
6068 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6070 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6071 (clobber (match_scratch:DI 2 "=d"))
6072 (clobber (match_scratch:DI 3 "=d"))]
6074 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6075 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6080 rtx dest = operands[0];
6081 rtx src = operands[1];
6082 rtx tmp1 = operands[2];
6083 rtx tmp2 = operands[3];
6084 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6086 if (GET_CODE (tmp1) == SCRATCH)
6087 tmp1 = gen_reg_rtx (DImode);
6088 if (GET_CODE (tmp2) == SCRATCH)
6089 tmp2 = gen_reg_rtx (DImode);
6091 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6092 emit_insn (gen_stfiwx (stack, tmp1));
6093 emit_insn (gen_lfiwax (tmp2, stack));
6094 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6097 [(set_attr "type" "fpload")
6098 (set_attr "length" "16")])
6100 (define_insn_and_split "*roundu32<mode>2_fprs"
6101 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6102 (unsigned_float:SFDF
6103 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6104 (clobber (match_scratch:DI 2 "=d"))
6105 (clobber (match_scratch:DI 3 "=d"))]
6107 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6108 && can_create_pseudo_p ()"
6113 rtx dest = operands[0];
6114 rtx src = operands[1];
6115 rtx tmp1 = operands[2];
6116 rtx tmp2 = operands[3];
6117 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6119 if (GET_CODE (tmp1) == SCRATCH)
6120 tmp1 = gen_reg_rtx (DImode);
6121 if (GET_CODE (tmp2) == SCRATCH)
6122 tmp2 = gen_reg_rtx (DImode);
6124 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6125 emit_insn (gen_stfiwx (stack, tmp1));
6126 emit_insn (gen_lfiwzx (tmp2, stack));
6127 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6130 [(set_attr "type" "fpload")
6131 (set_attr "length" "16")])
6133 ;; No VSX equivalent to fctid
6134 (define_insn "lrint<mode>di2"
6135 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6136 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6138 "TARGET_HARD_FLOAT && TARGET_FPRND"
6140 [(set_attr "type" "fp")])
6142 (define_insn "btrunc<mode>2"
6143 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6144 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6146 "TARGET_HARD_FLOAT && TARGET_FPRND"
6150 [(set_attr "type" "fp")])
6152 (define_insn "ceil<mode>2"
6153 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6154 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6156 "TARGET_HARD_FLOAT && TARGET_FPRND"
6160 [(set_attr "type" "fp")])
6162 (define_insn "floor<mode>2"
6163 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6164 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6166 "TARGET_HARD_FLOAT && TARGET_FPRND"
6170 [(set_attr "type" "fp")])
6172 ;; No VSX equivalent to frin
6173 (define_insn "round<mode>2"
6174 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6175 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6177 "TARGET_HARD_FLOAT && TARGET_FPRND"
6179 [(set_attr "type" "fp")])
6181 (define_insn "*xsrdpi<mode>2"
6182 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6183 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6185 "TARGET_HARD_FLOAT && TARGET_VSX"
6187 [(set_attr "type" "fp")])
6189 (define_expand "lround<mode>di2"
6191 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6193 (set (match_operand:DI 0 "gpc_reg_operand")
6194 (unspec:DI [(match_dup 2)]
6196 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6198 operands[2] = gen_reg_rtx (<MODE>mode);
6201 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6202 (define_insn "stfiwx"
6203 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6204 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6210 [(set_attr "type" "fpstore")
6211 (set_attr "isa" "*,p8v")])
6213 ;; If we don't have a direct conversion to single precision, don't enable this
6214 ;; conversion for 32-bit without fast math, because we don't have the insn to
6215 ;; generate the fixup swizzle to avoid double rounding problems.
6216 (define_expand "floatsisf2"
6217 [(set (match_operand:SF 0 "gpc_reg_operand")
6218 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6220 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6222 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6224 if (TARGET_FCFIDS && TARGET_LFIWAX)
6226 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6229 else if (TARGET_FCFID && TARGET_LFIWAX)
6231 rtx dfreg = gen_reg_rtx (DFmode);
6232 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6233 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6238 rtx dreg = operands[1];
6240 dreg = force_reg (SImode, dreg);
6241 dreg = convert_to_mode (DImode, dreg, false);
6242 emit_insn (gen_floatdisf2 (operands[0], dreg));
6247 (define_insn "floatdidf2"
6248 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6249 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6250 "TARGET_FCFID && TARGET_HARD_FLOAT"
6254 [(set_attr "type" "fp")])
6256 ; Allow the combiner to merge source memory operands to the conversion so that
6257 ; the optimizer/register allocator doesn't try to load the value too early in a
6258 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6259 ; hit. We will split after reload to avoid the trip through the GPRs
6261 (define_insn_and_split "*floatdidf2_mem"
6262 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6263 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6264 (clobber (match_scratch:DI 2 "=d,wa"))]
6265 "TARGET_HARD_FLOAT && TARGET_FCFID"
6267 "&& reload_completed"
6268 [(set (match_dup 2) (match_dup 1))
6269 (set (match_dup 0) (float:DF (match_dup 2)))]
6271 [(set_attr "length" "8")
6272 (set_attr "type" "fpload")])
6274 (define_expand "floatunsdidf2"
6275 [(set (match_operand:DF 0 "gpc_reg_operand")
6277 (match_operand:DI 1 "gpc_reg_operand")))]
6278 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6281 (define_insn "*floatunsdidf2_fcfidu"
6282 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6283 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6284 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6288 [(set_attr "type" "fp")])
6290 (define_insn_and_split "*floatunsdidf2_mem"
6291 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6292 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6293 (clobber (match_scratch:DI 2 "=d,wa"))]
6294 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6296 "&& reload_completed"
6297 [(set (match_dup 2) (match_dup 1))
6298 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6300 [(set_attr "length" "8")
6301 (set_attr "type" "fpload")])
6303 (define_expand "floatdisf2"
6304 [(set (match_operand:SF 0 "gpc_reg_operand")
6305 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6306 "TARGET_FCFID && TARGET_HARD_FLOAT
6307 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6311 rtx val = operands[1];
6312 if (!flag_unsafe_math_optimizations)
6314 rtx label = gen_label_rtx ();
6315 val = gen_reg_rtx (DImode);
6316 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6319 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6324 (define_insn "floatdisf2_fcfids"
6325 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6326 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6327 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6331 [(set_attr "type" "fp")
6332 (set_attr "isa" "*,p8v")])
6334 (define_insn_and_split "*floatdisf2_mem"
6335 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6336 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6337 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6338 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6340 "&& reload_completed"
6343 emit_move_insn (operands[2], operands[1]);
6344 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6347 [(set_attr "length" "8")
6348 (set_attr "isa" "*,p8v,p8v")])
6350 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6351 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6352 ;; from double rounding.
6353 ;; Instead of creating a new cpu type for two FP operations, just use fp
6354 (define_insn_and_split "floatdisf2_internal1"
6355 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6356 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6357 (clobber (match_scratch:DF 2 "=d"))]
6358 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6360 "&& reload_completed"
6362 (float:DF (match_dup 1)))
6364 (float_truncate:SF (match_dup 2)))]
6366 [(set_attr "length" "8")
6367 (set_attr "type" "fp")])
6369 ;; Twiddles bits to avoid double rounding.
6370 ;; Bits that might be truncated when converting to DFmode are replaced
6371 ;; by a bit that won't be lost at that stage, but is below the SFmode
6372 ;; rounding position.
6373 (define_expand "floatdisf2_internal2"
6374 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6376 (clobber (reg:DI CA_REGNO))])
6377 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6379 (set (match_dup 3) (plus:DI (match_dup 3)
6381 (set (match_dup 0) (plus:DI (match_dup 0)
6383 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6385 (set (match_dup 0) (ior:DI (match_dup 0)
6387 (set (match_dup 0) (and:DI (match_dup 0)
6389 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6390 (label_ref (match_operand:DI 2 ""))
6392 (set (match_dup 0) (match_dup 1))]
6393 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6395 operands[3] = gen_reg_rtx (DImode);
6396 operands[4] = gen_reg_rtx (CCUNSmode);
6399 (define_expand "floatunsdisf2"
6400 [(set (match_operand:SF 0 "gpc_reg_operand")
6401 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6402 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6405 (define_insn "floatunsdisf2_fcfidus"
6406 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6407 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6408 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6412 [(set_attr "type" "fp")
6413 (set_attr "isa" "*,p8v")])
6415 (define_insn_and_split "*floatunsdisf2_mem"
6416 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6417 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6418 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6419 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6421 "&& reload_completed"
6424 emit_move_insn (operands[2], operands[1]);
6425 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6428 [(set_attr "type" "fpload")
6429 (set_attr "length" "8")
6430 (set_attr "isa" "*,p8v,p8v")])
6432 ;; Define the TImode operations that can be done in a small number
6433 ;; of instructions. The & constraints are to prevent the register
6434 ;; allocator from allocating registers that overlap with the inputs
6435 ;; (for example, having an input in 7,8 and an output in 6,7). We
6436 ;; also allow for the output being the same as one of the inputs.
6438 (define_expand "addti3"
6439 [(set (match_operand:TI 0 "gpc_reg_operand")
6440 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6441 (match_operand:TI 2 "reg_or_short_operand")))]
6444 rtx lo0 = gen_lowpart (DImode, operands[0]);
6445 rtx lo1 = gen_lowpart (DImode, operands[1]);
6446 rtx lo2 = gen_lowpart (DImode, operands[2]);
6447 rtx hi0 = gen_highpart (DImode, operands[0]);
6448 rtx hi1 = gen_highpart (DImode, operands[1]);
6449 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6451 if (!reg_or_short_operand (lo2, DImode))
6452 lo2 = force_reg (DImode, lo2);
6453 if (!adde_operand (hi2, DImode))
6454 hi2 = force_reg (DImode, hi2);
6456 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6457 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6461 (define_expand "subti3"
6462 [(set (match_operand:TI 0 "gpc_reg_operand")
6463 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6464 (match_operand:TI 2 "gpc_reg_operand")))]
6467 rtx lo0 = gen_lowpart (DImode, operands[0]);
6468 rtx lo1 = gen_lowpart (DImode, operands[1]);
6469 rtx lo2 = gen_lowpart (DImode, operands[2]);
6470 rtx hi0 = gen_highpart (DImode, operands[0]);
6471 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6472 rtx hi2 = gen_highpart (DImode, operands[2]);
6474 if (!reg_or_short_operand (lo1, DImode))
6475 lo1 = force_reg (DImode, lo1);
6476 if (!adde_operand (hi1, DImode))
6477 hi1 = force_reg (DImode, hi1);
6479 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6480 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6484 ;; 128-bit logical operations expanders
6486 (define_expand "and<mode>3"
6487 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6488 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6489 (match_operand:BOOL_128 2 "vlogical_operand")))]
6493 (define_expand "ior<mode>3"
6494 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6495 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6496 (match_operand:BOOL_128 2 "vlogical_operand")))]
6500 (define_expand "xor<mode>3"
6501 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6502 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6503 (match_operand:BOOL_128 2 "vlogical_operand")))]
6507 (define_expand "nor<mode>3"
6508 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6510 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6511 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6515 (define_expand "andc<mode>3"
6516 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6518 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6519 (match_operand:BOOL_128 1 "vlogical_operand")))]
6523 ;; Power8 vector logical instructions.
6524 (define_expand "eqv<mode>3"
6525 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6527 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6528 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6529 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6532 ;; Rewrite nand into canonical form
6533 (define_expand "nand<mode>3"
6534 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6536 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6537 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6538 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6541 ;; The canonical form is to have the negated element first, so we need to
6542 ;; reverse arguments.
6543 (define_expand "orc<mode>3"
6544 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6546 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6547 (match_operand:BOOL_128 1 "vlogical_operand")))]
6548 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6551 ;; 128-bit logical operations insns and split operations
6552 (define_insn_and_split "*and<mode>3_internal"
6553 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6555 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6556 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6559 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6560 return "xxland %x0,%x1,%x2";
6562 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6563 return "vand %0,%1,%2";
6567 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6570 rs6000_split_logical (operands, AND, false, false, false);
6575 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6576 (const_string "veclogical")
6577 (const_string "integer")))
6578 (set (attr "length")
6580 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6583 (match_test "TARGET_POWERPC64")
6585 (const_string "16"))))])
6588 (define_insn_and_split "*bool<mode>3_internal"
6589 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6590 (match_operator:BOOL_128 3 "boolean_or_operator"
6591 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6592 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6595 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6596 return "xxl%q3 %x0,%x1,%x2";
6598 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6599 return "v%q3 %0,%1,%2";
6603 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6606 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6611 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6612 (const_string "veclogical")
6613 (const_string "integer")))
6614 (set (attr "length")
6616 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6619 (match_test "TARGET_POWERPC64")
6621 (const_string "16"))))])
6624 (define_insn_and_split "*boolc<mode>3_internal1"
6625 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6626 (match_operator:BOOL_128 3 "boolean_operator"
6628 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6629 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6630 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6632 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6633 return "xxl%q3 %x0,%x1,%x2";
6635 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6636 return "v%q3 %0,%1,%2";
6640 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6641 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6644 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6649 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6650 (const_string "veclogical")
6651 (const_string "integer")))
6652 (set (attr "length")
6654 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6657 (match_test "TARGET_POWERPC64")
6659 (const_string "16"))))])
6661 (define_insn_and_split "*boolc<mode>3_internal2"
6662 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6663 (match_operator:TI2 3 "boolean_operator"
6665 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6666 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6667 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6669 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6672 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6675 [(set_attr "type" "integer")
6676 (set (attr "length")
6678 (match_test "TARGET_POWERPC64")
6680 (const_string "16")))])
6683 (define_insn_and_split "*boolcc<mode>3_internal1"
6684 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6685 (match_operator:BOOL_128 3 "boolean_operator"
6687 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6689 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6690 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6692 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6693 return "xxl%q3 %x0,%x1,%x2";
6695 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6696 return "v%q3 %0,%1,%2";
6700 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6701 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6704 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6709 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6710 (const_string "veclogical")
6711 (const_string "integer")))
6712 (set (attr "length")
6714 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6717 (match_test "TARGET_POWERPC64")
6719 (const_string "16"))))])
6721 (define_insn_and_split "*boolcc<mode>3_internal2"
6722 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6723 (match_operator:TI2 3 "boolean_operator"
6725 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6727 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6728 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6730 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6733 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6736 [(set_attr "type" "integer")
6737 (set (attr "length")
6739 (match_test "TARGET_POWERPC64")
6741 (const_string "16")))])
6745 (define_insn_and_split "*eqv<mode>3_internal1"
6746 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6749 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6750 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6753 if (vsx_register_operand (operands[0], <MODE>mode))
6754 return "xxleqv %x0,%x1,%x2";
6758 "TARGET_P8_VECTOR && reload_completed
6759 && int_reg_operand (operands[0], <MODE>mode)"
6762 rs6000_split_logical (operands, XOR, true, false, false);
6767 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6768 (const_string "veclogical")
6769 (const_string "integer")))
6770 (set (attr "length")
6772 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6775 (match_test "TARGET_POWERPC64")
6777 (const_string "16"))))])
6779 (define_insn_and_split "*eqv<mode>3_internal2"
6780 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6783 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6784 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6787 "reload_completed && !TARGET_P8_VECTOR"
6790 rs6000_split_logical (operands, XOR, true, false, false);
6793 [(set_attr "type" "integer")
6794 (set (attr "length")
6796 (match_test "TARGET_POWERPC64")
6798 (const_string "16")))])
6800 ;; 128-bit one's complement
6801 (define_insn_and_split "one_cmpl<mode>2"
6802 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6804 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6807 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6808 return "xxlnor %x0,%x1,%x1";
6810 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6811 return "vnor %0,%1,%1";
6815 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6818 rs6000_split_logical (operands, NOT, false, false, false);
6823 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6824 (const_string "veclogical")
6825 (const_string "integer")))
6826 (set (attr "length")
6828 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6831 (match_test "TARGET_POWERPC64")
6833 (const_string "16"))))])
6836 ;; Now define ways of moving data around.
6838 ;; Set up a register with a value from the GOT table
6840 (define_expand "movsi_got"
6841 [(set (match_operand:SI 0 "gpc_reg_operand")
6842 (unspec:SI [(match_operand:SI 1 "got_operand")
6843 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6844 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6846 if (GET_CODE (operands[1]) == CONST)
6848 rtx offset = const0_rtx;
6849 HOST_WIDE_INT value;
6851 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6852 value = INTVAL (offset);
6855 rtx tmp = (!can_create_pseudo_p ()
6857 : gen_reg_rtx (Pmode));
6858 emit_insn (gen_movsi_got (tmp, operands[1]));
6859 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6864 operands[2] = rs6000_got_register (operands[1]);
6867 (define_insn "*movsi_got_internal"
6868 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6869 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6870 (match_operand:SI 2 "gpc_reg_operand" "b")]
6872 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6873 "lwz %0,%a1@got(%2)"
6874 [(set_attr "type" "load")])
6876 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6877 ;; didn't get allocated to a hard register.
6879 [(set (match_operand:SI 0 "gpc_reg_operand")
6880 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6881 (match_operand:SI 2 "memory_operand")]
6883 "DEFAULT_ABI == ABI_V4
6885 && reload_completed"
6886 [(set (match_dup 0) (match_dup 2))
6887 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6891 ;; MR LA LWZ LFIWZX LXSIWZX
6892 ;; STW STFIWX STXSIWX LI LIS
6893 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6894 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6896 (define_insn "*movsi_internal1"
6897 [(set (match_operand:SI 0 "nonimmediate_operand"
6903 (match_operand:SI 1 "input_operand"
6909 "gpc_reg_operand (operands[0], SImode)
6910 || gpc_reg_operand (operands[1], SImode)"
6936 "*, *, load, fpload, fpload,
6937 store, fpstore, fpstore, *, *,
6938 *, veclogical, vecsimple, vecsimple, vecsimple,
6939 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6950 *, p8v, p9v, p9v, p8v,
6951 p9v, p8v, p9v, p8v, p8v,
6954 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6955 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6957 ;; Because SF values are actually stored as DF values within the vector
6958 ;; registers, we need to convert the value to the vector SF format when
6959 ;; we need to use the bits in a union or similar cases. We only need
6960 ;; to do this transformation when the value is a vector register. Loads,
6961 ;; stores, and transfers within GPRs are assumed to be safe.
6963 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6964 ;; no alternatives, because the call is created as part of secondary_reload,
6965 ;; and operand #2's register class is used to allocate the temporary register.
6966 ;; This function is called before reload, and it creates the temporary as
6969 ;; MR LWZ LFIWZX LXSIWZX STW
6970 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6973 (define_insn_and_split "movsi_from_sf"
6974 [(set (match_operand:SI 0 "nonimmediate_operand"
6975 "=r, r, ?*d, ?*v, m,
6978 (unspec:SI [(match_operand:SF 1 "input_operand"
6983 (clobber (match_scratch:V4SF 2
6987 "TARGET_NO_SF_SUBREG
6988 && (register_operand (operands[0], SImode)
6989 || register_operand (operands[1], SFmode))"
7002 "&& reload_completed
7003 && int_reg_operand (operands[0], SImode)
7004 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7007 rtx op0 = operands[0];
7008 rtx op1 = operands[1];
7009 rtx op2 = operands[2];
7010 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7011 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7013 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7014 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7018 "*, load, fpload, fpload, store,
7019 fpstore, fpstore, fpstore, mftgpr, fp,
7027 *, p9v, p8v, p8v, p8v,
7030 ;; movsi_from_sf with zero extension
7032 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7035 (define_insn_and_split "*movdi_from_sf_zero_ext"
7036 [(set (match_operand:DI 0 "gpc_reg_operand"
7037 "=r, r, ?*d, ?*v, r,
7040 (unspec:SI [(match_operand:SF 1 "input_operand"
7043 UNSPEC_SI_FROM_SF)))
7044 (clobber (match_scratch:V4SF 2
7047 "TARGET_DIRECT_MOVE_64BIT
7048 && (register_operand (operands[0], DImode)
7049 || register_operand (operands[1], SImode))"
7058 "&& reload_completed
7059 && register_operand (operands[0], DImode)
7060 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7063 rtx op0 = operands[0];
7064 rtx op1 = operands[1];
7065 rtx op2 = operands[2];
7066 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7068 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7069 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7073 "*, load, fpload, fpload, two,
7079 "*, *, p8v, p8v, p8v,
7082 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7083 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7084 ;; conversion explicitly since that doesn't work in most cases if the input
7085 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7086 ;; former handles cases where the input will not fit in a SFmode, and the
7087 ;; latter assumes the value has already been rounded.
7088 (define_insn "*movsi_from_df"
7089 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7090 (unspec:SI [(float_truncate:SF
7091 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7092 UNSPEC_SI_FROM_SF))]
7093 "TARGET_NO_SF_SUBREG"
7095 [(set_attr "type" "fp")])
7097 ;; Split a load of a large constant into the appropriate two-insn
7101 [(set (match_operand:SI 0 "gpc_reg_operand")
7102 (match_operand:SI 1 "const_int_operand"))]
7103 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7104 && (INTVAL (operands[1]) & 0xffff) != 0"
7108 (ior:SI (match_dup 0)
7111 if (rs6000_emit_set_const (operands[0], operands[1]))
7117 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7119 [(set (match_operand:DI 0 "altivec_register_operand")
7120 (match_operand:DI 1 "xxspltib_constant_split"))]
7121 "TARGET_P9_VECTOR && reload_completed"
7124 rtx op0 = operands[0];
7125 rtx op1 = operands[1];
7126 int r = REGNO (op0);
7127 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7129 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7130 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7134 (define_insn "*mov<mode>_internal2"
7135 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7136 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7138 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7144 [(set_attr "type" "cmp,logical,cmp")
7145 (set_attr "dot" "yes")
7146 (set_attr "length" "4,4,8")])
7149 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7150 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7152 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7154 [(set (match_dup 0) (match_dup 1))
7156 (compare:CC (match_dup 0)
7160 (define_expand "mov<mode>"
7161 [(set (match_operand:INT 0 "general_operand")
7162 (match_operand:INT 1 "any_operand"))]
7165 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7169 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7170 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7171 ;; MTVSRWZ MF%1 MT%1 NOP
7172 (define_insn "*mov<mode>_internal"
7173 [(set (match_operand:QHI 0 "nonimmediate_operand"
7174 "=r, r, wa, m, Z, r,
7175 wa, wa, wa, v, ?v, r,
7177 (match_operand:QHI 1 "input_operand"
7179 wa, O, wM, wB, wS, wa,
7181 "gpc_reg_operand (operands[0], <MODE>mode)
7182 || gpc_reg_operand (operands[1], <MODE>mode)"
7201 "*, load, fpload, store, fpstore, *,
7202 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7203 mffgpr, mfjmpr, mtjmpr, *")
7209 "*, *, p9v, *, p9v, *,
7210 p9v, p9v, p9v, p9v, p9v, p9v,
7214 ;; Here is how to move condition codes around. When we store CC data in
7215 ;; an integer register or memory, we store just the high-order 4 bits.
7216 ;; This lets us not shift in the most common case of CR0.
7217 (define_expand "movcc"
7218 [(set (match_operand:CC 0 "nonimmediate_operand")
7219 (match_operand:CC 1 "nonimmediate_operand"))]
7223 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7225 (define_insn "*movcc_<mode>"
7226 [(set (match_operand:CC_any 0 "nonimmediate_operand"
7227 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7228 (match_operand:CC_any 1 "general_operand"
7229 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7230 "register_operand (operands[0], <MODE>mode)
7231 || register_operand (operands[1], <MODE>mode)"
7235 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7238 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7245 [(set_attr_alternative "type"
7246 [(const_string "cr_logical")
7247 (const_string "mtcr")
7248 (const_string "mtcr")
7249 (const_string "cr_logical")
7250 (if_then_else (match_test "TARGET_MFCRF")
7251 (const_string "mfcrf") (const_string "mfcr"))
7252 (if_then_else (match_test "TARGET_MFCRF")
7253 (const_string "mfcrf") (const_string "mfcr"))
7254 (const_string "integer")
7255 (const_string "integer")
7256 (const_string "mfjmpr")
7257 (const_string "mtjmpr")
7258 (const_string "load")
7259 (const_string "store")])
7260 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7262 ;; For floating-point, we normally deal with the floating-point registers
7263 ;; unless -msoft-float is used. The sole exception is that parameter passing
7264 ;; can produce floating-point values in fixed-point registers. Unless the
7265 ;; value is a simple constant or already in memory, we deal with this by
7266 ;; allocating memory and copying the value explicitly via that memory location.
7268 ;; Move 32-bit binary/decimal floating point
7269 (define_expand "mov<mode>"
7270 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7271 (match_operand:FMOVE32 1 "any_operand"))]
7274 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7279 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7280 (match_operand:FMOVE32 1 "const_double_operand"))]
7282 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7283 || (SUBREG_P (operands[0])
7284 && REG_P (SUBREG_REG (operands[0]))
7285 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7286 [(set (match_dup 2) (match_dup 3))]
7290 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7292 if (! TARGET_POWERPC64)
7293 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7295 operands[2] = gen_lowpart (SImode, operands[0]);
7297 operands[3] = gen_int_mode (l, SImode);
7300 ;; Originally, we tried to keep movsf and movsd common, but the differences
7301 ;; addressing was making it rather difficult to hide with mode attributes. In
7302 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7303 ;; before the VSX stores meant that the register allocator would tend to do a
7304 ;; direct move to the GPR (which involves conversion from scalar to
7305 ;; vector/memory formats) to save values in the traditional Altivec registers,
7306 ;; while SDmode had problems on power6 if the GPR store was not first due to
7307 ;; the power6 not having an integer store operation.
7309 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7310 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7311 ;; MR MT<x> MF<x> NOP
7313 (define_insn "movsf_hardfloat"
7314 [(set (match_operand:SF 0 "nonimmediate_operand"
7315 "=!r, f, v, wa, m, wY,
7316 Z, m, wa, !r, f, wa,
7318 (match_operand:SF 1 "input_operand"
7322 "(register_operand (operands[0], SFmode)
7323 || register_operand (operands[1], SFmode))
7324 && TARGET_HARD_FLOAT
7325 && (TARGET_ALLOW_SF_SUBREG
7326 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7339 xscpsgndp %x0,%x1,%x1
7345 "load, fpload, fpload, fpload, fpstore, fpstore,
7346 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7347 *, mtjmpr, mfjmpr, *")
7349 "*, *, p9v, p8v, *, p9v,
7353 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7354 ;; FMR MR MT%0 MF%1 NOP
7355 (define_insn "movsd_hardfloat"
7356 [(set (match_operand:SD 0 "nonimmediate_operand"
7357 "=!r, d, m, Z, ?d, ?r,
7358 f, !r, *c*l, !r, *h")
7359 (match_operand:SD 1 "input_operand"
7362 "(register_operand (operands[0], SDmode)
7363 || register_operand (operands[1], SDmode))
7364 && TARGET_HARD_FLOAT"
7378 "load, fpload, store, fpstore, mffgpr, mftgpr,
7379 fpsimple, *, mtjmpr, mfjmpr, *")
7381 "*, p7, *, *, p8v, p8v,
7384 ;; MR MT%0 MF%0 LWZ STW LI
7385 ;; LIS G-const. F/n-const NOP
7386 (define_insn "*mov<mode>_softfloat"
7387 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7388 "=r, *c*l, r, r, m, r,
7391 (match_operand:FMOVE32 1 "input_operand"
7395 "(gpc_reg_operand (operands[0], <MODE>mode)
7396 || gpc_reg_operand (operands[1], <MODE>mode))
7397 && TARGET_SOFT_FLOAT"
7410 "*, mtjmpr, mfjmpr, load, store, *,
7417 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7418 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7420 ;; Because SF values are actually stored as DF values within the vector
7421 ;; registers, we need to convert the value to the vector SF format when
7422 ;; we need to use the bits in a union or similar cases. We only need
7423 ;; to do this transformation when the value is a vector register. Loads,
7424 ;; stores, and transfers within GPRs are assumed to be safe.
7426 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7427 ;; no alternatives, because the call is created as part of secondary_reload,
7428 ;; and operand #2's register class is used to allocate the temporary register.
7429 ;; This function is called before reload, and it creates the temporary as
7432 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7433 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7434 (define_insn_and_split "movsf_from_si"
7435 [(set (match_operand:SF 0 "nonimmediate_operand"
7436 "=!r, f, v, wa, m, Z,
7438 (unspec:SF [(match_operand:SI 1 "input_operand"
7442 (clobber (match_scratch:DI 2
7445 "TARGET_NO_SF_SUBREG
7446 && (register_operand (operands[0], SFmode)
7447 || register_operand (operands[1], SImode))"
7460 "&& reload_completed
7461 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7462 && int_reg_operand_not_pseudo (operands[1], SImode)"
7465 rtx op0 = operands[0];
7466 rtx op1 = operands[1];
7467 rtx op2 = operands[2];
7468 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7470 /* Move SF value to upper 32-bits for xscvspdpn. */
7471 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7472 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7473 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7480 "load, fpload, fpload, fpload, store, fpstore,
7481 fpstore, vecfloat, mffgpr, *")
7483 "*, *, p9v, p8v, *, *,
7484 p8v, p8v, p8v, *")])
7487 ;; Move 64-bit binary/decimal floating point
7488 (define_expand "mov<mode>"
7489 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7490 (match_operand:FMOVE64 1 "any_operand"))]
7493 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7498 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7499 (match_operand:FMOVE64 1 "const_int_operand"))]
7500 "! TARGET_POWERPC64 && reload_completed
7501 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7502 || (SUBREG_P (operands[0])
7503 && REG_P (SUBREG_REG (operands[0]))
7504 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7505 [(set (match_dup 2) (match_dup 4))
7506 (set (match_dup 3) (match_dup 1))]
7508 int endian = (WORDS_BIG_ENDIAN == 0);
7509 HOST_WIDE_INT value = INTVAL (operands[1]);
7511 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7512 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7513 operands[4] = GEN_INT (value >> 32);
7514 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7518 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7519 (match_operand:FMOVE64 1 "const_double_operand"))]
7520 "! TARGET_POWERPC64 && reload_completed
7521 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7522 || (SUBREG_P (operands[0])
7523 && REG_P (SUBREG_REG (operands[0]))
7524 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7525 [(set (match_dup 2) (match_dup 4))
7526 (set (match_dup 3) (match_dup 5))]
7528 int endian = (WORDS_BIG_ENDIAN == 0);
7531 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
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_mode (l[endian], SImode);
7536 operands[5] = gen_int_mode (l[1 - endian], SImode);
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 3))]
7549 int endian = (WORDS_BIG_ENDIAN == 0);
7553 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7555 operands[2] = gen_lowpart (DImode, operands[0]);
7556 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7557 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7558 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7560 operands[3] = gen_int_mode (val, DImode);
7563 ;; Don't have reload use general registers to load a constant. It is
7564 ;; less efficient than loading the constant into an FP register, since
7565 ;; it will probably be used there.
7567 ;; The move constraints are ordered to prefer floating point registers before
7568 ;; general purpose registers to avoid doing a store and a load to get the value
7569 ;; into a floating point register when it is needed for a floating point
7570 ;; operation. Prefer traditional floating point registers over VSX registers,
7571 ;; since the D-form version of the memory instructions does not need a GPR for
7572 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7575 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7576 ;; except for 0.0 which can be created on VSX with an xor instruction.
7578 ;; STFD LFD FMR LXSD STXSD
7579 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7583 (define_insn "*mov<mode>_hardfloat32"
7584 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7585 "=m, d, d, <f64_p9>, wY,
7586 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7588 (match_operand:FMOVE64 1 "input_operand"
7589 "d, m, d, wY, <f64_p9>,
7590 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7592 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7593 && (gpc_reg_operand (operands[0], <MODE>mode)
7594 || gpc_reg_operand (operands[1], <MODE>mode))"
7610 "fpstore, fpload, fpsimple, fpload, fpstore,
7611 fpload, fpstore, veclogical, veclogical, two,
7613 (set_attr "size" "64")
7623 ;; STW LWZ MR G-const H-const F-const
7625 (define_insn "*mov<mode>_softfloat32"
7626 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7627 "=Y, r, r, r, r, r")
7629 (match_operand:FMOVE64 1 "input_operand"
7630 "r, Y, r, G, H, F"))]
7633 && (gpc_reg_operand (operands[0], <MODE>mode)
7634 || gpc_reg_operand (operands[1], <MODE>mode))"
7637 "store, load, two, *, *, *")
7640 "8, 8, 8, 8, 12, 16")])
7642 ; ld/std require word-aligned displacements -> 'Y' constraint.
7643 ; List Y->r and r->Y before r->r for reload.
7645 ;; STFD LFD FMR LXSD STXSD
7646 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7647 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7648 ;; NOP MFVSRD MTVSRD
7650 (define_insn "*mov<mode>_hardfloat64"
7651 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7652 "=m, d, d, <f64_p9>, wY,
7653 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7654 YZ, r, !r, *c*l, !r,
7656 (match_operand:FMOVE64 1 "input_operand"
7657 "d, m, d, wY, <f64_p9>,
7658 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7661 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7662 && (gpc_reg_operand (operands[0], <MODE>mode)
7663 || gpc_reg_operand (operands[1], <MODE>mode))"
7684 "fpstore, fpload, fpsimple, fpload, fpstore,
7685 fpload, fpstore, veclogical, veclogical, integer,
7686 store, load, *, mtjmpr, mfjmpr,
7688 (set_attr "size" "64")
7695 ;; STD LD MR MT<SPR> MF<SPR> G-const
7696 ;; H-const F-const Special
7698 (define_insn "*mov<mode>_softfloat64"
7699 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7700 "=Y, r, r, *c*l, r, r,
7703 (match_operand:FMOVE64 1 "input_operand"
7707 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7708 && (gpc_reg_operand (operands[0], <MODE>mode)
7709 || gpc_reg_operand (operands[1], <MODE>mode))"
7721 "store, load, *, mtjmpr, mfjmpr, *,
7728 (define_expand "mov<mode>"
7729 [(set (match_operand:FMOVE128 0 "general_operand")
7730 (match_operand:FMOVE128 1 "any_operand"))]
7733 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7737 ;; It's important to list Y->r and r->Y before r->r because otherwise
7738 ;; reload, given m->r, will try to pick r->r and reload it, which
7739 ;; doesn't make progress.
7741 ;; We can't split little endian direct moves of TDmode, because the words are
7742 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7743 ;; problematical. Don't allow direct move for this case.
7745 ;; FPR load FPR store FPR move FPR zero GPR load
7746 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
7748 (define_insn_and_split "*mov<mode>_64bit_dm"
7749 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7753 (match_operand:FMOVE128_FPR 1 "input_operand"
7754 "d, m, d, <zero_fp>, r,
7755 <zero_fp>, Y, r, d, r"))]
7757 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7758 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7759 && (gpc_reg_operand (operands[0], <MODE>mode)
7760 || gpc_reg_operand (operands[1], <MODE>mode))"
7762 "&& reload_completed"
7765 rs6000_split_multireg_move (operands[0], operands[1]);
7768 [(set_attr "length" "8")
7769 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7770 (set_attr "max_prefixed_insns" "2")
7771 (set_attr "num_insns" "2")])
7773 (define_insn_and_split "*movtd_64bit_nodm"
7774 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7775 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7776 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7777 && (gpc_reg_operand (operands[0], TDmode)
7778 || gpc_reg_operand (operands[1], TDmode))"
7780 "&& reload_completed"
7783 rs6000_split_multireg_move (operands[0], operands[1]);
7786 [(set_attr "length" "8,8,8,12,12,8")
7787 (set_attr "max_prefixed_insns" "2")
7788 (set_attr "num_insns" "2,2,2,3,3,2")])
7790 (define_insn_and_split "*mov<mode>_32bit"
7791 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7792 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7793 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7794 && (FLOAT128_2REG_P (<MODE>mode)
7795 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7796 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7797 && (gpc_reg_operand (operands[0], <MODE>mode)
7798 || gpc_reg_operand (operands[1], <MODE>mode))"
7800 "&& reload_completed"
7803 rs6000_split_multireg_move (operands[0], operands[1]);
7806 [(set_attr "length" "8,8,8,8,20,20,16")])
7808 (define_insn_and_split "*mov<mode>_softfloat"
7809 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7810 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7812 && (gpc_reg_operand (operands[0], <MODE>mode)
7813 || gpc_reg_operand (operands[1], <MODE>mode))"
7815 "&& reload_completed"
7818 rs6000_split_multireg_move (operands[0], operands[1]);
7821 [(set_attr_alternative "length"
7822 [(if_then_else (match_test "TARGET_POWERPC64")
7824 (const_string "16"))
7825 (if_then_else (match_test "TARGET_POWERPC64")
7827 (const_string "16"))
7828 (if_then_else (match_test "TARGET_POWERPC64")
7830 (const_string "32"))
7831 (if_then_else (match_test "TARGET_POWERPC64")
7833 (const_string "16"))])])
7835 (define_expand "@extenddf<mode>2"
7836 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7837 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7838 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7840 if (FLOAT128_IEEE_P (<MODE>mode))
7841 rs6000_expand_float128_convert (operands[0], operands[1], false);
7842 else if (TARGET_VSX)
7843 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7846 rtx zero = gen_reg_rtx (DFmode);
7847 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7849 emit_insn (gen_extenddf2_fprs (<MODE>mode,
7850 operands[0], operands[1], zero));
7855 ;; Allow memory operands for the source to be created by the combiner.
7856 (define_insn_and_split "@extenddf<mode>2_fprs"
7857 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7858 (float_extend:IBM128
7859 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7860 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7861 "!TARGET_VSX && TARGET_HARD_FLOAT
7862 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7864 "&& reload_completed"
7865 [(set (match_dup 3) (match_dup 1))
7866 (set (match_dup 4) (match_dup 2))]
7868 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7869 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7871 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7872 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7875 (define_insn_and_split "@extenddf<mode>2_vsx"
7876 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7877 (float_extend:IBM128
7878 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7879 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7881 "&& reload_completed"
7882 [(set (match_dup 2) (match_dup 1))
7883 (set (match_dup 3) (match_dup 4))]
7885 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7886 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7888 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7889 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7890 operands[4] = CONST0_RTX (DFmode);
7893 (define_expand "extendsf<mode>2"
7894 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7895 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7896 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7898 if (FLOAT128_IEEE_P (<MODE>mode))
7899 rs6000_expand_float128_convert (operands[0], operands[1], false);
7902 rtx tmp = gen_reg_rtx (DFmode);
7903 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7904 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7909 (define_expand "trunc<mode>df2"
7910 [(set (match_operand:DF 0 "gpc_reg_operand")
7911 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7912 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7914 if (FLOAT128_IEEE_P (<MODE>mode))
7916 rs6000_expand_float128_convert (operands[0], operands[1], false);
7921 (define_insn_and_split "trunc<mode>df2_internal1"
7922 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7924 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7925 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7926 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7930 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7933 emit_note (NOTE_INSN_DELETED);
7936 [(set_attr "type" "fpsimple")])
7938 (define_insn "trunc<mode>df2_internal2"
7939 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7940 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7941 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7942 && TARGET_LONG_DOUBLE_128"
7944 [(set_attr "type" "fp")])
7946 (define_expand "trunc<mode>sf2"
7947 [(set (match_operand:SF 0 "gpc_reg_operand")
7948 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7949 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7951 if (FLOAT128_IEEE_P (<MODE>mode))
7952 rs6000_expand_float128_convert (operands[0], operands[1], false);
7955 rtx tmp = gen_reg_rtx (DFmode);
7956 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7957 emit_insn (gen_truncdfsf2 (operands[0], tmp));
7962 (define_expand "floatsi<mode>2"
7963 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7964 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7965 (clobber (match_scratch:DI 2))])]
7966 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7968 rtx op0 = operands[0];
7969 rtx op1 = operands[1];
7971 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7973 else if (FLOAT128_IEEE_P (<MODE>mode))
7975 rs6000_expand_float128_convert (op0, op1, false);
7980 rtx tmp = gen_reg_rtx (DFmode);
7981 expand_float (tmp, op1, false);
7982 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
7987 ; fadd, but rounding towards zero.
7988 ; This is probably not the optimal code sequence.
7989 (define_insn "fix_trunc_helper<mode>"
7990 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7991 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7992 UNSPEC_FIX_TRUNC_TF))
7993 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7994 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7995 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7996 [(set_attr "type" "fp")
7997 (set_attr "length" "20")])
7999 (define_expand "fix_trunc<mode>si2"
8000 [(set (match_operand:SI 0 "gpc_reg_operand")
8001 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8002 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8004 rtx op0 = operands[0];
8005 rtx op1 = operands[1];
8007 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8011 if (FLOAT128_IEEE_P (<MODE>mode))
8012 rs6000_expand_float128_convert (op0, op1, false);
8014 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8019 (define_expand "@fix_trunc<mode>si2_fprs"
8020 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8021 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8022 (clobber (match_dup 2))
8023 (clobber (match_dup 3))
8024 (clobber (match_dup 4))
8025 (clobber (match_dup 5))])]
8026 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8028 operands[2] = gen_reg_rtx (DFmode);
8029 operands[3] = gen_reg_rtx (DFmode);
8030 operands[4] = gen_reg_rtx (DImode);
8031 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8034 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8035 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8036 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8037 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8038 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8039 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8040 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8041 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8047 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8050 gcc_assert (MEM_P (operands[5]));
8051 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8053 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8054 emit_move_insn (operands[5], operands[4]);
8055 emit_move_insn (operands[0], lowword);
8059 (define_expand "fix_trunc<mode>di2"
8060 [(set (match_operand:DI 0 "gpc_reg_operand")
8061 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8062 "TARGET_FLOAT128_TYPE"
8064 if (!TARGET_FLOAT128_HW)
8066 rs6000_expand_float128_convert (operands[0], operands[1], false);
8071 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8072 [(set (match_operand:SDI 0 "gpc_reg_operand")
8073 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8074 "TARGET_FLOAT128_TYPE"
8076 rs6000_expand_float128_convert (operands[0], operands[1], true);
8080 (define_expand "floatdi<mode>2"
8081 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8082 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8083 "TARGET_FLOAT128_TYPE"
8085 if (!TARGET_FLOAT128_HW)
8087 rs6000_expand_float128_convert (operands[0], operands[1], false);
8092 (define_expand "floatunsdi<IEEE128:mode>2"
8093 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8094 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8095 "TARGET_FLOAT128_TYPE"
8097 if (!TARGET_FLOAT128_HW)
8099 rs6000_expand_float128_convert (operands[0], operands[1], true);
8104 (define_expand "floatuns<IEEE128:mode>2"
8105 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8106 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8107 "TARGET_FLOAT128_TYPE"
8109 rtx op0 = operands[0];
8110 rtx op1 = operands[1];
8112 if (TARGET_FLOAT128_HW)
8113 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8115 rs6000_expand_float128_convert (op0, op1, true);
8119 (define_expand "neg<mode>2"
8120 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8121 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8122 "FLOAT128_IEEE_P (<MODE>mode)
8123 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8125 if (FLOAT128_IEEE_P (<MODE>mode))
8127 if (TARGET_FLOAT128_HW)
8128 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8129 else if (TARGET_FLOAT128_TYPE)
8130 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8131 operands[0], operands[1]));
8134 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8135 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8137 operands[1], <MODE>mode);
8139 if (target && !rtx_equal_p (target, operands[0]))
8140 emit_move_insn (operands[0], target);
8146 (define_insn "neg<mode>2_internal"
8147 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8148 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8149 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8151 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8152 return "fneg %L0,%L1\;fneg %0,%1";
8154 return "fneg %0,%1\;fneg %L0,%L1";
8156 [(set_attr "type" "fpsimple")
8157 (set_attr "length" "8")])
8159 (define_expand "abs<mode>2"
8160 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8161 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8162 "FLOAT128_IEEE_P (<MODE>mode)
8163 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8167 if (FLOAT128_IEEE_P (<MODE>mode))
8169 if (TARGET_FLOAT128_HW)
8171 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8174 else if (TARGET_FLOAT128_TYPE)
8176 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8177 operands[0], operands[1]));
8184 label = gen_label_rtx ();
8185 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8190 (define_expand "@abs<mode>2_internal"
8191 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8192 (match_operand:IBM128 1 "gpc_reg_operand"))
8193 (set (match_dup 3) (match_dup 5))
8194 (set (match_dup 5) (abs:DF (match_dup 5)))
8195 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8196 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8197 (label_ref (match_operand 2 ""))
8199 (set (match_dup 6) (neg:DF (match_dup 6)))]
8200 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8202 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8203 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8204 operands[3] = gen_reg_rtx (DFmode);
8205 operands[4] = gen_reg_rtx (CCFPmode);
8206 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8207 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8211 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8214 (define_expand "ieee_128bit_negative_zero"
8215 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8216 "TARGET_FLOAT128_TYPE"
8218 rtvec v = rtvec_alloc (16);
8221 for (i = 0; i < 16; i++)
8222 RTVEC_ELT (v, i) = const0_rtx;
8224 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8225 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8227 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8231 ;; IEEE 128-bit negate
8233 ;; We have 2 insns here for negate and absolute value. The first uses
8234 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8235 ;; insns, and second insn after the first split pass loads up the bit to
8236 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8237 ;; neg/abs to create the constant just once.
8239 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8240 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8241 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8242 (clobber (match_scratch:V16QI 2 "=v"))]
8243 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8246 [(parallel [(set (match_dup 0)
8247 (neg:IEEE128 (match_dup 1)))
8248 (use (match_dup 2))])]
8250 if (GET_CODE (operands[2]) == SCRATCH)
8251 operands[2] = gen_reg_rtx (V16QImode);
8253 operands[3] = gen_reg_rtx (V16QImode);
8254 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8256 [(set_attr "length" "8")
8257 (set_attr "type" "vecsimple")])
8259 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8260 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8261 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8262 (use (match_operand:V16QI 2 "register_operand" "v"))]
8263 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8264 "xxlxor %x0,%x1,%x2"
8265 [(set_attr "type" "veclogical")])
8267 ;; IEEE 128-bit absolute value
8268 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8269 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8270 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8271 (clobber (match_scratch:V16QI 2 "=v"))]
8272 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8275 [(parallel [(set (match_dup 0)
8276 (abs:IEEE128 (match_dup 1)))
8277 (use (match_dup 2))])]
8279 if (GET_CODE (operands[2]) == SCRATCH)
8280 operands[2] = gen_reg_rtx (V16QImode);
8282 operands[3] = gen_reg_rtx (V16QImode);
8283 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8285 [(set_attr "length" "8")
8286 (set_attr "type" "vecsimple")])
8288 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8289 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8290 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8291 (use (match_operand:V16QI 2 "register_operand" "v"))]
8292 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8293 "xxlandc %x0,%x1,%x2"
8294 [(set_attr "type" "veclogical")])
8296 ;; IEEE 128-bit negative absolute value
8297 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8298 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8301 (match_operand:IEEE128 1 "register_operand" "wa"))))
8302 (clobber (match_scratch:V16QI 2 "=v"))]
8303 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8304 && FLOAT128_IEEE_P (<MODE>mode)"
8307 [(parallel [(set (match_dup 0)
8308 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8309 (use (match_dup 2))])]
8311 if (GET_CODE (operands[2]) == SCRATCH)
8312 operands[2] = gen_reg_rtx (V16QImode);
8314 operands[3] = gen_reg_rtx (V16QImode);
8315 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8317 [(set_attr "length" "8")
8318 (set_attr "type" "vecsimple")])
8320 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8321 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8324 (match_operand:IEEE128 1 "register_operand" "wa"))))
8325 (use (match_operand:V16QI 2 "register_operand" "v"))]
8326 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8328 [(set_attr "type" "veclogical")])
8330 ;; Float128 conversion functions. These expand to library function calls.
8331 ;; We use expand to convert from IBM double double to IEEE 128-bit
8332 ;; and trunc for the opposite.
8333 (define_expand "extendiftf2"
8334 [(set (match_operand:TF 0 "gpc_reg_operand")
8335 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8336 "TARGET_FLOAT128_TYPE"
8338 rs6000_expand_float128_convert (operands[0], operands[1], false);
8342 (define_expand "extendifkf2"
8343 [(set (match_operand:KF 0 "gpc_reg_operand")
8344 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8345 "TARGET_FLOAT128_TYPE"
8347 rs6000_expand_float128_convert (operands[0], operands[1], false);
8351 (define_expand "extendtfkf2"
8352 [(set (match_operand:KF 0 "gpc_reg_operand")
8353 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8354 "TARGET_FLOAT128_TYPE"
8356 rs6000_expand_float128_convert (operands[0], operands[1], false);
8360 (define_expand "extendtfif2"
8361 [(set (match_operand:IF 0 "gpc_reg_operand")
8362 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8363 "TARGET_FLOAT128_TYPE"
8365 rs6000_expand_float128_convert (operands[0], operands[1], false);
8369 (define_expand "trunciftf2"
8370 [(set (match_operand:TF 0 "gpc_reg_operand")
8371 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8372 "TARGET_FLOAT128_TYPE"
8374 rs6000_expand_float128_convert (operands[0], operands[1], false);
8378 (define_expand "truncifkf2"
8379 [(set (match_operand:KF 0 "gpc_reg_operand")
8380 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8381 "TARGET_FLOAT128_TYPE"
8383 rs6000_expand_float128_convert (operands[0], operands[1], false);
8387 (define_expand "trunckftf2"
8388 [(set (match_operand:TF 0 "gpc_reg_operand")
8389 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8390 "TARGET_FLOAT128_TYPE"
8392 rs6000_expand_float128_convert (operands[0], operands[1], false);
8396 (define_expand "trunctfif2"
8397 [(set (match_operand:IF 0 "gpc_reg_operand")
8398 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8399 "TARGET_FLOAT128_TYPE"
8401 rs6000_expand_float128_convert (operands[0], operands[1], false);
8405 (define_insn_and_split "*extend<mode>tf2_internal"
8406 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8408 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8409 "TARGET_FLOAT128_TYPE
8410 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8412 "&& reload_completed"
8413 [(set (match_dup 0) (match_dup 2))]
8415 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8418 (define_insn_and_split "*extendtf<mode>2_internal"
8419 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8421 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8422 "TARGET_FLOAT128_TYPE
8423 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8425 "&& reload_completed"
8426 [(set (match_dup 0) (match_dup 2))]
8428 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8432 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8433 ;; must have 3 arguments, and scratch register constraint must be a single
8436 ;; Reload patterns to support gpr load/store with misaligned mem.
8437 ;; and multiple gpr load/store at offset >= 0xfffc
8438 (define_expand "reload_<mode>_store"
8439 [(parallel [(match_operand 0 "memory_operand" "=m")
8440 (match_operand 1 "gpc_reg_operand" "r")
8441 (match_operand:GPR 2 "register_operand" "=&b")])]
8444 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8448 (define_expand "reload_<mode>_load"
8449 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8450 (match_operand 1 "memory_operand" "m")
8451 (match_operand:GPR 2 "register_operand" "=b")])]
8454 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8459 ;; Reload patterns for various types using the vector registers. We may need
8460 ;; an additional base register to convert the reg+offset addressing to reg+reg
8461 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8462 ;; index register for gpr registers.
8463 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8464 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8465 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8466 (match_operand:P 2 "register_operand" "=b")])]
8469 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8473 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8474 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8475 (match_operand:RELOAD 1 "memory_operand" "m")
8476 (match_operand:P 2 "register_operand" "=b")])]
8479 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8484 ;; Reload sometimes tries to move the address to a GPR, and can generate
8485 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8486 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8488 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8489 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8490 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8491 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8493 "TARGET_ALTIVEC && reload_completed"
8495 "&& reload_completed"
8497 (plus:P (match_dup 1)
8500 (and:P (match_dup 0)
8503 ;; Power8 merge instructions to allow direct move to/from floating point
8504 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8505 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8506 ;; value, since it is allocated in reload and not all of the flow information
8507 ;; is setup for it. We have two patterns to do the two moves between gprs and
8508 ;; fprs. There isn't a dependancy between the two, but we could potentially
8509 ;; schedule other instructions between the two instructions.
8511 (define_insn "p8_fmrgow_<mode>"
8512 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8514 (match_operand:DF 1 "register_operand" "d")
8515 (match_operand:DF 2 "register_operand" "d")]
8516 UNSPEC_P8V_FMRGOW))]
8517 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8519 [(set_attr "type" "fpsimple")])
8521 (define_insn "p8_mtvsrwz"
8522 [(set (match_operand:DF 0 "register_operand" "=d")
8523 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8524 UNSPEC_P8V_MTVSRWZ))]
8525 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8527 [(set_attr "type" "mftgpr")])
8529 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8530 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8531 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8532 UNSPEC_P8V_RELOAD_FROM_GPR))
8533 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8534 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8536 "&& reload_completed"
8539 rtx dest = operands[0];
8540 rtx src = operands[1];
8541 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8542 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8543 rtx gpr_hi_reg = gen_highpart (SImode, src);
8544 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8546 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8547 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8548 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8551 [(set_attr "length" "12")
8552 (set_attr "type" "three")])
8554 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8555 (define_insn "p8_mtvsrd_df"
8556 [(set (match_operand:DF 0 "register_operand" "=wa")
8557 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8558 UNSPEC_P8V_MTVSRD))]
8559 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8561 [(set_attr "type" "mftgpr")])
8563 (define_insn "p8_xxpermdi_<mode>"
8564 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8565 (unspec:FMOVE128_GPR [
8566 (match_operand:DF 1 "register_operand" "wa")
8567 (match_operand:DF 2 "register_operand" "wa")]
8568 UNSPEC_P8V_XXPERMDI))]
8569 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8570 "xxpermdi %x0,%x1,%x2,0"
8571 [(set_attr "type" "vecperm")])
8573 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8574 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8575 (unspec:FMOVE128_GPR
8576 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8577 UNSPEC_P8V_RELOAD_FROM_GPR))
8578 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8579 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8581 "&& reload_completed"
8584 rtx dest = operands[0];
8585 rtx src = operands[1];
8586 /* You might think that we could use op0 as one temp and a DF clobber
8587 as op2, but you'd be wrong. Secondary reload move patterns don't
8588 check for overlap of the clobber and the destination. */
8589 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8590 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8591 rtx gpr_hi_reg = gen_highpart (DImode, src);
8592 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8594 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8595 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8596 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8599 [(set_attr "length" "12")
8600 (set_attr "type" "three")])
8603 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8604 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8606 && (int_reg_operand (operands[0], <MODE>mode)
8607 || int_reg_operand (operands[1], <MODE>mode))
8608 && (!TARGET_DIRECT_MOVE_128
8609 || (!vsx_register_operand (operands[0], <MODE>mode)
8610 && !vsx_register_operand (operands[1], <MODE>mode)))"
8613 rs6000_split_multireg_move (operands[0], operands[1]);
8617 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8618 ;; type is stored internally as double precision in the VSX registers, we have
8619 ;; to convert it from the vector format.
8620 (define_insn "p8_mtvsrd_sf"
8621 [(set (match_operand:SF 0 "register_operand" "=wa")
8622 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8623 UNSPEC_P8V_MTVSRD))]
8624 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8626 [(set_attr "type" "mftgpr")])
8628 (define_insn_and_split "reload_vsx_from_gprsf"
8629 [(set (match_operand:SF 0 "register_operand" "=wa")
8630 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8631 UNSPEC_P8V_RELOAD_FROM_GPR))
8632 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8633 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8635 "&& reload_completed"
8638 rtx op0 = operands[0];
8639 rtx op1 = operands[1];
8640 rtx op2 = operands[2];
8641 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8643 /* Move SF value to upper 32-bits for xscvspdpn. */
8644 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8645 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8646 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8649 [(set_attr "length" "8")
8650 (set_attr "type" "two")])
8652 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8653 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8654 ;; and then doing a move of that.
8655 (define_insn "p8_mfvsrd_3_<mode>"
8656 [(set (match_operand:DF 0 "register_operand" "=r")
8657 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8658 UNSPEC_P8V_RELOAD_FROM_VSX))]
8659 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8661 [(set_attr "type" "mftgpr")])
8663 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8664 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8665 (unspec:FMOVE128_GPR
8666 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8667 UNSPEC_P8V_RELOAD_FROM_VSX))
8668 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8669 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8671 "&& reload_completed"
8674 rtx dest = operands[0];
8675 rtx src = operands[1];
8676 rtx tmp = operands[2];
8677 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8678 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8680 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8681 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8682 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8685 [(set_attr "length" "12")
8686 (set_attr "type" "three")])
8688 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8689 ;; type is stored internally as double precision, we have to convert it to the
8692 (define_insn_and_split "reload_gpr_from_vsxsf"
8693 [(set (match_operand:SF 0 "register_operand" "=r")
8694 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8695 UNSPEC_P8V_RELOAD_FROM_VSX))
8696 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8697 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8699 "&& reload_completed"
8702 rtx op0 = operands[0];
8703 rtx op1 = operands[1];
8704 rtx op2 = operands[2];
8705 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8706 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8708 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8709 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8712 [(set_attr "length" "8")
8713 (set_attr "type" "two")
8714 (set_attr "isa" "p8v")])
8716 ;; Next come the multi-word integer load and store and the load and store
8719 ;; List r->r after r->Y, otherwise reload will try to reload a
8720 ;; non-offsettable address by using r->r which won't make progress.
8721 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8722 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8724 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8725 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8726 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8729 (define_insn "*movdi_internal32"
8730 [(set (match_operand:DI 0 "nonimmediate_operand"
8731 "=Y, r, r, m, ^d, ^d,
8732 r, wY, Z, ^v, $v, ^wa,
8733 wa, wa, v, wa, *i, v,
8735 (match_operand:DI 1 "input_operand"
8736 "r, Y, r, ^d, m, ^d,
8737 IJKnF, ^v, $v, wY, Z, ^wa,
8738 Oj, wM, OjwM, Oj, wM, wS,
8741 && (gpc_reg_operand (operands[0], DImode)
8742 || gpc_reg_operand (operands[1], DImode))"
8764 "store, load, *, fpstore, fpload, fpsimple,
8765 *, fpstore, fpstore, fpload, fpload, veclogical,
8766 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8768 (set_attr "size" "64")
8776 *, p9v, p7v, p9v, p7v, *,
8777 p9v, p9v, p7v, *, *, p7v,
8781 [(set (match_operand:DI 0 "gpc_reg_operand")
8782 (match_operand:DI 1 "const_int_operand"))]
8783 "! TARGET_POWERPC64 && reload_completed
8784 && gpr_or_gpr_p (operands[0], operands[1])
8785 && !direct_move_p (operands[0], operands[1])"
8786 [(set (match_dup 2) (match_dup 4))
8787 (set (match_dup 3) (match_dup 1))]
8789 HOST_WIDE_INT value = INTVAL (operands[1]);
8790 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8792 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8794 operands[4] = GEN_INT (value >> 32);
8795 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8799 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8800 (match_operand:DIFD 1 "input_operand"))]
8801 "reload_completed && !TARGET_POWERPC64
8802 && gpr_or_gpr_p (operands[0], operands[1])
8803 && !direct_move_p (operands[0], operands[1])"
8806 rs6000_split_multireg_move (operands[0], operands[1]);
8810 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8811 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8812 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8813 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8814 ;; VSX->GPR GPR->VSX
8815 (define_insn "*movdi_internal64"
8816 [(set (match_operand:DI 0 "nonimmediate_operand"
8817 "=YZ, r, r, r, r, r,
8818 m, ^d, ^d, wY, Z, $v,
8819 $v, ^wa, wa, wa, v, wa,
8820 wa, v, v, r, *h, *h,
8822 (match_operand:DI 1 "input_operand"
8823 "r, YZ, r, I, L, nF,
8824 ^d, m, ^d, ^v, $v, wY,
8825 Z, ^wa, Oj, wM, OjwM, Oj,
8826 wM, wS, wB, *h, r, 0,
8829 && (gpc_reg_operand (operands[0], DImode)
8830 || gpc_reg_operand (operands[1], DImode))"
8859 "store, load, *, *, *, *,
8860 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8861 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8862 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8864 (set_attr "size" "64")
8873 *, *, *, p9v, p7v, p9v,
8874 p7v, *, p9v, p9v, p7v, *,
8875 *, p7v, p7v, *, *, *,
8878 ; Some DImode loads are best done as a load of -1 followed by a mask
8881 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8882 (match_operand:DI 1 "const_int_operand"))]
8884 && num_insns_constant (operands[1], DImode) > 1
8885 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8886 && rs6000_is_valid_and_mask (operands[1], DImode)"
8890 (and:DI (match_dup 0)
8894 ;; Split a load of a large constant into the appropriate five-instruction
8895 ;; sequence. Handle anything in a constant number of insns.
8896 ;; When non-easy constants can go in the TOC, this should use
8897 ;; easy_fp_constant predicate.
8899 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8900 (match_operand:DI 1 "const_int_operand"))]
8901 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8902 [(set (match_dup 0) (match_dup 2))
8903 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8905 if (rs6000_emit_set_const (operands[0], operands[1]))
8912 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8913 (match_operand:DI 1 "const_scalar_int_operand"))]
8914 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8915 [(set (match_dup 0) (match_dup 2))
8916 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8918 if (rs6000_emit_set_const (operands[0], operands[1]))
8925 [(set (match_operand:DI 0 "altivec_register_operand")
8926 (match_operand:DI 1 "s5bit_cint_operand"))]
8927 "TARGET_VSX && reload_completed"
8930 rtx op0 = operands[0];
8931 rtx op1 = operands[1];
8932 int r = REGNO (op0);
8933 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8935 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8936 if (op1 != const0_rtx && op1 != constm1_rtx)
8938 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8939 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8944 ;; Split integer constants that can be loaded with XXSPLTIB and a
8945 ;; sign extend operation.
8947 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8948 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8949 "TARGET_P9_VECTOR && reload_completed"
8952 rtx op0 = operands[0];
8953 rtx op1 = operands[1];
8954 int r = REGNO (op0);
8955 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8957 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8958 if (<MODE>mode == DImode)
8959 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8960 else if (<MODE>mode == SImode)
8961 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8962 else if (<MODE>mode == HImode)
8964 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8965 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8971 ;; TImode/PTImode is similar, except that we usually want to compute the
8972 ;; address into a register and use lsi/stsi (the exception is during reload).
8974 (define_insn "*mov<mode>_string"
8975 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8976 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8978 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8979 && (gpc_reg_operand (operands[0], <MODE>mode)
8980 || gpc_reg_operand (operands[1], <MODE>mode))"
8982 [(set_attr "type" "store,store,load,load,*,*")
8983 (set_attr "update" "yes")
8984 (set_attr "indexed" "yes")
8985 (set_attr "cell_micro" "conditional")])
8987 (define_insn "*mov<mode>_ppc64"
8988 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8989 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8990 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8991 && (gpc_reg_operand (operands[0], <MODE>mode)
8992 || gpc_reg_operand (operands[1], <MODE>mode)))"
8994 return rs6000_output_move_128bit (operands);
8996 [(set_attr "type" "store,store,load,load,*,*")
8997 (set_attr "length" "8")
8998 (set_attr "max_prefixed_insns" "2")])
9001 [(set (match_operand:TI2 0 "int_reg_operand")
9002 (match_operand:TI2 1 "const_scalar_int_operand"))]
9004 && (VECTOR_MEM_NONE_P (<MODE>mode)
9005 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9006 [(set (match_dup 2) (match_dup 4))
9007 (set (match_dup 3) (match_dup 5))]
9009 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9011 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9013 if (CONST_WIDE_INT_P (operands[1]))
9015 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9016 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9018 else if (CONST_INT_P (operands[1]))
9020 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9021 operands[5] = operands[1];
9028 [(set (match_operand:TI2 0 "nonimmediate_operand")
9029 (match_operand:TI2 1 "input_operand"))]
9031 && gpr_or_gpr_p (operands[0], operands[1])
9032 && !direct_move_p (operands[0], operands[1])
9033 && !quad_load_store_p (operands[0], operands[1])"
9036 rs6000_split_multireg_move (operands[0], operands[1]);
9040 (define_expand "setmemsi"
9041 [(parallel [(set (match_operand:BLK 0 "")
9042 (match_operand 2 "const_int_operand"))
9043 (use (match_operand:SI 1 ""))
9044 (use (match_operand:SI 3 ""))])]
9047 /* If value to set is not zero, use the library routine. */
9048 if (operands[2] != const0_rtx)
9051 if (expand_block_clear (operands))
9057 ;; String compare N insn.
9058 ;; Argument 0 is the target (result)
9059 ;; Argument 1 is the destination
9060 ;; Argument 2 is the source
9061 ;; Argument 3 is the length
9062 ;; Argument 4 is the alignment
9064 (define_expand "cmpstrnsi"
9065 [(parallel [(set (match_operand:SI 0)
9066 (compare:SI (match_operand:BLK 1)
9067 (match_operand:BLK 2)))
9068 (use (match_operand:SI 3))
9069 (use (match_operand:SI 4))])]
9070 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9072 if (optimize_insn_for_size_p ())
9075 if (expand_strn_compare (operands, 0))
9081 ;; String compare insn.
9082 ;; Argument 0 is the target (result)
9083 ;; Argument 1 is the destination
9084 ;; Argument 2 is the source
9085 ;; Argument 3 is the alignment
9087 (define_expand "cmpstrsi"
9088 [(parallel [(set (match_operand:SI 0)
9089 (compare:SI (match_operand:BLK 1)
9090 (match_operand:BLK 2)))
9091 (use (match_operand:SI 3))])]
9092 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9094 if (optimize_insn_for_size_p ())
9097 if (expand_strn_compare (operands, 1))
9103 ;; Block compare insn.
9104 ;; Argument 0 is the target (result)
9105 ;; Argument 1 is the destination
9106 ;; Argument 2 is the source
9107 ;; Argument 3 is the length
9108 ;; Argument 4 is the alignment
9110 (define_expand "cmpmemsi"
9111 [(parallel [(set (match_operand:SI 0)
9112 (compare:SI (match_operand:BLK 1)
9113 (match_operand:BLK 2)))
9114 (use (match_operand:SI 3))
9115 (use (match_operand:SI 4))])]
9118 if (expand_block_compare (operands))
9124 ;; String/block copy insn (source and destination must not overlap).
9125 ;; Argument 0 is the destination
9126 ;; Argument 1 is the source
9127 ;; Argument 2 is the length
9128 ;; Argument 3 is the alignment
9130 (define_expand "cpymemsi"
9131 [(parallel [(set (match_operand:BLK 0 "")
9132 (match_operand:BLK 1 ""))
9133 (use (match_operand:SI 2 ""))
9134 (use (match_operand:SI 3 ""))])]
9137 if (expand_block_move (operands, false))
9143 ;; String/block move insn (source and destination may overlap).
9144 ;; Argument 0 is the destination
9145 ;; Argument 1 is the source
9146 ;; Argument 2 is the length
9147 ;; Argument 3 is the alignment
9149 (define_expand "movmemsi"
9150 [(parallel [(set (match_operand:BLK 0 "")
9151 (match_operand:BLK 1 ""))
9152 (use (match_operand:SI 2 ""))
9153 (use (match_operand:SI 3 ""))])]
9156 if (expand_block_move (operands, true))
9163 ;; Define insns that do load or store with update. Some of these we can
9164 ;; get by using pre-decrement or pre-increment, but the hardware can also
9165 ;; do cases where the increment is not the size of the object.
9167 ;; In all these cases, we use operands 0 and 1 for the register being
9168 ;; incremented because those are the operands that local-alloc will
9169 ;; tie and these are the pair most likely to be tieable (and the ones
9170 ;; that will benefit the most).
9172 (define_insn "*movdi_update1"
9173 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9174 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9175 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9176 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9177 (plus:P (match_dup 1) (match_dup 2)))]
9178 "TARGET_POWERPC64 && TARGET_UPDATE
9179 && (!avoiding_indexed_address_p (DImode)
9180 || !gpc_reg_operand (operands[2], Pmode))"
9184 [(set_attr "type" "load")
9185 (set_attr "update" "yes")
9186 (set_attr "indexed" "yes,no")])
9188 (define_insn "movdi_<mode>_update"
9189 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9190 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9191 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9192 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9193 (plus:P (match_dup 1) (match_dup 2)))]
9194 "TARGET_POWERPC64 && TARGET_UPDATE
9195 && (!avoiding_indexed_address_p (DImode)
9196 || !gpc_reg_operand (operands[2], Pmode)
9197 || (REG_P (operands[0])
9198 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9202 [(set_attr "type" "store")
9203 (set_attr "update" "yes")
9204 (set_attr "indexed" "yes,no")])
9206 ;; This pattern is only conditional on TARGET_64BIT, as it is
9207 ;; needed for stack allocation, even if the user passes -mno-update.
9208 (define_insn "movdi_update_stack"
9209 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9210 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9211 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9212 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9213 (plus:DI (match_dup 1) (match_dup 2)))]
9218 [(set_attr "type" "store")
9219 (set_attr "update" "yes")
9220 (set_attr "indexed" "yes,no")])
9222 (define_insn "*movsi_update1"
9223 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9224 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9225 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9226 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9227 (plus:P (match_dup 1) (match_dup 2)))]
9229 && (!avoiding_indexed_address_p (SImode)
9230 || !gpc_reg_operand (operands[2], Pmode))"
9234 [(set_attr "type" "load")
9235 (set_attr "update" "yes")
9236 (set_attr "indexed" "yes,no")])
9238 (define_insn "*movsi_update2"
9239 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9241 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9242 (match_operand:P 2 "gpc_reg_operand" "r")))))
9243 (set (match_operand:P 0 "gpc_reg_operand" "=b")
9244 (plus:P (match_dup 1) (match_dup 2)))]
9245 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9247 [(set_attr "type" "load")
9248 (set_attr "sign_extend" "yes")
9249 (set_attr "update" "yes")
9250 (set_attr "indexed" "yes")])
9252 (define_insn "movsi_<mode>_update"
9253 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9254 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9255 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9256 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9257 (plus:P (match_dup 1) (match_dup 2)))]
9259 && (!avoiding_indexed_address_p (SImode)
9260 || !gpc_reg_operand (operands[2], Pmode)
9261 || (REG_P (operands[0])
9262 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9266 [(set_attr "type" "store")
9267 (set_attr "update" "yes")
9268 (set_attr "indexed" "yes,no")])
9270 ;; This is an unconditional pattern; needed for stack allocation, even
9271 ;; if the user passes -mno-update.
9272 (define_insn "movsi_update_stack"
9273 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9274 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9275 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9276 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9277 (plus:SI (match_dup 1) (match_dup 2)))]
9282 [(set_attr "type" "store")
9283 (set_attr "update" "yes")
9284 (set_attr "indexed" "yes,no")])
9286 (define_insn "*movhi_update1"
9287 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9288 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9289 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9290 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9291 (plus:P (match_dup 1) (match_dup 2)))]
9293 && (!avoiding_indexed_address_p (HImode)
9294 || !gpc_reg_operand (operands[2], SImode))"
9298 [(set_attr "type" "load")
9299 (set_attr "update" "yes")
9300 (set_attr "indexed" "yes,no")])
9302 (define_insn "*movhi_update2"
9303 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9305 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9306 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9307 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9308 (plus:P (match_dup 1) (match_dup 2)))]
9310 && (!avoiding_indexed_address_p (HImode)
9311 || !gpc_reg_operand (operands[2], Pmode))"
9315 [(set_attr "type" "load")
9316 (set_attr "update" "yes")
9317 (set_attr "indexed" "yes,no")])
9319 (define_insn "*movhi_update3"
9320 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9322 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9323 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9324 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9325 (plus:P (match_dup 1) (match_dup 2)))]
9327 && !(avoiding_indexed_address_p (HImode)
9328 && gpc_reg_operand (operands[2], Pmode))"
9332 [(set_attr "type" "load")
9333 (set_attr "sign_extend" "yes")
9334 (set_attr "update" "yes")
9335 (set_attr "indexed" "yes,no")])
9337 (define_insn "*movhi_update4"
9338 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9339 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9340 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9341 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9342 (plus:P (match_dup 1) (match_dup 2)))]
9344 && (!avoiding_indexed_address_p (HImode)
9345 || !gpc_reg_operand (operands[2], Pmode))"
9349 [(set_attr "type" "store")
9350 (set_attr "update" "yes")
9351 (set_attr "indexed" "yes,no")])
9353 (define_insn "*movqi_update1"
9354 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9355 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9356 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9357 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9358 (plus:P (match_dup 1) (match_dup 2)))]
9360 && (!avoiding_indexed_address_p (QImode)
9361 || !gpc_reg_operand (operands[2], Pmode))"
9365 [(set_attr "type" "load")
9366 (set_attr "update" "yes")
9367 (set_attr "indexed" "yes,no")])
9369 (define_insn "*movqi_update2"
9370 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9372 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9373 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9374 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9375 (plus:P (match_dup 1) (match_dup 2)))]
9377 && (!avoiding_indexed_address_p (QImode)
9378 || !gpc_reg_operand (operands[2], Pmode))"
9382 [(set_attr "type" "load")
9383 (set_attr "update" "yes")
9384 (set_attr "indexed" "yes,no")])
9386 (define_insn "*movqi_update3"
9387 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9388 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9389 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9390 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9391 (plus:P (match_dup 1) (match_dup 2)))]
9393 && (!avoiding_indexed_address_p (QImode)
9394 || !gpc_reg_operand (operands[2], Pmode))"
9398 [(set_attr "type" "store")
9399 (set_attr "update" "yes")
9400 (set_attr "indexed" "yes,no")])
9402 (define_insn "*mov<SFDF:mode>_update1"
9403 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9404 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9405 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9406 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9407 (plus:P (match_dup 1) (match_dup 2)))]
9408 "TARGET_HARD_FLOAT && TARGET_UPDATE
9409 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9410 || !gpc_reg_operand (operands[2], Pmode))"
9414 [(set_attr "type" "fpload")
9415 (set_attr "update" "yes")
9416 (set_attr "indexed" "yes,no")
9417 (set_attr "size" "<SFDF:bits>")])
9419 (define_insn "*mov<SFDF:mode>_update2"
9420 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9421 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9422 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9423 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9424 (plus:P (match_dup 1) (match_dup 2)))]
9425 "TARGET_HARD_FLOAT && TARGET_UPDATE
9426 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9427 || !gpc_reg_operand (operands[2], Pmode))"
9431 [(set_attr "type" "fpstore")
9432 (set_attr "update" "yes")
9433 (set_attr "indexed" "yes,no")
9434 (set_attr "size" "<SFDF:bits>")])
9436 (define_insn "*movsf_update3"
9437 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9438 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9439 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9440 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9441 (plus:P (match_dup 1) (match_dup 2)))]
9442 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9443 && (!avoiding_indexed_address_p (SFmode)
9444 || !gpc_reg_operand (operands[2], Pmode))"
9448 [(set_attr "type" "load")
9449 (set_attr "update" "yes")
9450 (set_attr "indexed" "yes,no")])
9452 (define_insn "*movsf_update4"
9453 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9454 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9455 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9456 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9457 (plus:P (match_dup 1) (match_dup 2)))]
9458 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9459 && (!avoiding_indexed_address_p (SFmode)
9460 || !gpc_reg_operand (operands[2], Pmode))"
9464 [(set_attr "type" "store")
9465 (set_attr "update" "yes")
9466 (set_attr "indexed" "yes,no")])
9469 ;; After inserting conditional returns we can sometimes have
9470 ;; unnecessary register moves. Unfortunately we cannot have a
9471 ;; modeless peephole here, because some single SImode sets have early
9472 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9473 ;; sequences, using get_attr_length here will smash the operands
9474 ;; array. Neither is there an early_cobbler_p predicate.
9475 ;; Also this optimization interferes with scalars going into
9476 ;; altivec registers (the code does reloading through the FPRs).
9478 [(set (match_operand:DF 0 "gpc_reg_operand")
9479 (match_operand:DF 1 "any_operand"))
9480 (set (match_operand:DF 2 "gpc_reg_operand")
9483 && peep2_reg_dead_p (2, operands[0])"
9484 [(set (match_dup 2) (match_dup 1))])
9487 [(set (match_operand:SF 0 "gpc_reg_operand")
9488 (match_operand:SF 1 "any_operand"))
9489 (set (match_operand:SF 2 "gpc_reg_operand")
9492 && peep2_reg_dead_p (2, operands[0])"
9493 [(set (match_dup 2) (match_dup 1))])
9498 (define_insn_and_split "*tls_gd<bits>"
9499 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9500 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9501 (match_operand:P 2 "gpc_reg_operand" "b")]
9503 "HAVE_AS_TLS && TARGET_ELF"
9504 "addi %0,%2,%1@got@tlsgd"
9505 "&& TARGET_CMODEL != CMODEL_SMALL"
9508 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9510 (lo_sum:P (match_dup 3)
9511 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9513 operands[3] = gen_reg_rtx (<MODE>mode);
9515 [(set (attr "length")
9516 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9520 (define_insn "*tls_gd_high<bits>"
9521 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9523 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9524 (match_operand:P 2 "gpc_reg_operand" "b")]
9526 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9527 "addis %0,%2,%1@got@tlsgd@ha")
9529 (define_insn "*tls_gd_low<bits>"
9530 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9531 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9532 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9533 (match_operand:P 3 "gpc_reg_operand" "b")]
9535 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9536 "addi %0,%1,%2@got@tlsgd@l")
9538 (define_insn_and_split "*tls_ld<bits>"
9539 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9540 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9542 "HAVE_AS_TLS && TARGET_ELF"
9543 "addi %0,%1,%&@got@tlsld"
9544 "&& TARGET_CMODEL != CMODEL_SMALL"
9547 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9549 (lo_sum:P (match_dup 2)
9550 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9552 operands[2] = gen_reg_rtx (<MODE>mode);
9554 [(set (attr "length")
9555 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9559 (define_insn "*tls_ld_high<bits>"
9560 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9562 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9564 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9565 "addis %0,%1,%&@got@tlsld@ha")
9567 (define_insn "*tls_ld_low<bits>"
9568 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9569 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9570 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9572 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9573 "addi %0,%1,%&@got@tlsld@l")
9575 (define_insn "tls_dtprel_<bits>"
9576 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9577 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9578 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9581 "addi %0,%1,%2@dtprel")
9583 (define_insn "tls_dtprel_ha_<bits>"
9584 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9585 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9586 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9587 UNSPEC_TLSDTPRELHA))]
9589 "addis %0,%1,%2@dtprel@ha")
9591 (define_insn "tls_dtprel_lo_<bits>"
9592 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9593 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9594 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9595 UNSPEC_TLSDTPRELLO))]
9597 "addi %0,%1,%2@dtprel@l")
9599 (define_insn_and_split "tls_got_dtprel_<bits>"
9600 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9601 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9602 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9603 UNSPEC_TLSGOTDTPREL))]
9605 "<ptrload> %0,%2@got@dtprel(%1)"
9606 "&& TARGET_CMODEL != CMODEL_SMALL"
9609 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9611 (lo_sum:P (match_dup 3)
9612 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9614 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9616 [(set (attr "length")
9617 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9621 (define_insn "*tls_got_dtprel_high<bits>"
9622 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9624 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9625 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9626 UNSPEC_TLSGOTDTPREL)))]
9627 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9628 "addis %0,%1,%2@got@dtprel@ha")
9630 (define_insn "*tls_got_dtprel_low<bits>"
9631 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9632 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9633 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9634 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9635 UNSPEC_TLSGOTDTPREL)))]
9636 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9637 "<ptrload> %0,%2@got@dtprel@l(%1)")
9639 (define_insn "tls_tprel_<bits>"
9640 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9641 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9642 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9645 "addi %0,%1,%2@tprel")
9647 (define_insn "tls_tprel_ha_<bits>"
9648 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9649 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9650 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9651 UNSPEC_TLSTPRELHA))]
9653 "addis %0,%1,%2@tprel@ha")
9655 (define_insn "tls_tprel_lo_<bits>"
9656 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9657 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9658 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9659 UNSPEC_TLSTPRELLO))]
9661 "addi %0,%1,%2@tprel@l")
9663 ;; "b" output constraint here and on tls_tls input to support linker tls
9664 ;; optimization. The linker may edit the instructions emitted by a
9665 ;; tls_got_tprel/tls_tls pair to addis,addi.
9666 (define_insn_and_split "tls_got_tprel_<bits>"
9667 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9668 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9669 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9670 UNSPEC_TLSGOTTPREL))]
9672 "<ptrload> %0,%2@got@tprel(%1)"
9673 "&& TARGET_CMODEL != CMODEL_SMALL"
9676 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9678 (lo_sum:P (match_dup 3)
9679 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9681 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9683 [(set (attr "length")
9684 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9688 (define_insn "*tls_got_tprel_high<bits>"
9689 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9691 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9692 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9693 UNSPEC_TLSGOTTPREL)))]
9694 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9695 "addis %0,%1,%2@got@tprel@ha")
9697 (define_insn "*tls_got_tprel_low<bits>"
9698 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9699 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9700 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9701 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9702 UNSPEC_TLSGOTTPREL)))]
9703 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9704 "<ptrload> %0,%2@got@tprel@l(%1)")
9706 (define_insn "tls_tls_<bits>"
9707 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9708 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9709 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9711 "TARGET_ELF && HAVE_AS_TLS"
9714 (define_expand "tls_get_tpointer"
9715 [(set (match_operand:SI 0 "gpc_reg_operand")
9716 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9717 "TARGET_XCOFF && HAVE_AS_TLS"
9719 emit_insn (gen_tls_get_tpointer_internal ());
9720 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9724 (define_insn "tls_get_tpointer_internal"
9726 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9727 (clobber (reg:SI LR_REGNO))]
9728 "TARGET_XCOFF && HAVE_AS_TLS"
9729 "bla __get_tpointer")
9731 (define_expand "tls_get_addr<mode>"
9732 [(set (match_operand:P 0 "gpc_reg_operand")
9733 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9734 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9735 "TARGET_XCOFF && HAVE_AS_TLS"
9737 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9738 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9739 emit_insn (gen_tls_get_addr_internal<mode> ());
9740 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9744 (define_insn "tls_get_addr_internal<mode>"
9746 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9750 (clobber (reg:P 11))
9751 (clobber (reg:CC CR0_REGNO))
9752 (clobber (reg:P LR_REGNO))]
9753 "TARGET_XCOFF && HAVE_AS_TLS"
9754 "bla __tls_get_addr")
9756 ;; Next come insns related to the calling sequence.
9758 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9759 ;; We move the back-chain and decrement the stack pointer.
9761 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9762 ;; constant alloca, using that predicate will force the generic code to put
9763 ;; the constant size into a register before calling the expander.
9765 ;; As a result the expander would not have the constant size information
9766 ;; in those cases and would have to generate less efficient code.
9768 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9769 ;; the constant size. The value is forced into a register if necessary.
9771 (define_expand "allocate_stack"
9772 [(set (match_operand 0 "gpc_reg_operand")
9773 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9775 (minus (reg 1) (match_dup 1)))]
9778 rtx chain = gen_reg_rtx (Pmode);
9779 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9781 rtx insn, par, set, mem;
9783 /* By allowing reg_or_cint_operand as the predicate we can get
9784 better code for stack-clash-protection because we do not lose
9785 size information. But the rest of the code expects the operand
9786 to be reg_or_short_operand. If it isn't, then force it into
9788 rtx orig_op1 = operands[1];
9789 if (!reg_or_short_operand (operands[1], Pmode))
9790 operands[1] = force_reg (Pmode, operands[1]);
9792 emit_move_insn (chain, stack_bot);
9794 /* Check stack bounds if necessary. */
9795 if (crtl->limit_stack)
9798 available = expand_binop (Pmode, sub_optab,
9799 stack_pointer_rtx, stack_limit_rtx,
9800 NULL_RTX, 1, OPTAB_WIDEN);
9801 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9804 /* Allocate and probe if requested.
9805 This may look similar to the loop we use for prologue allocations,
9806 but it is critically different. For the former we know the loop
9807 will iterate, but do not know that generally here. The former
9808 uses that knowledge to rotate the loop. Combining them would be
9809 possible with some performance cost. */
9810 if (flag_stack_clash_protection)
9812 rtx rounded_size, last_addr, residual;
9813 HOST_WIDE_INT probe_interval;
9814 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9815 &residual, &probe_interval,
9818 /* We do occasionally get in here with constant sizes, we might
9819 as well do a reasonable job when we obviously can. */
9820 if (rounded_size != const0_rtx)
9822 rtx loop_lab, end_loop;
9823 bool rotated = CONST_INT_P (rounded_size);
9824 rtx update = GEN_INT (-probe_interval);
9825 if (probe_interval > 32768)
9826 update = force_reg (Pmode, update);
9828 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9829 last_addr, rotated);
9832 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9836 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9839 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9840 last_addr, rotated);
9843 /* Now handle residuals. We just have to set operands[1] correctly
9844 and let the rest of the expander run. */
9845 operands[1] = residual;
9848 if (!(CONST_INT_P (operands[1])
9849 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9851 operands[1] = force_reg (Pmode, operands[1]);
9852 neg_op0 = gen_reg_rtx (Pmode);
9853 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9856 neg_op0 = GEN_INT (-INTVAL (operands[1]));
9858 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9859 : gen_movdi_update_stack))
9860 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9862 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9863 it now and set the alias set/attributes. The above gen_*_update
9864 calls will generate a PARALLEL with the MEM set being the first
9866 par = PATTERN (insn);
9867 gcc_assert (GET_CODE (par) == PARALLEL);
9868 set = XVECEXP (par, 0, 0);
9869 gcc_assert (GET_CODE (set) == SET);
9870 mem = SET_DEST (set);
9871 gcc_assert (MEM_P (mem));
9872 MEM_NOTRAP_P (mem) = 1;
9873 set_mem_alias_set (mem, get_frame_alias_set ());
9875 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9879 ;; These patterns say how to save and restore the stack pointer. We need not
9880 ;; save the stack pointer at function level since we are careful to
9881 ;; preserve the backchain. At block level, we have to restore the backchain
9882 ;; when we restore the stack pointer.
9884 ;; For nonlocal gotos, we must save both the stack pointer and its
9885 ;; backchain and restore both. Note that in the nonlocal case, the
9886 ;; save area is a memory location.
9888 (define_expand "save_stack_function"
9889 [(match_operand 0 "any_operand")
9890 (match_operand 1 "any_operand")]
9894 (define_expand "restore_stack_function"
9895 [(match_operand 0 "any_operand")
9896 (match_operand 1 "any_operand")]
9900 ;; Adjust stack pointer (op0) to a new value (op1).
9901 ;; First copy old stack backchain to new location, and ensure that the
9902 ;; scheduler won't reorder the sp assignment before the backchain write.
9903 (define_expand "restore_stack_block"
9904 [(set (match_dup 2) (match_dup 3))
9905 (set (match_dup 4) (match_dup 2))
9907 (set (match_operand 0 "register_operand")
9908 (match_operand 1 "register_operand"))]
9913 operands[1] = force_reg (Pmode, operands[1]);
9914 operands[2] = gen_reg_rtx (Pmode);
9915 operands[3] = gen_frame_mem (Pmode, operands[0]);
9916 operands[4] = gen_frame_mem (Pmode, operands[1]);
9917 p = rtvec_alloc (1);
9918 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9920 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9923 (define_expand "save_stack_nonlocal"
9924 [(set (match_dup 3) (match_dup 4))
9925 (set (match_operand 0 "memory_operand") (match_dup 3))
9926 (set (match_dup 2) (match_operand 1 "register_operand"))]
9929 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9931 /* Copy the backchain to the first word, sp to the second. */
9932 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9933 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9934 operands[3] = gen_reg_rtx (Pmode);
9935 operands[4] = gen_frame_mem (Pmode, operands[1]);
9938 (define_expand "restore_stack_nonlocal"
9939 [(set (match_dup 2) (match_operand 1 "memory_operand"))
9940 (set (match_dup 3) (match_dup 4))
9941 (set (match_dup 5) (match_dup 2))
9943 (set (match_operand 0 "register_operand") (match_dup 3))]
9946 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9949 /* Restore the backchain from the first word, sp from the second. */
9950 operands[2] = gen_reg_rtx (Pmode);
9951 operands[3] = gen_reg_rtx (Pmode);
9952 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9953 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9954 operands[5] = gen_frame_mem (Pmode, operands[3]);
9955 p = rtvec_alloc (1);
9956 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9958 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9961 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
9962 ;; to the symbol or label.
9963 (define_insn "*pcrel_local_addr"
9964 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9965 (match_operand:DI 1 "pcrel_local_address"))]
9968 [(set_attr "prefixed" "yes")])
9970 ;; Load up a PC-relative address to an external symbol. If the symbol and the
9971 ;; program are both defined in the main program, the linker will optimize this
9972 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
9973 ;; the dynamic linker and loaded up. Print_operand_address will append a
9974 ;; @got@pcrel to the symbol.
9975 (define_insn "*pcrel_extern_addr"
9976 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9977 (match_operand:DI 1 "pcrel_external_address"))]
9980 [(set_attr "prefixed" "yes")
9981 (set_attr "type" "load")])
9983 ;; TOC register handling.
9985 ;; Code to initialize the TOC register...
9987 (define_insn "load_toc_aix_si"
9988 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9989 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9991 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9994 extern int need_toc_init;
9996 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9997 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9998 operands[2] = gen_rtx_REG (Pmode, 2);
9999 return "lwz %0,%1(%2)";
10001 [(set_attr "type" "load")
10002 (set_attr "update" "no")
10003 (set_attr "indexed" "no")])
10005 (define_insn "load_toc_aix_di"
10006 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10007 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10008 (use (reg:DI 2))])]
10009 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10012 extern int need_toc_init;
10014 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10015 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10017 strcat (buf, "@toc");
10018 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10019 operands[2] = gen_rtx_REG (Pmode, 2);
10020 return "ld %0,%1(%2)";
10022 [(set_attr "type" "load")
10023 (set_attr "update" "no")
10024 (set_attr "indexed" "no")])
10026 (define_insn "load_toc_v4_pic_si"
10027 [(set (reg:SI LR_REGNO)
10028 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10029 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10030 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10031 [(set_attr "type" "branch")])
10033 (define_expand "load_toc_v4_PIC_1"
10034 [(parallel [(set (reg:SI LR_REGNO)
10035 (match_operand:SI 0 "immediate_operand" "s"))
10036 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10037 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10038 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10041 (define_insn "load_toc_v4_PIC_1_normal"
10042 [(set (reg:SI LR_REGNO)
10043 (match_operand:SI 0 "immediate_operand" "s"))
10044 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10045 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10046 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10047 "bcl 20,31,%0\n%0:"
10048 [(set_attr "type" "branch")
10049 (set_attr "cannot_copy" "yes")])
10051 (define_insn "load_toc_v4_PIC_1_476"
10052 [(set (reg:SI LR_REGNO)
10053 (match_operand:SI 0 "immediate_operand" "s"))
10054 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10055 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10056 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10059 static char templ[32];
10061 get_ppc476_thunk_name (name);
10062 sprintf (templ, "bl %s\n%%0:", name);
10065 [(set_attr "type" "branch")
10066 (set_attr "cannot_copy" "yes")])
10068 (define_expand "load_toc_v4_PIC_1b"
10069 [(parallel [(set (reg:SI LR_REGNO)
10070 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10071 (label_ref (match_operand 1 ""))]
10074 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10077 (define_insn "load_toc_v4_PIC_1b_normal"
10078 [(set (reg:SI LR_REGNO)
10079 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10080 (label_ref (match_operand 1 "" ""))]
10083 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10084 "bcl 20,31,$+8\;.long %0-$"
10085 [(set_attr "type" "branch")
10086 (set_attr "length" "8")])
10088 (define_insn "load_toc_v4_PIC_1b_476"
10089 [(set (reg:SI LR_REGNO)
10090 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10091 (label_ref (match_operand 1 "" ""))]
10094 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10097 static char templ[32];
10099 get_ppc476_thunk_name (name);
10100 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10103 [(set_attr "type" "branch")
10104 (set_attr "length" "16")])
10106 (define_insn "load_toc_v4_PIC_2"
10107 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10109 (match_operand:SI 1 "gpc_reg_operand" "b")
10111 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10112 (match_operand:SI 3 "immediate_operand" "s"))))))]
10113 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10115 [(set_attr "type" "load")])
10117 (define_insn "load_toc_v4_PIC_3b"
10118 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10120 (match_operand:SI 1 "gpc_reg_operand" "b")
10123 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10124 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10125 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10126 "addis %0,%1,%2-%3@ha")
10128 (define_insn "load_toc_v4_PIC_3c"
10129 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10131 (match_operand:SI 1 "gpc_reg_operand" "b")
10133 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10134 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10135 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10136 "addi %0,%1,%2-%3@l")
10138 ;; If the TOC is shared over a translation unit, as happens with all
10139 ;; the kinds of PIC that we support, we need to restore the TOC
10140 ;; pointer only when jumping over units of translation.
10141 ;; On Darwin, we need to reload the picbase.
10143 (define_expand "builtin_setjmp_receiver"
10144 [(use (label_ref (match_operand 0 "")))]
10145 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10146 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10147 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10150 if (DEFAULT_ABI == ABI_DARWIN)
10152 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10153 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10157 crtl->uses_pic_offset_table = 1;
10158 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10159 CODE_LABEL_NUMBER (operands[0]));
10160 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10162 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10163 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10164 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10165 picrtx, tmplabrtx));
10169 rs6000_emit_load_toc_table (FALSE);
10173 ;; Largetoc support
10174 (define_insn "*largetoc_high"
10175 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10177 (unspec [(match_operand:DI 1 "" "")
10178 (match_operand:DI 2 "gpc_reg_operand" "b")]
10180 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10181 "addis %0,%2,%1@toc@ha")
10183 (define_insn "*largetoc_high_aix<mode>"
10184 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10186 (unspec [(match_operand:P 1 "" "")
10187 (match_operand:P 2 "gpc_reg_operand" "b")]
10189 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10190 "addis %0,%1@u(%2)")
10192 (define_insn "*largetoc_high_plus"
10193 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10196 (unspec [(match_operand:DI 1 "" "")
10197 (match_operand:DI 2 "gpc_reg_operand" "b")]
10199 (match_operand:DI 3 "add_cint_operand" "n"))))]
10200 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10201 "addis %0,%2,%1+%3@toc@ha")
10203 (define_insn "*largetoc_high_plus_aix<mode>"
10204 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10207 (unspec [(match_operand:P 1 "" "")
10208 (match_operand:P 2 "gpc_reg_operand" "b")]
10210 (match_operand:P 3 "add_cint_operand" "n"))))]
10211 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10212 "addis %0,%1+%3@u(%2)")
10214 (define_insn "*largetoc_low"
10215 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10216 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10217 (match_operand:DI 2 "" "")))]
10218 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10221 (define_insn "*largetoc_low_aix<mode>"
10222 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10223 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10224 (match_operand:P 2 "" "")))]
10225 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10228 (define_insn_and_split "*tocref<mode>"
10229 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10230 (match_operand:P 1 "small_toc_ref" "R"))]
10233 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10234 [(set (match_dup 0) (high:P (match_dup 1)))
10235 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10237 ;; Elf specific ways of loading addresses for non-PIC code.
10238 ;; The output of this could be r0, but we make a very strong
10239 ;; preference for a base register because it will usually
10240 ;; be needed there.
10241 (define_insn "elf_high"
10242 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10243 (high:SI (match_operand 1 "" "")))]
10244 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10247 (define_insn "elf_low"
10248 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10249 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10250 (match_operand 2 "" "")))]
10251 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10254 (define_insn "*pltseq_tocsave_<mode>"
10255 [(set (match_operand:P 0 "memory_operand" "=m")
10256 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10257 (match_operand:P 2 "symbol_ref_operand" "s")
10258 (match_operand:P 3 "" "")]
10261 && DEFAULT_ABI == ABI_ELFv2"
10263 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10266 (define_insn "*pltseq_plt16_ha_<mode>"
10267 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10268 (unspec:P [(match_operand:P 1 "" "")
10269 (match_operand:P 2 "symbol_ref_operand" "s")
10270 (match_operand:P 3 "" "")]
10274 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10277 (define_insn "*pltseq_plt16_lo_<mode>"
10278 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10279 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10280 (match_operand:P 2 "symbol_ref_operand" "s")
10281 (match_operand:P 3 "" "")]
10285 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10287 [(set_attr "type" "load")])
10289 (define_insn "*pltseq_mtctr_<mode>"
10290 [(set (match_operand:P 0 "register_operand" "=c")
10291 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10292 (match_operand:P 2 "symbol_ref_operand" "s")
10293 (match_operand:P 3 "" "")]
10297 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10300 (define_insn "*pltseq_plt_pcrel<mode>"
10301 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10302 (unspec:P [(match_operand:P 1 "" "")
10303 (match_operand:P 2 "symbol_ref_operand" "s")
10304 (match_operand:P 3 "" "")]
10305 UNSPEC_PLT_PCREL))]
10306 "HAVE_AS_PLTSEQ && TARGET_ELF
10307 && rs6000_pcrel_p (cfun)"
10309 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10311 [(set_attr "type" "load")
10312 (set_attr "length" "12")])
10314 ;; Call and call_value insns
10315 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10316 (define_expand "call"
10317 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10318 (match_operand 1 ""))
10319 (use (match_operand 2 ""))
10320 (clobber (reg:SI LR_REGNO))])]
10324 if (MACHOPIC_INDIRECT)
10325 operands[0] = machopic_indirect_call_target (operands[0]);
10328 gcc_assert (MEM_P (operands[0]));
10330 operands[0] = XEXP (operands[0], 0);
10332 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10333 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10334 else if (DEFAULT_ABI == ABI_V4)
10335 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10336 else if (DEFAULT_ABI == ABI_DARWIN)
10337 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10339 gcc_unreachable ();
10344 (define_expand "call_value"
10345 [(parallel [(set (match_operand 0 "")
10346 (call (mem:SI (match_operand 1 "address_operand"))
10347 (match_operand 2 "")))
10348 (use (match_operand 3 ""))
10349 (clobber (reg:SI LR_REGNO))])]
10353 if (MACHOPIC_INDIRECT)
10354 operands[1] = machopic_indirect_call_target (operands[1]);
10357 gcc_assert (MEM_P (operands[1]));
10359 operands[1] = XEXP (operands[1], 0);
10361 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10362 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10363 else if (DEFAULT_ABI == ABI_V4)
10364 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10365 else if (DEFAULT_ABI == ABI_DARWIN)
10366 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10368 gcc_unreachable ();
10373 ;; Call to function in current module. No TOC pointer reload needed.
10374 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10375 ;; either the function was not prototyped, or it was prototyped as a
10376 ;; variable argument function. It is > 0 if FP registers were passed
10377 ;; and < 0 if they were not.
10379 (define_insn "*call_local32"
10380 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10382 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10383 (clobber (reg:SI LR_REGNO))]
10384 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10386 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10387 output_asm_insn ("crxor 6,6,6", operands);
10389 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10390 output_asm_insn ("creqv 6,6,6", operands);
10392 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10394 [(set_attr "type" "branch")
10395 (set_attr "length" "4,8")])
10397 (define_insn "*call_local64"
10398 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10400 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10401 (clobber (reg:DI LR_REGNO))]
10402 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10404 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10405 output_asm_insn ("crxor 6,6,6", operands);
10407 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10408 output_asm_insn ("creqv 6,6,6", operands);
10410 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10412 [(set_attr "type" "branch")
10413 (set_attr "length" "4,8")])
10415 (define_insn "*call_value_local32"
10416 [(set (match_operand 0 "" "")
10417 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10418 (match_operand 2)))
10419 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10420 (clobber (reg:SI LR_REGNO))]
10421 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10423 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10424 output_asm_insn ("crxor 6,6,6", operands);
10426 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10427 output_asm_insn ("creqv 6,6,6", operands);
10429 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10431 [(set_attr "type" "branch")
10432 (set_attr "length" "4,8")])
10435 (define_insn "*call_value_local64"
10436 [(set (match_operand 0 "" "")
10437 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10438 (match_operand 2)))
10439 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10440 (clobber (reg:DI LR_REGNO))]
10441 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10443 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10444 output_asm_insn ("crxor 6,6,6", operands);
10446 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10447 output_asm_insn ("creqv 6,6,6", operands);
10449 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10451 [(set_attr "type" "branch")
10452 (set_attr "length" "4,8")])
10455 ;; A function pointer under System V is just a normal pointer
10456 ;; operands[0] is the function pointer
10457 ;; operands[1] is the tls call arg
10458 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10459 ;; which indicates how to set cr1
10461 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10462 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10464 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10465 (clobber (reg:P LR_REGNO))]
10466 "DEFAULT_ABI == ABI_V4
10467 || DEFAULT_ABI == ABI_DARWIN"
10469 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10470 output_asm_insn ("crxor 6,6,6", operands);
10472 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10473 output_asm_insn ("creqv 6,6,6", operands);
10475 return rs6000_indirect_call_template (operands, 0);
10477 [(set_attr "type" "jmpreg")
10478 (set (attr "length")
10479 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10480 (match_test "which_alternative != 1"))
10481 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10482 (const_string "12")
10483 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10484 (match_test "which_alternative != 1"))
10485 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10486 (const_string "8")]
10487 (const_string "4")))])
10489 (define_insn "*call_nonlocal_sysv<mode>"
10490 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10492 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10493 (clobber (reg:P LR_REGNO))]
10494 "(DEFAULT_ABI == ABI_DARWIN
10495 || (DEFAULT_ABI == ABI_V4
10496 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10498 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10499 output_asm_insn ("crxor 6,6,6", operands);
10501 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10502 output_asm_insn ("creqv 6,6,6", operands);
10504 return rs6000_call_template (operands, 0);
10506 [(set_attr "type" "branch,branch")
10507 (set_attr "length" "4,8")])
10509 (define_insn "*call_nonlocal_sysv_secure<mode>"
10510 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10512 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10513 (use (match_operand:SI 3 "register_operand" "r,r"))
10514 (clobber (reg:P LR_REGNO))]
10515 "(DEFAULT_ABI == ABI_V4
10516 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10517 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
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_call_template (operands, 0);
10527 [(set_attr "type" "branch,branch")
10528 (set_attr "length" "4,8")])
10530 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10531 [(set (match_operand 0 "" "")
10532 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10533 (match_operand:P 2 "unspec_tls" "")))
10534 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10535 (clobber (reg:P LR_REGNO))]
10536 "DEFAULT_ABI == ABI_V4
10537 || DEFAULT_ABI == ABI_DARWIN"
10539 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10540 output_asm_insn ("crxor 6,6,6", operands);
10542 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10543 output_asm_insn ("creqv 6,6,6", operands);
10545 return rs6000_indirect_call_template (operands, 1);
10547 [(set_attr "type" "jmpreg")
10548 (set (attr "length")
10550 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10553 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10554 (match_test "which_alternative != 1"))
10558 (define_insn "*call_value_nonlocal_sysv<mode>"
10559 [(set (match_operand 0 "" "")
10560 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10561 (match_operand:P 2 "unspec_tls" "")))
10562 (use (match_operand:SI 3 "immediate_operand" "n"))
10563 (clobber (reg:P LR_REGNO))]
10564 "(DEFAULT_ABI == ABI_DARWIN
10565 || (DEFAULT_ABI == ABI_V4
10566 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10568 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10569 output_asm_insn ("crxor 6,6,6", operands);
10571 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10572 output_asm_insn ("creqv 6,6,6", operands);
10574 return rs6000_call_template (operands, 1);
10576 [(set_attr "type" "branch")
10577 (set (attr "length")
10578 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10582 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10583 [(set (match_operand 0 "" "")
10584 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10585 (match_operand:P 2 "unspec_tls" "")))
10586 (use (match_operand:SI 3 "immediate_operand" "n"))
10587 (use (match_operand:SI 4 "register_operand" "r"))
10588 (clobber (reg:P LR_REGNO))]
10589 "(DEFAULT_ABI == ABI_V4
10590 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10591 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10593 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10594 output_asm_insn ("crxor 6,6,6", operands);
10596 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10597 output_asm_insn ("creqv 6,6,6", operands);
10599 return rs6000_call_template (operands, 1);
10601 [(set_attr "type" "branch")
10602 (set (attr "length")
10603 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10607 ;; Call to AIX abi function in the same module.
10609 (define_insn "*call_local_aix<mode>"
10610 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10612 (clobber (reg:P LR_REGNO))]
10613 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10615 if (rs6000_pcrel_p (cfun))
10616 return "bl %z0@notoc";
10619 [(set_attr "type" "branch")])
10621 (define_insn "*call_value_local_aix<mode>"
10622 [(set (match_operand 0 "" "")
10623 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10624 (match_operand 2)))
10625 (clobber (reg:P LR_REGNO))]
10626 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10628 if (rs6000_pcrel_p (cfun))
10629 return "bl %z1@notoc";
10632 [(set_attr "type" "branch")])
10634 ;; Call to AIX abi function which may be in another module.
10635 ;; Restore the TOC pointer (r2) after the call.
10637 (define_insn "*call_nonlocal_aix<mode>"
10638 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10640 (clobber (reg:P LR_REGNO))]
10641 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10643 return rs6000_call_template (operands, 0);
10645 [(set_attr "type" "branch")
10646 (set (attr "length")
10647 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10651 (define_insn "*call_value_nonlocal_aix<mode>"
10652 [(set (match_operand 0 "" "")
10653 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10654 (match_operand:P 2 "unspec_tls" "")))
10655 (clobber (reg:P LR_REGNO))]
10656 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10658 return rs6000_call_template (operands, 1);
10660 [(set_attr "type" "branch")
10661 (set (attr "length")
10662 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10666 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10667 ;; Operand0 is the addresss of the function to call
10668 ;; Operand2 is the location in the function descriptor to load r2 from
10669 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10671 (define_insn "*call_indirect_aix<mode>"
10672 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10674 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10675 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10676 (clobber (reg:P LR_REGNO))]
10677 "DEFAULT_ABI == ABI_AIX"
10679 return rs6000_indirect_call_template (operands, 0);
10681 [(set_attr "type" "jmpreg")
10682 (set (attr "length")
10683 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10684 (match_test "which_alternative != 1"))
10685 (const_string "16")
10686 (const_string "12")))])
10688 (define_insn "*call_value_indirect_aix<mode>"
10689 [(set (match_operand 0 "" "")
10690 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10691 (match_operand:P 2 "unspec_tls" "")))
10692 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10693 (set (reg:P TOC_REGNUM)
10694 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10696 (clobber (reg:P LR_REGNO))]
10697 "DEFAULT_ABI == ABI_AIX"
10699 return rs6000_indirect_call_template (operands, 1);
10701 [(set_attr "type" "jmpreg")
10702 (set (attr "length")
10703 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10704 (match_test "which_alternative != 1"))
10705 (const_string "16")
10706 (const_string "12")))])
10708 ;; Call to indirect functions with the ELFv2 ABI.
10709 ;; Operand0 is the addresss of the function to call
10710 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10712 (define_insn "*call_indirect_elfv2<mode>"
10713 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10715 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10716 (clobber (reg:P LR_REGNO))]
10717 "DEFAULT_ABI == ABI_ELFv2"
10719 return rs6000_indirect_call_template (operands, 0);
10721 [(set_attr "type" "jmpreg")
10722 (set (attr "length")
10723 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10724 (match_test "which_alternative != 1"))
10725 (const_string "12")
10726 (const_string "8")))])
10728 (define_insn "*call_indirect_pcrel<mode>"
10729 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10731 (clobber (reg:P LR_REGNO))]
10732 "rs6000_pcrel_p (cfun)"
10734 return rs6000_indirect_call_template (operands, 0);
10736 [(set_attr "type" "jmpreg")
10737 (set (attr "length")
10738 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10739 (match_test "which_alternative != 1"))
10741 (const_string "4")))])
10743 (define_insn "*call_value_indirect_elfv2<mode>"
10744 [(set (match_operand 0 "" "")
10745 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10746 (match_operand:P 2 "unspec_tls" "")))
10747 (set (reg:P TOC_REGNUM)
10748 (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")]
10750 (clobber (reg:P LR_REGNO))]
10751 "DEFAULT_ABI == ABI_ELFv2"
10753 return rs6000_indirect_call_template (operands, 1);
10755 [(set_attr "type" "jmpreg")
10756 (set (attr "length")
10757 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10758 (match_test "which_alternative != 1"))
10759 (const_string "12")
10760 (const_string "8")))])
10762 (define_insn "*call_value_indirect_pcrel<mode>"
10763 [(set (match_operand 0 "" "")
10764 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10765 (match_operand:P 2 "unspec_tls" "")))
10766 (clobber (reg:P LR_REGNO))]
10767 "rs6000_pcrel_p (cfun)"
10769 return rs6000_indirect_call_template (operands, 1);
10771 [(set_attr "type" "jmpreg")
10772 (set (attr "length")
10773 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10774 (match_test "which_alternative != 1"))
10776 (const_string "4")))])
10778 ;; Call subroutine returning any type.
10779 (define_expand "untyped_call"
10780 [(parallel [(call (match_operand 0 "")
10782 (match_operand 1 "")
10783 (match_operand 2 "")])]
10788 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10790 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10792 rtx set = XVECEXP (operands[2], 0, i);
10793 emit_move_insn (SET_DEST (set), SET_SRC (set));
10796 /* The optimizer does not know that the call sets the function value
10797 registers we stored in the result block. We avoid problems by
10798 claiming that all hard registers are used and clobbered at this
10800 emit_insn (gen_blockage ());
10805 ;; sibling call patterns
10806 (define_expand "sibcall"
10807 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10808 (match_operand 1 ""))
10809 (use (match_operand 2 ""))
10814 if (MACHOPIC_INDIRECT)
10815 operands[0] = machopic_indirect_call_target (operands[0]);
10818 gcc_assert (MEM_P (operands[0]));
10819 gcc_assert (CONST_INT_P (operands[1]));
10821 operands[0] = XEXP (operands[0], 0);
10823 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10824 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10825 else if (DEFAULT_ABI == ABI_V4)
10826 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10827 else if (DEFAULT_ABI == ABI_DARWIN)
10828 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10830 gcc_unreachable ();
10835 (define_expand "sibcall_value"
10836 [(parallel [(set (match_operand 0 "register_operand")
10837 (call (mem:SI (match_operand 1 "address_operand"))
10838 (match_operand 2 "")))
10839 (use (match_operand 3 ""))
10844 if (MACHOPIC_INDIRECT)
10845 operands[1] = machopic_indirect_call_target (operands[1]);
10848 gcc_assert (MEM_P (operands[1]));
10849 gcc_assert (CONST_INT_P (operands[2]));
10851 operands[1] = XEXP (operands[1], 0);
10853 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10854 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10855 else if (DEFAULT_ABI == ABI_V4)
10856 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10857 else if (DEFAULT_ABI == ABI_DARWIN)
10858 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10860 gcc_unreachable ();
10865 (define_insn "*sibcall_local32"
10866 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10868 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10870 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10872 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10873 output_asm_insn ("crxor 6,6,6", operands);
10875 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10876 output_asm_insn ("creqv 6,6,6", operands);
10878 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10880 [(set_attr "type" "branch")
10881 (set_attr "length" "4,8")])
10883 (define_insn "*sibcall_local64"
10884 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10886 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10888 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10890 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10891 output_asm_insn ("crxor 6,6,6", operands);
10893 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10894 output_asm_insn ("creqv 6,6,6", operands);
10896 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10898 [(set_attr "type" "branch")
10899 (set_attr "length" "4,8")])
10901 (define_insn "*sibcall_value_local32"
10902 [(set (match_operand 0 "" "")
10903 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10904 (match_operand 2)))
10905 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10907 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10909 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10910 output_asm_insn ("crxor 6,6,6", operands);
10912 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10913 output_asm_insn ("creqv 6,6,6", operands);
10915 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10917 [(set_attr "type" "branch")
10918 (set_attr "length" "4,8")])
10920 (define_insn "*sibcall_value_local64"
10921 [(set (match_operand 0 "" "")
10922 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10923 (match_operand 2)))
10924 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10926 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10928 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10929 output_asm_insn ("crxor 6,6,6", operands);
10931 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10932 output_asm_insn ("creqv 6,6,6", operands);
10934 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10936 [(set_attr "type" "branch")
10937 (set_attr "length" "4,8")])
10939 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10940 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10942 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10944 "DEFAULT_ABI == ABI_V4
10945 || DEFAULT_ABI == ABI_DARWIN"
10947 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10948 output_asm_insn ("crxor 6,6,6", operands);
10950 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10951 output_asm_insn ("creqv 6,6,6", operands);
10953 return rs6000_indirect_sibcall_template (operands, 0);
10955 [(set_attr "type" "jmpreg")
10956 (set (attr "length")
10957 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10958 (match_test "which_alternative != 1"))
10959 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10960 (const_string "12")
10961 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10962 (match_test "which_alternative != 1"))
10963 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10964 (const_string "8")]
10965 (const_string "4")))])
10967 (define_insn "*sibcall_nonlocal_sysv<mode>"
10968 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10970 (use (match_operand 2 "immediate_operand" "O,n"))
10972 "(DEFAULT_ABI == ABI_DARWIN
10973 || DEFAULT_ABI == ABI_V4)
10974 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10976 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10977 output_asm_insn ("crxor 6,6,6", operands);
10979 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10980 output_asm_insn ("creqv 6,6,6", operands);
10982 return rs6000_sibcall_template (operands, 0);
10984 [(set_attr "type" "branch")
10985 (set_attr "length" "4,8")])
10987 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
10988 [(set (match_operand 0 "" "")
10989 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10990 (match_operand 2)))
10991 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10993 "DEFAULT_ABI == ABI_V4
10994 || DEFAULT_ABI == ABI_DARWIN"
10996 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10997 output_asm_insn ("crxor 6,6,6", operands);
10999 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11000 output_asm_insn ("creqv 6,6,6", operands);
11002 return rs6000_indirect_sibcall_template (operands, 1);
11004 [(set_attr "type" "jmpreg")
11005 (set (attr "length")
11006 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11007 (match_test "which_alternative != 1"))
11008 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11009 (const_string "12")
11010 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11011 (match_test "which_alternative != 1"))
11012 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11013 (const_string "8")]
11014 (const_string "4")))])
11016 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11017 [(set (match_operand 0 "" "")
11018 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11019 (match_operand 2)))
11020 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11022 "(DEFAULT_ABI == ABI_DARWIN
11023 || DEFAULT_ABI == ABI_V4)
11024 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11026 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11027 output_asm_insn ("crxor 6,6,6", operands);
11029 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11030 output_asm_insn ("creqv 6,6,6", operands);
11032 return rs6000_sibcall_template (operands, 1);
11034 [(set_attr "type" "branch")
11035 (set_attr "length" "4,8")])
11037 ;; AIX ABI sibling call patterns.
11039 (define_insn "*sibcall_aix<mode>"
11040 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11043 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11045 if (which_alternative == 0)
11046 return rs6000_sibcall_template (operands, 0);
11050 [(set_attr "type" "branch")])
11052 (define_insn "*sibcall_value_aix<mode>"
11053 [(set (match_operand 0 "" "")
11054 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11055 (match_operand 2)))
11057 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11059 if (which_alternative == 0)
11060 return rs6000_sibcall_template (operands, 1);
11064 [(set_attr "type" "branch")])
11066 (define_expand "sibcall_epilogue"
11067 [(use (const_int 0))]
11070 if (!TARGET_SCHED_PROLOG)
11071 emit_insn (gen_blockage ());
11072 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11076 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11077 ;; all of memory. This blocks insns from being moved across this point.
11079 (define_insn "blockage"
11080 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11083 [(set_attr "length" "0")])
11085 (define_expand "probe_stack_address"
11086 [(use (match_operand 0 "address_operand"))]
11089 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11090 MEM_VOLATILE_P (operands[0]) = 1;
11093 emit_insn (gen_probe_stack_di (operands[0]));
11095 emit_insn (gen_probe_stack_si (operands[0]));
11099 (define_insn "probe_stack_<mode>"
11100 [(set (match_operand:P 0 "memory_operand" "=m")
11101 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11104 operands[1] = gen_rtx_REG (Pmode, 0);
11105 return "st<wd>%U0%X0 %1,%0";
11107 [(set_attr "type" "store")
11108 (set (attr "update")
11109 (if_then_else (match_operand 0 "update_address_mem")
11110 (const_string "yes")
11111 (const_string "no")))
11112 (set (attr "indexed")
11113 (if_then_else (match_operand 0 "indexed_address_mem")
11114 (const_string "yes")
11115 (const_string "no")))])
11117 (define_insn "probe_stack_range<P:mode>"
11118 [(set (match_operand:P 0 "register_operand" "=&r")
11119 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11120 (match_operand:P 2 "register_operand" "r")
11121 (match_operand:P 3 "register_operand" "r")]
11122 UNSPECV_PROBE_STACK_RANGE))]
11124 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11125 [(set_attr "type" "three")])
11127 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11128 ;; signed & unsigned, and one type of branch.
11130 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11131 ;; insns, and branches.
11133 (define_expand "cbranch<mode>4"
11134 [(use (match_operator 0 "comparison_operator"
11135 [(match_operand:GPR 1 "gpc_reg_operand")
11136 (match_operand:GPR 2 "reg_or_short_operand")]))
11137 (use (match_operand 3))]
11140 /* Take care of the possibility that operands[2] might be negative but
11141 this might be a logical operation. That insn doesn't exist. */
11142 if (CONST_INT_P (operands[2])
11143 && INTVAL (operands[2]) < 0)
11145 operands[2] = force_reg (<MODE>mode, operands[2]);
11146 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11147 GET_MODE (operands[0]),
11148 operands[1], operands[2]);
11151 rs6000_emit_cbranch (<MODE>mode, operands);
11155 (define_expand "cbranch<mode>4"
11156 [(use (match_operator 0 "comparison_operator"
11157 [(match_operand:FP 1 "gpc_reg_operand")
11158 (match_operand:FP 2 "gpc_reg_operand")]))
11159 (use (match_operand 3))]
11162 rs6000_emit_cbranch (<MODE>mode, operands);
11166 (define_expand "cstore<mode>4_signed"
11167 [(use (match_operator 1 "signed_comparison_operator"
11168 [(match_operand:P 2 "gpc_reg_operand")
11169 (match_operand:P 3 "gpc_reg_operand")]))
11170 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11173 enum rtx_code cond_code = GET_CODE (operands[1]);
11175 rtx op0 = operands[0];
11176 rtx op1 = operands[2];
11177 rtx op2 = operands[3];
11179 if (cond_code == GE || cond_code == LT)
11181 cond_code = swap_condition (cond_code);
11182 std::swap (op1, op2);
11185 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11186 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11187 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11189 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11190 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11191 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11193 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11195 if (cond_code == LE)
11196 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11199 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11200 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11201 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11207 (define_expand "cstore<mode>4_unsigned"
11208 [(use (match_operator 1 "unsigned_comparison_operator"
11209 [(match_operand:P 2 "gpc_reg_operand")
11210 (match_operand:P 3 "reg_or_short_operand")]))
11211 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11214 enum rtx_code cond_code = GET_CODE (operands[1]);
11216 rtx op0 = operands[0];
11217 rtx op1 = operands[2];
11218 rtx op2 = operands[3];
11220 if (cond_code == GEU || cond_code == LTU)
11222 cond_code = swap_condition (cond_code);
11223 std::swap (op1, op2);
11226 if (!gpc_reg_operand (op1, <MODE>mode))
11227 op1 = force_reg (<MODE>mode, op1);
11228 if (!reg_or_short_operand (op2, <MODE>mode))
11229 op2 = force_reg (<MODE>mode, op2);
11231 rtx tmp = gen_reg_rtx (<MODE>mode);
11232 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11234 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11235 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11237 if (cond_code == LEU)
11238 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11240 emit_insn (gen_neg<mode>2 (op0, tmp2));
11245 (define_expand "cstore_si_as_di"
11246 [(use (match_operator 1 "unsigned_comparison_operator"
11247 [(match_operand:SI 2 "gpc_reg_operand")
11248 (match_operand:SI 3 "reg_or_short_operand")]))
11249 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11252 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11253 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11255 operands[2] = force_reg (SImode, operands[2]);
11256 operands[3] = force_reg (SImode, operands[3]);
11257 rtx op1 = gen_reg_rtx (DImode);
11258 rtx op2 = gen_reg_rtx (DImode);
11259 convert_move (op1, operands[2], uns_flag);
11260 convert_move (op2, operands[3], uns_flag);
11262 if (cond_code == GT || cond_code == LE)
11264 cond_code = swap_condition (cond_code);
11265 std::swap (op1, op2);
11268 rtx tmp = gen_reg_rtx (DImode);
11269 rtx tmp2 = gen_reg_rtx (DImode);
11270 emit_insn (gen_subdi3 (tmp, op1, op2));
11271 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11277 gcc_unreachable ();
11282 tmp3 = gen_reg_rtx (DImode);
11283 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11287 convert_move (operands[0], tmp3, 1);
11292 (define_expand "cstore<mode>4_signed_imm"
11293 [(use (match_operator 1 "signed_comparison_operator"
11294 [(match_operand:GPR 2 "gpc_reg_operand")
11295 (match_operand:GPR 3 "immediate_operand")]))
11296 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11299 bool invert = false;
11301 enum rtx_code cond_code = GET_CODE (operands[1]);
11303 rtx op0 = operands[0];
11304 rtx op1 = operands[2];
11305 HOST_WIDE_INT val = INTVAL (operands[3]);
11307 if (cond_code == GE || cond_code == GT)
11309 cond_code = reverse_condition (cond_code);
11313 if (cond_code == LE)
11316 rtx tmp = gen_reg_rtx (<MODE>mode);
11317 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11318 rtx x = gen_reg_rtx (<MODE>mode);
11320 emit_insn (gen_and<mode>3 (x, op1, tmp));
11322 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11326 rtx tmp = gen_reg_rtx (<MODE>mode);
11327 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11331 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11332 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11337 (define_expand "cstore<mode>4_unsigned_imm"
11338 [(use (match_operator 1 "unsigned_comparison_operator"
11339 [(match_operand:GPR 2 "gpc_reg_operand")
11340 (match_operand:GPR 3 "immediate_operand")]))
11341 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11344 bool invert = false;
11346 enum rtx_code cond_code = GET_CODE (operands[1]);
11348 rtx op0 = operands[0];
11349 rtx op1 = operands[2];
11350 HOST_WIDE_INT val = INTVAL (operands[3]);
11352 if (cond_code == GEU || cond_code == GTU)
11354 cond_code = reverse_condition (cond_code);
11358 if (cond_code == LEU)
11361 rtx tmp = gen_reg_rtx (<MODE>mode);
11362 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11363 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11364 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11365 rtx x = gen_reg_rtx (<MODE>mode);
11367 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11369 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11373 rtx tmp = gen_reg_rtx (<MODE>mode);
11374 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11378 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11379 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11384 (define_expand "cstore<mode>4"
11385 [(use (match_operator 1 "comparison_operator"
11386 [(match_operand:GPR 2 "gpc_reg_operand")
11387 (match_operand:GPR 3 "reg_or_short_operand")]))
11388 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11391 /* Expanding EQ and NE directly to some machine instructions does not help
11392 but does hurt combine. So don't. */
11393 if (GET_CODE (operands[1]) == EQ)
11394 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11395 else if (<MODE>mode == Pmode
11396 && GET_CODE (operands[1]) == NE)
11397 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11398 else if (GET_CODE (operands[1]) == NE)
11400 rtx tmp = gen_reg_rtx (<MODE>mode);
11401 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11402 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11405 /* If ISEL is fast, expand to it. */
11406 else if (TARGET_ISEL)
11407 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11409 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11410 etc. combinations magically work out just right. */
11411 else if (<MODE>mode == Pmode
11412 && unsigned_comparison_operator (operands[1], VOIDmode))
11413 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11414 operands[2], operands[3]));
11416 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11417 else if (<MODE>mode == SImode && Pmode == DImode)
11418 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11419 operands[2], operands[3]));
11421 /* For signed comparisons against a constant, we can do some simple
11423 else if (signed_comparison_operator (operands[1], VOIDmode)
11424 && CONST_INT_P (operands[3]))
11425 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11426 operands[2], operands[3]));
11428 /* And similarly for unsigned comparisons. */
11429 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11430 && CONST_INT_P (operands[3]))
11431 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11432 operands[2], operands[3]));
11434 /* We also do not want to use mfcr for signed comparisons. */
11435 else if (<MODE>mode == Pmode
11436 && signed_comparison_operator (operands[1], VOIDmode))
11437 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11438 operands[2], operands[3]));
11440 /* Everything else, use the mfcr brute force. */
11442 rs6000_emit_sCOND (<MODE>mode, operands);
11447 (define_expand "cstore<mode>4"
11448 [(use (match_operator 1 "comparison_operator"
11449 [(match_operand:FP 2 "gpc_reg_operand")
11450 (match_operand:FP 3 "gpc_reg_operand")]))
11451 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11454 rs6000_emit_sCOND (<MODE>mode, operands);
11459 (define_expand "stack_protect_set"
11460 [(match_operand 0 "memory_operand")
11461 (match_operand 1 "memory_operand")]
11464 if (rs6000_stack_protector_guard == SSP_TLS)
11466 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11467 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11468 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11469 operands[1] = gen_rtx_MEM (Pmode, addr);
11473 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11475 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11480 (define_insn "stack_protect_setsi"
11481 [(set (match_operand:SI 0 "memory_operand" "=m")
11482 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11483 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11485 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11486 [(set_attr "type" "three")
11487 (set_attr "length" "12")])
11489 ;; We can't use the prefixed attribute here because there are two memory
11490 ;; instructions. We can't split the insn due to the fact that this operation
11491 ;; needs to be done in one piece.
11492 (define_insn "stack_protect_setdi"
11493 [(set (match_operand:DI 0 "memory_operand" "=Y")
11494 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11495 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11498 if (prefixed_memory (operands[1], DImode))
11499 output_asm_insn ("pld %2,%1", operands);
11501 output_asm_insn ("ld%U1%X1 %2,%1", operands);
11503 if (prefixed_memory (operands[0], DImode))
11504 output_asm_insn ("pstd %2,%0", operands);
11506 output_asm_insn ("std%U0%X0 %2,%0", operands);
11510 [(set_attr "type" "three")
11512 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11513 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
11514 ;; the LI 0 at the end.
11515 (set_attr "prefixed" "no")
11516 (set_attr "num_insns" "3")
11517 (set (attr "length")
11518 (cond [(and (match_operand 0 "prefixed_memory")
11519 (match_operand 1 "prefixed_memory"))
11522 (ior (match_operand 0 "prefixed_memory")
11523 (match_operand 1 "prefixed_memory"))
11528 (define_expand "stack_protect_test"
11529 [(match_operand 0 "memory_operand")
11530 (match_operand 1 "memory_operand")
11531 (match_operand 2 "")]
11534 rtx guard = operands[1];
11536 if (rs6000_stack_protector_guard == SSP_TLS)
11538 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11539 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11540 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11541 guard = gen_rtx_MEM (Pmode, addr);
11544 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11545 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11546 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11547 emit_jump_insn (jump);
11552 (define_insn "stack_protect_testsi"
11553 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11554 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11555 (match_operand:SI 2 "memory_operand" "m,m")]
11557 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11558 (clobber (match_scratch:SI 3 "=&r,&r"))]
11561 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11562 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11563 [(set_attr "length" "16,20")])
11565 ;; We can't use the prefixed attribute here because there are two memory
11566 ;; instructions. We can't split the insn due to the fact that this operation
11567 ;; needs to be done in one piece.
11568 (define_insn "stack_protect_testdi"
11569 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11570 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11571 (match_operand:DI 2 "memory_operand" "Y,Y")]
11573 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11574 (clobber (match_scratch:DI 3 "=&r,&r"))]
11577 if (prefixed_memory (operands[1], DImode))
11578 output_asm_insn ("pld %3,%1", operands);
11580 output_asm_insn ("ld%U1%X1 %3,%1", operands);
11582 if (prefixed_memory (operands[2], DImode))
11583 output_asm_insn ("pld %4,%2", operands);
11585 output_asm_insn ("ld%U2%X2 %4,%2", operands);
11587 if (which_alternative == 0)
11588 output_asm_insn ("xor. %3,%3,%4", operands);
11590 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11594 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11595 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
11596 ;; 8 bytes to do the test.
11597 [(set_attr "prefixed" "no")
11598 (set_attr "num_insns" "4,5")
11599 (set (attr "length")
11600 (cond [(and (match_operand 1 "prefixed_memory")
11601 (match_operand 2 "prefixed_memory"))
11602 (if_then_else (eq_attr "alternative" "0")
11606 (ior (match_operand 1 "prefixed_memory")
11607 (match_operand 2 "prefixed_memory"))
11608 (if_then_else (eq_attr "alternative" "0")
11612 (if_then_else (eq_attr "alternative" "0")
11614 (const_int 20))))])
11617 ;; Here are the actual compare insns.
11618 (define_insn "*cmp<mode>_signed"
11619 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11620 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11621 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11623 "cmp<wd>%I2 %0,%1,%2"
11624 [(set_attr "type" "cmp")])
11626 (define_insn "*cmp<mode>_unsigned"
11627 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11628 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11629 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11631 "cmpl<wd>%I2 %0,%1,%2"
11632 [(set_attr "type" "cmp")])
11634 ;; If we are comparing a register for equality with a large constant,
11635 ;; we can do this with an XOR followed by a compare. But this is profitable
11636 ;; only if the large constant is only used for the comparison (and in this
11637 ;; case we already have a register to reuse as scratch).
11639 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11640 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11643 [(set (match_operand:SI 0 "register_operand")
11644 (match_operand:SI 1 "logical_const_operand"))
11645 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11647 (match_operand:SI 2 "logical_const_operand")]))
11648 (set (match_operand:CC 4 "cc_reg_operand")
11649 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11652 (if_then_else (match_operator 6 "equality_operator"
11653 [(match_dup 4) (const_int 0)])
11654 (match_operand 7 "")
11655 (match_operand 8 "")))]
11656 "peep2_reg_dead_p (3, operands[0])
11657 && peep2_reg_dead_p (4, operands[4])
11658 && REGNO (operands[0]) != REGNO (operands[5])"
11659 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11660 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11661 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11664 /* Get the constant we are comparing against, and see what it looks like
11665 when sign-extended from 16 to 32 bits. Then see what constant we could
11666 XOR with SEXTC to get the sign-extended value. */
11667 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11669 operands[1], operands[2]);
11670 HOST_WIDE_INT c = INTVAL (cnst);
11671 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11672 HOST_WIDE_INT xorv = c ^ sextc;
11674 operands[9] = GEN_INT (xorv);
11675 operands[10] = GEN_INT (sextc);
11678 ;; Only need to compare second words if first words equal
11679 (define_insn "*cmp<mode>_internal1"
11680 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11681 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11682 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11683 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11684 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11685 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11686 [(set_attr "type" "fpcompare")
11687 (set_attr "length" "12")])
11689 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11690 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11691 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11692 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11693 (clobber (match_scratch:DF 3 "=d"))
11694 (clobber (match_scratch:DF 4 "=d"))
11695 (clobber (match_scratch:DF 5 "=d"))
11696 (clobber (match_scratch:DF 6 "=d"))
11697 (clobber (match_scratch:DF 7 "=d"))
11698 (clobber (match_scratch:DF 8 "=d"))
11699 (clobber (match_scratch:DF 9 "=d"))
11700 (clobber (match_scratch:DF 10 "=d"))
11701 (clobber (match_scratch:GPR 11 "=b"))]
11702 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11703 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11705 "&& reload_completed"
11706 [(set (match_dup 3) (match_dup 14))
11707 (set (match_dup 4) (match_dup 15))
11708 (set (match_dup 9) (abs:DF (match_dup 5)))
11709 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11710 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11711 (label_ref (match_dup 12))
11713 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11714 (set (pc) (label_ref (match_dup 13)))
11716 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11717 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11718 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11719 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11722 REAL_VALUE_TYPE rv;
11723 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11724 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11726 operands[5] = simplify_gen_subreg (DFmode, operands[1],
11727 <IBM128:MODE>mode, hi_word);
11728 operands[6] = simplify_gen_subreg (DFmode, operands[1],
11729 <IBM128:MODE>mode, lo_word);
11730 operands[7] = simplify_gen_subreg (DFmode, operands[2],
11731 <IBM128:MODE>mode, hi_word);
11732 operands[8] = simplify_gen_subreg (DFmode, operands[2],
11733 <IBM128:MODE>mode, lo_word);
11734 operands[12] = gen_label_rtx ();
11735 operands[13] = gen_label_rtx ();
11737 operands[14] = force_const_mem (DFmode,
11738 const_double_from_real_value (rv, DFmode));
11739 operands[15] = force_const_mem (DFmode,
11740 const_double_from_real_value (dconst0,
11745 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11746 operands[14] = gen_const_mem (DFmode, tocref);
11747 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11748 operands[15] = gen_const_mem (DFmode, tocref);
11749 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11750 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11754 ;; Now we have the scc insns. We can do some combinations because of the
11755 ;; way the machine works.
11757 ;; Note that this is probably faster if we can put an insn between the
11758 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11759 ;; cases the insns below which don't use an intermediate CR field will
11760 ;; be used instead.
11762 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11763 (match_operator:GPR 1 "scc_comparison_operator"
11764 [(match_operand 2 "cc_reg_operand" "y")
11767 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11768 [(set (attr "type")
11769 (cond [(match_test "TARGET_MFCRF")
11770 (const_string "mfcrf")
11772 (const_string "mfcr")))
11773 (set_attr "length" "8")])
11775 (define_insn_and_split ""
11776 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11777 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11778 [(match_operand 2 "cc_reg_operand" "y,y")
11781 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11782 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11785 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11787 "&& reload_completed"
11788 [(set (match_dup 3)
11789 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11791 (compare:CC (match_dup 3)
11794 [(set_attr "type" "shift")
11795 (set_attr "dot" "yes")
11796 (set_attr "length" "8,16")])
11799 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11800 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11801 [(match_operand 2 "cc_reg_operand" "y")
11803 (match_operand:SI 3 "const_int_operand" "n")))]
11806 int is_bit = ccr_bit (operands[1], 1);
11807 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11810 gcc_assert (is_bit != -1);
11811 if (is_bit >= put_bit)
11812 count = is_bit - put_bit;
11814 count = 32 - (put_bit - is_bit);
11816 operands[4] = GEN_INT (count);
11817 operands[5] = GEN_INT (put_bit);
11819 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11821 [(set (attr "type")
11822 (cond [(match_test "TARGET_MFCRF")
11823 (const_string "mfcrf")
11825 (const_string "mfcr")))
11826 (set_attr "length" "8")])
11829 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11831 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11832 [(match_operand 2 "cc_reg_operand" "y,y")
11834 (match_operand:SI 3 "const_int_operand" "n,n"))
11836 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11837 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11841 int is_bit = ccr_bit (operands[1], 1);
11842 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11845 gcc_assert (is_bit != -1);
11846 /* Force split for non-cc0 compare. */
11847 if (which_alternative == 1)
11850 if (is_bit >= put_bit)
11851 count = is_bit - put_bit;
11853 count = 32 - (put_bit - is_bit);
11855 operands[5] = GEN_INT (count);
11856 operands[6] = GEN_INT (put_bit);
11858 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11860 [(set_attr "type" "shift")
11861 (set_attr "dot" "yes")
11862 (set_attr "length" "8,16")])
11865 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11867 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11868 [(match_operand 2 "cc_reg_operand")
11870 (match_operand:SI 3 "const_int_operand"))
11872 (set (match_operand:SI 4 "gpc_reg_operand")
11873 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11876 [(set (match_dup 4)
11877 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11880 (compare:CC (match_dup 4)
11885 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11886 (define_code_attr UNS [(eq "CC")
11888 (lt "CC") (ltu "CCUNS")
11889 (gt "CC") (gtu "CCUNS")
11890 (le "CC") (leu "CCUNS")
11891 (ge "CC") (geu "CCUNS")])
11892 (define_code_attr UNSu_ [(eq "")
11897 (ge "") (geu "u_")])
11898 (define_code_attr UNSIK [(eq "I")
11903 (ge "I") (geu "K")])
11905 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11906 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11907 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11908 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11909 (clobber (match_scratch:GPR 3 "=r"))
11910 (clobber (match_scratch:GPR 4 "=r"))
11911 (clobber (match_scratch:<UNS> 5 "=y"))]
11913 && !(<CODE> == EQ && operands[2] == const0_rtx)
11914 && !(<CODE> == NE && operands[2] == const0_rtx
11915 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11920 rtx_code code = <CODE>;
11921 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11923 HOST_WIDE_INT val = INTVAL (operands[2]);
11924 if (code == LT && val != -0x8000)
11929 if (code == GT && val != 0x7fff)
11934 if (code == LTU && val != 0)
11939 if (code == GTU && val != 0xffff)
11944 operands[2] = GEN_INT (val);
11947 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11948 operands[3] = const0_rtx;
11951 if (GET_CODE (operands[3]) == SCRATCH)
11952 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11953 emit_move_insn (operands[3], const0_rtx);
11956 if (GET_CODE (operands[4]) == SCRATCH)
11957 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11958 emit_move_insn (operands[4], const1_rtx);
11960 if (GET_CODE (operands[5]) == SCRATCH)
11961 operands[5] = gen_reg_rtx (<UNS>mode);
11963 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11964 emit_insn (gen_rtx_SET (operands[5], c1));
11966 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11967 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11968 emit_move_insn (operands[0], x);
11972 [(set (attr "cost")
11973 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11975 || <CODE> == LE || <CODE> == GE
11976 || <CODE> == LEU || <CODE> == GEU")
11978 (const_string "10")))])
11980 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11983 (define_expand "eq<mode>3"
11985 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11986 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11987 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11988 (clobber (match_scratch:GPR 3 "=r"))
11989 (clobber (match_scratch:GPR 4 "=r"))])]
11992 if (TARGET_ISEL && operands[2] != const0_rtx)
11994 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12000 (define_insn_and_split "*eq<mode>3"
12001 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12002 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12003 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12004 (clobber (match_scratch:GPR 3 "=r"))
12005 (clobber (match_scratch:GPR 4 "=r"))]
12006 "!(TARGET_ISEL && operands[2] != const0_rtx)"
12009 [(set (match_dup 4)
12010 (clz:GPR (match_dup 3)))
12012 (lshiftrt:GPR (match_dup 4)
12015 operands[3] = rs6000_emit_eqne (<MODE>mode,
12016 operands[1], operands[2], operands[3]);
12018 if (GET_CODE (operands[4]) == SCRATCH)
12019 operands[4] = gen_reg_rtx (<MODE>mode);
12021 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12023 [(set (attr "length")
12024 (if_then_else (match_test "operands[2] == const0_rtx")
12026 (const_string "12")))])
12028 (define_expand "ne<mode>3"
12030 (set (match_operand:P 0 "gpc_reg_operand" "=r")
12031 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12032 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12033 (clobber (match_scratch:P 3 "=r"))
12034 (clobber (match_scratch:P 4 "=r"))
12035 (clobber (reg:P CA_REGNO))])]
12038 if (TARGET_ISEL && operands[2] != const0_rtx)
12040 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12046 (define_insn_and_split "*ne<mode>3"
12047 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12048 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12049 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12050 (clobber (match_scratch:P 3 "=r"))
12051 (clobber (match_scratch:P 4 "=r"))
12052 (clobber (reg:P CA_REGNO))]
12053 "!(TARGET_ISEL && operands[2] != const0_rtx)"
12056 [(parallel [(set (match_dup 4)
12057 (plus:P (match_dup 3)
12059 (set (reg:P CA_REGNO)
12060 (ne:P (match_dup 3)
12062 (parallel [(set (match_dup 0)
12063 (plus:P (plus:P (not:P (match_dup 4))
12066 (clobber (reg:P CA_REGNO))])]
12068 operands[3] = rs6000_emit_eqne (<MODE>mode,
12069 operands[1], operands[2], operands[3]);
12071 if (GET_CODE (operands[4]) == SCRATCH)
12072 operands[4] = gen_reg_rtx (<MODE>mode);
12074 [(set (attr "length")
12075 (if_then_else (match_test "operands[2] == const0_rtx")
12077 (const_string "12")))])
12079 (define_insn_and_split "*neg_eq_<mode>"
12080 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12081 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12082 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12083 (clobber (match_scratch:P 3 "=r"))
12084 (clobber (match_scratch:P 4 "=r"))
12085 (clobber (reg:P CA_REGNO))]
12089 [(parallel [(set (match_dup 4)
12090 (plus:P (match_dup 3)
12092 (set (reg:P CA_REGNO)
12093 (ne:P (match_dup 3)
12095 (parallel [(set (match_dup 0)
12096 (plus:P (reg:P CA_REGNO)
12098 (clobber (reg:P CA_REGNO))])]
12100 operands[3] = rs6000_emit_eqne (<MODE>mode,
12101 operands[1], operands[2], operands[3]);
12103 if (GET_CODE (operands[4]) == SCRATCH)
12104 operands[4] = gen_reg_rtx (<MODE>mode);
12106 [(set (attr "length")
12107 (if_then_else (match_test "operands[2] == const0_rtx")
12109 (const_string "12")))])
12111 (define_insn_and_split "*neg_ne_<mode>"
12112 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12113 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12114 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12115 (clobber (match_scratch:P 3 "=r"))
12116 (clobber (match_scratch:P 4 "=r"))
12117 (clobber (reg:P CA_REGNO))]
12121 [(parallel [(set (match_dup 4)
12122 (neg:P (match_dup 3)))
12123 (set (reg:P CA_REGNO)
12124 (eq:P (match_dup 3)
12126 (parallel [(set (match_dup 0)
12127 (plus:P (reg:P CA_REGNO)
12129 (clobber (reg:P CA_REGNO))])]
12131 operands[3] = rs6000_emit_eqne (<MODE>mode,
12132 operands[1], operands[2], operands[3]);
12134 if (GET_CODE (operands[4]) == SCRATCH)
12135 operands[4] = gen_reg_rtx (<MODE>mode);
12137 [(set (attr "length")
12138 (if_then_else (match_test "operands[2] == const0_rtx")
12140 (const_string "12")))])
12142 (define_insn_and_split "*plus_eq_<mode>"
12143 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12144 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12145 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12146 (match_operand:P 3 "gpc_reg_operand" "r")))
12147 (clobber (match_scratch:P 4 "=r"))
12148 (clobber (match_scratch:P 5 "=r"))
12149 (clobber (reg:P CA_REGNO))]
12153 [(parallel [(set (match_dup 5)
12154 (neg:P (match_dup 4)))
12155 (set (reg:P CA_REGNO)
12156 (eq:P (match_dup 4)
12158 (parallel [(set (match_dup 0)
12159 (plus:P (match_dup 3)
12161 (clobber (reg:P CA_REGNO))])]
12163 operands[4] = rs6000_emit_eqne (<MODE>mode,
12164 operands[1], operands[2], operands[4]);
12166 if (GET_CODE (operands[5]) == SCRATCH)
12167 operands[5] = gen_reg_rtx (<MODE>mode);
12169 [(set (attr "length")
12170 (if_then_else (match_test "operands[2] == const0_rtx")
12172 (const_string "12")))])
12174 (define_insn_and_split "*plus_ne_<mode>"
12175 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12176 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12177 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12178 (match_operand:P 3 "gpc_reg_operand" "r")))
12179 (clobber (match_scratch:P 4 "=r"))
12180 (clobber (match_scratch:P 5 "=r"))
12181 (clobber (reg:P CA_REGNO))]
12185 [(parallel [(set (match_dup 5)
12186 (plus:P (match_dup 4)
12188 (set (reg:P CA_REGNO)
12189 (ne:P (match_dup 4)
12191 (parallel [(set (match_dup 0)
12192 (plus:P (match_dup 3)
12194 (clobber (reg:P CA_REGNO))])]
12196 operands[4] = rs6000_emit_eqne (<MODE>mode,
12197 operands[1], operands[2], operands[4]);
12199 if (GET_CODE (operands[5]) == SCRATCH)
12200 operands[5] = gen_reg_rtx (<MODE>mode);
12202 [(set (attr "length")
12203 (if_then_else (match_test "operands[2] == const0_rtx")
12205 (const_string "12")))])
12207 (define_insn_and_split "*minus_eq_<mode>"
12208 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12209 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12210 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12211 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12212 (clobber (match_scratch:P 4 "=r"))
12213 (clobber (match_scratch:P 5 "=r"))
12214 (clobber (reg:P CA_REGNO))]
12218 [(parallel [(set (match_dup 5)
12219 (plus:P (match_dup 4)
12221 (set (reg:P CA_REGNO)
12222 (ne:P (match_dup 4)
12224 (parallel [(set (match_dup 0)
12225 (plus:P (plus:P (match_dup 3)
12228 (clobber (reg:P CA_REGNO))])]
12230 operands[4] = rs6000_emit_eqne (<MODE>mode,
12231 operands[1], operands[2], operands[4]);
12233 if (GET_CODE (operands[5]) == SCRATCH)
12234 operands[5] = gen_reg_rtx (<MODE>mode);
12236 [(set (attr "length")
12237 (if_then_else (match_test "operands[2] == const0_rtx")
12239 (const_string "12")))])
12241 (define_insn_and_split "*minus_ne_<mode>"
12242 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12243 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12244 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12245 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12246 (clobber (match_scratch:P 4 "=r"))
12247 (clobber (match_scratch:P 5 "=r"))
12248 (clobber (reg:P CA_REGNO))]
12252 [(parallel [(set (match_dup 5)
12253 (neg:P (match_dup 4)))
12254 (set (reg:P CA_REGNO)
12255 (eq:P (match_dup 4)
12257 (parallel [(set (match_dup 0)
12258 (plus:P (plus:P (match_dup 3)
12261 (clobber (reg:P CA_REGNO))])]
12263 operands[4] = rs6000_emit_eqne (<MODE>mode,
12264 operands[1], operands[2], operands[4]);
12266 if (GET_CODE (operands[5]) == SCRATCH)
12267 operands[5] = gen_reg_rtx (<MODE>mode);
12269 [(set (attr "length")
12270 (if_then_else (match_test "operands[2] == const0_rtx")
12272 (const_string "12")))])
12274 (define_insn_and_split "*eqsi3_ext<mode>"
12275 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12276 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12277 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12278 (clobber (match_scratch:SI 3 "=r"))
12279 (clobber (match_scratch:SI 4 "=r"))]
12283 [(set (match_dup 4)
12284 (clz:SI (match_dup 3)))
12287 (lshiftrt:SI (match_dup 4)
12290 operands[3] = rs6000_emit_eqne (SImode,
12291 operands[1], operands[2], operands[3]);
12293 if (GET_CODE (operands[4]) == SCRATCH)
12294 operands[4] = gen_reg_rtx (SImode);
12296 [(set (attr "length")
12297 (if_then_else (match_test "operands[2] == const0_rtx")
12299 (const_string "12")))])
12301 (define_insn_and_split "*nesi3_ext<mode>"
12302 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12303 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12304 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12305 (clobber (match_scratch:SI 3 "=r"))
12306 (clobber (match_scratch:SI 4 "=r"))
12307 (clobber (match_scratch:EXTSI 5 "=r"))]
12311 [(set (match_dup 4)
12312 (clz:SI (match_dup 3)))
12315 (lshiftrt:SI (match_dup 4)
12318 (xor:EXTSI (match_dup 5)
12321 operands[3] = rs6000_emit_eqne (SImode,
12322 operands[1], operands[2], operands[3]);
12324 if (GET_CODE (operands[4]) == SCRATCH)
12325 operands[4] = gen_reg_rtx (SImode);
12326 if (GET_CODE (operands[5]) == SCRATCH)
12327 operands[5] = gen_reg_rtx (<MODE>mode);
12329 [(set (attr "length")
12330 (if_then_else (match_test "operands[2] == const0_rtx")
12331 (const_string "12")
12332 (const_string "16")))])
12334 ;; Conditional branches.
12335 ;; These either are a single bc insn, or a bc around a b.
12337 (define_insn "*cbranch"
12339 (if_then_else (match_operator 1 "branch_comparison_operator"
12340 [(match_operand 2 "cc_reg_operand" "y")
12342 (label_ref (match_operand 0))
12346 return output_cbranch (operands[1], "%l0", 0, insn);
12348 [(set_attr "type" "branch")
12349 (set (attr "length")
12350 (if_then_else (and (ge (minus (match_dup 0) (pc))
12351 (const_int -32768))
12352 (lt (minus (match_dup 0) (pc))
12353 (const_int 32764)))
12357 ;; Conditional return.
12358 (define_insn "*creturn"
12360 (if_then_else (match_operator 0 "branch_comparison_operator"
12361 [(match_operand 1 "cc_reg_operand" "y")
12367 return output_cbranch (operands[0], NULL, 0, insn);
12369 [(set_attr "type" "jmpreg")])
12371 ;; Logic on condition register values.
12373 ; This pattern matches things like
12374 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12375 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12377 ; which are generated by the branch logic.
12378 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12380 (define_insn "cceq_ior_compare"
12381 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12382 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12383 [(match_operator:SI 2
12384 "branch_positive_comparison_operator"
12386 "cc_reg_operand" "y,y")
12388 (match_operator:SI 4
12389 "branch_positive_comparison_operator"
12391 "cc_reg_operand" "0,y")
12395 "cr%q1 %E0,%j2,%j4"
12396 [(set_attr "type" "cr_logical")
12397 (set_attr "cr_logical_3op" "no,yes")])
12399 ; Why is the constant -1 here, but 1 in the previous pattern?
12400 ; Because ~1 has all but the low bit set.
12401 (define_insn "cceq_ior_compare_complement"
12402 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12403 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12404 [(not:SI (match_operator:SI 2
12405 "branch_positive_comparison_operator"
12407 "cc_reg_operand" "y,y")
12409 (match_operator:SI 4
12410 "branch_positive_comparison_operator"
12412 "cc_reg_operand" "0,y")
12416 "cr%q1 %E0,%j2,%j4"
12417 [(set_attr "type" "cr_logical")
12418 (set_attr "cr_logical_3op" "no,yes")])
12420 (define_insn "*cceq_rev_compare"
12421 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12422 (compare:CCEQ (match_operator:SI 1
12423 "branch_positive_comparison_operator"
12425 "cc_reg_operand" "0,y")
12430 [(set_attr "type" "cr_logical")
12431 (set_attr "cr_logical_3op" "no,yes")])
12433 ;; If we are comparing the result of two comparisons, this can be done
12434 ;; using creqv or crxor.
12436 (define_insn_and_split ""
12437 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12438 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12439 [(match_operand 2 "cc_reg_operand" "y")
12441 (match_operator 3 "branch_comparison_operator"
12442 [(match_operand 4 "cc_reg_operand" "y")
12447 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12450 int positive_1, positive_2;
12452 positive_1 = branch_positive_comparison_operator (operands[1],
12453 GET_MODE (operands[1]));
12454 positive_2 = branch_positive_comparison_operator (operands[3],
12455 GET_MODE (operands[3]));
12458 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12459 GET_CODE (operands[1])),
12461 operands[2], const0_rtx);
12462 else if (GET_MODE (operands[1]) != SImode)
12463 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12464 operands[2], const0_rtx);
12467 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12468 GET_CODE (operands[3])),
12470 operands[4], const0_rtx);
12471 else if (GET_MODE (operands[3]) != SImode)
12472 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12473 operands[4], const0_rtx);
12475 if (positive_1 == positive_2)
12477 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12478 operands[5] = constm1_rtx;
12482 operands[5] = const1_rtx;
12486 ;; Unconditional branch and return.
12488 (define_insn "jump"
12490 (label_ref (match_operand 0)))]
12493 [(set_attr "type" "branch")])
12495 (define_insn "<return_str>return"
12499 [(set_attr "type" "jmpreg")])
12501 (define_expand "indirect_jump"
12502 [(set (pc) (match_operand 0 "register_operand"))]
12505 if (!rs6000_speculate_indirect_jumps) {
12506 rtx ccreg = gen_reg_rtx (CCmode);
12507 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12512 (define_insn "*indirect_jump<mode>"
12514 (match_operand:P 0 "register_operand" "c,*l"))]
12515 "rs6000_speculate_indirect_jumps"
12517 [(set_attr "type" "jmpreg")])
12519 (define_insn "@indirect_jump<mode>_nospec"
12520 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12521 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12522 "!rs6000_speculate_indirect_jumps"
12523 "crset %E1\;beq%T0- %1\;b $"
12524 [(set_attr "type" "jmpreg")
12525 (set_attr "length" "12")])
12527 ;; Table jump for switch statements:
12528 (define_expand "tablejump"
12529 [(use (match_operand 0))
12530 (use (label_ref (match_operand 1)))]
12533 if (rs6000_speculate_indirect_jumps)
12536 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12538 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12542 rtx ccreg = gen_reg_rtx (CCmode);
12545 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12547 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12548 emit_jump_insn (jump);
12553 (define_expand "tablejumpsi"
12554 [(set (match_dup 3)
12555 (plus:SI (match_operand:SI 0)
12557 (parallel [(set (pc)
12559 (use (label_ref (match_operand 1)))])]
12560 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12562 operands[0] = force_reg (SImode, operands[0]);
12563 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12564 operands[3] = gen_reg_rtx (SImode);
12567 (define_expand "tablejumpsi_nospec"
12568 [(set (match_dup 4)
12569 (plus:SI (match_operand:SI 0)
12571 (parallel [(set (pc)
12573 (use (label_ref (match_operand 1)))
12574 (clobber (match_operand 2))])]
12575 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12577 operands[0] = force_reg (SImode, operands[0]);
12578 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12579 operands[4] = gen_reg_rtx (SImode);
12582 (define_expand "tablejumpdi"
12583 [(set (match_dup 4)
12584 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12586 (plus:DI (match_dup 4)
12588 (parallel [(set (pc)
12590 (use (label_ref (match_operand 1)))])]
12591 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12593 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12594 operands[3] = gen_reg_rtx (DImode);
12595 operands[4] = gen_reg_rtx (DImode);
12598 (define_expand "tablejumpdi_nospec"
12599 [(set (match_dup 5)
12600 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12602 (plus:DI (match_dup 5)
12604 (parallel [(set (pc)
12606 (use (label_ref (match_operand 1)))
12607 (clobber (match_operand 2))])]
12608 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12610 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12611 operands[4] = gen_reg_rtx (DImode);
12612 operands[5] = gen_reg_rtx (DImode);
12615 (define_insn "*tablejump<mode>_internal1"
12617 (match_operand:P 0 "register_operand" "c,*l"))
12618 (use (label_ref (match_operand 1)))]
12619 "rs6000_speculate_indirect_jumps"
12621 [(set_attr "type" "jmpreg")])
12623 (define_insn "*tablejump<mode>_internal1_nospec"
12625 (match_operand:P 0 "register_operand" "c,*l"))
12626 (use (label_ref (match_operand 1)))
12627 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12628 "!rs6000_speculate_indirect_jumps"
12629 "crset %E2\;beq%T0- %2\;b $"
12630 [(set_attr "type" "jmpreg")
12631 (set_attr "length" "12")])
12634 [(unspec [(const_int 0)] UNSPEC_NOP)]
12638 (define_insn "group_ending_nop"
12639 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12642 operands[0] = gen_rtx_REG (Pmode,
12643 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12644 return "ori %0,%0,0";
12647 (define_insn "speculation_barrier"
12648 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12651 operands[0] = gen_rtx_REG (Pmode, 31);
12652 return "ori %0,%0,0";
12655 ;; Define the subtract-one-and-jump insns, starting with the template
12656 ;; so loop.c knows what to generate.
12658 (define_expand "doloop_end"
12659 [(use (match_operand 0)) ; loop pseudo
12660 (use (match_operand 1))] ; label
12663 if (GET_MODE (operands[0]) != Pmode)
12666 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12670 (define_expand "@ctr<mode>"
12671 [(parallel [(set (pc)
12672 (if_then_else (ne (match_operand:P 0 "register_operand")
12674 (label_ref (match_operand 1))
12677 (plus:P (match_dup 0)
12679 (clobber (match_scratch:CC 2))
12680 (clobber (match_scratch:P 3))])]
12684 ;; We need to be able to do this for any operand, including MEM, or we
12685 ;; will cause reload to blow up since we don't allow output reloads on
12687 ;; For the length attribute to be calculated correctly, the
12688 ;; label MUST be operand 0.
12689 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12690 ;; the ctr<mode> insns.
12692 (define_code_iterator eqne [eq ne])
12693 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12694 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12696 (define_insn "<bd>_<mode>"
12698 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12700 (label_ref (match_operand 0))
12702 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12703 (plus:P (match_dup 1)
12705 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12706 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12709 if (which_alternative != 0)
12711 else if (get_attr_length (insn) == 4)
12714 return "<bd_neg> $+8\;b %l0";
12716 [(set_attr "type" "branch")
12717 (set_attr_alternative "length"
12718 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12719 (const_int -32768))
12720 (lt (minus (match_dup 0) (pc))
12721 (const_int 32764)))
12724 (const_string "16")
12725 (const_string "20")
12726 (const_string "20")])])
12728 ;; Now the splitter if we could not allocate the CTR register
12731 (if_then_else (match_operator 2 "comparison_operator"
12732 [(match_operand:P 1 "gpc_reg_operand")
12735 (match_operand 6)))
12736 (set (match_operand:P 0 "nonimmediate_operand")
12737 (plus:P (match_dup 1)
12739 (clobber (match_scratch:CC 3))
12740 (clobber (match_scratch:P 4))]
12743 (if_then_else (match_dup 7)
12747 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12749 emit_insn (gen_rtx_SET (operands[3],
12750 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12751 if (int_reg_operand (operands[0], <MODE>mode))
12752 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12755 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12756 emit_move_insn (operands[0], operands[4]);
12758 /* No DONE so branch comes from the pattern. */
12761 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12762 ;; Note that in the case of long branches we have to decompose this into
12763 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12764 ;; and the CR bit, which means there is no way to conveniently invert the
12765 ;; comparison as is done with plain bdnz/bdz.
12767 (define_insn "<bd>tf_<mode>"
12771 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12773 (match_operator 3 "branch_comparison_operator"
12774 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12776 (label_ref (match_operand 0))
12778 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12779 (plus:P (match_dup 1)
12781 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12782 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12783 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12786 if (which_alternative != 0)
12788 else if (get_attr_length (insn) == 4)
12790 if (branch_positive_comparison_operator (operands[3],
12791 GET_MODE (operands[3])))
12792 return "<bd>t %j3,%l0";
12794 return "<bd>f %j3,%l0";
12798 static char seq[96];
12799 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12800 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12804 [(set_attr "type" "branch")
12805 (set_attr_alternative "length"
12806 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12807 (const_int -32768))
12808 (lt (minus (match_dup 0) (pc))
12809 (const_int 32764)))
12812 (const_string "16")
12813 (const_string "20")
12814 (const_string "20")])])
12816 ;; Now the splitter if we could not allocate the CTR register
12821 (match_operator 1 "comparison_operator"
12822 [(match_operand:P 0 "gpc_reg_operand")
12824 (match_operator 3 "branch_comparison_operator"
12825 [(match_operand 2 "cc_reg_operand")
12828 (match_operand 5)))
12829 (set (match_operand:P 6 "nonimmediate_operand")
12830 (plus:P (match_dup 0)
12832 (clobber (match_scratch:P 7))
12833 (clobber (match_scratch:CC 8))
12834 (clobber (match_scratch:CCEQ 9))]
12838 rtx ctr = operands[0];
12839 rtx ctrcmp = operands[1];
12840 rtx ccin = operands[2];
12841 rtx cccmp = operands[3];
12842 rtx dst1 = operands[4];
12843 rtx dst2 = operands[5];
12844 rtx ctrout = operands[6];
12845 rtx ctrtmp = operands[7];
12846 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12847 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12849 cmpcode = reverse_condition (cmpcode);
12850 /* Generate crand/crandc here. */
12851 emit_insn (gen_rtx_SET (operands[8],
12852 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12853 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12855 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12857 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12858 operands[8], cccmp, ccin));
12860 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12861 operands[8], cccmp, ccin));
12862 if (int_reg_operand (ctrout, <MODE>mode))
12863 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12866 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12867 emit_move_insn (ctrout, ctrtmp);
12869 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12870 emit_jump_insn (gen_rtx_SET (pc_rtx,
12871 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12877 (define_insn "trap"
12878 [(trap_if (const_int 1) (const_int 0))]
12881 [(set_attr "type" "trap")])
12883 (define_expand "ctrap<mode>4"
12884 [(trap_if (match_operator 0 "ordered_comparison_operator"
12885 [(match_operand:GPR 1 "register_operand")
12886 (match_operand:GPR 2 "reg_or_short_operand")])
12887 (match_operand 3 "zero_constant" ""))]
12892 [(trap_if (match_operator 0 "ordered_comparison_operator"
12893 [(match_operand:GPR 1 "register_operand" "r")
12894 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12897 "t<wd>%V0%I2 %1,%2"
12898 [(set_attr "type" "trap")])
12900 ;; Insns related to generating the function prologue and epilogue.
12902 (define_expand "prologue"
12903 [(use (const_int 0))]
12906 rs6000_emit_prologue ();
12907 if (!TARGET_SCHED_PROLOG)
12908 emit_insn (gen_blockage ());
12912 (define_insn "*movesi_from_cr_one"
12913 [(match_parallel 0 "mfcr_operation"
12914 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12915 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12916 (match_operand 3 "immediate_operand" "n")]
12917 UNSPEC_MOVESI_FROM_CR))])]
12922 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12924 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12925 operands[4] = GEN_INT (mask);
12926 output_asm_insn ("mfcr %1,%4", operands);
12930 [(set_attr "type" "mfcrf")])
12932 ;; Don't include the volatile CRs since their values are not used wrt CR save
12933 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12934 ;; prologue past an insn (early exit test) that defines a register used in the
12936 (define_insn "prologue_movesi_from_cr"
12937 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12938 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12939 (reg:CC CR4_REGNO)]
12940 UNSPEC_MOVESI_FROM_CR))]
12943 [(set_attr "type" "mfcr")])
12945 (define_insn "*crsave"
12946 [(match_parallel 0 "crsave_operation"
12947 [(set (match_operand:SI 1 "memory_operand" "=m")
12948 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12951 [(set_attr "type" "store")])
12953 (define_insn "*stmw"
12954 [(match_parallel 0 "stmw_operation"
12955 [(set (match_operand:SI 1 "memory_operand" "=m")
12956 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12959 [(set_attr "type" "store")
12960 (set_attr "update" "yes")
12961 (set_attr "indexed" "yes")])
12963 ; The following comment applies to:
12967 ; return_and_restore_gpregs*
12968 ; return_and_restore_fpregs*
12969 ; return_and_restore_fpregs_aix*
12971 ; The out-of-line save / restore functions expects one input argument.
12972 ; Since those are not standard call_insn's, we must avoid using
12973 ; MATCH_OPERAND for that argument. That way the register rename
12974 ; optimization will not try to rename this register.
12975 ; Each pattern is repeated for each possible register number used in
12976 ; various ABIs (r11, r1, and for some functions r12)
12978 (define_insn "*save_gpregs_<mode>_r11"
12979 [(match_parallel 0 "any_parallel_operand"
12980 [(clobber (reg:P LR_REGNO))
12981 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12983 (set (match_operand:P 2 "memory_operand" "=m")
12984 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12987 [(set_attr "type" "branch")])
12989 (define_insn "*save_gpregs_<mode>_r12"
12990 [(match_parallel 0 "any_parallel_operand"
12991 [(clobber (reg:P LR_REGNO))
12992 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12994 (set (match_operand:P 2 "memory_operand" "=m")
12995 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12998 [(set_attr "type" "branch")])
13000 (define_insn "*save_gpregs_<mode>_r1"
13001 [(match_parallel 0 "any_parallel_operand"
13002 [(clobber (reg:P LR_REGNO))
13003 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13005 (set (match_operand:P 2 "memory_operand" "=m")
13006 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13009 [(set_attr "type" "branch")])
13011 (define_insn "*save_fpregs_<mode>_r11"
13012 [(match_parallel 0 "any_parallel_operand"
13013 [(clobber (reg:P LR_REGNO))
13014 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13016 (set (match_operand:DF 2 "memory_operand" "=m")
13017 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13020 [(set_attr "type" "branch")])
13022 (define_insn "*save_fpregs_<mode>_r12"
13023 [(match_parallel 0 "any_parallel_operand"
13024 [(clobber (reg:P LR_REGNO))
13025 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13027 (set (match_operand:DF 2 "memory_operand" "=m")
13028 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13031 [(set_attr "type" "branch")])
13033 (define_insn "*save_fpregs_<mode>_r1"
13034 [(match_parallel 0 "any_parallel_operand"
13035 [(clobber (reg:P LR_REGNO))
13036 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13038 (set (match_operand:DF 2 "memory_operand" "=m")
13039 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13042 [(set_attr "type" "branch")])
13044 ; This is to explain that changes to the stack pointer should
13045 ; not be moved over loads from or stores to stack memory.
13046 (define_insn "stack_tie"
13047 [(match_parallel 0 "tie_operand"
13048 [(set (mem:BLK (reg 1)) (const_int 0))])]
13051 [(set_attr "length" "0")])
13053 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13054 ; stay behind all restores from the stack, it cannot be reordered to before
13055 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13056 (define_insn "stack_restore_tie"
13057 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13058 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13059 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13060 (set (mem:BLK (scratch)) (const_int 0))]
13065 [(set_attr "type" "*,add")])
13067 (define_expand "epilogue"
13068 [(use (const_int 0))]
13071 if (!TARGET_SCHED_PROLOG)
13072 emit_insn (gen_blockage ());
13073 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13077 ; On some processors, doing the mtcrf one CC register at a time is
13078 ; faster (like on the 604e). On others, doing them all at once is
13079 ; faster; for instance, on the 601 and 750.
13081 (define_expand "movsi_to_cr_one"
13082 [(set (match_operand:CC 0 "cc_reg_operand")
13083 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13084 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13086 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13088 (define_insn "*movsi_to_cr"
13089 [(match_parallel 0 "mtcrf_operation"
13090 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13091 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13092 (match_operand 3 "immediate_operand" "n")]
13093 UNSPEC_MOVESI_TO_CR))])]
13098 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13099 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13100 operands[4] = GEN_INT (mask);
13101 return "mtcrf %4,%2";
13103 [(set_attr "type" "mtcr")])
13105 (define_insn "*mtcrfsi"
13106 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13107 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13108 (match_operand 2 "immediate_operand" "n")]
13109 UNSPEC_MOVESI_TO_CR))]
13110 "REG_P (operands[0])
13111 && CR_REGNO_P (REGNO (operands[0]))
13112 && CONST_INT_P (operands[2])
13113 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13115 [(set_attr "type" "mtcr")])
13117 ; The load-multiple instructions have similar properties.
13118 ; Note that "load_multiple" is a name known to the machine-independent
13119 ; code that actually corresponds to the PowerPC load-string.
13121 (define_insn "*lmw"
13122 [(match_parallel 0 "lmw_operation"
13123 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13124 (match_operand:SI 2 "memory_operand" "m"))])]
13127 [(set_attr "type" "load")
13128 (set_attr "update" "yes")
13129 (set_attr "indexed" "yes")
13130 (set_attr "cell_micro" "always")])
13132 ; FIXME: "any_parallel_operand" is a bit flexible...
13134 ; The following comment applies to:
13138 ; return_and_restore_gpregs*
13139 ; return_and_restore_fpregs*
13140 ; return_and_restore_fpregs_aix*
13142 ; The out-of-line save / restore functions expects one input argument.
13143 ; Since those are not standard call_insn's, we must avoid using
13144 ; MATCH_OPERAND for that argument. That way the register rename
13145 ; optimization will not try to rename this register.
13146 ; Each pattern is repeated for each possible register number used in
13147 ; various ABIs (r11, r1, and for some functions r12)
13149 (define_insn "*restore_gpregs_<mode>_r11"
13150 [(match_parallel 0 "any_parallel_operand"
13151 [(clobber (reg:P LR_REGNO))
13152 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13154 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13155 (match_operand:P 3 "memory_operand" "m"))])]
13158 [(set_attr "type" "branch")])
13160 (define_insn "*restore_gpregs_<mode>_r12"
13161 [(match_parallel 0 "any_parallel_operand"
13162 [(clobber (reg:P LR_REGNO))
13163 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13165 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13166 (match_operand:P 3 "memory_operand" "m"))])]
13169 [(set_attr "type" "branch")])
13171 (define_insn "*restore_gpregs_<mode>_r1"
13172 [(match_parallel 0 "any_parallel_operand"
13173 [(clobber (reg:P LR_REGNO))
13174 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13176 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13177 (match_operand:P 3 "memory_operand" "m"))])]
13180 [(set_attr "type" "branch")])
13182 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13183 [(match_parallel 0 "any_parallel_operand"
13185 (clobber (reg:P LR_REGNO))
13186 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13188 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13189 (match_operand:P 3 "memory_operand" "m"))])]
13192 [(set_attr "type" "branch")])
13194 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13195 [(match_parallel 0 "any_parallel_operand"
13197 (clobber (reg:P LR_REGNO))
13198 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13200 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13201 (match_operand:P 3 "memory_operand" "m"))])]
13204 [(set_attr "type" "branch")])
13206 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13207 [(match_parallel 0 "any_parallel_operand"
13209 (clobber (reg:P LR_REGNO))
13210 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13212 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13213 (match_operand:P 3 "memory_operand" "m"))])]
13216 [(set_attr "type" "branch")])
13218 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13219 [(match_parallel 0 "any_parallel_operand"
13221 (clobber (reg:P LR_REGNO))
13222 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13224 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13225 (match_operand:DF 3 "memory_operand" "m"))])]
13228 [(set_attr "type" "branch")])
13230 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13231 [(match_parallel 0 "any_parallel_operand"
13233 (clobber (reg:P LR_REGNO))
13234 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13236 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13237 (match_operand:DF 3 "memory_operand" "m"))])]
13240 [(set_attr "type" "branch")])
13242 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13243 [(match_parallel 0 "any_parallel_operand"
13245 (clobber (reg:P LR_REGNO))
13246 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13248 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13249 (match_operand:DF 3 "memory_operand" "m"))])]
13252 [(set_attr "type" "branch")])
13254 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13255 [(match_parallel 0 "any_parallel_operand"
13257 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13259 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13260 (match_operand:DF 3 "memory_operand" "m"))])]
13263 [(set_attr "type" "branch")])
13265 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13266 [(match_parallel 0 "any_parallel_operand"
13268 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13270 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13271 (match_operand:DF 3 "memory_operand" "m"))])]
13274 [(set_attr "type" "branch")])
13276 ; This is used in compiling the unwind routines.
13277 (define_expand "eh_return"
13278 [(use (match_operand 0 "general_operand"))]
13281 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13285 ; We can't expand this before we know where the link register is stored.
13286 (define_insn_and_split "@eh_set_lr_<mode>"
13287 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13288 (clobber (match_scratch:P 1 "=&b"))]
13294 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13298 (define_insn "prefetch"
13299 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13300 (match_operand:SI 1 "const_int_operand" "n")
13301 (match_operand:SI 2 "const_int_operand" "n"))]
13306 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13307 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13308 The AIX assembler does not support the three operand form of dcbt
13309 and dcbtst on Power 7 (-mpwr7). */
13310 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13312 if (REG_P (operands[0]))
13314 if (INTVAL (operands[1]) == 0)
13315 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13317 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13321 if (INTVAL (operands[1]) == 0)
13322 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13324 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13327 [(set_attr "type" "load")])
13329 ;; Handle -fsplit-stack.
13331 (define_expand "split_stack_prologue"
13335 rs6000_expand_split_stack_prologue ();
13339 (define_expand "load_split_stack_limit"
13340 [(set (match_operand 0)
13341 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13344 emit_insn (gen_rtx_SET (operands[0],
13345 gen_rtx_UNSPEC (Pmode,
13346 gen_rtvec (1, const0_rtx),
13347 UNSPEC_STACK_CHECK)));
13351 (define_insn "load_split_stack_limit_di"
13352 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13353 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13355 "ld %0,-0x7040(13)"
13356 [(set_attr "type" "load")
13357 (set_attr "update" "no")
13358 (set_attr "indexed" "no")])
13360 (define_insn "load_split_stack_limit_si"
13361 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13362 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13364 "lwz %0,-0x7020(2)"
13365 [(set_attr "type" "load")
13366 (set_attr "update" "no")
13367 (set_attr "indexed" "no")])
13369 ;; A return instruction which the middle-end doesn't see.
13370 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13371 ;; after the call to __morestack.
13372 (define_insn "split_stack_return"
13373 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13376 [(set_attr "type" "jmpreg")])
13378 ;; If there are operand 0 bytes available on the stack, jump to
13380 (define_expand "split_stack_space_check"
13381 [(set (match_dup 2)
13382 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13384 (minus (reg STACK_POINTER_REGNUM)
13385 (match_operand 0)))
13386 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13387 (set (pc) (if_then_else
13388 (geu (match_dup 4) (const_int 0))
13389 (label_ref (match_operand 1))
13393 rs6000_split_stack_space_check (operands[0], operands[1]);
13397 (define_insn "bpermd_<mode>"
13398 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13399 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13400 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13403 [(set_attr "type" "popcnt")])
13406 ;; Builtin fma support. Handle
13407 ;; Note that the conditions for expansion are in the FMA_F iterator.
13409 (define_expand "fma<mode>4"
13410 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13412 (match_operand:FMA_F 1 "gpc_reg_operand")
13413 (match_operand:FMA_F 2 "gpc_reg_operand")
13414 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13418 (define_insn "*fma<mode>4_fpr"
13419 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13421 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13422 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13423 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13424 "TARGET_HARD_FLOAT"
13426 fmadd<s> %0,%1,%2,%3
13427 xsmadda<sd>p %x0,%x1,%x2
13428 xsmaddm<sd>p %x0,%x1,%x3"
13429 [(set_attr "type" "fp")
13430 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13432 ; Altivec only has fma and nfms.
13433 (define_expand "fms<mode>4"
13434 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13436 (match_operand:FMA_F 1 "gpc_reg_operand")
13437 (match_operand:FMA_F 2 "gpc_reg_operand")
13438 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13439 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13442 (define_insn "*fms<mode>4_fpr"
13443 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13445 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13446 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13447 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13448 "TARGET_HARD_FLOAT"
13450 fmsub<s> %0,%1,%2,%3
13451 xsmsuba<sd>p %x0,%x1,%x2
13452 xsmsubm<sd>p %x0,%x1,%x3"
13453 [(set_attr "type" "fp")
13454 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13456 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13457 (define_expand "fnma<mode>4"
13458 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13461 (match_operand:FMA_F 1 "gpc_reg_operand")
13462 (match_operand:FMA_F 2 "gpc_reg_operand")
13463 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13464 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13467 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13468 (define_expand "fnms<mode>4"
13469 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13472 (match_operand:FMA_F 1 "gpc_reg_operand")
13473 (match_operand:FMA_F 2 "gpc_reg_operand")
13474 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13475 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13478 ; Not an official optab name, but used from builtins.
13479 (define_expand "nfma<mode>4"
13480 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13483 (match_operand:FMA_F 1 "gpc_reg_operand")
13484 (match_operand:FMA_F 2 "gpc_reg_operand")
13485 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13486 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13489 (define_insn "*nfma<mode>4_fpr"
13490 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13493 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13494 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13495 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13496 "TARGET_HARD_FLOAT"
13498 fnmadd<s> %0,%1,%2,%3
13499 xsnmadda<sd>p %x0,%x1,%x2
13500 xsnmaddm<sd>p %x0,%x1,%x3"
13501 [(set_attr "type" "fp")
13502 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13504 ; Not an official optab name, but used from builtins.
13505 (define_expand "nfms<mode>4"
13506 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13509 (match_operand:FMA_F 1 "gpc_reg_operand")
13510 (match_operand:FMA_F 2 "gpc_reg_operand")
13511 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13515 (define_insn "*nfmssf4_fpr"
13516 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13519 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13520 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13522 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13523 "TARGET_HARD_FLOAT"
13525 fnmsub<s> %0,%1,%2,%3
13526 xsnmsuba<sd>p %x0,%x1,%x2
13527 xsnmsubm<sd>p %x0,%x1,%x3"
13528 [(set_attr "type" "fp")
13529 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13531 (define_expand "rs6000_get_timebase"
13532 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13535 if (TARGET_POWERPC64)
13536 emit_insn (gen_rs6000_mftb_di (operands[0]));
13538 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13542 (define_insn "rs6000_get_timebase_ppc32"
13543 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13544 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13545 (clobber (match_scratch:SI 1 "=r"))
13546 (clobber (match_scratch:CC 2 "=y"))]
13547 "!TARGET_POWERPC64"
13549 if (WORDS_BIG_ENDIAN)
13552 return "mfspr %0,269\;"
13560 return "mftbu %0\;"
13569 return "mfspr %L0,269\;"
13577 return "mftbu %L0\;"
13584 [(set_attr "length" "20")])
13586 (define_insn "rs6000_mftb_<mode>"
13587 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13588 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13592 return "mfspr %0,268";
13598 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13599 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13600 (define_insn "rs6000_mffsl_hw"
13601 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13602 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13603 "TARGET_HARD_FLOAT"
13606 (define_expand "rs6000_mffsl"
13607 [(set (match_operand:DF 0 "gpc_reg_operand")
13608 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13609 "TARGET_HARD_FLOAT"
13611 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13612 otherwise fall back to the older mffs instruction to emulate the mffsl
13615 if (!TARGET_P9_MISC)
13617 rtx tmp_di = gen_reg_rtx (DImode);
13618 rtx tmp_df = gen_reg_rtx (DFmode);
13620 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13621 instruction using the mffs instruction and masking off the bits
13622 the mmsl instruciton actually reads. */
13623 emit_insn (gen_rs6000_mffs (tmp_df));
13624 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13625 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13627 operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13631 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13635 (define_insn "rs6000_mffs"
13636 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13637 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13638 "TARGET_HARD_FLOAT"
13641 (define_insn "rs6000_mtfsf"
13642 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13643 (match_operand:DF 1 "gpc_reg_operand" "d")]
13645 "TARGET_HARD_FLOAT"
13648 (define_insn "rs6000_mtfsf_hi"
13649 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13650 (match_operand:DF 1 "gpc_reg_operand" "d")]
13652 "TARGET_HARD_FLOAT"
13656 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13657 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13658 ;; register that is being loaded. The fused ops must be physically adjacent.
13660 ;; On Power8 GPR loads, we try to use the register that is being load. The
13661 ;; peephole2 then gathers any other fused possibilities that it can find after
13662 ;; register allocation. If power9 fusion is selected, we also fuse floating
13663 ;; point loads/stores.
13665 ;; Find cases where the addis that feeds into a load instruction is either used
13666 ;; once or is the same as the target register, and replace it with the fusion
13670 [(set (match_operand:P 0 "base_reg_operand")
13671 (match_operand:P 1 "fusion_gpr_addis"))
13672 (set (match_operand:INT1 2 "base_reg_operand")
13673 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13675 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13679 expand_fusion_gpr_load (operands);
13683 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13686 (define_insn "*fusion_gpr_load_<mode>"
13687 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13688 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13689 UNSPEC_FUSION_GPR))]
13692 return emit_fusion_gpr_load (operands[0], operands[1]);
13694 [(set_attr "type" "load")
13695 (set_attr "length" "8")])
13698 ;; Optimize cases where we want to do a D-form load (register+offset) on
13699 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13704 ;; and we change this to:
13709 [(match_scratch:P 0 "b")
13710 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13711 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13712 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13714 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13715 [(set (match_dup 0)
13720 rtx tmp_reg = operands[0];
13721 rtx mem = operands[2];
13722 rtx addr = XEXP (mem, 0);
13723 rtx add_op0, add_op1, new_addr;
13725 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13726 add_op0 = XEXP (addr, 0);
13727 add_op1 = XEXP (addr, 1);
13728 gcc_assert (REG_P (add_op0));
13729 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13731 operands[4] = add_op1;
13732 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13735 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13736 ;; Altivec register, and the register allocator has generated:
13740 ;; and we change this to:
13745 [(match_scratch:P 0 "b")
13746 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13747 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13748 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13750 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13751 [(set (match_dup 0)
13756 rtx tmp_reg = operands[0];
13757 rtx mem = operands[3];
13758 rtx addr = XEXP (mem, 0);
13759 rtx add_op0, add_op1, new_addr;
13761 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13762 add_op0 = XEXP (addr, 0);
13763 add_op1 = XEXP (addr, 1);
13764 gcc_assert (REG_P (add_op0));
13765 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13767 operands[4] = add_op1;
13768 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13772 ;; Miscellaneous ISA 2.06 (power7) instructions
13773 (define_insn "addg6s"
13774 [(set (match_operand:SI 0 "register_operand" "=r")
13775 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13776 (match_operand:SI 2 "register_operand" "r")]
13780 [(set_attr "type" "integer")])
13782 (define_insn "cdtbcd"
13783 [(set (match_operand:SI 0 "register_operand" "=r")
13784 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13788 [(set_attr "type" "integer")])
13790 (define_insn "cbcdtd"
13791 [(set (match_operand:SI 0 "register_operand" "=r")
13792 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13796 [(set_attr "type" "integer")])
13798 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13801 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13802 (UNSPEC_DIVEU "eu")])
13804 (define_insn "div<div_extend>_<mode>"
13805 [(set (match_operand:GPR 0 "register_operand" "=r")
13806 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13807 (match_operand:GPR 2 "register_operand" "r")]
13808 UNSPEC_DIV_EXTEND))]
13810 "div<wd><div_extend> %0,%1,%2"
13811 [(set_attr "type" "div")
13812 (set_attr "size" "<bits>")])
13815 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13817 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13818 (define_mode_attr FP128_64 [(TF "DF")
13823 (define_expand "unpack<mode>"
13824 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13826 [(match_operand:FMOVE128 1 "register_operand")
13827 (match_operand:QI 2 "const_0_to_1_operand")]
13828 UNSPEC_UNPACK_128BIT))]
13829 "FLOAT128_2REG_P (<MODE>mode)"
13832 (define_insn_and_split "unpack<mode>_dm"
13833 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13835 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13836 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13837 UNSPEC_UNPACK_128BIT))]
13838 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13840 "&& reload_completed"
13841 [(set (match_dup 0) (match_dup 3))]
13843 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13845 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13847 emit_note (NOTE_INSN_DELETED);
13851 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13853 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13855 (define_insn_and_split "unpack<mode>_nodm"
13856 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13858 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13859 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13860 UNSPEC_UNPACK_128BIT))]
13861 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13863 "&& reload_completed"
13864 [(set (match_dup 0) (match_dup 3))]
13866 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13868 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13870 emit_note (NOTE_INSN_DELETED);
13874 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13876 [(set_attr "type" "fp,fpstore")])
13878 (define_insn_and_split "pack<mode>"
13879 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13881 [(match_operand:<FP128_64> 1 "register_operand" "d")
13882 (match_operand:<FP128_64> 2 "register_operand" "d")]
13883 UNSPEC_PACK_128BIT))]
13884 "FLOAT128_2REG_P (<MODE>mode)"
13886 "&& reload_completed"
13887 [(set (match_dup 3) (match_dup 1))
13888 (set (match_dup 4) (match_dup 2))]
13890 unsigned dest_hi = REGNO (operands[0]);
13891 unsigned dest_lo = dest_hi + 1;
13893 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13894 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13896 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13897 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13899 [(set_attr "type" "fp")
13900 (set_attr "length" "8")])
13902 (define_insn "unpack<mode>"
13903 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13904 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13905 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13906 UNSPEC_UNPACK_128BIT))]
13907 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13909 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13910 return ASM_COMMENT_START " xxpermdi to same register";
13912 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13913 return "xxpermdi %x0,%x1,%x1,%3";
13915 [(set_attr "type" "vecperm")])
13917 (define_insn "pack<mode>"
13918 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13919 (unspec:FMOVE128_VSX
13920 [(match_operand:DI 1 "register_operand" "wa")
13921 (match_operand:DI 2 "register_operand" "wa")]
13922 UNSPEC_PACK_128BIT))]
13924 "xxpermdi %x0,%x1,%x2,0"
13925 [(set_attr "type" "vecperm")])
13929 ;; ISA 2.08 IEEE 128-bit floating point support.
13931 (define_insn "add<mode>3"
13932 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13934 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13935 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13936 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13938 [(set_attr "type" "vecfloat")
13939 (set_attr "size" "128")])
13941 (define_insn "sub<mode>3"
13942 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13944 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13945 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13946 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13948 [(set_attr "type" "vecfloat")
13949 (set_attr "size" "128")])
13951 (define_insn "mul<mode>3"
13952 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13954 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13955 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13956 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13958 [(set_attr "type" "qmul")
13959 (set_attr "size" "128")])
13961 (define_insn "div<mode>3"
13962 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13964 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13965 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13966 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13968 [(set_attr "type" "vecdiv")
13969 (set_attr "size" "128")])
13971 (define_insn "sqrt<mode>2"
13972 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13974 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13975 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13977 [(set_attr "type" "vecdiv")
13978 (set_attr "size" "128")])
13980 (define_expand "copysign<mode>3"
13981 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13982 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13983 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13984 "FLOAT128_IEEE_P (<MODE>mode)"
13986 if (TARGET_FLOAT128_HW)
13987 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13990 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13995 (define_insn "copysign<mode>3_hard"
13996 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13998 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13999 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14001 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14002 "xscpsgnqp %0,%2,%1"
14003 [(set_attr "type" "vecmove")
14004 (set_attr "size" "128")])
14006 (define_insn "copysign<mode>3_soft"
14007 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14009 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14010 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14012 (clobber (match_scratch:IEEE128 3 "=&v"))]
14013 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14014 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14015 [(set_attr "type" "veccomplex")
14016 (set_attr "length" "8")])
14018 (define_insn "@neg<mode>2_hw"
14019 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14021 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14022 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14024 [(set_attr "type" "vecmove")
14025 (set_attr "size" "128")])
14028 (define_insn "@abs<mode>2_hw"
14029 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14031 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14032 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14034 [(set_attr "type" "vecmove")
14035 (set_attr "size" "128")])
14038 (define_insn "*nabs<mode>2_hw"
14039 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14042 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14043 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14045 [(set_attr "type" "vecmove")
14046 (set_attr "size" "128")])
14048 ;; Initially don't worry about doing fusion
14049 (define_insn "fma<mode>4_hw"
14050 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14052 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14053 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14054 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14055 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14056 "xsmaddqp %0,%1,%2"
14057 [(set_attr "type" "qmul")
14058 (set_attr "size" "128")])
14060 (define_insn "*fms<mode>4_hw"
14061 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14063 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14064 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14066 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14067 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14068 "xsmsubqp %0,%1,%2"
14069 [(set_attr "type" "qmul")
14070 (set_attr "size" "128")])
14072 (define_insn "*nfma<mode>4_hw"
14073 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14076 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14077 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14078 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14079 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14080 "xsnmaddqp %0,%1,%2"
14081 [(set_attr "type" "qmul")
14082 (set_attr "size" "128")])
14084 (define_insn "*nfms<mode>4_hw"
14085 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14088 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14089 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14091 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14092 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14093 "xsnmsubqp %0,%1,%2"
14094 [(set_attr "type" "qmul")
14095 (set_attr "size" "128")])
14097 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14098 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14099 (float_extend:IEEE128
14100 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14101 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14103 [(set_attr "type" "vecfloat")
14104 (set_attr "size" "128")])
14106 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14107 ;; point is a simple copy.
14108 (define_insn_and_split "extendkftf2"
14109 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14110 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14111 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14115 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14118 emit_note (NOTE_INSN_DELETED);
14121 [(set_attr "type" "*,veclogical")
14122 (set_attr "length" "0,4")])
14124 (define_insn_and_split "trunctfkf2"
14125 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14126 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14127 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14131 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14134 emit_note (NOTE_INSN_DELETED);
14137 [(set_attr "type" "*,veclogical")
14138 (set_attr "length" "0,4")])
14140 (define_insn "trunc<mode>df2_hw"
14141 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14143 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14144 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14146 [(set_attr "type" "vecfloat")
14147 (set_attr "size" "128")])
14149 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14150 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14152 (define_insn_and_split "trunc<mode>sf2_hw"
14153 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14155 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14156 (clobber (match_scratch:DF 2 "=v"))]
14157 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14160 [(set (match_dup 2)
14161 (unspec:DF [(match_dup 1)]
14162 UNSPEC_TRUNC_ROUND_TO_ODD))
14164 (float_truncate:SF (match_dup 2)))]
14166 if (GET_CODE (operands[2]) == SCRATCH)
14167 operands[2] = gen_reg_rtx (DFmode);
14169 [(set_attr "type" "vecfloat")
14170 (set_attr "length" "8")
14171 (set_attr "isa" "p8v")])
14173 ;; Conversion between IEEE 128-bit and integer types
14175 ;; The fix function for DImode and SImode was declared earlier as a
14176 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14177 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14178 ;; unless we have the IEEE 128-bit hardware.
14180 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14181 ;; to provide a GPR target that used direct move and a conversion in the GPR
14182 ;; which works around QImode/HImode not being allowed in vector registers in
14183 ;; ISA 2.07 (power8).
14184 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14185 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14186 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14187 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14188 "xscvqp<su><wd>z %0,%1"
14189 [(set_attr "type" "vecfloat")
14190 (set_attr "size" "128")])
14192 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14193 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14195 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14196 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14197 "xscvqp<su>wz %0,%1"
14198 [(set_attr "type" "vecfloat")
14199 (set_attr "size" "128")])
14201 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14202 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14203 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14204 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14206 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14207 (clobber (match_scratch:QHSI 2 "=v"))]
14208 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14210 "&& reload_completed"
14211 [(set (match_dup 2)
14212 (any_fix:QHSI (match_dup 1)))
14216 (define_insn "float_<mode>di2_hw"
14217 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14218 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14219 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14221 [(set_attr "type" "vecfloat")
14222 (set_attr "size" "128")])
14224 (define_insn_and_split "float_<mode>si2_hw"
14225 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14226 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14227 (clobber (match_scratch:DI 2 "=v"))]
14228 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14231 [(set (match_dup 2)
14232 (sign_extend:DI (match_dup 1)))
14234 (float:IEEE128 (match_dup 2)))]
14236 if (GET_CODE (operands[2]) == SCRATCH)
14237 operands[2] = gen_reg_rtx (DImode);
14239 if (MEM_P (operands[1]))
14240 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14243 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14244 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14245 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14246 (clobber (match_scratch:DI 2 "=X,r,X"))]
14247 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14249 "&& reload_completed"
14252 rtx dest = operands[0];
14253 rtx src = operands[1];
14254 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14256 if (altivec_register_operand (src, <QHI:MODE>mode))
14257 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14258 else if (int_reg_operand (src, <QHI:MODE>mode))
14260 rtx ext_di = operands[2];
14261 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14262 emit_move_insn (dest_di, ext_di);
14264 else if (MEM_P (src))
14266 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14267 emit_move_insn (dest_qhi, src);
14268 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14271 gcc_unreachable ();
14273 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14276 [(set_attr "length" "8,12,12")
14277 (set_attr "type" "vecfloat")
14278 (set_attr "size" "128")])
14280 (define_insn "floatuns_<mode>di2_hw"
14281 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14282 (unsigned_float:IEEE128
14283 (match_operand:DI 1 "altivec_register_operand" "v")))]
14284 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14286 [(set_attr "type" "vecfloat")
14287 (set_attr "size" "128")])
14289 (define_insn_and_split "floatuns_<mode>si2_hw"
14290 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14291 (unsigned_float:IEEE128
14292 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14293 (clobber (match_scratch:DI 2 "=v"))]
14294 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14297 [(set (match_dup 2)
14298 (zero_extend:DI (match_dup 1)))
14300 (float:IEEE128 (match_dup 2)))]
14302 if (GET_CODE (operands[2]) == SCRATCH)
14303 operands[2] = gen_reg_rtx (DImode);
14305 if (MEM_P (operands[1]))
14306 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14309 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14310 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14311 (unsigned_float:IEEE128
14312 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14313 (clobber (match_scratch:DI 2 "=X,r,X"))]
14314 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14316 "&& reload_completed"
14319 rtx dest = operands[0];
14320 rtx src = operands[1];
14321 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14323 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14324 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14325 else if (int_reg_operand (src, <QHI:MODE>mode))
14327 rtx ext_di = operands[2];
14328 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14329 emit_move_insn (dest_di, ext_di);
14332 gcc_unreachable ();
14334 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14337 [(set_attr "length" "8,12,8")
14338 (set_attr "type" "vecfloat")
14339 (set_attr "size" "128")])
14341 ;; IEEE 128-bit round to integer built-in functions
14342 (define_insn "floor<mode>2"
14343 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14345 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14347 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14349 [(set_attr "type" "vecfloat")
14350 (set_attr "size" "128")])
14352 (define_insn "ceil<mode>2"
14353 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14355 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14357 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14359 [(set_attr "type" "vecfloat")
14360 (set_attr "size" "128")])
14362 (define_insn "btrunc<mode>2"
14363 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14365 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14367 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14369 [(set_attr "type" "vecfloat")
14370 (set_attr "size" "128")])
14372 (define_insn "round<mode>2"
14373 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14375 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14377 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14379 [(set_attr "type" "vecfloat")
14380 (set_attr "size" "128")])
14382 ;; IEEE 128-bit instructions with round to odd semantics
14383 (define_insn "add<mode>3_odd"
14384 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14386 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14387 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14388 UNSPEC_ADD_ROUND_TO_ODD))]
14389 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14390 "xsaddqpo %0,%1,%2"
14391 [(set_attr "type" "vecfloat")
14392 (set_attr "size" "128")])
14394 (define_insn "sub<mode>3_odd"
14395 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14397 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14398 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14399 UNSPEC_SUB_ROUND_TO_ODD))]
14400 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14401 "xssubqpo %0,%1,%2"
14402 [(set_attr "type" "vecfloat")
14403 (set_attr "size" "128")])
14405 (define_insn "mul<mode>3_odd"
14406 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14408 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14409 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14410 UNSPEC_MUL_ROUND_TO_ODD))]
14411 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14412 "xsmulqpo %0,%1,%2"
14413 [(set_attr "type" "qmul")
14414 (set_attr "size" "128")])
14416 (define_insn "div<mode>3_odd"
14417 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14419 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14420 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14421 UNSPEC_DIV_ROUND_TO_ODD))]
14422 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14423 "xsdivqpo %0,%1,%2"
14424 [(set_attr "type" "vecdiv")
14425 (set_attr "size" "128")])
14427 (define_insn "sqrt<mode>2_odd"
14428 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14430 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14431 UNSPEC_SQRT_ROUND_TO_ODD))]
14432 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14434 [(set_attr "type" "vecdiv")
14435 (set_attr "size" "128")])
14437 (define_insn "fma<mode>4_odd"
14438 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14440 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14441 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14442 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14443 UNSPEC_FMA_ROUND_TO_ODD))]
14444 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14445 "xsmaddqpo %0,%1,%2"
14446 [(set_attr "type" "qmul")
14447 (set_attr "size" "128")])
14449 (define_insn "*fms<mode>4_odd"
14450 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14452 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14453 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14455 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14456 UNSPEC_FMA_ROUND_TO_ODD))]
14457 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14458 "xsmsubqpo %0,%1,%2"
14459 [(set_attr "type" "qmul")
14460 (set_attr "size" "128")])
14462 (define_insn "*nfma<mode>4_odd"
14463 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14466 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14467 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14468 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14469 UNSPEC_FMA_ROUND_TO_ODD)))]
14470 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14471 "xsnmaddqpo %0,%1,%2"
14472 [(set_attr "type" "qmul")
14473 (set_attr "size" "128")])
14475 (define_insn "*nfms<mode>4_odd"
14476 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14479 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14480 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14482 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14483 UNSPEC_FMA_ROUND_TO_ODD)))]
14484 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14485 "xsnmsubqpo %0,%1,%2"
14486 [(set_attr "type" "qmul")
14487 (set_attr "size" "128")])
14489 (define_insn "trunc<mode>df2_odd"
14490 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14491 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14492 UNSPEC_TRUNC_ROUND_TO_ODD))]
14493 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14495 [(set_attr "type" "vecfloat")
14496 (set_attr "size" "128")])
14498 ;; IEEE 128-bit comparisons
14499 (define_insn "*cmp<mode>_hw"
14500 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14501 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14502 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14503 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14504 "xscmpuqp %0,%1,%2"
14505 [(set_attr "type" "veccmp")
14506 (set_attr "size" "128")])
14508 ;; Miscellaneous ISA 3.0 (power9) instructions
14510 (define_insn "darn_32"
14511 [(set (match_operand:SI 0 "register_operand" "=r")
14512 (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14515 [(set_attr "type" "integer")])
14517 (define_insn "darn_raw"
14518 [(set (match_operand:DI 0 "register_operand" "=r")
14519 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14520 "TARGET_P9_MISC && TARGET_64BIT"
14522 [(set_attr "type" "integer")])
14524 (define_insn "darn"
14525 [(set (match_operand:DI 0 "register_operand" "=r")
14526 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14527 "TARGET_P9_MISC && TARGET_64BIT"
14529 [(set_attr "type" "integer")])
14531 ;; Test byte within range.
14533 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14534 ;; represents a byte whose value is ignored in this context and
14535 ;; vv, the least significant byte, holds the byte value that is to
14536 ;; be tested for membership within the range specified by operand 2.
14537 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14539 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14540 ;; vv <= hi. Otherwise, set register operand 0 to 0.
14542 ;; Though the instructions to which this expansion maps operate on
14543 ;; 64-bit registers, the current implementation only operates on
14544 ;; SI-mode operands as the high-order bits provide no information
14545 ;; that is not already available in the low-order bits. To avoid the
14546 ;; costs of data widening operations, future enhancements might allow
14547 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14548 (define_expand "cmprb"
14549 [(set (match_dup 3)
14550 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14551 (match_operand:SI 2 "gpc_reg_operand" "r")]
14553 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14554 (if_then_else:SI (lt (match_dup 3)
14557 (if_then_else (gt (match_dup 3)
14563 operands[3] = gen_reg_rtx (CCmode);
14566 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14567 ;; represents a byte whose value is ignored in this context and
14568 ;; vv, the least significant byte, holds the byte value that is to
14569 ;; be tested for membership within the range specified by operand 2.
14570 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14572 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14573 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
14574 ;; 3 bits of the target CR register are all set to 0.
14575 (define_insn "*cmprb_internal"
14576 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14577 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14578 (match_operand:SI 2 "gpc_reg_operand" "r")]
14582 [(set_attr "type" "logical")])
14584 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14585 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
14586 ;; if the GT bit (0x4) of condition register operand 1 is on.
14587 ;; Otherwise, set operand 0 to 0. Note that the result stored into
14588 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14589 ;; within condition register operand 1.
14590 (define_insn "setb_signed"
14591 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14592 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14595 (if_then_else (gt (match_dup 1)
14601 [(set_attr "type" "logical")])
14603 (define_insn "setb_unsigned"
14604 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14605 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14608 (if_then_else (gtu (match_dup 1)
14614 [(set_attr "type" "logical")])
14616 ;; Test byte within two ranges.
14618 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14619 ;; represents a byte whose value is ignored in this context and
14620 ;; vv, the least significant byte, holds the byte value that is to
14621 ;; be tested for membership within the range specified by operand 2.
14622 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14624 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14625 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
14628 ;; Though the instructions to which this expansion maps operate on
14629 ;; 64-bit registers, the current implementation only operates on
14630 ;; SI-mode operands as the high-order bits provide no information
14631 ;; that is not already available in the low-order bits. To avoid the
14632 ;; costs of data widening operations, future enhancements might allow
14633 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14634 (define_expand "cmprb2"
14635 [(set (match_dup 3)
14636 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14637 (match_operand:SI 2 "gpc_reg_operand" "r")]
14639 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14640 (if_then_else:SI (lt (match_dup 3)
14643 (if_then_else (gt (match_dup 3)
14649 operands[3] = gen_reg_rtx (CCmode);
14652 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14653 ;; represents a byte whose value is ignored in this context and
14654 ;; vv, the least significant byte, holds the byte value that is to
14655 ;; be tested for membership within the ranges specified by operand 2.
14656 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14658 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14659 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14660 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
14661 ;; CR register are all set to 0.
14662 (define_insn "*cmprb2_internal"
14663 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14664 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14665 (match_operand:SI 2 "gpc_reg_operand" "r")]
14669 [(set_attr "type" "logical")])
14671 ;; Test byte membership within set of 8 bytes.
14673 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14674 ;; represents a byte whose value is ignored in this context and
14675 ;; vv, the least significant byte, holds the byte value that is to
14676 ;; be tested for membership within the set specified by operand 2.
14677 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14679 ;; Return in target register operand 0 a value of 1 if vv equals one
14680 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
14681 ;; register operand 0 to 0. Note that the 8 byte values held within
14682 ;; operand 2 need not be unique.
14684 ;; Though the instructions to which this expansion maps operate on
14685 ;; 64-bit registers, the current implementation requires that operands
14686 ;; 0 and 1 have mode SI as the high-order bits provide no information
14687 ;; that is not already available in the low-order bits. To avoid the
14688 ;; costs of data widening operations, future enhancements might allow
14689 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14690 (define_expand "cmpeqb"
14691 [(set (match_dup 3)
14692 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14693 (match_operand:DI 2 "gpc_reg_operand" "r")]
14695 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14696 (if_then_else:SI (lt (match_dup 3)
14699 (if_then_else (gt (match_dup 3)
14703 "TARGET_P9_MISC && TARGET_64BIT"
14705 operands[3] = gen_reg_rtx (CCmode);
14708 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14709 ;; represents a byte whose value is ignored in this context and
14710 ;; vv, the least significant byte, holds the byte value that is to
14711 ;; be tested for membership within the set specified by operand 2.
14712 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14714 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14715 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
14716 ;; set the GT bit to zero. The other 3 bits of the target CR register
14717 ;; are all set to 0.
14718 (define_insn "*cmpeqb_internal"
14719 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14720 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14721 (match_operand:DI 2 "gpc_reg_operand" "r")]
14723 "TARGET_P9_MISC && TARGET_64BIT"
14725 [(set_attr "type" "logical")])
14728 (include "sync.md")
14729 (include "vector.md")
14731 (include "altivec.md")
14733 (include "crypto.md")