1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2015 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)
38 (ARG_POINTER_REGNUM 67)
49 (FIRST_ALTIVEC_REGNO 77)
50 (LAST_ALTIVEC_REGNO 108)
55 (FRAME_POINTER_REGNUM 113)
59 (FIRST_SPE_HIGH_REGNO 117)
60 (LAST_SPE_HIGH_REGNO 148)
67 (define_c_enum "unspec"
68 [UNSPEC_FRSP ; frsp for POWER machines
69 UNSPEC_PROBE_STACK ; probe stack memory reference
70 UNSPEC_TOCPTR ; address of a word pointing to the TOC
71 UNSPEC_TOC ; address of the TOC (more-or-less)
72 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
74 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
80 UNSPEC_LD_MPIC ; load_macho_picbase
81 UNSPEC_RELD_MPIC ; re-load_macho_picbase
82 UNSPEC_MPIC_CORRECT ; macho_correct_pic
96 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
97 UNSPEC_MV_CR_GT ; move_from_CR_gt_bit
115 UNSPEC_MACHOPIC_OFFSET
128 UNSPEC_P8V_RELOAD_FROM_GPR
131 UNSPEC_P8V_RELOAD_FROM_VSX
146 ;; UNSPEC_VOLATILE usage
149 (define_c_enum "unspecv"
151 UNSPECV_LL ; load-locked
152 UNSPECV_SC ; store-conditional
153 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
154 UNSPECV_EH_RR ; eh_reg_restore
155 UNSPECV_ISYNC ; isync instruction
156 UNSPECV_MFTB ; move from time base
157 UNSPECV_NLGR ; non-local goto receiver
158 UNSPECV_MFFS ; Move from FPSCR
159 UNSPECV_MTFSF ; Move to FPSCR Fields
163 ;; Define an insn type attribute. This is used in function unit delay
167 add,logical,shift,insert,
169 exts,cntlz,popcnt,isel,
170 load,store,fpload,fpstore,vecload,vecstore,
172 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
173 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
174 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
176 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
177 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
179 (const_string "integer"))
181 ;; What data size does this instruction work on?
182 ;; This is used for insert, mul.
183 (define_attr "size" "8,16,32,64" (const_string "32"))
185 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
186 ;; This is used for add, logical, shift, exts, mul.
187 (define_attr "dot" "no,yes" (const_string "no"))
189 ;; Does this instruction sign-extend its result?
190 ;; This is used for load insns.
191 (define_attr "sign_extend" "no,yes" (const_string "no"))
193 ;; Does this instruction use indexed (that is, reg+reg) addressing?
194 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
195 ;; it is automatically set based on that. If a load or store instruction
196 ;; has fewer than two operands it needs to set this attribute manually
197 ;; or the compiler will crash.
198 (define_attr "indexed" "no,yes"
199 (if_then_else (ior (match_operand 0 "indexed_address_mem")
200 (match_operand 1 "indexed_address_mem"))
202 (const_string "no")))
204 ;; Does this instruction use update addressing?
205 ;; This is used for load and store insns. See the comments for "indexed".
206 (define_attr "update" "no,yes"
207 (if_then_else (ior (match_operand 0 "update_address_mem")
208 (match_operand 1 "update_address_mem"))
210 (const_string "no")))
212 ;; Is this instruction using operands[2] as shift amount, and can that be a
214 ;; This is used for shift insns.
215 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
217 ;; Is this instruction using a shift amount from a register?
218 ;; This is used for shift insns.
219 (define_attr "var_shift" "no,yes"
220 (if_then_else (and (eq_attr "type" "shift")
221 (eq_attr "maybe_var_shift" "yes"))
222 (if_then_else (match_operand 2 "gpc_reg_operand")
225 (const_string "no")))
227 ;; Define floating point instruction sub-types for use with Xfpu.md
228 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
230 ;; Length (in bytes).
231 ; '(pc)' in the following doesn't include the instruction itself; it is
232 ; calculated as if the instruction had zero size.
233 (define_attr "length" ""
234 (if_then_else (eq_attr "type" "branch")
235 (if_then_else (and (ge (minus (match_dup 0) (pc))
237 (lt (minus (match_dup 0) (pc))
243 ;; Processor type -- this attribute must exactly match the processor_type
244 ;; enumeration in rs6000-opts.h.
246 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
247 ppc750,ppc7400,ppc7450,
248 ppc403,ppc405,ppc440,ppc476,
249 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
250 power4,power5,power6,power7,power8,
251 rs64a,mpccore,cell,ppca2,titan"
252 (const (symbol_ref "rs6000_cpu_attr")))
255 ;; If this instruction is microcoded on the CELL processor
256 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
257 (define_attr "cell_micro" "not,conditional,always"
258 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
259 (eq_attr "dot" "yes"))
260 (and (eq_attr "type" "load")
261 (eq_attr "sign_extend" "yes"))
262 (and (eq_attr "type" "shift")
263 (eq_attr "var_shift" "yes")))
264 (const_string "always")
265 (const_string "not")))
267 (automata_option "ndfa")
280 (include "e300c2c3.md")
281 (include "e500mc.md")
282 (include "e500mc64.md")
285 (include "power4.md")
286 (include "power5.md")
287 (include "power6.md")
288 (include "power7.md")
289 (include "power8.md")
295 (include "predicates.md")
296 (include "constraints.md")
298 (include "darwin.md")
303 ; This mode iterator allows :GPR to be used to indicate the allowable size
304 ; of whole values in GPRs.
305 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
307 ; Any supported integer mode.
308 (define_mode_iterator INT [QI HI SI DI TI PTI])
310 ; Any supported integer mode that fits in one register.
311 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
313 ; Everything we can extend QImode to.
314 (define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")])
316 ; Everything we can extend HImode to.
317 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
319 ; Everything we can extend SImode to.
320 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
322 ; QImode or HImode for small atomic ops
323 (define_mode_iterator QHI [QI HI])
325 ; HImode or SImode for sign extended fusion ops
326 (define_mode_iterator HSI [HI SI])
328 ; SImode or DImode, even if DImode doesn't fit in GPRs.
329 (define_mode_iterator SDI [SI DI])
331 ; The size of a pointer. Also, the size of the value that a record-condition
332 ; (one with a '.') will compare; and the size used for arithmetic carries.
333 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
335 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
336 ; PTImode is GPR only)
337 (define_mode_iterator TI2 [TI PTI])
339 ; Any hardware-supported floating-point mode
340 (define_mode_iterator FP [
341 (SF "TARGET_HARD_FLOAT
342 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
343 (DF "TARGET_HARD_FLOAT
344 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
345 (TF "!TARGET_IEEEQUAD
347 && (TARGET_FPRS || TARGET_E500_DOUBLE)
348 && TARGET_LONG_DOUBLE_128")
352 ; Any fma capable floating-point mode.
353 (define_mode_iterator FMA_F [
354 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
355 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
356 || VECTOR_UNIT_VSX_P (DFmode)")
357 (V2SF "TARGET_PAIRED_FLOAT")
358 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
359 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
362 ; Floating point move iterators to combine binary and decimal moves
363 (define_mode_iterator FMOVE32 [SF SD])
364 (define_mode_iterator FMOVE64 [DF DD])
365 (define_mode_iterator FMOVE64X [DI DF DD])
366 (define_mode_iterator FMOVE128 [(TF "!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128")
367 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
369 ; Iterators for 128 bit types for direct move
370 (define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE")
379 ; Whether a floating point move is ok, don't allow SD without hardware FP
380 (define_mode_attr fmove_ok [(SF "")
382 (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
385 ; Convert REAL_VALUE to the appropriate bits
386 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
387 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
388 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
389 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
391 ; Definitions for load to 32-bit fpr register
392 (define_mode_attr f32_lr [(SF "f") (SD "wz")])
393 (define_mode_attr f32_lm [(SF "m") (SD "Z")])
394 (define_mode_attr f32_li [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
395 (define_mode_attr f32_lv [(SF "lxsspx %x0,%y1") (SD "lxsiwzx %x0,%y1")])
397 ; Definitions for store from 32-bit fpr register
398 (define_mode_attr f32_sr [(SF "f") (SD "wx")])
399 (define_mode_attr f32_sm [(SF "m") (SD "Z")])
400 (define_mode_attr f32_si [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
401 (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")])
403 ; Definitions for 32-bit fpr direct move
404 ; At present, the decimal modes are not allowed in the traditional altivec
405 ; registers, so restrict the constraints to just the traditional FPRs.
406 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
408 ; Definitions for 32-bit VSX
409 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
411 ; Definitions for 32-bit use of altivec registers
412 (define_mode_attr f32_av [(SF "wu") (SD "wn")])
414 ; Definitions for 64-bit VSX
415 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
417 ; Definitions for 64-bit direct move
418 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
420 ; Definitions for 64-bit use of altivec registers
421 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
423 ; These modes do not fit in integer registers in 32-bit mode.
424 ; but on e500v2, the gpr are 64 bit registers
425 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
427 ; Iterator for reciprocal estimate instructions
428 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
430 ; Iterator for just SF/DF
431 (define_mode_iterator SFDF [SF DF])
433 ; SF/DF suffix for traditional floating instructions
434 (define_mode_attr Ftrad [(SF "s") (DF "")])
436 ; SF/DF suffix for VSX instructions
437 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
439 ; SF/DF constraint for arithmetic on traditional floating point registers
440 (define_mode_attr Ff [(SF "f") (DF "d")])
442 ; SF/DF constraint for arithmetic on VSX registers
443 (define_mode_attr Fv [(SF "wy") (DF "ws")])
445 ; SF/DF constraint for arithmetic on altivec registers
446 (define_mode_attr Fa [(SF "wu") (DF "wv")])
448 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
449 (define_mode_attr Fs [(SF "s") (DF "d")])
452 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
453 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
455 ; Conditional returns.
456 (define_code_iterator any_return [return simple_return])
457 (define_code_attr return_pred [(return "direct_return ()")
458 (simple_return "1")])
459 (define_code_attr return_str [(return "") (simple_return "simple_")])
462 (define_code_iterator iorxor [ior xor])
464 ; Signed/unsigned variants of ops.
465 (define_code_iterator any_extend [sign_extend zero_extend])
466 (define_code_attr u [(sign_extend "") (zero_extend "u")])
467 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
469 ; Various instructions that come in SI and DI forms.
470 ; A generic w/d attribute, for things like cmpw/cmpd.
471 (define_mode_attr wd [(QI "b")
480 ;; How many bits in this mode?
481 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
484 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
486 ;; ISEL/ISEL64 target selection
487 (define_mode_attr sel [(SI "") (DI "64")])
489 ;; Bitmask for shift instructions
490 (define_mode_attr hH [(SI "h") (DI "H")])
492 ;; A mode twice the size of the given mode
493 (define_mode_attr dmode [(SI "di") (DI "ti")])
494 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
496 ;; Suffix for reload patterns
497 (define_mode_attr ptrsize [(SI "32bit")
500 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
501 (DI "TARGET_64BIT")])
503 (define_mode_attr mptrsize [(SI "si")
506 (define_mode_attr ptrload [(SI "lwz")
509 (define_mode_attr ptrm [(SI "m")
512 (define_mode_attr rreg [(SF "f")
519 (define_mode_attr rreg2 [(SF "f")
522 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
523 (DF "TARGET_FCFID")])
525 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
526 (DF "TARGET_E500_DOUBLE")])
528 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
529 (DF "TARGET_DOUBLE_FLOAT")])
531 ;; Mode iterator for logical operations on 128-bit types
532 (define_mode_iterator BOOL_128 [TI
534 (V16QI "TARGET_ALTIVEC")
535 (V8HI "TARGET_ALTIVEC")
536 (V4SI "TARGET_ALTIVEC")
537 (V4SF "TARGET_ALTIVEC")
538 (V2DI "TARGET_ALTIVEC")
539 (V2DF "TARGET_ALTIVEC")
540 (V1TI "TARGET_ALTIVEC")])
542 ;; For the GPRs we use 3 constraints for register outputs, two that are the
543 ;; same as the output register, and a third where the output register is an
544 ;; early clobber, so we don't have to deal with register overlaps. For the
545 ;; vector types, we prefer to use the vector registers. For TI mode, allow
548 ;; Mode attribute for boolean operation register constraints for output
549 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
551 (V16QI "wa,v,&?r,?r,?r")
552 (V8HI "wa,v,&?r,?r,?r")
553 (V4SI "wa,v,&?r,?r,?r")
554 (V4SF "wa,v,&?r,?r,?r")
555 (V2DI "wa,v,&?r,?r,?r")
556 (V2DF "wa,v,&?r,?r,?r")
557 (V1TI "wa,v,&?r,?r,?r")])
559 ;; Mode attribute for boolean operation register constraints for operand1
560 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
568 (V1TI "wa,v,r,0,r")])
570 ;; Mode attribute for boolean operation register constraints for operand2
571 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
579 (V1TI "wa,v,r,r,0")])
581 ;; Mode attribute for boolean operation register constraints for operand1
582 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
583 ;; is used for operand1 or operand2
584 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
592 (V1TI "wa,v,r,0,0")])
594 ;; Reload iterator for creating the function to allocate a base register to
595 ;; supplement addressing modes.
596 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
597 SF SD SI DF DD DI TI PTI])
600 ;; Start with fixed-point load and store insns. Here we put only the more
601 ;; complex forms. Basic data transfer is done later.
603 (define_insn "zero_extendqi<mode>2"
604 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
605 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
610 [(set_attr "type" "load,shift")])
612 (define_insn_and_split "*zero_extendqi<mode>2_dot"
613 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
614 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
616 (clobber (match_scratch:EXTQI 0 "=r,r"))]
617 "rs6000_gen_cell_microcode"
621 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
623 (zero_extend:EXTQI (match_dup 1)))
625 (compare:CC (match_dup 0)
628 [(set_attr "type" "logical")
629 (set_attr "dot" "yes")
630 (set_attr "length" "4,8")])
632 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
633 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
634 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
636 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
637 (zero_extend:EXTQI (match_dup 1)))]
638 "rs6000_gen_cell_microcode"
642 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
644 (zero_extend:EXTQI (match_dup 1)))
646 (compare:CC (match_dup 0)
649 [(set_attr "type" "logical")
650 (set_attr "dot" "yes")
651 (set_attr "length" "4,8")])
654 (define_insn "zero_extendhi<mode>2"
655 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
656 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
660 rlwinm %0,%1,0,0xffff"
661 [(set_attr "type" "load,shift")])
663 (define_insn_and_split "*zero_extendhi<mode>2_dot"
664 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
665 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
667 (clobber (match_scratch:EXTHI 0 "=r,r"))]
668 "rs6000_gen_cell_microcode"
672 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
674 (zero_extend:EXTHI (match_dup 1)))
676 (compare:CC (match_dup 0)
679 [(set_attr "type" "logical")
680 (set_attr "dot" "yes")
681 (set_attr "length" "4,8")])
683 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
684 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
685 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
687 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
688 (zero_extend:EXTHI (match_dup 1)))]
689 "rs6000_gen_cell_microcode"
693 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
695 (zero_extend:EXTHI (match_dup 1)))
697 (compare:CC (match_dup 0)
700 [(set_attr "type" "logical")
701 (set_attr "dot" "yes")
702 (set_attr "length" "4,8")])
705 (define_insn "zero_extendsi<mode>2"
706 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
707 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
715 [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
717 (define_insn_and_split "*zero_extendsi<mode>2_dot"
718 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
719 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
721 (clobber (match_scratch:EXTSI 0 "=r,r"))]
722 "rs6000_gen_cell_microcode"
726 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
728 (zero_extend:DI (match_dup 1)))
730 (compare:CC (match_dup 0)
733 [(set_attr "type" "shift")
734 (set_attr "dot" "yes")
735 (set_attr "length" "4,8")])
737 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
738 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
739 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
741 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
742 (zero_extend:EXTSI (match_dup 1)))]
743 "rs6000_gen_cell_microcode"
747 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
749 (zero_extend:EXTSI (match_dup 1)))
751 (compare:CC (match_dup 0)
754 [(set_attr "type" "shift")
755 (set_attr "dot" "yes")
756 (set_attr "length" "4,8")])
759 (define_insn "extendqi<mode>2"
760 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
761 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
764 [(set_attr "type" "exts")])
766 (define_insn_and_split "*extendqi<mode>2_dot"
767 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
768 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
770 (clobber (match_scratch:EXTQI 0 "=r,r"))]
771 "rs6000_gen_cell_microcode"
775 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
777 (sign_extend:EXTQI (match_dup 1)))
779 (compare:CC (match_dup 0)
782 [(set_attr "type" "exts")
783 (set_attr "dot" "yes")
784 (set_attr "length" "4,8")])
786 (define_insn_and_split "*extendqi<mode>2_dot2"
787 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
788 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
790 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
791 (sign_extend:EXTQI (match_dup 1)))]
792 "rs6000_gen_cell_microcode"
796 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
798 (sign_extend:EXTQI (match_dup 1)))
800 (compare:CC (match_dup 0)
803 [(set_attr "type" "exts")
804 (set_attr "dot" "yes")
805 (set_attr "length" "4,8")])
808 (define_expand "extendhi<mode>2"
809 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
810 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
814 (define_insn "*extendhi<mode>2"
815 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
816 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
817 "rs6000_gen_cell_microcode"
821 [(set_attr "type" "load,exts")
822 (set_attr "sign_extend" "yes")])
824 (define_insn "*extendhi<mode>2_noload"
825 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
826 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
827 "!rs6000_gen_cell_microcode"
829 [(set_attr "type" "exts")])
831 (define_insn_and_split "*extendhi<mode>2_dot"
832 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
833 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
835 (clobber (match_scratch:EXTHI 0 "=r,r"))]
836 "rs6000_gen_cell_microcode"
840 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
842 (sign_extend:EXTHI (match_dup 1)))
844 (compare:CC (match_dup 0)
847 [(set_attr "type" "exts")
848 (set_attr "dot" "yes")
849 (set_attr "length" "4,8")])
851 (define_insn_and_split "*extendhi<mode>2_dot2"
852 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
853 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
855 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
856 (sign_extend:EXTHI (match_dup 1)))]
857 "rs6000_gen_cell_microcode"
861 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
863 (sign_extend:EXTHI (match_dup 1)))
865 (compare:CC (match_dup 0)
868 [(set_attr "type" "exts")
869 (set_attr "dot" "yes")
870 (set_attr "length" "4,8")])
873 (define_insn "extendsi<mode>2"
874 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
875 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
883 [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
884 (set_attr "sign_extend" "yes")])
886 (define_insn_and_split "*extendsi<mode>2_dot"
887 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
888 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
890 (clobber (match_scratch:EXTSI 0 "=r,r"))]
891 "rs6000_gen_cell_microcode"
895 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
897 (sign_extend:EXTSI (match_dup 1)))
899 (compare:CC (match_dup 0)
902 [(set_attr "type" "exts")
903 (set_attr "dot" "yes")
904 (set_attr "length" "4,8")])
906 (define_insn_and_split "*extendsi<mode>2_dot2"
907 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
908 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
910 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
911 (sign_extend:EXTSI (match_dup 1)))]
912 "rs6000_gen_cell_microcode"
916 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
918 (sign_extend:EXTSI (match_dup 1)))
920 (compare:CC (match_dup 0)
923 [(set_attr "type" "exts")
924 (set_attr "dot" "yes")
925 (set_attr "length" "4,8")])
927 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
929 (define_insn "*macchwc"
930 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
931 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
932 (match_operand:SI 2 "gpc_reg_operand" "r")
935 (match_operand:HI 1 "gpc_reg_operand" "r")))
936 (match_operand:SI 4 "gpc_reg_operand" "0"))
938 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
939 (plus:SI (mult:SI (ashiftrt:SI
947 [(set_attr "type" "halfmul")])
949 (define_insn "*macchw"
950 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
951 (plus:SI (mult:SI (ashiftrt:SI
952 (match_operand:SI 2 "gpc_reg_operand" "r")
955 (match_operand:HI 1 "gpc_reg_operand" "r")))
956 (match_operand:SI 3 "gpc_reg_operand" "0")))]
959 [(set_attr "type" "halfmul")])
961 (define_insn "*macchwuc"
962 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
963 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
964 (match_operand:SI 2 "gpc_reg_operand" "r")
967 (match_operand:HI 1 "gpc_reg_operand" "r")))
968 (match_operand:SI 4 "gpc_reg_operand" "0"))
970 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
971 (plus:SI (mult:SI (lshiftrt:SI
979 [(set_attr "type" "halfmul")])
981 (define_insn "*macchwu"
982 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
983 (plus:SI (mult:SI (lshiftrt:SI
984 (match_operand:SI 2 "gpc_reg_operand" "r")
987 (match_operand:HI 1 "gpc_reg_operand" "r")))
988 (match_operand:SI 3 "gpc_reg_operand" "0")))]
991 [(set_attr "type" "halfmul")])
993 (define_insn "*machhwc"
994 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
995 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
996 (match_operand:SI 1 "gpc_reg_operand" "%r")
999 (match_operand:SI 2 "gpc_reg_operand" "r")
1001 (match_operand:SI 4 "gpc_reg_operand" "0"))
1003 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1004 (plus:SI (mult:SI (ashiftrt:SI
1013 [(set_attr "type" "halfmul")])
1015 (define_insn "*machhw"
1016 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1017 (plus:SI (mult:SI (ashiftrt:SI
1018 (match_operand:SI 1 "gpc_reg_operand" "%r")
1021 (match_operand:SI 2 "gpc_reg_operand" "r")
1023 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1026 [(set_attr "type" "halfmul")])
1028 (define_insn "*machhwuc"
1029 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1030 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1031 (match_operand:SI 1 "gpc_reg_operand" "%r")
1034 (match_operand:SI 2 "gpc_reg_operand" "r")
1036 (match_operand:SI 4 "gpc_reg_operand" "0"))
1038 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1039 (plus:SI (mult:SI (lshiftrt:SI
1048 [(set_attr "type" "halfmul")])
1050 (define_insn "*machhwu"
1051 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1052 (plus:SI (mult:SI (lshiftrt:SI
1053 (match_operand:SI 1 "gpc_reg_operand" "%r")
1056 (match_operand:SI 2 "gpc_reg_operand" "r")
1058 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1061 [(set_attr "type" "halfmul")])
1063 (define_insn "*maclhwc"
1064 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1065 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1066 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1068 (match_operand:HI 2 "gpc_reg_operand" "r")))
1069 (match_operand:SI 4 "gpc_reg_operand" "0"))
1071 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1072 (plus:SI (mult:SI (sign_extend:SI
1079 [(set_attr "type" "halfmul")])
1081 (define_insn "*maclhw"
1082 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1083 (plus:SI (mult:SI (sign_extend:SI
1084 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1086 (match_operand:HI 2 "gpc_reg_operand" "r")))
1087 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1090 [(set_attr "type" "halfmul")])
1092 (define_insn "*maclhwuc"
1093 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1094 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1095 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1097 (match_operand:HI 2 "gpc_reg_operand" "r")))
1098 (match_operand:SI 4 "gpc_reg_operand" "0"))
1100 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1101 (plus:SI (mult:SI (zero_extend:SI
1108 [(set_attr "type" "halfmul")])
1110 (define_insn "*maclhwu"
1111 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1112 (plus:SI (mult:SI (zero_extend:SI
1113 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1115 (match_operand:HI 2 "gpc_reg_operand" "r")))
1116 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1119 [(set_attr "type" "halfmul")])
1121 (define_insn "*nmacchwc"
1122 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1123 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1124 (mult:SI (ashiftrt:SI
1125 (match_operand:SI 2 "gpc_reg_operand" "r")
1128 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1130 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1131 (minus:SI (match_dup 4)
1132 (mult:SI (ashiftrt:SI
1139 [(set_attr "type" "halfmul")])
1141 (define_insn "*nmacchw"
1142 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1143 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1144 (mult:SI (ashiftrt:SI
1145 (match_operand:SI 2 "gpc_reg_operand" "r")
1148 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1151 [(set_attr "type" "halfmul")])
1153 (define_insn "*nmachhwc"
1154 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1155 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1156 (mult:SI (ashiftrt:SI
1157 (match_operand:SI 1 "gpc_reg_operand" "%r")
1160 (match_operand:SI 2 "gpc_reg_operand" "r")
1163 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1164 (minus:SI (match_dup 4)
1165 (mult:SI (ashiftrt:SI
1173 [(set_attr "type" "halfmul")])
1175 (define_insn "*nmachhw"
1176 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1177 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1178 (mult:SI (ashiftrt:SI
1179 (match_operand:SI 1 "gpc_reg_operand" "%r")
1182 (match_operand:SI 2 "gpc_reg_operand" "r")
1186 [(set_attr "type" "halfmul")])
1188 (define_insn "*nmaclhwc"
1189 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1190 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1191 (mult:SI (sign_extend:SI
1192 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1194 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1196 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1197 (minus:SI (match_dup 4)
1198 (mult:SI (sign_extend:SI
1204 [(set_attr "type" "halfmul")])
1206 (define_insn "*nmaclhw"
1207 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1208 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1209 (mult:SI (sign_extend:SI
1210 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1212 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1215 [(set_attr "type" "halfmul")])
1217 (define_insn "*mulchwc"
1218 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1219 (compare:CC (mult:SI (ashiftrt:SI
1220 (match_operand:SI 2 "gpc_reg_operand" "r")
1223 (match_operand:HI 1 "gpc_reg_operand" "r")))
1225 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1226 (mult:SI (ashiftrt:SI
1233 [(set_attr "type" "halfmul")])
1235 (define_insn "*mulchw"
1236 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1237 (mult:SI (ashiftrt:SI
1238 (match_operand:SI 2 "gpc_reg_operand" "r")
1241 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1244 [(set_attr "type" "halfmul")])
1246 (define_insn "*mulchwuc"
1247 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1248 (compare:CC (mult:SI (lshiftrt:SI
1249 (match_operand:SI 2 "gpc_reg_operand" "r")
1252 (match_operand:HI 1 "gpc_reg_operand" "r")))
1254 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1255 (mult:SI (lshiftrt:SI
1262 [(set_attr "type" "halfmul")])
1264 (define_insn "*mulchwu"
1265 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1266 (mult:SI (lshiftrt:SI
1267 (match_operand:SI 2 "gpc_reg_operand" "r")
1270 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1273 [(set_attr "type" "halfmul")])
1275 (define_insn "*mulhhwc"
1276 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1277 (compare:CC (mult:SI (ashiftrt:SI
1278 (match_operand:SI 1 "gpc_reg_operand" "%r")
1281 (match_operand:SI 2 "gpc_reg_operand" "r")
1284 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1285 (mult:SI (ashiftrt:SI
1293 [(set_attr "type" "halfmul")])
1295 (define_insn "*mulhhw"
1296 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1297 (mult:SI (ashiftrt:SI
1298 (match_operand:SI 1 "gpc_reg_operand" "%r")
1301 (match_operand:SI 2 "gpc_reg_operand" "r")
1305 [(set_attr "type" "halfmul")])
1307 (define_insn "*mulhhwuc"
1308 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1309 (compare:CC (mult:SI (lshiftrt:SI
1310 (match_operand:SI 1 "gpc_reg_operand" "%r")
1313 (match_operand:SI 2 "gpc_reg_operand" "r")
1316 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1317 (mult:SI (lshiftrt:SI
1325 [(set_attr "type" "halfmul")])
1327 (define_insn "*mulhhwu"
1328 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1329 (mult:SI (lshiftrt:SI
1330 (match_operand:SI 1 "gpc_reg_operand" "%r")
1333 (match_operand:SI 2 "gpc_reg_operand" "r")
1337 [(set_attr "type" "halfmul")])
1339 (define_insn "*mullhwc"
1340 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1341 (compare:CC (mult:SI (sign_extend:SI
1342 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1344 (match_operand:HI 2 "gpc_reg_operand" "r")))
1346 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347 (mult:SI (sign_extend:SI
1353 [(set_attr "type" "halfmul")])
1355 (define_insn "*mullhw"
1356 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1357 (mult:SI (sign_extend:SI
1358 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1360 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1363 [(set_attr "type" "halfmul")])
1365 (define_insn "*mullhwuc"
1366 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1367 (compare:CC (mult:SI (zero_extend:SI
1368 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1370 (match_operand:HI 2 "gpc_reg_operand" "r")))
1372 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1373 (mult:SI (zero_extend:SI
1379 [(set_attr "type" "halfmul")])
1381 (define_insn "*mullhwu"
1382 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1383 (mult:SI (zero_extend:SI
1384 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1386 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1389 [(set_attr "type" "halfmul")])
1391 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1392 (define_insn "dlmzb"
1393 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1394 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1395 (match_operand:SI 2 "gpc_reg_operand" "r")]
1397 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1398 (unspec:SI [(match_dup 1)
1404 (define_expand "strlensi"
1405 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1406 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1407 (match_operand:QI 2 "const_int_operand" "")
1408 (match_operand 3 "const_int_operand" "")]
1409 UNSPEC_DLMZB_STRLEN))
1410 (clobber (match_scratch:CC 4 "=x"))]
1411 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1413 rtx result = operands[0];
1414 rtx src = operands[1];
1415 rtx search_char = operands[2];
1416 rtx align = operands[3];
1417 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1418 rtx loop_label, end_label, mem, cr0, cond;
1419 if (search_char != const0_rtx
1420 || GET_CODE (align) != CONST_INT
1421 || INTVAL (align) < 8)
1423 word1 = gen_reg_rtx (SImode);
1424 word2 = gen_reg_rtx (SImode);
1425 scratch_dlmzb = gen_reg_rtx (SImode);
1426 scratch_string = gen_reg_rtx (Pmode);
1427 loop_label = gen_label_rtx ();
1428 end_label = gen_label_rtx ();
1429 addr = force_reg (Pmode, XEXP (src, 0));
1430 emit_move_insn (scratch_string, addr);
1431 emit_label (loop_label);
1432 mem = change_address (src, SImode, scratch_string);
1433 emit_move_insn (word1, mem);
1434 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1435 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1436 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1437 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1438 emit_jump_insn (gen_rtx_SET (pc_rtx,
1439 gen_rtx_IF_THEN_ELSE (VOIDmode,
1445 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1446 emit_jump_insn (gen_rtx_SET (pc_rtx,
1447 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1449 emit_label (end_label);
1450 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1451 emit_insn (gen_subsi3 (result, scratch_string, addr));
1452 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1456 ;; Fixed-point arithmetic insns.
1458 (define_expand "add<mode>3"
1459 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1460 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1461 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1464 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1466 rtx lo0 = gen_lowpart (SImode, operands[0]);
1467 rtx lo1 = gen_lowpart (SImode, operands[1]);
1468 rtx lo2 = gen_lowpart (SImode, operands[2]);
1469 rtx hi0 = gen_highpart (SImode, operands[0]);
1470 rtx hi1 = gen_highpart (SImode, operands[1]);
1471 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1473 if (!reg_or_short_operand (lo2, SImode))
1474 lo2 = force_reg (SImode, lo2);
1475 if (!adde_operand (hi2, SImode))
1476 hi2 = force_reg (SImode, hi2);
1478 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1479 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1483 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1485 rtx tmp = ((!can_create_pseudo_p ()
1486 || rtx_equal_p (operands[0], operands[1]))
1487 ? operands[0] : gen_reg_rtx (<MODE>mode));
1489 HOST_WIDE_INT val = INTVAL (operands[2]);
1490 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1491 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1493 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1496 /* The ordering here is important for the prolog expander.
1497 When space is allocated from the stack, adding 'low' first may
1498 produce a temporary deallocation (which would be bad). */
1499 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1500 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1505 (define_insn "*add<mode>3"
1506 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1507 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1508 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1514 [(set_attr "type" "add")])
1516 (define_insn "addsi3_high"
1517 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1518 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1519 (high:SI (match_operand 2 "" ""))))]
1520 "TARGET_MACHO && !TARGET_64BIT"
1521 "addis %0,%1,ha16(%2)"
1522 [(set_attr "type" "add")])
1524 (define_insn_and_split "*add<mode>3_dot"
1525 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1526 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1527 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1529 (clobber (match_scratch:GPR 0 "=r,r"))]
1530 "<MODE>mode == Pmode"
1534 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1536 (plus:GPR (match_dup 1)
1539 (compare:CC (match_dup 0)
1542 [(set_attr "type" "add")
1543 (set_attr "dot" "yes")
1544 (set_attr "length" "4,8")])
1546 (define_insn_and_split "*add<mode>3_dot2"
1547 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1548 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1549 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1551 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1552 (plus:GPR (match_dup 1)
1554 "<MODE>mode == Pmode"
1558 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1560 (plus:GPR (match_dup 1)
1563 (compare:CC (match_dup 0)
1566 [(set_attr "type" "add")
1567 (set_attr "dot" "yes")
1568 (set_attr "length" "4,8")])
1570 (define_insn_and_split "*add<mode>3_imm_dot"
1571 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1572 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1573 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1575 (clobber (match_scratch:GPR 0 "=r,r"))
1576 (clobber (reg:GPR CA_REGNO))]
1577 "<MODE>mode == Pmode"
1581 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1583 (plus:GPR (match_dup 1)
1586 (compare:CC (match_dup 0)
1589 [(set_attr "type" "add")
1590 (set_attr "dot" "yes")
1591 (set_attr "length" "4,8")])
1593 (define_insn_and_split "*add<mode>3_imm_dot2"
1594 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1595 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1596 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1598 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1599 (plus:GPR (match_dup 1)
1601 (clobber (reg:GPR CA_REGNO))]
1602 "<MODE>mode == Pmode"
1606 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1608 (plus:GPR (match_dup 1)
1611 (compare:CC (match_dup 0)
1614 [(set_attr "type" "add")
1615 (set_attr "dot" "yes")
1616 (set_attr "length" "4,8")])
1618 ;; Split an add that we can't do in one insn into two insns, each of which
1619 ;; does one 16-bit part. This is used by combine. Note that the low-order
1620 ;; add should be last in case the result gets used in an address.
1623 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1624 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1625 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1627 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1628 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1630 HOST_WIDE_INT val = INTVAL (operands[2]);
1631 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1632 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1634 operands[4] = GEN_INT (low);
1635 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1636 operands[3] = GEN_INT (rest);
1637 else if (can_create_pseudo_p ())
1639 operands[3] = gen_reg_rtx (DImode);
1640 emit_move_insn (operands[3], operands[2]);
1641 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1649 (define_insn "add<mode>3_carry"
1650 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1651 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1652 (match_operand:P 2 "reg_or_short_operand" "rI")))
1653 (set (reg:P CA_REGNO)
1654 (ltu:P (plus:P (match_dup 1)
1659 [(set_attr "type" "add")])
1661 (define_insn "*add<mode>3_imm_carry_pos"
1662 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1663 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1664 (match_operand:P 2 "short_cint_operand" "n")))
1665 (set (reg:P CA_REGNO)
1666 (geu:P (match_dup 1)
1667 (match_operand:P 3 "const_int_operand" "n")))]
1668 "INTVAL (operands[2]) > 0
1669 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1671 [(set_attr "type" "add")])
1673 (define_insn "*add<mode>3_imm_carry_0"
1674 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1675 (match_operand:P 1 "gpc_reg_operand" "r"))
1676 (set (reg:P CA_REGNO)
1680 [(set_attr "type" "add")])
1682 (define_insn "*add<mode>3_imm_carry_m1"
1683 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1684 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1686 (set (reg:P CA_REGNO)
1691 [(set_attr "type" "add")])
1693 (define_insn "*add<mode>3_imm_carry_neg"
1694 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1695 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1696 (match_operand:P 2 "short_cint_operand" "n")))
1697 (set (reg:P CA_REGNO)
1698 (gtu:P (match_dup 1)
1699 (match_operand:P 3 "const_int_operand" "n")))]
1700 "INTVAL (operands[2]) < 0
1701 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1703 [(set_attr "type" "add")])
1706 (define_expand "add<mode>3_carry_in"
1708 (set (match_operand:GPR 0 "gpc_reg_operand")
1709 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1710 (match_operand:GPR 2 "adde_operand"))
1711 (reg:GPR CA_REGNO)))
1712 (clobber (reg:GPR CA_REGNO))])]
1715 if (operands[2] == const0_rtx)
1717 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1720 if (operands[2] == constm1_rtx)
1722 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1727 (define_insn "*add<mode>3_carry_in_internal"
1728 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1729 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1730 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1731 (reg:GPR CA_REGNO)))
1732 (clobber (reg:GPR CA_REGNO))]
1735 [(set_attr "type" "add")])
1737 (define_insn "add<mode>3_carry_in_0"
1738 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1739 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1740 (reg:GPR CA_REGNO)))
1741 (clobber (reg:GPR CA_REGNO))]
1744 [(set_attr "type" "add")])
1746 (define_insn "add<mode>3_carry_in_m1"
1747 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1748 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1751 (clobber (reg:GPR CA_REGNO))]
1754 [(set_attr "type" "add")])
1757 (define_expand "one_cmpl<mode>2"
1758 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1759 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1762 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1764 rs6000_split_logical (operands, NOT, false, false, false);
1769 (define_insn "*one_cmpl<mode>2"
1770 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1771 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1775 (define_insn_and_split "*one_cmpl<mode>2_dot"
1776 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1777 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1779 (clobber (match_scratch:GPR 0 "=r,r"))]
1780 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1784 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1786 (not:GPR (match_dup 1)))
1788 (compare:CC (match_dup 0)
1791 [(set_attr "type" "logical")
1792 (set_attr "dot" "yes")
1793 (set_attr "length" "4,8")])
1795 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1796 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1797 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1799 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1800 (not:GPR (match_dup 1)))]
1801 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1805 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1807 (not:GPR (match_dup 1)))
1809 (compare:CC (match_dup 0)
1812 [(set_attr "type" "logical")
1813 (set_attr "dot" "yes")
1814 (set_attr "length" "4,8")])
1817 (define_expand "sub<mode>3"
1818 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1819 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1820 (match_operand:SDI 2 "gpc_reg_operand" "")))]
1823 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1825 rtx lo0 = gen_lowpart (SImode, operands[0]);
1826 rtx lo1 = gen_lowpart (SImode, operands[1]);
1827 rtx lo2 = gen_lowpart (SImode, operands[2]);
1828 rtx hi0 = gen_highpart (SImode, operands[0]);
1829 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1830 rtx hi2 = gen_highpart (SImode, operands[2]);
1832 if (!reg_or_short_operand (lo1, SImode))
1833 lo1 = force_reg (SImode, lo1);
1834 if (!adde_operand (hi1, SImode))
1835 hi1 = force_reg (SImode, hi1);
1837 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1838 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1842 if (short_cint_operand (operands[1], <MODE>mode))
1844 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1849 (define_insn "*subf<mode>3"
1850 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1851 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1852 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1855 [(set_attr "type" "add")])
1857 (define_insn_and_split "*subf<mode>3_dot"
1858 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1859 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1860 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1862 (clobber (match_scratch:GPR 0 "=r,r"))]
1863 "<MODE>mode == Pmode"
1867 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1869 (minus:GPR (match_dup 2)
1872 (compare:CC (match_dup 0)
1875 [(set_attr "type" "add")
1876 (set_attr "dot" "yes")
1877 (set_attr "length" "4,8")])
1879 (define_insn_and_split "*subf<mode>3_dot2"
1880 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1881 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1882 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1884 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1885 (minus:GPR (match_dup 2)
1887 "<MODE>mode == Pmode"
1891 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1893 (minus:GPR (match_dup 2)
1896 (compare:CC (match_dup 0)
1899 [(set_attr "type" "add")
1900 (set_attr "dot" "yes")
1901 (set_attr "length" "4,8")])
1903 (define_insn "subf<mode>3_imm"
1904 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1905 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
1906 (match_operand:GPR 1 "gpc_reg_operand" "r")))
1907 (clobber (reg:GPR CA_REGNO))]
1910 [(set_attr "type" "add")])
1913 (define_insn "subf<mode>3_carry"
1914 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1915 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
1916 (match_operand:P 1 "gpc_reg_operand" "r")))
1917 (set (reg:P CA_REGNO)
1918 (leu:P (match_dup 1)
1922 [(set_attr "type" "add")])
1924 (define_insn "*subf<mode>3_imm_carry_0"
1925 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1926 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
1927 (set (reg:P CA_REGNO)
1932 [(set_attr "type" "add")])
1934 (define_insn "*subf<mode>3_imm_carry_m1"
1935 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1936 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
1937 (set (reg:P CA_REGNO)
1941 [(set_attr "type" "add")])
1944 (define_expand "subf<mode>3_carry_in"
1946 (set (match_operand:GPR 0 "gpc_reg_operand")
1947 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
1949 (match_operand:GPR 2 "adde_operand")))
1950 (clobber (reg:GPR CA_REGNO))])]
1953 if (operands[2] == const0_rtx)
1955 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
1958 if (operands[2] == constm1_rtx)
1960 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
1965 (define_insn "*subf<mode>3_carry_in_internal"
1966 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1967 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
1969 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1970 (clobber (reg:GPR CA_REGNO))]
1973 [(set_attr "type" "add")])
1975 (define_insn "subf<mode>3_carry_in_0"
1976 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1977 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
1978 (reg:GPR CA_REGNO)))
1979 (clobber (reg:GPR CA_REGNO))]
1982 [(set_attr "type" "add")])
1984 (define_insn "subf<mode>3_carry_in_m1"
1985 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1986 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
1987 (match_operand:GPR 1 "gpc_reg_operand" "r"))
1989 (clobber (reg:GPR CA_REGNO))]
1992 [(set_attr "type" "add")])
1994 (define_insn "subf<mode>3_carry_in_xx"
1995 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1996 (plus:GPR (reg:GPR CA_REGNO)
1998 (clobber (reg:GPR CA_REGNO))]
2001 [(set_attr "type" "add")])
2004 (define_insn "neg<mode>2"
2005 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2006 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2009 [(set_attr "type" "add")])
2011 (define_insn_and_split "*neg<mode>2_dot"
2012 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2013 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2015 (clobber (match_scratch:GPR 0 "=r,r"))]
2016 "<MODE>mode == Pmode"
2020 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2022 (neg:GPR (match_dup 1)))
2024 (compare:CC (match_dup 0)
2027 [(set_attr "type" "add")
2028 (set_attr "dot" "yes")
2029 (set_attr "length" "4,8")])
2031 (define_insn_and_split "*neg<mode>2_dot2"
2032 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2033 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2035 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2036 (neg:GPR (match_dup 1)))]
2037 "<MODE>mode == Pmode"
2041 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2043 (neg:GPR (match_dup 1)))
2045 (compare:CC (match_dup 0)
2048 [(set_attr "type" "add")
2049 (set_attr "dot" "yes")
2050 (set_attr "length" "4,8")])
2053 (define_insn "clz<mode>2"
2054 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2055 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2058 [(set_attr "type" "cntlz")])
2060 (define_expand "ctz<mode>2"
2062 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2064 (and:GPR (match_dup 1)
2067 (clz:GPR (match_dup 3)))
2068 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2069 (minus:GPR (match_dup 5)
2071 (clobber (reg:GPR CA_REGNO))])]
2074 operands[2] = gen_reg_rtx (<MODE>mode);
2075 operands[3] = gen_reg_rtx (<MODE>mode);
2076 operands[4] = gen_reg_rtx (<MODE>mode);
2077 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2080 (define_expand "ffs<mode>2"
2082 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2084 (and:GPR (match_dup 1)
2087 (clz:GPR (match_dup 3)))
2088 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2089 (minus:GPR (match_dup 5)
2091 (clobber (reg:GPR CA_REGNO))])]
2094 operands[2] = gen_reg_rtx (<MODE>mode);
2095 operands[3] = gen_reg_rtx (<MODE>mode);
2096 operands[4] = gen_reg_rtx (<MODE>mode);
2097 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2101 (define_expand "popcount<mode>2"
2102 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2103 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2104 "TARGET_POPCNTB || TARGET_POPCNTD"
2106 rs6000_emit_popcount (operands[0], operands[1]);
2110 (define_insn "popcntb<mode>2"
2111 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2112 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2116 [(set_attr "type" "popcnt")])
2118 (define_insn "popcntd<mode>2"
2119 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2120 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2123 [(set_attr "type" "popcnt")])
2126 (define_expand "parity<mode>2"
2127 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2128 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2131 rs6000_emit_parity (operands[0], operands[1]);
2135 (define_insn "parity<mode>2_cmpb"
2136 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2137 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2138 "TARGET_CMPB && TARGET_POPCNTB"
2140 [(set_attr "type" "popcnt")])
2143 ;; Since the hardware zeros the upper part of the register, save generating the
2144 ;; AND immediate if we are converting to unsigned
2145 (define_insn "*bswaphi2_extenddi"
2146 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2148 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2151 [(set_attr "length" "4")
2152 (set_attr "type" "load")])
2154 (define_insn "*bswaphi2_extendsi"
2155 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2157 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2160 [(set_attr "length" "4")
2161 (set_attr "type" "load")])
2163 (define_expand "bswaphi2"
2164 [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2166 (match_operand:HI 1 "reg_or_mem_operand" "")))
2167 (clobber (match_scratch:SI 2 ""))])]
2170 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2171 operands[1] = force_reg (HImode, operands[1]);
2174 (define_insn "bswaphi2_internal"
2175 [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2177 (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2178 (clobber (match_scratch:SI 2 "=X,X,&r"))]
2184 [(set_attr "length" "4,4,12")
2185 (set_attr "type" "load,store,*")])
2188 [(set (match_operand:HI 0 "gpc_reg_operand" "")
2189 (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2190 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2193 (and:SI (lshiftrt:SI (match_dup 4)
2197 (and:SI (ashift:SI (match_dup 4)
2199 (const_int 65280))) ;; 0xff00
2201 (ior:SI (match_dup 3)
2205 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2206 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2209 (define_insn "*bswapsi2_extenddi"
2210 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2212 (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2215 [(set_attr "length" "4")
2216 (set_attr "type" "load")])
2218 (define_expand "bswapsi2"
2219 [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2221 (match_operand:SI 1 "reg_or_mem_operand" "")))]
2224 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2225 operands[1] = force_reg (SImode, operands[1]);
2228 (define_insn "*bswapsi2_internal"
2229 [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2231 (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2237 [(set_attr "length" "4,4,12")
2238 (set_attr "type" "load,store,*")])
2240 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2241 ;; zero_extract insns do not change for -mlittle.
2243 [(set (match_operand:SI 0 "gpc_reg_operand" "")
2244 (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2247 (rotate:SI (match_dup 1) (const_int 8)))
2248 (set (zero_extract:SI (match_dup 0)
2252 (set (zero_extract:SI (match_dup 0)
2255 (rotate:SI (match_dup 1)
2259 (define_expand "bswapdi2"
2260 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2262 (match_operand:DI 1 "reg_or_mem_operand" "")))
2263 (clobber (match_scratch:DI 2 ""))
2264 (clobber (match_scratch:DI 3 ""))])]
2267 if (!REG_P (operands[0]) && !REG_P (operands[1]))
2268 operands[1] = force_reg (DImode, operands[1]);
2270 if (!TARGET_POWERPC64)
2272 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2273 that uses 64-bit registers needs the same scratch registers as 64-bit
2275 emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2280 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2281 (define_insn "*bswapdi2_ldbrx"
2282 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2283 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2284 (clobber (match_scratch:DI 2 "=X,X,&r"))
2285 (clobber (match_scratch:DI 3 "=X,X,&r"))]
2286 "TARGET_POWERPC64 && TARGET_LDBRX
2287 && (REG_P (operands[0]) || REG_P (operands[1]))"
2292 [(set_attr "length" "4,4,36")
2293 (set_attr "type" "load,store,*")])
2295 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2296 (define_insn "*bswapdi2_64bit"
2297 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2298 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2299 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2300 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2301 "TARGET_POWERPC64 && !TARGET_LDBRX
2302 && (REG_P (operands[0]) || REG_P (operands[1]))
2303 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2304 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2306 [(set_attr "length" "16,12,36")])
2309 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2310 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2311 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2312 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2313 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2317 rtx dest = operands[0];
2318 rtx src = operands[1];
2319 rtx op2 = operands[2];
2320 rtx op3 = operands[3];
2321 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2322 BYTES_BIG_ENDIAN ? 4 : 0);
2323 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2324 BYTES_BIG_ENDIAN ? 4 : 0);
2330 addr1 = XEXP (src, 0);
2331 if (GET_CODE (addr1) == PLUS)
2333 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2334 if (TARGET_AVOID_XFORM)
2336 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2340 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2342 else if (TARGET_AVOID_XFORM)
2344 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2349 emit_move_insn (op2, GEN_INT (4));
2350 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2353 word1 = change_address (src, SImode, addr1);
2354 word2 = change_address (src, SImode, addr2);
2356 if (BYTES_BIG_ENDIAN)
2358 emit_insn (gen_bswapsi2 (op3_32, word2));
2359 emit_insn (gen_bswapsi2 (dest_32, word1));
2363 emit_insn (gen_bswapsi2 (op3_32, word1));
2364 emit_insn (gen_bswapsi2 (dest_32, word2));
2367 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2368 emit_insn (gen_iordi3 (dest, dest, op3));
2373 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2374 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2375 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2376 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2377 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2381 rtx dest = operands[0];
2382 rtx src = operands[1];
2383 rtx op2 = operands[2];
2384 rtx op3 = operands[3];
2385 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2386 BYTES_BIG_ENDIAN ? 4 : 0);
2387 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2388 BYTES_BIG_ENDIAN ? 4 : 0);
2394 addr1 = XEXP (dest, 0);
2395 if (GET_CODE (addr1) == PLUS)
2397 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2398 if (TARGET_AVOID_XFORM)
2400 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2404 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2406 else if (TARGET_AVOID_XFORM)
2408 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2413 emit_move_insn (op2, GEN_INT (4));
2414 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2417 word1 = change_address (dest, SImode, addr1);
2418 word2 = change_address (dest, SImode, addr2);
2420 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2422 if (BYTES_BIG_ENDIAN)
2424 emit_insn (gen_bswapsi2 (word1, src_si));
2425 emit_insn (gen_bswapsi2 (word2, op3_si));
2429 emit_insn (gen_bswapsi2 (word2, src_si));
2430 emit_insn (gen_bswapsi2 (word1, op3_si));
2436 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2437 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2438 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2439 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2440 "TARGET_POWERPC64 && reload_completed"
2444 rtx dest = operands[0];
2445 rtx src = operands[1];
2446 rtx op2 = operands[2];
2447 rtx op3 = operands[3];
2448 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2449 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2450 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2451 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2452 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2454 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2455 emit_insn (gen_bswapsi2 (dest_si, src_si));
2456 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2457 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2458 emit_insn (gen_iordi3 (dest, dest, op3));
2462 (define_insn "bswapdi2_32bit"
2463 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2464 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2465 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2466 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2468 [(set_attr "length" "16,12,36")])
2471 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2472 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2473 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2474 "!TARGET_POWERPC64 && reload_completed"
2478 rtx dest = operands[0];
2479 rtx src = operands[1];
2480 rtx op2 = operands[2];
2481 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2482 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2488 addr1 = XEXP (src, 0);
2489 if (GET_CODE (addr1) == PLUS)
2491 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2492 if (TARGET_AVOID_XFORM
2493 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2495 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2499 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2501 else if (TARGET_AVOID_XFORM
2502 || REGNO (addr1) == REGNO (dest2))
2504 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2509 emit_move_insn (op2, GEN_INT (4));
2510 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2513 word1 = change_address (src, SImode, addr1);
2514 word2 = change_address (src, SImode, addr2);
2516 emit_insn (gen_bswapsi2 (dest2, word1));
2517 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2518 thus allowing us to omit an early clobber on the output. */
2519 emit_insn (gen_bswapsi2 (dest1, word2));
2524 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2525 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2526 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2527 "!TARGET_POWERPC64 && reload_completed"
2531 rtx dest = operands[0];
2532 rtx src = operands[1];
2533 rtx op2 = operands[2];
2534 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2535 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2541 addr1 = XEXP (dest, 0);
2542 if (GET_CODE (addr1) == PLUS)
2544 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2545 if (TARGET_AVOID_XFORM)
2547 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2551 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2553 else if (TARGET_AVOID_XFORM)
2555 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2560 emit_move_insn (op2, GEN_INT (4));
2561 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2564 word1 = change_address (dest, SImode, addr1);
2565 word2 = change_address (dest, SImode, addr2);
2567 emit_insn (gen_bswapsi2 (word2, src1));
2568 emit_insn (gen_bswapsi2 (word1, src2));
2573 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2574 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2575 (clobber (match_operand:SI 2 "" ""))]
2576 "!TARGET_POWERPC64 && reload_completed"
2580 rtx dest = operands[0];
2581 rtx src = operands[1];
2582 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2583 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2584 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2585 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2587 emit_insn (gen_bswapsi2 (dest1, src2));
2588 emit_insn (gen_bswapsi2 (dest2, src1));
2593 (define_insn "mul<mode>3"
2594 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2595 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2596 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2601 [(set_attr "type" "mul")
2603 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2605 (match_operand:GPR 2 "short_cint_operand" "")
2606 (const_string "16")]
2607 (const_string "<bits>")))])
2609 (define_insn_and_split "*mul<mode>3_dot"
2610 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2611 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2612 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2614 (clobber (match_scratch:GPR 0 "=r,r"))]
2615 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2619 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2621 (mult:GPR (match_dup 1)
2624 (compare:CC (match_dup 0)
2627 [(set_attr "type" "mul")
2628 (set_attr "size" "<bits>")
2629 (set_attr "dot" "yes")
2630 (set_attr "length" "4,8")])
2632 (define_insn_and_split "*mul<mode>3_dot2"
2633 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2634 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2635 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2637 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2638 (mult:GPR (match_dup 1)
2640 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2644 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2646 (mult:GPR (match_dup 1)
2649 (compare:CC (match_dup 0)
2652 [(set_attr "type" "mul")
2653 (set_attr "size" "<bits>")
2654 (set_attr "dot" "yes")
2655 (set_attr "length" "4,8")])
2658 (define_expand "<su>mul<mode>3_highpart"
2659 [(set (match_operand:GPR 0 "gpc_reg_operand")
2661 (mult:<DMODE> (any_extend:<DMODE>
2662 (match_operand:GPR 1 "gpc_reg_operand"))
2664 (match_operand:GPR 2 "gpc_reg_operand")))
2668 if (<MODE>mode == SImode && TARGET_POWERPC64)
2670 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2675 if (!WORDS_BIG_ENDIAN)
2677 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2683 (define_insn "*<su>mul<mode>3_highpart"
2684 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2686 (mult:<DMODE> (any_extend:<DMODE>
2687 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2689 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2691 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2692 "mulh<wd><u> %0,%1,%2"
2693 [(set_attr "type" "mul")
2694 (set_attr "size" "<bits>")])
2696 (define_insn "<su>mulsi3_highpart_le"
2697 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2699 (mult:DI (any_extend:DI
2700 (match_operand:SI 1 "gpc_reg_operand" "r"))
2702 (match_operand:SI 2 "gpc_reg_operand" "r")))
2704 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2706 [(set_attr "type" "mul")])
2708 (define_insn "<su>muldi3_highpart_le"
2709 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2711 (mult:TI (any_extend:TI
2712 (match_operand:DI 1 "gpc_reg_operand" "r"))
2714 (match_operand:DI 2 "gpc_reg_operand" "r")))
2716 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2718 [(set_attr "type" "mul")
2719 (set_attr "size" "64")])
2721 (define_insn "<su>mulsi3_highpart_64"
2722 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2725 (mult:DI (any_extend:DI
2726 (match_operand:SI 1 "gpc_reg_operand" "r"))
2728 (match_operand:SI 2 "gpc_reg_operand" "r")))
2732 [(set_attr "type" "mul")])
2734 (define_expand "<u>mul<mode><dmode>3"
2735 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2736 (mult:<DMODE> (any_extend:<DMODE>
2737 (match_operand:GPR 1 "gpc_reg_operand"))
2739 (match_operand:GPR 2 "gpc_reg_operand"))))]
2740 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2742 rtx l = gen_reg_rtx (<MODE>mode);
2743 rtx h = gen_reg_rtx (<MODE>mode);
2744 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2745 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2746 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2747 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2752 (define_insn "udiv<mode>3"
2753 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2754 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2755 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2758 [(set_attr "type" "div")
2759 (set_attr "size" "<bits>")])
2762 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2763 ;; modulus. If it isn't a power of two, force operands into register and do
2765 (define_expand "div<mode>3"
2766 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2767 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2768 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2771 if (CONST_INT_P (operands[2])
2772 && INTVAL (operands[2]) > 0
2773 && exact_log2 (INTVAL (operands[2])) >= 0)
2775 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2779 operands[2] = force_reg (<MODE>mode, operands[2]);
2782 (define_insn "*div<mode>3"
2783 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2784 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2785 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2788 [(set_attr "type" "div")
2789 (set_attr "size" "<bits>")])
2791 (define_insn "div<mode>3_sra"
2792 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2793 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2794 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2795 (clobber (reg:GPR CA_REGNO))]
2797 "sra<wd>i %0,%1,%p2\;addze %0,%0"
2798 [(set_attr "type" "two")
2799 (set_attr "length" "8")])
2801 (define_insn_and_split "*div<mode>3_sra_dot"
2802 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2803 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2804 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2806 (clobber (match_scratch:GPR 0 "=r,r"))
2807 (clobber (reg:GPR CA_REGNO))]
2808 "<MODE>mode == Pmode"
2810 sra<wd>i %0,%1,%p2\;addze. %0,%0
2812 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2813 [(parallel [(set (match_dup 0)
2814 (div:GPR (match_dup 1)
2816 (clobber (reg:GPR CA_REGNO))])
2818 (compare:CC (match_dup 0)
2821 [(set_attr "type" "two")
2822 (set_attr "length" "8,12")
2823 (set_attr "cell_micro" "not")])
2825 (define_insn_and_split "*div<mode>3_sra_dot2"
2826 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2827 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2828 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2830 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2831 (div:GPR (match_dup 1)
2833 (clobber (reg:GPR CA_REGNO))]
2834 "<MODE>mode == Pmode"
2836 sra<wd>i %0,%1,%p2\;addze. %0,%0
2838 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2839 [(parallel [(set (match_dup 0)
2840 (div:GPR (match_dup 1)
2842 (clobber (reg:GPR CA_REGNO))])
2844 (compare:CC (match_dup 0)
2847 [(set_attr "type" "two")
2848 (set_attr "length" "8,12")
2849 (set_attr "cell_micro" "not")])
2851 (define_expand "mod<mode>3"
2852 [(use (match_operand:GPR 0 "gpc_reg_operand" ""))
2853 (use (match_operand:GPR 1 "gpc_reg_operand" ""))
2854 (use (match_operand:GPR 2 "reg_or_cint_operand" ""))]
2861 if (GET_CODE (operands[2]) != CONST_INT
2862 || INTVAL (operands[2]) <= 0
2863 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2866 temp1 = gen_reg_rtx (<MODE>mode);
2867 temp2 = gen_reg_rtx (<MODE>mode);
2869 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
2870 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
2871 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
2875 ;; Logical instructions
2876 ;; The logical instructions are mostly combined by using match_operator,
2877 ;; but the plain AND insns are somewhat different because there is no
2878 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
2879 ;; those rotate-and-mask operations. Thus, the AND insns come first.
2881 (define_expand "and<mode>3"
2882 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2883 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
2884 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
2887 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2889 rs6000_split_logical (operands, AND, false, false, false);
2893 if (logical_const_operand (operands[2], <MODE>mode)
2894 && !any_mask_operand (operands[2], <MODE>mode))
2896 if (rs6000_gen_cell_microcode)
2898 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
2902 operands[2] = force_reg (<MODE>mode, operands[2]);
2905 if ((<MODE>mode == DImode && !and64_2_operand (operands[2], <MODE>mode))
2906 || (<MODE>mode != DImode && !and_operand (operands[2], <MODE>mode)))
2907 operands[2] = force_reg (<MODE>mode, operands[2]);
2911 (define_insn "and<mode>3_imm"
2912 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2913 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
2914 (match_operand:GPR 2 "logical_const_operand" "n")))
2915 (clobber (match_scratch:CC 3 "=x"))]
2916 "rs6000_gen_cell_microcode
2917 && !any_mask_operand (operands[2], <MODE>mode)"
2918 "andi%e2. %0,%1,%u2"
2919 [(set_attr "type" "logical")
2920 (set_attr "dot" "yes")])
2922 (define_insn_and_split "*and<mode>3_imm_dot"
2923 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2924 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2925 (match_operand:GPR 2 "logical_const_operand" "n,n"))
2927 (clobber (match_scratch:GPR 0 "=r,r"))
2928 (clobber (match_scratch:CC 4 "=X,x"))]
2929 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2930 && rs6000_gen_cell_microcode
2931 && !any_mask_operand (operands[2], <MODE>mode)"
2935 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2936 [(parallel [(set (match_dup 0)
2937 (and:GPR (match_dup 1)
2939 (clobber (match_dup 4))])
2941 (compare:CC (match_dup 0)
2944 [(set_attr "type" "logical")
2945 (set_attr "dot" "yes")
2946 (set_attr "length" "4,8")])
2948 (define_insn_and_split "*and<mode>3_imm_dot2"
2949 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2950 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2951 (match_operand:GPR 2 "logical_const_operand" "n,n"))
2953 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2954 (and:GPR (match_dup 1)
2956 (clobber (match_scratch:CC 4 "=X,x"))]
2957 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2958 && rs6000_gen_cell_microcode
2959 && !any_mask_operand (operands[2], <MODE>mode)"
2963 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2964 [(parallel [(set (match_dup 0)
2965 (and:GPR (match_dup 1)
2967 (clobber (match_dup 4))])
2969 (compare:CC (match_dup 0)
2972 [(set_attr "type" "logical")
2973 (set_attr "dot" "yes")
2974 (set_attr "length" "4,8")])
2976 (define_insn_and_split "*and<mode>3_imm_mask_dot"
2977 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
2978 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2979 (match_operand:GPR 2 "logical_const_operand" "n,n"))
2981 (clobber (match_scratch:GPR 0 "=r,r"))]
2982 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
2983 && rs6000_gen_cell_microcode
2984 && any_mask_operand (operands[2], <MODE>mode)"
2988 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2990 (and:GPR (match_dup 1)
2993 (compare:CC (match_dup 0)
2996 [(set_attr "type" "logical")
2997 (set_attr "dot" "yes")
2998 (set_attr "length" "4,8")])
3000 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3001 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3002 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3003 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3005 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3006 (and:GPR (match_dup 1)
3008 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3009 && rs6000_gen_cell_microcode
3010 && any_mask_operand (operands[2], <MODE>mode)"
3014 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3016 (and:GPR (match_dup 1)
3019 (compare:CC (match_dup 0)
3022 [(set_attr "type" "logical")
3023 (set_attr "dot" "yes")
3024 (set_attr "length" "4,8")])
3027 (define_insn "*and<mode>3_mask"
3028 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3029 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3030 (match_operand:GPR 2 "any_mask_operand" "S,T")))]
3033 rldic%B2 %0,%1,0,%S2
3034 rlwinm %0,%1,0,%m2,%M2"
3035 [(set_attr "type" "shift")])
3037 (define_insn_and_split "*and<mode>3_mask_dot"
3038 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
3039 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
3040 (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
3042 (clobber (match_scratch:GPR 0 "=r,r,r,r"))]
3043 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3044 && rs6000_gen_cell_microcode
3045 && !logical_const_operand (operands[2], <MODE>mode)"
3047 rldic%B2. %0,%1,0,%S2
3048 rlwinm. %0,%1,0,%m2,%M2
3051 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3053 (and:GPR (match_dup 1)
3056 (compare:CC (match_dup 0)
3059 [(set_attr "type" "shift")
3060 (set_attr "dot" "yes")
3061 (set_attr "length" "4,4,8,8")])
3063 (define_insn_and_split "*and<mode>3_mask_dot2"
3064 [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
3065 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")
3066 (match_operand:GPR 2 "any_mask_operand" "S,T,S,T"))
3068 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
3069 (and:GPR (match_dup 1)
3071 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3072 && rs6000_gen_cell_microcode
3073 && !logical_const_operand (operands[2], <MODE>mode)"
3075 rldic%B2. %0,%1,0,%S2
3076 rlwinm. %0,%1,0,%m2,%M2
3079 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3081 (and:GPR (match_dup 1)
3084 (compare:CC (match_dup 0)
3087 [(set_attr "type" "shift")
3088 (set_attr "dot" "yes")
3089 (set_attr "length" "4,4,8,8")])
3093 (define_insn "andsi3_internal0_nomc"
3094 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3095 (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
3096 (match_operand:SI 2 "and_operand" "?r,T")))]
3097 "!rs6000_gen_cell_microcode"
3100 rlwinm %0,%1,0,%m2,%M2"
3101 [(set_attr "type" "logical,shift")])
3104 ;; Handle the PowerPC64 rlwinm corner case
3106 (define_insn_and_split "*andsi3_internal6"
3107 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3108 (and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3109 (match_operand:SI 2 "mask_operand_wrap" "i")))]
3114 (and:SI (rotate:SI (match_dup 1) (match_dup 3))
3117 (rotate:SI (match_dup 0) (match_dup 5)))]
3120 int mb = extract_MB (operands[2]);
3121 int me = extract_ME (operands[2]);
3122 operands[3] = GEN_INT (me + 1);
3123 operands[5] = GEN_INT (32 - (me + 1));
3124 operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
3126 [(set_attr "length" "8")])
3129 (define_expand "<code><mode>3"
3130 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3131 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3132 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3135 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3137 rs6000_split_logical (operands, <CODE>, false, false, false);
3141 if (non_logical_cint_operand (operands[2], <MODE>mode))
3143 rtx tmp = ((!can_create_pseudo_p ()
3144 || rtx_equal_p (operands[0], operands[1]))
3145 ? operands[0] : gen_reg_rtx (<MODE>mode));
3147 HOST_WIDE_INT value = INTVAL (operands[2]);
3148 HOST_WIDE_INT lo = value & 0xffff;
3149 HOST_WIDE_INT hi = value - lo;
3151 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3152 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3156 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3157 operands[2] = force_reg (<MODE>mode, operands[2]);
3161 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3162 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3163 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3166 (iorxor:GPR (match_dup 1)
3169 (iorxor:GPR (match_dup 3)
3172 operands[3] = ((!can_create_pseudo_p ()
3173 || rtx_equal_p (operands[0], operands[1]))
3174 ? operands[0] : gen_reg_rtx (<MODE>mode));
3176 HOST_WIDE_INT value = INTVAL (operands[2]);
3177 HOST_WIDE_INT lo = value & 0xffff;
3178 HOST_WIDE_INT hi = value - lo;
3180 operands[4] = GEN_INT (hi);
3181 operands[5] = GEN_INT (lo);
3184 (define_insn "*bool<mode>3_imm"
3185 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3186 (match_operator:GPR 3 "boolean_or_operator"
3187 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3188 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3191 [(set_attr "type" "logical")])
3193 (define_insn "*bool<mode>3"
3194 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3195 (match_operator:GPR 3 "boolean_operator"
3196 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3197 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3200 [(set_attr "type" "logical")])
3202 (define_insn_and_split "*bool<mode>3_dot"
3203 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3204 (compare:CC (match_operator:GPR 3 "boolean_operator"
3205 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3206 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3208 (clobber (match_scratch:GPR 0 "=r,r"))]
3209 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3213 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3217 (compare:CC (match_dup 0)
3220 [(set_attr "type" "logical")
3221 (set_attr "dot" "yes")
3222 (set_attr "length" "4,8")])
3224 (define_insn_and_split "*bool<mode>3_dot2"
3225 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3226 (compare:CC (match_operator:GPR 3 "boolean_operator"
3227 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3228 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3230 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3232 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3236 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3240 (compare:CC (match_dup 0)
3243 [(set_attr "type" "logical")
3244 (set_attr "dot" "yes")
3245 (set_attr "length" "4,8")])
3248 (define_insn "*boolc<mode>3"
3249 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3250 (match_operator:GPR 3 "boolean_operator"
3251 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3252 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3255 [(set_attr "type" "logical")])
3257 (define_insn_and_split "*boolc<mode>3_dot"
3258 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3259 (compare:CC (match_operator:GPR 3 "boolean_operator"
3260 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3261 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3263 (clobber (match_scratch:GPR 0 "=r,r"))]
3264 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3268 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3272 (compare:CC (match_dup 0)
3275 [(set_attr "type" "logical")
3276 (set_attr "dot" "yes")
3277 (set_attr "length" "4,8")])
3279 (define_insn_and_split "*boolc<mode>3_dot2"
3280 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3281 (compare:CC (match_operator:GPR 3 "boolean_operator"
3282 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3283 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3285 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3287 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3291 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3295 (compare:CC (match_dup 0)
3298 [(set_attr "type" "logical")
3299 (set_attr "dot" "yes")
3300 (set_attr "length" "4,8")])
3303 (define_insn "*boolcc<mode>3"
3304 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3305 (match_operator:GPR 3 "boolean_operator"
3306 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3307 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3310 [(set_attr "type" "logical")])
3312 (define_insn_and_split "*boolcc<mode>3_dot"
3313 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3314 (compare:CC (match_operator:GPR 3 "boolean_operator"
3315 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3316 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3318 (clobber (match_scratch:GPR 0 "=r,r"))]
3319 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3323 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3327 (compare:CC (match_dup 0)
3330 [(set_attr "type" "logical")
3331 (set_attr "dot" "yes")
3332 (set_attr "length" "4,8")])
3334 (define_insn_and_split "*boolcc<mode>3_dot2"
3335 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3336 (compare:CC (match_operator:GPR 3 "boolean_operator"
3337 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3338 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3340 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3342 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3346 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3350 (compare:CC (match_dup 0)
3353 [(set_attr "type" "logical")
3354 (set_attr "dot" "yes")
3355 (set_attr "length" "4,8")])
3358 ;; TODO: Should have dots of this as well.
3359 (define_insn "*eqv<mode>3"
3360 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3361 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3362 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3365 [(set_attr "type" "logical")])
3367 ;; Rotate and shift insns, in all their variants. These support shifts,
3368 ;; field inserts and extracts, and various combinations thereof.
3369 (define_expand "insv"
3370 [(set (zero_extract (match_operand 0 "gpc_reg_operand" "")
3371 (match_operand:SI 1 "const_int_operand" "")
3372 (match_operand:SI 2 "const_int_operand" ""))
3373 (match_operand 3 "gpc_reg_operand" ""))]
3377 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
3378 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3379 compiler if the address of the structure is taken later. Likewise, do
3380 not handle invalid E500 subregs. */
3381 if (GET_CODE (operands[0]) == SUBREG
3382 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD
3383 || ((TARGET_E500_DOUBLE || TARGET_SPE)
3384 && invalid_e500_subreg (operands[0], GET_MODE (operands[0])))))
3387 if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode)
3388 emit_insn (gen_insvdi_internal (operands[0], operands[1], operands[2],
3391 emit_insn (gen_insvsi_internal (operands[0], operands[1], operands[2],
3396 (define_insn "insvsi_internal"
3397 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3398 (match_operand:SI 1 "const_int_operand" "i")
3399 (match_operand:SI 2 "const_int_operand" "i"))
3400 (match_operand:SI 3 "gpc_reg_operand" "r"))]
3404 int start = INTVAL (operands[2]) & 31;
3405 int size = INTVAL (operands[1]) & 31;
3407 operands[4] = GEN_INT (32 - start - size);
3408 operands[1] = GEN_INT (start + size - 1);
3409 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3411 [(set_attr "type" "insert")])
3413 (define_insn "*insvsi_internal1"
3414 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3415 (match_operand:SI 1 "const_int_operand" "i")
3416 (match_operand:SI 2 "const_int_operand" "i"))
3417 (rotate:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3418 (match_operand:SI 4 "const_int_operand" "i")))]
3419 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3422 int shift = INTVAL (operands[4]) & 31;
3423 int start = INTVAL (operands[2]) & 31;
3424 int size = INTVAL (operands[1]) & 31;
3426 operands[4] = GEN_INT (shift - start - size);
3427 operands[1] = GEN_INT (start + size - 1);
3428 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3430 [(set_attr "type" "insert")])
3432 (define_insn "*insvsi_internal2"
3433 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3434 (match_operand:SI 1 "const_int_operand" "i")
3435 (match_operand:SI 2 "const_int_operand" "i"))
3436 (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3437 (match_operand:SI 4 "const_int_operand" "i")))]
3438 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3441 int shift = INTVAL (operands[4]) & 31;
3442 int start = INTVAL (operands[2]) & 31;
3443 int size = INTVAL (operands[1]) & 31;
3445 operands[4] = GEN_INT (32 - shift - start - size);
3446 operands[1] = GEN_INT (start + size - 1);
3447 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3449 [(set_attr "type" "insert")])
3451 (define_insn "*insvsi_internal3"
3452 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3453 (match_operand:SI 1 "const_int_operand" "i")
3454 (match_operand:SI 2 "const_int_operand" "i"))
3455 (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3456 (match_operand:SI 4 "const_int_operand" "i")))]
3457 "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
3460 int shift = INTVAL (operands[4]) & 31;
3461 int start = INTVAL (operands[2]) & 31;
3462 int size = INTVAL (operands[1]) & 31;
3464 operands[4] = GEN_INT (32 - shift - start - size);
3465 operands[1] = GEN_INT (start + size - 1);
3466 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3468 [(set_attr "type" "insert")])
3470 (define_insn "*insvsi_internal4"
3471 [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
3472 (match_operand:SI 1 "const_int_operand" "i")
3473 (match_operand:SI 2 "const_int_operand" "i"))
3474 (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3475 (match_operand:SI 4 "const_int_operand" "i")
3476 (match_operand:SI 5 "const_int_operand" "i")))]
3477 "INTVAL (operands[4]) >= INTVAL (operands[1])"
3480 int extract_start = INTVAL (operands[5]) & 31;
3481 int extract_size = INTVAL (operands[4]) & 31;
3482 int insert_start = INTVAL (operands[2]) & 31;
3483 int insert_size = INTVAL (operands[1]) & 31;
3485 /* Align extract field with insert field */
3486 operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
3487 operands[1] = GEN_INT (insert_start + insert_size - 1);
3488 return \"rlwimi %0,%3,%h5,%h2,%h1\";
3490 [(set_attr "type" "insert")])
3492 ;; combine patterns for rlwimi
3493 (define_insn "*insvsi_internal5"
3494 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3495 (ior:SI (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3496 (match_operand:SI 1 "mask_operand" "i"))
3497 (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3498 (match_operand:SI 2 "const_int_operand" "i"))
3499 (match_operand:SI 5 "mask_operand" "i"))))]
3500 "INTVAL(operands[1]) == ~INTVAL(operands[5])"
3503 int me = extract_ME(operands[5]);
3504 int mb = extract_MB(operands[5]);
3505 operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3506 operands[2] = GEN_INT(mb);
3507 operands[1] = GEN_INT(me);
3508 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3510 [(set_attr "type" "insert")])
3512 (define_insn "*insvsi_internal6"
3513 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3514 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3515 (match_operand:SI 2 "const_int_operand" "i"))
3516 (match_operand:SI 5 "mask_operand" "i"))
3517 (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3518 (match_operand:SI 1 "mask_operand" "i"))))]
3519 "INTVAL(operands[1]) == ~INTVAL(operands[5])"
3522 int me = extract_ME(operands[5]);
3523 int mb = extract_MB(operands[5]);
3524 operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3525 operands[2] = GEN_INT(mb);
3526 operands[1] = GEN_INT(me);
3527 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3529 [(set_attr "type" "insert")])
3531 (define_insn "insvdi_internal"
3532 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3533 (match_operand:SI 1 "const_int_operand" "i")
3534 (match_operand:SI 2 "const_int_operand" "i"))
3535 (match_operand:DI 3 "gpc_reg_operand" "r"))]
3539 int start = INTVAL (operands[2]) & 63;
3540 int size = INTVAL (operands[1]) & 63;
3542 operands[1] = GEN_INT (64 - start - size);
3543 return \"rldimi %0,%3,%H1,%H2\";
3545 [(set_attr "type" "insert")
3546 (set_attr "size" "64")])
3548 (define_insn "*insvdi_internal2"
3549 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3550 (match_operand:SI 1 "const_int_operand" "i")
3551 (match_operand:SI 2 "const_int_operand" "i"))
3552 (ashiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3553 (match_operand:SI 4 "const_int_operand" "i")))]
3555 && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3558 int shift = INTVAL (operands[4]) & 63;
3559 int start = (INTVAL (operands[2]) & 63) - 32;
3560 int size = INTVAL (operands[1]) & 63;
3562 operands[4] = GEN_INT (64 - shift - start - size);
3563 operands[2] = GEN_INT (start);
3564 operands[1] = GEN_INT (start + size - 1);
3565 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3568 (define_insn "*insvdi_internal3"
3569 [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3570 (match_operand:SI 1 "const_int_operand" "i")
3571 (match_operand:SI 2 "const_int_operand" "i"))
3572 (lshiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3573 (match_operand:SI 4 "const_int_operand" "i")))]
3575 && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3578 int shift = INTVAL (operands[4]) & 63;
3579 int start = (INTVAL (operands[2]) & 63) - 32;
3580 int size = INTVAL (operands[1]) & 63;
3582 operands[4] = GEN_INT (64 - shift - start - size);
3583 operands[2] = GEN_INT (start);
3584 operands[1] = GEN_INT (start + size - 1);
3585 return \"rlwimi %0,%3,%h4,%h2,%h1\";
3588 (define_expand "extzv"
3589 [(set (match_operand 0 "gpc_reg_operand" "")
3590 (zero_extract (match_operand 1 "gpc_reg_operand" "")
3591 (match_operand:SI 2 "const_int_operand" "")
3592 (match_operand:SI 3 "const_int_operand" "")))]
3596 /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
3597 the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3598 compiler if the address of the structure is taken later. */
3599 if (GET_CODE (operands[0]) == SUBREG
3600 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
3603 if (TARGET_POWERPC64 && GET_MODE (operands[1]) == DImode)
3604 emit_insn (gen_extzvdi_internal (operands[0], operands[1], operands[2],
3612 (define_insn "extzvdi_internal"
3613 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3614 (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3615 (match_operand:SI 2 "const_int_operand" "i")
3616 (match_operand:SI 3 "const_int_operand" "i")))]
3620 int start = INTVAL (operands[3]) & 63;
3621 int size = INTVAL (operands[2]) & 63;
3623 if (start + size >= 64)
3624 operands[3] = const0_rtx;
3626 operands[3] = GEN_INT (start + size);
3627 operands[2] = GEN_INT (64 - size);
3628 return \"rldicl %0,%1,%3,%2\";
3630 [(set_attr "type" "shift")])
3632 (define_insn "*extzvdi_internal1"
3633 [(set (match_operand:CC 0 "gpc_reg_operand" "=x")
3634 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3635 (match_operand:SI 2 "const_int_operand" "i")
3636 (match_operand:SI 3 "const_int_operand" "i"))
3638 (clobber (match_scratch:DI 4 "=r"))]
3639 "TARGET_64BIT && rs6000_gen_cell_microcode"
3642 int start = INTVAL (operands[3]) & 63;
3643 int size = INTVAL (operands[2]) & 63;
3645 if (start + size >= 64)
3646 operands[3] = const0_rtx;
3648 operands[3] = GEN_INT (start + size);
3649 operands[2] = GEN_INT (64 - size);
3650 return \"rldicl. %4,%1,%3,%2\";
3652 [(set_attr "type" "shift")
3653 (set_attr "dot" "yes")])
3655 (define_insn "*extzvdi_internal2"
3656 [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
3657 (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3658 (match_operand:SI 2 "const_int_operand" "i")
3659 (match_operand:SI 3 "const_int_operand" "i"))
3661 (set (match_operand:DI 0 "gpc_reg_operand" "=r")
3662 (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
3663 "TARGET_64BIT && rs6000_gen_cell_microcode"
3666 int start = INTVAL (operands[3]) & 63;
3667 int size = INTVAL (operands[2]) & 63;
3669 if (start + size >= 64)
3670 operands[3] = const0_rtx;
3672 operands[3] = GEN_INT (start + size);
3673 operands[2] = GEN_INT (64 - size);
3674 return \"rldicl. %0,%1,%3,%2\";
3676 [(set_attr "type" "shift")
3677 (set_attr "dot" "yes")])
3680 (define_insn "rotl<mode>3"
3681 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3682 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3683 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3685 "rotl<wd>%I2 %0,%1,%<hH>2"
3686 [(set_attr "type" "shift")
3687 (set_attr "maybe_var_shift" "yes")])
3689 (define_insn "*rotlsi3_64"
3690 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3692 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3693 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3695 "rotlw%I2 %0,%1,%h2"
3696 [(set_attr "type" "shift")
3697 (set_attr "maybe_var_shift" "yes")])
3699 (define_insn_and_split "*rotl<mode>3_dot"
3700 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3701 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3702 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3704 (clobber (match_scratch:GPR 0 "=r,r"))]
3705 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3707 rotl<wd>%I2. %0,%1,%<hH>2
3709 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3711 (rotate:GPR (match_dup 1)
3714 (compare:CC (match_dup 0)
3717 [(set_attr "type" "shift")
3718 (set_attr "maybe_var_shift" "yes")
3719 (set_attr "dot" "yes")
3720 (set_attr "length" "4,8")])
3722 (define_insn_and_split "*rotl<mode>3_dot2"
3723 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3724 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3725 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3727 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3728 (rotate:GPR (match_dup 1)
3730 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3732 rotl<wd>%I2. %0,%1,%<hH>2
3734 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3736 (rotate:GPR (match_dup 1)
3739 (compare:CC (match_dup 0)
3742 [(set_attr "type" "shift")
3743 (set_attr "maybe_var_shift" "yes")
3744 (set_attr "dot" "yes")
3745 (set_attr "length" "4,8")])
3748 (define_insn "*rotlsi3_mask"
3749 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3750 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3751 (match_operand:SI 2 "reg_or_cint_operand" "rn"))
3752 (match_operand:SI 3 "mask_operand" "n")))]
3754 "rlw%I2nm %0,%1,%h2,%m3,%M3"
3755 [(set_attr "type" "shift")
3756 (set_attr "maybe_var_shift" "yes")])
3758 (define_insn_and_split "*rotlsi3_mask_dot"
3759 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3761 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3762 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3763 (match_operand:SI 3 "mask_operand" "n,n"))
3765 (clobber (match_scratch:SI 0 "=r,r"))]
3766 "rs6000_gen_cell_microcode
3767 && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)"
3769 rlw%I2nm. %0,%1,%h2,%m3,%M3
3771 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3773 (and:SI (rotate:SI (match_dup 1)
3777 (compare:CC (match_dup 0)
3780 [(set_attr "type" "shift")
3781 (set_attr "maybe_var_shift" "yes")
3782 (set_attr "dot" "yes")
3783 (set_attr "length" "4,8")])
3785 (define_insn_and_split "*rotlsi3_mask_dot2"
3786 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3788 (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3789 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3790 (match_operand:SI 3 "mask_operand" "n,n"))
3792 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3793 (and:SI (rotate:SI (match_dup 1)
3796 "rs6000_gen_cell_microcode
3797 && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)"
3799 rlw%I2nm. %0,%1,%h2,%m3,%M3
3801 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3803 (and:SI (rotate:SI (match_dup 1)
3807 (compare:CC (match_dup 0)
3810 [(set_attr "type" "shift")
3811 (set_attr "maybe_var_shift" "yes")
3812 (set_attr "dot" "yes")
3813 (set_attr "length" "4,8")])
3816 (define_insn "ashl<mode>3"
3817 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3818 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3819 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3821 "sl<wd>%I2 %0,%1,%<hH>2"
3822 [(set_attr "type" "shift")
3823 (set_attr "maybe_var_shift" "yes")])
3825 (define_insn "*ashlsi3_64"
3826 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3828 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3829 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3832 [(set_attr "type" "shift")
3833 (set_attr "maybe_var_shift" "yes")])
3835 (define_insn_and_split "*ashl<mode>3_dot"
3836 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3837 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3838 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3840 (clobber (match_scratch:GPR 0 "=r,r"))]
3841 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3843 sl<wd>%I2. %0,%1,%<hH>2
3845 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3847 (ashift:GPR (match_dup 1)
3850 (compare:CC (match_dup 0)
3853 [(set_attr "type" "shift")
3854 (set_attr "maybe_var_shift" "yes")
3855 (set_attr "dot" "yes")
3856 (set_attr "length" "4,8")])
3858 (define_insn_and_split "*ashl<mode>3_dot2"
3859 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3860 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3861 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3863 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3864 (ashift:GPR (match_dup 1)
3866 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3868 sl<wd>%I2. %0,%1,%<hH>2
3870 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3872 (ashift:GPR (match_dup 1)
3875 (compare:CC (match_dup 0)
3878 [(set_attr "type" "shift")
3879 (set_attr "maybe_var_shift" "yes")
3880 (set_attr "dot" "yes")
3881 (set_attr "length" "4,8")])
3884 (define_insn "*ashlsi3_imm_mask"
3885 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3886 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3887 (match_operand:SI 2 "const_int_operand" "i"))
3888 (match_operand:SI 3 "mask_operand" "n")))]
3889 "includes_lshift_p (operands[2], operands[3])"
3890 "rlwinm %0,%1,%h2,%m3,%M3"
3891 [(set_attr "type" "shift")])
3893 (define_insn_and_split "*ashlsi3_imm_mask_dot"
3894 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3896 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3897 (match_operand:SI 2 "const_int_operand" "i,i"))
3898 (match_operand:SI 3 "mask_operand" "n,n"))
3900 (clobber (match_scratch:SI 0 "=r,r"))]
3901 "rs6000_gen_cell_microcode
3902 && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
3903 && includes_lshift_p (operands[2], operands[3])"
3905 rlwinm. %0,%1,%h2,%m3,%M3
3907 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3909 (and:SI (ashift:SI (match_dup 1)
3913 (compare:CC (match_dup 0)
3916 [(set_attr "type" "shift")
3917 (set_attr "dot" "yes")
3918 (set_attr "length" "4,8")])
3920 (define_insn_and_split "*ashlsi3_imm_mask_dot2"
3921 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3923 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
3924 (match_operand:SI 2 "const_int_operand" "i,i"))
3925 (match_operand:SI 3 "mask_operand" "n,n"))
3927 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3928 (and:SI (ashift:SI (match_dup 1)
3931 "rs6000_gen_cell_microcode
3932 && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
3933 && includes_lshift_p (operands[2], operands[3])"
3935 rlwinm. %0,%1,%h2,%m3,%M3
3937 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3939 (and:SI (ashift:SI (match_dup 1)
3943 (compare:CC (match_dup 0)
3946 [(set_attr "type" "shift")
3947 (set_attr "dot" "yes")
3948 (set_attr "length" "4,8")])
3951 (define_insn "lshr<mode>3"
3952 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3953 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3954 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3956 "sr<wd>%I2 %0,%1,%<hH>2"
3957 [(set_attr "type" "shift")
3958 (set_attr "maybe_var_shift" "yes")])
3960 (define_insn "*lshrsi3_64"
3961 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3963 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3964 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3967 [(set_attr "type" "shift")
3968 (set_attr "maybe_var_shift" "yes")])
3970 (define_insn_and_split "*lshr<mode>3_dot"
3971 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3972 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3973 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3975 (clobber (match_scratch:GPR 0 "=r,r"))]
3976 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3978 sr<wd>%I2. %0,%1,%<hH>2
3980 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3982 (lshiftrt:GPR (match_dup 1)
3985 (compare:CC (match_dup 0)
3988 [(set_attr "type" "shift")
3989 (set_attr "maybe_var_shift" "yes")
3990 (set_attr "dot" "yes")
3991 (set_attr "length" "4,8")])
3993 (define_insn_and_split "*lshr<mode>3_dot2"
3994 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3995 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3996 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3998 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3999 (lshiftrt:GPR (match_dup 1)
4001 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4003 sr<wd>%I2. %0,%1,%<hH>2
4005 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4007 (lshiftrt:GPR (match_dup 1)
4010 (compare:CC (match_dup 0)
4013 [(set_attr "type" "shift")
4014 (set_attr "maybe_var_shift" "yes")
4015 (set_attr "dot" "yes")
4016 (set_attr "length" "4,8")])
4019 (define_insn "*lshrsi3_imm_mask"
4020 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4021 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4022 (match_operand:SI 2 "const_int_operand" "i"))
4023 (match_operand:SI 3 "mask_operand" "n")))]
4024 "includes_rshift_p (operands[2], operands[3])"
4025 "rlwinm %0,%1,%s2,%m3,%M3"
4026 [(set_attr "type" "shift")])
4028 (define_insn_and_split "*lshrsi3_imm_mask_dot"
4029 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4031 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4032 (match_operand:SI 2 "const_int_operand" "i,i"))
4033 (match_operand:SI 3 "mask_operand" "n,n"))
4035 (clobber (match_scratch:SI 0 "=r,r"))]
4036 "rs6000_gen_cell_microcode
4037 && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
4038 && includes_rshift_p (operands[2], operands[3])"
4040 rlwinm. %0,%1,%s2,%m3,%M3
4042 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4044 (and:SI (lshiftrt:SI (match_dup 1)
4048 (compare:CC (match_dup 0)
4051 [(set_attr "type" "shift")
4052 (set_attr "dot" "yes")
4053 (set_attr "length" "4,8")])
4055 (define_insn_and_split "*lshrsi3_imm_mask_dot2"
4056 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
4058 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
4059 (match_operand:SI 2 "const_int_operand" "i,i"))
4060 (match_operand:SI 3 "mask_operand" "n,n"))
4062 (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4063 (and:SI (lshiftrt:SI (match_dup 1)
4066 "rs6000_gen_cell_microcode
4067 && (TARGET_32BIT || UINTVAL (operands[3]) <= 0x7fffffff)
4068 && includes_rshift_p (operands[2], operands[3])"
4070 rlwinm. %0,%1,%s2,%m3,%M3
4072 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
4074 (and:SI (lshiftrt:SI (match_dup 1)
4078 (compare:CC (match_dup 0)
4081 [(set_attr "type" "shift")
4082 (set_attr "dot" "yes")
4083 (set_attr "length" "4,8")])
4086 (define_expand "ashr<mode>3"
4087 [(parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4088 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
4089 (match_operand:SI 2 "reg_or_cint_operand" "")))
4090 (clobber (reg:GPR CA_REGNO))])]
4093 /* The generic code does not generate optimal code for the low word
4094 (it should be a rlwimi and a rot). Until we have target code to
4095 solve this generically, keep this expander. */
4097 if (<MODE>mode == DImode && !TARGET_POWERPC64)
4099 if (CONST_INT_P (operands[2]))
4101 emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
4109 (define_insn "*ashr<mode>3"
4110 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4111 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4112 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4113 (clobber (reg:GPR CA_REGNO))]
4115 "sra<wd>%I2 %0,%1,%<hH>2"
4116 [(set_attr "type" "shift")
4117 (set_attr "maybe_var_shift" "yes")])
4119 (define_insn "*ashrsi3_64"
4120 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4122 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4123 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4124 (clobber (reg:SI CA_REGNO))]
4127 [(set_attr "type" "shift")
4128 (set_attr "maybe_var_shift" "yes")])
4130 (define_insn_and_split "*ashr<mode>3_dot"
4131 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4132 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4133 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4135 (clobber (match_scratch:GPR 0 "=r,r"))
4136 (clobber (reg:GPR CA_REGNO))]
4137 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4139 sra<wd>%I2. %0,%1,%<hH>2
4141 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4142 [(parallel [(set (match_dup 0)
4143 (ashiftrt:GPR (match_dup 1)
4145 (clobber (reg:GPR CA_REGNO))])
4147 (compare:CC (match_dup 0)
4150 [(set_attr "type" "shift")
4151 (set_attr "maybe_var_shift" "yes")
4152 (set_attr "dot" "yes")
4153 (set_attr "length" "4,8")])
4155 (define_insn_and_split "*ashr<mode>3_dot2"
4156 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4157 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4158 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4160 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4161 (ashiftrt:GPR (match_dup 1)
4163 (clobber (reg:GPR CA_REGNO))]
4164 "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4166 sra<wd>%I2. %0,%1,%<hH>2
4168 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4169 [(parallel [(set (match_dup 0)
4170 (ashiftrt:GPR (match_dup 1)
4172 (clobber (reg:GPR CA_REGNO))])
4174 (compare:CC (match_dup 0)
4177 [(set_attr "type" "shift")
4178 (set_attr "maybe_var_shift" "yes")
4179 (set_attr "dot" "yes")
4180 (set_attr "length" "4,8")])
4182 ;; Builtins to replace a division to generate FRE reciprocal estimate
4183 ;; instructions and the necessary fixup instructions
4184 (define_expand "recip<mode>3"
4185 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4186 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4187 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4188 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4190 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4194 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4195 ;; hardware division. This is only done before register allocation and with
4196 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4198 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4199 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4200 (match_operand 2 "gpc_reg_operand" "")))]
4201 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4202 && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4203 && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4206 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4210 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4211 ;; appropriate fixup.
4212 (define_expand "rsqrt<mode>2"
4213 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4214 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4215 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4217 rs6000_emit_swrsqrt (operands[0], operands[1]);
4221 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4222 ;; modes here, and also add in conditional vsx/power8-vector support to access
4223 ;; values in the traditional Altivec registers if the appropriate
4224 ;; -mupper-regs-{df,sf} option is enabled.
4226 (define_expand "abs<mode>2"
4227 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4228 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4229 "TARGET_<MODE>_INSN"
4232 (define_insn "*abs<mode>2_fpr"
4233 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4234 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4239 [(set_attr "type" "fp")
4240 (set_attr "fp_type" "fp_addsub_<Fs>")])
4242 (define_insn "*nabs<mode>2_fpr"
4243 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4246 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4251 [(set_attr "type" "fp")
4252 (set_attr "fp_type" "fp_addsub_<Fs>")])
4254 (define_expand "neg<mode>2"
4255 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4256 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4257 "TARGET_<MODE>_INSN"
4260 (define_insn "*neg<mode>2_fpr"
4261 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4262 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4267 [(set_attr "type" "fp")
4268 (set_attr "fp_type" "fp_addsub_<Fs>")])
4270 (define_expand "add<mode>3"
4271 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4272 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4273 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4274 "TARGET_<MODE>_INSN"
4277 (define_insn "*add<mode>3_fpr"
4278 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4279 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4280 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4283 fadd<Ftrad> %0,%1,%2
4284 xsadd<Fvsx> %x0,%x1,%x2"
4285 [(set_attr "type" "fp")
4286 (set_attr "fp_type" "fp_addsub_<Fs>")])
4288 (define_expand "sub<mode>3"
4289 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4290 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4291 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4292 "TARGET_<MODE>_INSN"
4295 (define_insn "*sub<mode>3_fpr"
4296 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4297 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4298 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4301 fsub<Ftrad> %0,%1,%2
4302 xssub<Fvsx> %x0,%x1,%x2"
4303 [(set_attr "type" "fp")
4304 (set_attr "fp_type" "fp_addsub_<Fs>")])
4306 (define_expand "mul<mode>3"
4307 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4308 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4309 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4310 "TARGET_<MODE>_INSN"
4313 (define_insn "*mul<mode>3_fpr"
4314 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4315 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4316 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4319 fmul<Ftrad> %0,%1,%2
4320 xsmul<Fvsx> %x0,%x1,%x2"
4321 [(set_attr "type" "dmul")
4322 (set_attr "fp_type" "fp_mul_<Fs>")])
4324 (define_expand "div<mode>3"
4325 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4326 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4327 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4328 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4331 (define_insn "*div<mode>3_fpr"
4332 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4333 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4334 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4335 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4337 fdiv<Ftrad> %0,%1,%2
4338 xsdiv<Fvsx> %x0,%x1,%x2"
4339 [(set_attr "type" "<Fs>div")
4340 (set_attr "fp_type" "fp_div_<Fs>")])
4342 (define_insn "sqrt<mode>2"
4343 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4344 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4345 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4346 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4349 xssqrt<Fvsx> %x0,%x1"
4350 [(set_attr "type" "<Fs>sqrt")
4351 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4353 ;; Floating point reciprocal approximation
4354 (define_insn "fre<Fs>"
4355 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4356 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
4362 [(set_attr "type" "fp")])
4364 (define_insn "*rsqrt<mode>2"
4365 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4366 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
4368 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4370 frsqrte<Ftrad> %0,%1
4371 xsrsqrte<Fvsx> %x0,%x1"
4372 [(set_attr "type" "fp")])
4374 ;; Floating point comparisons
4375 (define_insn "*cmp<mode>_fpr"
4376 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4377 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4378 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4382 xscmpudp %0,%x1,%x2"
4383 [(set_attr "type" "fpcompare")])
4385 ;; Floating point conversions
4386 (define_expand "extendsfdf2"
4387 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4388 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4389 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4392 (define_insn_and_split "*extendsfdf2_fpr"
4393 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu")
4394 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z")))]
4395 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4401 xscpsgndp %x0,%x1,%x1
4403 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4406 emit_note (NOTE_INSN_DELETED);
4409 [(set_attr "type" "fp,fp,fpload,fp,fp,fpload")])
4411 (define_expand "truncdfsf2"
4412 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4413 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4414 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4417 (define_insn "*truncdfsf2_fpr"
4418 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4419 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4420 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4424 [(set_attr "type" "fp")])
4426 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4427 ;; builtins.c and optabs.c that are not correct for IBM long double
4428 ;; when little-endian.
4429 (define_expand "signbittf2"
4431 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
4433 (subreg:DI (match_dup 2) 0))
4436 (set (match_operand:SI 0 "gpc_reg_operand" "")
4439 && TARGET_HARD_FLOAT
4440 && (TARGET_FPRS || TARGET_E500_DOUBLE)
4441 && TARGET_LONG_DOUBLE_128"
4443 operands[2] = gen_reg_rtx (DFmode);
4444 operands[3] = gen_reg_rtx (DImode);
4445 if (TARGET_POWERPC64)
4447 operands[4] = gen_reg_rtx (DImode);
4448 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4449 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4450 WORDS_BIG_ENDIAN ? 4 : 0);
4454 operands[4] = gen_reg_rtx (SImode);
4455 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4456 WORDS_BIG_ENDIAN ? 0 : 4);
4457 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4461 (define_expand "copysign<mode>3"
4463 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4465 (neg:SFDF (abs:SFDF (match_dup 1))))
4466 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4467 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4471 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4472 && ((TARGET_PPC_GFXOPT
4473 && !HONOR_NANS (<MODE>mode)
4474 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4476 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4478 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4480 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4485 operands[3] = gen_reg_rtx (<MODE>mode);
4486 operands[4] = gen_reg_rtx (<MODE>mode);
4487 operands[5] = CONST0_RTX (<MODE>mode);
4490 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4491 ;; compiler from optimizing -0.0
4492 (define_insn "copysign<mode>3_fcpsgn"
4493 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4494 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4495 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4497 "TARGET_<MODE>_FPR && TARGET_CMPB"
4500 xscpsgndp %x0,%x2,%x1"
4501 [(set_attr "type" "fp")])
4503 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4504 ;; fsel instruction and some auxiliary computations. Then we just have a
4505 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4507 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4508 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4509 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4510 ;; define_splits to make them if made by combine. On VSX machines we have the
4511 ;; min/max instructions.
4513 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4514 ;; to allow either DF/SF to use only traditional registers.
4516 (define_expand "smax<mode>3"
4517 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4518 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4519 (match_operand:SFDF 2 "gpc_reg_operand" ""))
4522 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4524 rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
4528 (define_insn "*smax<mode>3_vsx"
4529 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4530 (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4531 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4532 "TARGET_<MODE>_FPR && TARGET_VSX"
4533 "xsmaxdp %x0,%x1,%x2"
4534 [(set_attr "type" "fp")])
4536 (define_expand "smin<mode>3"
4537 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4538 (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4539 (match_operand:SFDF 2 "gpc_reg_operand" ""))
4542 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4544 rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
4548 (define_insn "*smin<mode>3_vsx"
4549 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4550 (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4551 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4552 "TARGET_<MODE>_FPR && TARGET_VSX"
4553 "xsmindp %x0,%x1,%x2"
4554 [(set_attr "type" "fp")])
4557 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4558 (match_operator:SFDF 3 "min_max_operator"
4559 [(match_operand:SFDF 1 "gpc_reg_operand" "")
4560 (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
4561 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
4565 rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
4571 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4572 (match_operator:SF 3 "min_max_operator"
4573 [(match_operand:SF 1 "gpc_reg_operand" "")
4574 (match_operand:SF 2 "gpc_reg_operand" "")]))]
4575 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
4576 && TARGET_SINGLE_FLOAT && !flag_trapping_math"
4579 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4580 operands[1], operands[2]);
4584 (define_expand "mov<mode>cc"
4585 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4586 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4587 (match_operand:GPR 2 "gpc_reg_operand" "")
4588 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4592 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4598 ;; We use the BASE_REGS for the isel input operands because, if rA is
4599 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4600 ;; because we may switch the operands and rB may end up being rA.
4602 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4603 ;; leave out the mode in operand 4 and use one pattern, but reload can
4604 ;; change the mode underneath our feet and then gets confused trying
4605 ;; to reload the value.
4606 (define_insn "isel_signed_<mode>"
4607 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4609 (match_operator 1 "scc_comparison_operator"
4610 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4612 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4613 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4616 { return output_isel (operands); }"
4617 [(set_attr "type" "isel")
4618 (set_attr "length" "4")])
4620 (define_insn "isel_unsigned_<mode>"
4621 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4623 (match_operator 1 "scc_comparison_operator"
4624 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4626 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4627 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4630 { return output_isel (operands); }"
4631 [(set_attr "type" "isel")
4632 (set_attr "length" "4")])
4634 ;; These patterns can be useful for combine; they let combine know that
4635 ;; isel can handle reversed comparisons so long as the operands are
4638 (define_insn "*isel_reversed_signed_<mode>"
4639 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4641 (match_operator 1 "scc_rev_comparison_operator"
4642 [(match_operand:CC 4 "cc_reg_operand" "y")
4644 (match_operand:GPR 2 "gpc_reg_operand" "b")
4645 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4648 { return output_isel (operands); }"
4649 [(set_attr "type" "isel")
4650 (set_attr "length" "4")])
4652 (define_insn "*isel_reversed_unsigned_<mode>"
4653 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4655 (match_operator 1 "scc_rev_comparison_operator"
4656 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4658 (match_operand:GPR 2 "gpc_reg_operand" "b")
4659 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4662 { return output_isel (operands); }"
4663 [(set_attr "type" "isel")
4664 (set_attr "length" "4")])
4666 (define_expand "movsfcc"
4667 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4668 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4669 (match_operand:SF 2 "gpc_reg_operand" "")
4670 (match_operand:SF 3 "gpc_reg_operand" "")))]
4671 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4674 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4680 (define_insn "*fselsfsf4"
4681 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4682 (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4683 (match_operand:SF 4 "zero_fp_constant" "F"))
4684 (match_operand:SF 2 "gpc_reg_operand" "f")
4685 (match_operand:SF 3 "gpc_reg_operand" "f")))]
4686 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4688 [(set_attr "type" "fp")])
4690 (define_insn "*fseldfsf4"
4691 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4692 (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4693 (match_operand:DF 4 "zero_fp_constant" "F"))
4694 (match_operand:SF 2 "gpc_reg_operand" "f")
4695 (match_operand:SF 3 "gpc_reg_operand" "f")))]
4696 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4698 [(set_attr "type" "fp")])
4700 ;; The conditional move instructions allow us to perform max and min
4701 ;; operations even when
4704 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4705 (match_operator:DF 3 "min_max_operator"
4706 [(match_operand:DF 1 "gpc_reg_operand" "")
4707 (match_operand:DF 2 "gpc_reg_operand" "")]))]
4708 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
4709 && !flag_trapping_math"
4712 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4713 operands[1], operands[2]);
4717 (define_expand "movdfcc"
4718 [(set (match_operand:DF 0 "gpc_reg_operand" "")
4719 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4720 (match_operand:DF 2 "gpc_reg_operand" "")
4721 (match_operand:DF 3 "gpc_reg_operand" "")))]
4722 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4725 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4731 (define_insn "*fseldfdf4"
4732 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4733 (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4734 (match_operand:DF 4 "zero_fp_constant" "F"))
4735 (match_operand:DF 2 "gpc_reg_operand" "d")
4736 (match_operand:DF 3 "gpc_reg_operand" "d")))]
4737 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4739 [(set_attr "type" "fp")])
4741 (define_insn "*fselsfdf4"
4742 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4743 (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4744 (match_operand:SF 4 "zero_fp_constant" "F"))
4745 (match_operand:DF 2 "gpc_reg_operand" "d")
4746 (match_operand:DF 3 "gpc_reg_operand" "d")))]
4747 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4749 [(set_attr "type" "fp")])
4751 ;; Conversions to and from floating-point.
4753 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4754 ; don't want to support putting SImode in FPR registers.
4755 (define_insn "lfiwax"
4756 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4757 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4759 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4764 [(set_attr "type" "fpload,fpload,mffgpr")])
4766 ; This split must be run before register allocation because it allocates the
4767 ; memory slot that is needed to move values to/from the FPR. We don't allocate
4768 ; it earlier to allow for the combiner to merge insns together where it might
4769 ; not be needed and also in case the insns are deleted as dead code.
4771 (define_insn_and_split "floatsi<mode>2_lfiwax"
4772 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4773 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4774 (clobber (match_scratch:DI 2 "=wj"))]
4775 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4776 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4782 rtx dest = operands[0];
4783 rtx src = operands[1];
4786 if (!MEM_P (src) && TARGET_POWERPC64
4787 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4788 tmp = convert_to_mode (DImode, src, false);
4792 if (GET_CODE (tmp) == SCRATCH)
4793 tmp = gen_reg_rtx (DImode);
4796 src = rs6000_address_for_fpconvert (src);
4797 emit_insn (gen_lfiwax (tmp, src));
4801 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4802 emit_move_insn (stack, src);
4803 emit_insn (gen_lfiwax (tmp, stack));
4806 emit_insn (gen_floatdi<mode>2 (dest, tmp));
4809 [(set_attr "length" "12")
4810 (set_attr "type" "fpload")])
4812 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4813 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4816 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4817 (clobber (match_scratch:DI 2 "=0,d"))]
4818 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4825 operands[1] = rs6000_address_for_fpconvert (operands[1]);
4826 if (GET_CODE (operands[2]) == SCRATCH)
4827 operands[2] = gen_reg_rtx (DImode);
4828 emit_insn (gen_lfiwax (operands[2], operands[1]));
4829 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4832 [(set_attr "length" "8")
4833 (set_attr "type" "fpload")])
4835 (define_insn "lfiwzx"
4836 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4837 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4839 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4844 [(set_attr "type" "fpload,fpload,mftgpr")])
4846 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
4847 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4848 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4849 (clobber (match_scratch:DI 2 "=wj"))]
4850 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4857 rtx dest = operands[0];
4858 rtx src = operands[1];
4861 if (!MEM_P (src) && TARGET_POWERPC64
4862 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4863 tmp = convert_to_mode (DImode, src, true);
4867 if (GET_CODE (tmp) == SCRATCH)
4868 tmp = gen_reg_rtx (DImode);
4871 src = rs6000_address_for_fpconvert (src);
4872 emit_insn (gen_lfiwzx (tmp, src));
4876 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4877 emit_move_insn (stack, src);
4878 emit_insn (gen_lfiwzx (tmp, stack));
4881 emit_insn (gen_floatdi<mode>2 (dest, tmp));
4884 [(set_attr "length" "12")
4885 (set_attr "type" "fpload")])
4887 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
4888 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4889 (unsigned_float:SFDF
4891 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4892 (clobber (match_scratch:DI 2 "=0,d"))]
4893 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4900 operands[1] = rs6000_address_for_fpconvert (operands[1]);
4901 if (GET_CODE (operands[2]) == SCRATCH)
4902 operands[2] = gen_reg_rtx (DImode);
4903 emit_insn (gen_lfiwzx (operands[2], operands[1]));
4904 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4907 [(set_attr "length" "8")
4908 (set_attr "type" "fpload")])
4910 ; For each of these conversions, there is a define_expand, a define_insn
4911 ; with a '#' template, and a define_split (with C code). The idea is
4912 ; to allow constant folding with the template of the define_insn,
4913 ; then to have the insns split later (between sched1 and final).
4915 (define_expand "floatsidf2"
4916 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
4917 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
4920 (clobber (match_dup 4))
4921 (clobber (match_dup 5))
4922 (clobber (match_dup 6))])]
4924 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4927 if (TARGET_E500_DOUBLE)
4929 if (!REG_P (operands[1]))
4930 operands[1] = force_reg (SImode, operands[1]);
4931 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
4934 else if (TARGET_LFIWAX && TARGET_FCFID)
4936 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
4939 else if (TARGET_FCFID)
4941 rtx dreg = operands[1];
4943 dreg = force_reg (SImode, dreg);
4944 dreg = convert_to_mode (DImode, dreg, false);
4945 emit_insn (gen_floatdidf2 (operands[0], dreg));
4949 if (!REG_P (operands[1]))
4950 operands[1] = force_reg (SImode, operands[1]);
4951 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
4952 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
4953 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
4954 operands[5] = gen_reg_rtx (DFmode);
4955 operands[6] = gen_reg_rtx (SImode);
4958 (define_insn_and_split "*floatsidf2_internal"
4959 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
4960 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
4961 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
4962 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
4963 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
4964 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
4965 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
4966 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4972 rtx lowword, highword;
4973 gcc_assert (MEM_P (operands[4]));
4974 highword = adjust_address (operands[4], SImode, 0);
4975 lowword = adjust_address (operands[4], SImode, 4);
4976 if (! WORDS_BIG_ENDIAN)
4977 std::swap (lowword, highword);
4979 emit_insn (gen_xorsi3 (operands[6], operands[1],
4980 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
4981 emit_move_insn (lowword, operands[6]);
4982 emit_move_insn (highword, operands[2]);
4983 emit_move_insn (operands[5], operands[4]);
4984 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
4987 [(set_attr "length" "24")
4988 (set_attr "type" "fp")])
4990 ;; If we don't have a direct conversion to single precision, don't enable this
4991 ;; conversion for 32-bit without fast math, because we don't have the insn to
4992 ;; generate the fixup swizzle to avoid double rounding problems.
4993 (define_expand "floatunssisf2"
4994 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4995 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4996 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
4999 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5000 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5001 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5006 if (!REG_P (operands[1]))
5007 operands[1] = force_reg (SImode, operands[1]);
5009 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5011 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5016 rtx dreg = operands[1];
5018 dreg = force_reg (SImode, dreg);
5019 dreg = convert_to_mode (DImode, dreg, true);
5020 emit_insn (gen_floatdisf2 (operands[0], dreg));
5025 (define_expand "floatunssidf2"
5026 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5027 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5030 (clobber (match_dup 4))
5031 (clobber (match_dup 5))])]
5033 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5036 if (TARGET_E500_DOUBLE)
5038 if (!REG_P (operands[1]))
5039 operands[1] = force_reg (SImode, operands[1]);
5040 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5043 else if (TARGET_LFIWZX && TARGET_FCFID)
5045 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5048 else if (TARGET_FCFID)
5050 rtx dreg = operands[1];
5052 dreg = force_reg (SImode, dreg);
5053 dreg = convert_to_mode (DImode, dreg, true);
5054 emit_insn (gen_floatdidf2 (operands[0], dreg));
5058 if (!REG_P (operands[1]))
5059 operands[1] = force_reg (SImode, operands[1]);
5060 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5061 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5062 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5063 operands[5] = gen_reg_rtx (DFmode);
5066 (define_insn_and_split "*floatunssidf2_internal"
5067 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5068 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5069 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5070 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5071 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5072 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5073 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5074 && !(TARGET_FCFID && TARGET_POWERPC64)"
5080 rtx lowword, highword;
5081 gcc_assert (MEM_P (operands[4]));
5082 highword = adjust_address (operands[4], SImode, 0);
5083 lowword = adjust_address (operands[4], SImode, 4);
5084 if (! WORDS_BIG_ENDIAN)
5085 std::swap (lowword, highword);
5087 emit_move_insn (lowword, operands[1]);
5088 emit_move_insn (highword, operands[2]);
5089 emit_move_insn (operands[5], operands[4]);
5090 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5093 [(set_attr "length" "20")
5094 (set_attr "type" "fp")])
5096 (define_expand "fix_trunc<mode>si2"
5097 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5098 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5099 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5102 if (!<E500_CONVERT>)
5107 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5110 tmp = gen_reg_rtx (DImode);
5111 stack = rs6000_allocate_stack_temp (DImode, true, false);
5112 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5119 ; Like the convert to float patterns, this insn must be split before
5120 ; register allocation so that it can allocate the memory slot if it
5122 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5123 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5124 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5125 (clobber (match_scratch:DI 2 "=d"))]
5126 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5127 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5128 && TARGET_STFIWX && can_create_pseudo_p ()"
5133 rtx dest = operands[0];
5134 rtx src = operands[1];
5135 rtx tmp = operands[2];
5137 if (GET_CODE (tmp) == SCRATCH)
5138 tmp = gen_reg_rtx (DImode);
5140 emit_insn (gen_fctiwz_<mode> (tmp, src));
5143 dest = rs6000_address_for_fpconvert (dest);
5144 emit_insn (gen_stfiwx (dest, tmp));
5147 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5149 dest = gen_lowpart (DImode, dest);
5150 emit_move_insn (dest, tmp);
5155 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5156 emit_insn (gen_stfiwx (stack, tmp));
5157 emit_move_insn (dest, stack);
5161 [(set_attr "length" "12")
5162 (set_attr "type" "fp")])
5164 (define_insn_and_split "fix_trunc<mode>si2_internal"
5165 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5166 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5167 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5168 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5169 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5176 gcc_assert (MEM_P (operands[3]));
5177 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5179 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5180 emit_move_insn (operands[3], operands[2]);
5181 emit_move_insn (operands[0], lowword);
5184 [(set_attr "length" "16")
5185 (set_attr "type" "fp")])
5187 (define_expand "fix_trunc<mode>di2"
5188 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5189 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5190 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5194 (define_insn "*fix_trunc<mode>di2_fctidz"
5195 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5196 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5197 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5202 [(set_attr "type" "fp")])
5204 (define_expand "fixuns_trunc<mode>si2"
5205 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5206 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5208 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5212 if (!<E500_CONVERT>)
5214 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5219 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5220 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5221 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5222 (clobber (match_scratch:DI 2 "=d"))]
5223 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5224 && TARGET_STFIWX && can_create_pseudo_p ()"
5229 rtx dest = operands[0];
5230 rtx src = operands[1];
5231 rtx tmp = operands[2];
5233 if (GET_CODE (tmp) == SCRATCH)
5234 tmp = gen_reg_rtx (DImode);
5236 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5239 dest = rs6000_address_for_fpconvert (dest);
5240 emit_insn (gen_stfiwx (dest, tmp));
5243 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5245 dest = gen_lowpart (DImode, dest);
5246 emit_move_insn (dest, tmp);
5251 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5252 emit_insn (gen_stfiwx (stack, tmp));
5253 emit_move_insn (dest, stack);
5257 [(set_attr "length" "12")
5258 (set_attr "type" "fp")])
5260 (define_expand "fixuns_trunc<mode>di2"
5261 [(set (match_operand:DI 0 "register_operand" "")
5262 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5263 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5266 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5267 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5268 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5269 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5274 [(set_attr "type" "fp")])
5276 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5277 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5278 ; because the first makes it clear that operand 0 is not live
5279 ; before the instruction.
5280 (define_insn "fctiwz_<mode>"
5281 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5282 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5284 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5288 [(set_attr "type" "fp")])
5290 (define_insn "fctiwuz_<mode>"
5291 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5292 (unspec:DI [(unsigned_fix:SI
5293 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5295 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5299 [(set_attr "type" "fp")])
5301 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5302 ;; since the friz instruction does not truncate the value if the floating
5303 ;; point value is < LONG_MIN or > LONG_MAX.
5304 (define_insn "*friz"
5305 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5306 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5307 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5308 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5312 [(set_attr "type" "fp")])
5314 ;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
5315 ;; load to properly sign extend the value, but at least doing a store, load
5316 ;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
5317 ;; if we have 32-bit memory ops
5318 (define_insn_and_split "*round32<mode>2_fprs"
5319 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5321 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5322 (clobber (match_scratch:DI 2 "=d"))
5323 (clobber (match_scratch:DI 3 "=d"))]
5324 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5325 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5326 && can_create_pseudo_p ()"
5331 rtx dest = operands[0];
5332 rtx src = operands[1];
5333 rtx tmp1 = operands[2];
5334 rtx tmp2 = operands[3];
5335 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5337 if (GET_CODE (tmp1) == SCRATCH)
5338 tmp1 = gen_reg_rtx (DImode);
5339 if (GET_CODE (tmp2) == SCRATCH)
5340 tmp2 = gen_reg_rtx (DImode);
5342 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5343 emit_insn (gen_stfiwx (stack, tmp1));
5344 emit_insn (gen_lfiwax (tmp2, stack));
5345 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5348 [(set_attr "type" "fpload")
5349 (set_attr "length" "16")])
5351 (define_insn_and_split "*roundu32<mode>2_fprs"
5352 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5353 (unsigned_float:SFDF
5354 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5355 (clobber (match_scratch:DI 2 "=d"))
5356 (clobber (match_scratch:DI 3 "=d"))]
5357 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5358 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
5359 && can_create_pseudo_p ()"
5364 rtx dest = operands[0];
5365 rtx src = operands[1];
5366 rtx tmp1 = operands[2];
5367 rtx tmp2 = operands[3];
5368 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5370 if (GET_CODE (tmp1) == SCRATCH)
5371 tmp1 = gen_reg_rtx (DImode);
5372 if (GET_CODE (tmp2) == SCRATCH)
5373 tmp2 = gen_reg_rtx (DImode);
5375 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5376 emit_insn (gen_stfiwx (stack, tmp1));
5377 emit_insn (gen_lfiwzx (tmp2, stack));
5378 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5381 [(set_attr "type" "fpload")
5382 (set_attr "length" "16")])
5384 ;; No VSX equivalent to fctid
5385 (define_insn "lrint<mode>di2"
5386 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5387 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5389 "TARGET_<MODE>_FPR && TARGET_FPRND"
5391 [(set_attr "type" "fp")])
5393 (define_insn "btrunc<mode>2"
5394 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5395 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5397 "TARGET_<MODE>_FPR && TARGET_FPRND"
5401 [(set_attr "type" "fp")
5402 (set_attr "fp_type" "fp_addsub_<Fs>")])
5404 (define_insn "ceil<mode>2"
5405 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5406 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5408 "TARGET_<MODE>_FPR && TARGET_FPRND"
5412 [(set_attr "type" "fp")
5413 (set_attr "fp_type" "fp_addsub_<Fs>")])
5415 (define_insn "floor<mode>2"
5416 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5417 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5419 "TARGET_<MODE>_FPR && TARGET_FPRND"
5423 [(set_attr "type" "fp")
5424 (set_attr "fp_type" "fp_addsub_<Fs>")])
5426 ;; No VSX equivalent to frin
5427 (define_insn "round<mode>2"
5428 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5429 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5431 "TARGET_<MODE>_FPR && TARGET_FPRND"
5433 [(set_attr "type" "fp")
5434 (set_attr "fp_type" "fp_addsub_<Fs>")])
5436 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5437 (define_insn "stfiwx"
5438 [(set (match_operand:SI 0 "memory_operand" "=Z")
5439 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
5443 [(set_attr "type" "fpstore")])
5445 ;; If we don't have a direct conversion to single precision, don't enable this
5446 ;; conversion for 32-bit without fast math, because we don't have the insn to
5447 ;; generate the fixup swizzle to avoid double rounding problems.
5448 (define_expand "floatsisf2"
5449 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5450 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5451 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5454 && ((TARGET_FCFIDS && TARGET_LFIWAX)
5455 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5456 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5461 if (!REG_P (operands[1]))
5462 operands[1] = force_reg (SImode, operands[1]);
5464 else if (TARGET_FCFIDS && TARGET_LFIWAX)
5466 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5469 else if (TARGET_FCFID && TARGET_LFIWAX)
5471 rtx dfreg = gen_reg_rtx (DFmode);
5472 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5473 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5478 rtx dreg = operands[1];
5480 dreg = force_reg (SImode, dreg);
5481 dreg = convert_to_mode (DImode, dreg, false);
5482 emit_insn (gen_floatdisf2 (operands[0], dreg));
5487 (define_expand "floatdidf2"
5488 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5489 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5490 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5493 (define_insn "*floatdidf2_fpr"
5494 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5495 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5496 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5500 [(set_attr "type" "fp")])
5502 ; Allow the combiner to merge source memory operands to the conversion so that
5503 ; the optimizer/register allocator doesn't try to load the value too early in a
5504 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5505 ; hit. We will split after reload to avoid the trip through the GPRs
5507 (define_insn_and_split "*floatdidf2_mem"
5508 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5509 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5510 (clobber (match_scratch:DI 2 "=d,wi"))]
5511 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5513 "&& reload_completed"
5514 [(set (match_dup 2) (match_dup 1))
5515 (set (match_dup 0) (float:DF (match_dup 2)))]
5517 [(set_attr "length" "8")
5518 (set_attr "type" "fpload")])
5520 (define_expand "floatunsdidf2"
5521 [(set (match_operand:DF 0 "gpc_reg_operand" "")
5523 (match_operand:DI 1 "gpc_reg_operand" "")))]
5524 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5527 (define_insn "*floatunsdidf2_fcfidu"
5528 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5529 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5530 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5534 [(set_attr "type" "fp")
5535 (set_attr "length" "4")])
5537 (define_insn_and_split "*floatunsdidf2_mem"
5538 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5539 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5540 (clobber (match_scratch:DI 2 "=d,wi"))]
5541 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5543 "&& reload_completed"
5544 [(set (match_dup 2) (match_dup 1))
5545 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5547 [(set_attr "length" "8")
5548 (set_attr "type" "fpload")])
5550 (define_expand "floatdisf2"
5551 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5552 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5553 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5554 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5559 rtx val = operands[1];
5560 if (!flag_unsafe_math_optimizations)
5562 rtx label = gen_label_rtx ();
5563 val = gen_reg_rtx (DImode);
5564 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5567 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5572 (define_insn "floatdisf2_fcfids"
5573 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5574 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5575 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5576 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5580 [(set_attr "type" "fp")])
5582 (define_insn_and_split "*floatdisf2_mem"
5583 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5584 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5585 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5586 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5587 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5589 "&& reload_completed"
5593 emit_move_insn (operands[2], operands[1]);
5594 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5597 [(set_attr "length" "8")])
5599 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5600 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5601 ;; from double rounding.
5602 ;; Instead of creating a new cpu type for two FP operations, just use fp
5603 (define_insn_and_split "floatdisf2_internal1"
5604 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5605 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5606 (clobber (match_scratch:DF 2 "=d"))]
5607 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5610 "&& reload_completed"
5612 (float:DF (match_dup 1)))
5614 (float_truncate:SF (match_dup 2)))]
5616 [(set_attr "length" "8")
5617 (set_attr "type" "fp")])
5619 ;; Twiddles bits to avoid double rounding.
5620 ;; Bits that might be truncated when converting to DFmode are replaced
5621 ;; by a bit that won't be lost at that stage, but is below the SFmode
5622 ;; rounding position.
5623 (define_expand "floatdisf2_internal2"
5624 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5626 (clobber (reg:DI CA_REGNO))])
5627 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5629 (set (match_dup 3) (plus:DI (match_dup 3)
5631 (set (match_dup 0) (plus:DI (match_dup 0)
5633 (set (match_dup 4) (compare:CCUNS (match_dup 3)
5635 (set (match_dup 0) (ior:DI (match_dup 0)
5637 (set (match_dup 0) (and:DI (match_dup 0)
5639 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5640 (label_ref (match_operand:DI 2 "" ""))
5642 (set (match_dup 0) (match_dup 1))]
5643 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5647 operands[3] = gen_reg_rtx (DImode);
5648 operands[4] = gen_reg_rtx (CCUNSmode);
5651 (define_expand "floatunsdisf2"
5652 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5653 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5654 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5655 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5658 (define_insn "floatunsdisf2_fcfidus"
5659 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5660 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5661 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5662 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5666 [(set_attr "type" "fp")])
5668 (define_insn_and_split "*floatunsdisf2_mem"
5669 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5670 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5671 (clobber (match_scratch:DI 2 "=d,d,wi"))]
5672 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5673 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5675 "&& reload_completed"
5679 emit_move_insn (operands[2], operands[1]);
5680 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5683 [(set_attr "length" "8")
5684 (set_attr "type" "fpload")])
5686 ;; Define the TImode operations that can be done in a small number
5687 ;; of instructions. The & constraints are to prevent the register
5688 ;; allocator from allocating registers that overlap with the inputs
5689 ;; (for example, having an input in 7,8 and an output in 6,7). We
5690 ;; also allow for the output being the same as one of the inputs.
5692 (define_expand "addti3"
5693 [(set (match_operand:TI 0 "gpc_reg_operand" "")
5694 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
5695 (match_operand:TI 2 "reg_or_short_operand" "")))]
5698 rtx lo0 = gen_lowpart (DImode, operands[0]);
5699 rtx lo1 = gen_lowpart (DImode, operands[1]);
5700 rtx lo2 = gen_lowpart (DImode, operands[2]);
5701 rtx hi0 = gen_highpart (DImode, operands[0]);
5702 rtx hi1 = gen_highpart (DImode, operands[1]);
5703 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
5705 if (!reg_or_short_operand (lo2, DImode))
5706 lo2 = force_reg (DImode, lo2);
5707 if (!adde_operand (hi2, DImode))
5708 hi2 = force_reg (DImode, hi2);
5710 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
5711 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
5715 (define_expand "subti3"
5716 [(set (match_operand:TI 0 "gpc_reg_operand" "")
5717 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
5718 (match_operand:TI 2 "gpc_reg_operand" "")))]
5721 rtx lo0 = gen_lowpart (DImode, operands[0]);
5722 rtx lo1 = gen_lowpart (DImode, operands[1]);
5723 rtx lo2 = gen_lowpart (DImode, operands[2]);
5724 rtx hi0 = gen_highpart (DImode, operands[0]);
5725 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
5726 rtx hi2 = gen_highpart (DImode, operands[2]);
5728 if (!reg_or_short_operand (lo1, DImode))
5729 lo1 = force_reg (DImode, lo1);
5730 if (!adde_operand (hi1, DImode))
5731 hi1 = force_reg (DImode, hi1);
5733 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
5734 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
5739 ;; Shift by a variable amount is too complex to be worth open-coding. We
5740 ;; just handle shifts by constants.
5741 (define_insn "ashrdi3_no_power"
5742 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
5743 (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5744 (match_operand:SI 2 "const_int_operand" "M,i")))
5745 (clobber (reg:SI CA_REGNO))]
5748 switch (which_alternative)
5753 if (WORDS_BIG_ENDIAN)
5754 return \"srawi %0,%1,31\;srawi %L0,%1,%h2\";
5756 return \"srawi %L0,%L1,31\;srawi %0,%L1,%h2\";
5758 if (WORDS_BIG_ENDIAN)
5759 return \"srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2\";
5761 return \"srwi %0,%1,%h2\;insrwi %0,%L1,%h2,0\;srawi %L0,%L1,%h2\";
5764 [(set_attr "type" "two,three")
5765 (set_attr "length" "8,12")])
5767 (define_insn "*ashrdisi3_noppc64be"
5768 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5769 (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
5770 (const_int 32)) 4))]
5771 "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN"
5774 if (REGNO (operands[0]) == REGNO (operands[1]))
5777 return \"mr %0,%1\";
5779 [(set_attr "length" "4")])
5782 ;; PowerPC64 DImode operations.
5784 (define_insn "*rotldi3_internal4"
5785 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
5786 (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
5787 (match_operand:DI 2 "reg_or_cint_operand" "rn"))
5788 (match_operand:DI 3 "mask64_operand" "n")))]
5790 "rld%I2c%B3 %0,%1,%H2,%S3"
5791 [(set_attr "type" "shift")
5792 (set_attr "maybe_var_shift" "yes")])
5794 (define_insn "*rotldi3_internal5"
5795 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
5797 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5798 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
5799 (match_operand:DI 3 "mask64_operand" "n,n"))
5801 (clobber (match_scratch:DI 4 "=r,r"))]
5804 rld%I2c%B3. %4,%1,%H2,%S3
5806 [(set_attr "type" "shift")
5807 (set_attr "maybe_var_shift" "yes")
5808 (set_attr "dot" "yes")
5809 (set_attr "length" "4,8")])
5812 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
5814 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
5815 (match_operand:DI 2 "reg_or_cint_operand" ""))
5816 (match_operand:DI 3 "mask64_operand" ""))
5818 (clobber (match_scratch:DI 4 ""))]
5819 "TARGET_POWERPC64 && reload_completed"
5821 (and:DI (rotate:DI (match_dup 1)
5825 (compare:CC (match_dup 4)
5829 (define_insn "*rotldi3_internal6"
5830 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
5832 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5833 (match_operand:DI 2 "reg_or_cint_operand" "rn,rn"))
5834 (match_operand:DI 3 "mask64_operand" "n,n"))
5836 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5837 (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
5840 rld%I2c%B3. %0,%1,%H2,%S3
5842 [(set_attr "type" "shift")
5843 (set_attr "maybe_var_shift" "yes")
5844 (set_attr "dot" "yes")
5845 (set_attr "length" "4,8")])
5848 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
5850 (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
5851 (match_operand:DI 2 "reg_or_cint_operand" ""))
5852 (match_operand:DI 3 "mask64_operand" ""))
5854 (set (match_operand:DI 0 "gpc_reg_operand" "")
5855 (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
5856 "TARGET_POWERPC64 && reload_completed"
5858 (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
5860 (compare:CC (match_dup 0)
5865 (define_insn "*ashldi3_internal4"
5866 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
5867 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
5868 (match_operand:SI 2 "const_int_operand" "i"))
5869 (match_operand:DI 3 "const_int_operand" "n")))]
5870 "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
5871 "rldic %0,%1,%H2,%W3"
5872 [(set_attr "type" "shift")])
5874 (define_insn "ashldi3_internal5"
5875 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
5877 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5878 (match_operand:SI 2 "const_int_operand" "i,i"))
5879 (match_operand:DI 3 "const_int_operand" "n,n"))
5881 (clobber (match_scratch:DI 4 "=r,r"))]
5882 "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
5884 rldic. %4,%1,%H2,%W3
5886 [(set_attr "type" "shift")
5887 (set_attr "dot" "yes")
5888 (set_attr "length" "4,8")])
5891 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
5893 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
5894 (match_operand:SI 2 "const_int_operand" ""))
5895 (match_operand:DI 3 "const_int_operand" ""))
5897 (clobber (match_scratch:DI 4 ""))]
5898 "TARGET_POWERPC64 && reload_completed
5899 && includes_rldic_lshift_p (operands[2], operands[3])"
5901 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
5904 (compare:CC (match_dup 4)
5908 (define_insn "*ashldi3_internal6"
5909 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
5911 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5912 (match_operand:SI 2 "const_int_operand" "i,i"))
5913 (match_operand:DI 3 "const_int_operand" "n,n"))
5915 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5916 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
5917 "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
5919 rldic. %0,%1,%H2,%W3
5921 [(set_attr "type" "shift")
5922 (set_attr "dot" "yes")
5923 (set_attr "length" "4,8")])
5926 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
5928 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
5929 (match_operand:SI 2 "const_int_operand" ""))
5930 (match_operand:DI 3 "const_int_operand" ""))
5932 (set (match_operand:DI 0 "gpc_reg_operand" "")
5933 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
5934 "TARGET_POWERPC64 && reload_completed
5935 && includes_rldic_lshift_p (operands[2], operands[3])"
5937 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
5940 (compare:CC (match_dup 0)
5944 (define_insn "*ashldi3_internal7"
5945 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
5946 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
5947 (match_operand:SI 2 "const_int_operand" "i"))
5948 (match_operand:DI 3 "mask64_operand" "n")))]
5949 "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
5950 "rldicr %0,%1,%H2,%S3"
5951 [(set_attr "type" "shift")])
5953 (define_insn "ashldi3_internal8"
5954 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
5956 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5957 (match_operand:SI 2 "const_int_operand" "i,i"))
5958 (match_operand:DI 3 "mask64_operand" "n,n"))
5960 (clobber (match_scratch:DI 4 "=r,r"))]
5961 "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
5963 rldicr. %4,%1,%H2,%S3
5965 [(set_attr "type" "shift")
5966 (set_attr "dot" "yes")
5967 (set_attr "length" "4,8")])
5970 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
5972 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
5973 (match_operand:SI 2 "const_int_operand" ""))
5974 (match_operand:DI 3 "mask64_operand" ""))
5976 (clobber (match_scratch:DI 4 ""))]
5977 "TARGET_POWERPC64 && reload_completed
5978 && includes_rldicr_lshift_p (operands[2], operands[3])"
5980 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
5983 (compare:CC (match_dup 4)
5987 (define_insn "*ashldi3_internal9"
5988 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
5990 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
5991 (match_operand:SI 2 "const_int_operand" "i,i"))
5992 (match_operand:DI 3 "mask64_operand" "n,n"))
5994 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5995 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
5996 "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
5998 rldicr. %0,%1,%H2,%S3
6000 [(set_attr "type" "shift")
6001 (set_attr "dot" "yes")
6002 (set_attr "length" "4,8")])
6005 [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "")
6007 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
6008 (match_operand:SI 2 "const_int_operand" ""))
6009 (match_operand:DI 3 "mask64_operand" ""))
6011 (set (match_operand:DI 0 "gpc_reg_operand" "")
6012 (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
6013 "TARGET_POWERPC64 && reload_completed
6014 && includes_rldicr_lshift_p (operands[2], operands[3])"
6016 (and:DI (ashift:DI (match_dup 1) (match_dup 2))
6019 (compare:CC (match_dup 0)
6024 (define_insn_and_split "*anddi3_2rld"
6025 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
6026 (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
6027 (match_operand:DI 2 "and_2rld_operand" "n")))]
6032 (and:DI (rotate:DI (match_dup 1)
6036 (and:DI (rotate:DI (match_dup 0)
6040 build_mask64_2_operands (operands[2], &operands[4]);
6042 [(set_attr "length" "8")])
6044 (define_insn_and_split "*anddi3_2rld_dot"
6045 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6046 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
6047 (match_operand:DI 2 "and_2rld_operand" "n,n"))
6049 (clobber (match_scratch:DI 0 "=r,r"))]
6050 "TARGET_64BIT && rs6000_gen_cell_microcode"
6054 "&& reload_completed"
6056 (and:DI (rotate:DI (match_dup 1)
6059 (parallel [(set (match_dup 3)
6060 (compare:CC (and:DI (rotate:DI (match_dup 0)
6064 (clobber (match_dup 0))])]
6066 build_mask64_2_operands (operands[2], &operands[4]);
6068 [(set_attr "type" "two")
6069 (set_attr "dot" "yes")
6070 (set_attr "length" "8,12")])
6072 (define_insn_and_split "*anddi3_2rld_dot2"
6073 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6074 (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
6075 (match_operand:DI 2 "and_2rld_operand" "n,n"))
6077 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6078 (and:DI (match_dup 1)
6080 "TARGET_64BIT && rs6000_gen_cell_microcode"
6084 "&& reload_completed"
6086 (and:DI (rotate:DI (match_dup 1)
6089 (parallel [(set (match_dup 3)
6090 (compare:CC (and:DI (rotate:DI (match_dup 0)
6095 (and:DI (rotate:DI (match_dup 0)
6099 build_mask64_2_operands (operands[2], &operands[4]);
6101 [(set_attr "type" "two")
6102 (set_attr "dot" "yes")
6103 (set_attr "length" "8,12")])
6105 ;; 128-bit logical operations expanders
6107 (define_expand "and<mode>3"
6108 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6109 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6110 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6114 (define_expand "ior<mode>3"
6115 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6116 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6117 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6121 (define_expand "xor<mode>3"
6122 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6123 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6124 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6128 (define_expand "one_cmpl<mode>2"
6129 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6130 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6134 (define_expand "nor<mode>3"
6135 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6137 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6138 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6142 (define_expand "andc<mode>3"
6143 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6145 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6146 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6150 ;; Power8 vector logical instructions.
6151 (define_expand "eqv<mode>3"
6152 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6154 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6155 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6156 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6159 ;; Rewrite nand into canonical form
6160 (define_expand "nand<mode>3"
6161 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6163 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6164 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6165 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6168 ;; The canonical form is to have the negated element first, so we need to
6169 ;; reverse arguments.
6170 (define_expand "orc<mode>3"
6171 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6173 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6174 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6175 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6178 ;; 128-bit logical operations insns and split operations
6179 (define_insn_and_split "*and<mode>3_internal"
6180 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6182 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6183 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6186 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6187 return "xxland %x0,%x1,%x2";
6189 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6190 return "vand %0,%1,%2";
6194 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6197 rs6000_split_logical (operands, AND, false, false, false);
6202 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6203 (const_string "vecsimple")
6204 (const_string "integer")))
6205 (set (attr "length")
6207 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6210 (match_test "TARGET_POWERPC64")
6212 (const_string "16"))))])
6215 (define_insn_and_split "*bool<mode>3_internal"
6216 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6217 (match_operator:BOOL_128 3 "boolean_or_operator"
6218 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6219 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6222 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6223 return "xxl%q3 %x0,%x1,%x2";
6225 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6226 return "v%q3 %0,%1,%2";
6230 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6233 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6238 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6239 (const_string "vecsimple")
6240 (const_string "integer")))
6241 (set (attr "length")
6243 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6246 (match_test "TARGET_POWERPC64")
6248 (const_string "16"))))])
6251 (define_insn_and_split "*boolc<mode>3_internal1"
6252 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6253 (match_operator:BOOL_128 3 "boolean_operator"
6255 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6256 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6257 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6259 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6260 return "xxl%q3 %x0,%x1,%x2";
6262 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6263 return "v%q3 %0,%1,%2";
6267 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6268 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6271 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6276 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6277 (const_string "vecsimple")
6278 (const_string "integer")))
6279 (set (attr "length")
6281 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6284 (match_test "TARGET_POWERPC64")
6286 (const_string "16"))))])
6288 (define_insn_and_split "*boolc<mode>3_internal2"
6289 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6290 (match_operator:TI2 3 "boolean_operator"
6292 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6293 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6294 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6296 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6299 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6302 [(set_attr "type" "integer")
6303 (set (attr "length")
6305 (match_test "TARGET_POWERPC64")
6307 (const_string "16")))])
6310 (define_insn_and_split "*boolcc<mode>3_internal1"
6311 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6312 (match_operator:BOOL_128 3 "boolean_operator"
6314 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6316 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6317 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6319 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6320 return "xxl%q3 %x0,%x1,%x2";
6322 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6323 return "v%q3 %0,%1,%2";
6327 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6328 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6331 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6336 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6337 (const_string "vecsimple")
6338 (const_string "integer")))
6339 (set (attr "length")
6341 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6344 (match_test "TARGET_POWERPC64")
6346 (const_string "16"))))])
6348 (define_insn_and_split "*boolcc<mode>3_internal2"
6349 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6350 (match_operator:TI2 3 "boolean_operator"
6352 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6354 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6355 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6357 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6360 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6363 [(set_attr "type" "integer")
6364 (set (attr "length")
6366 (match_test "TARGET_POWERPC64")
6368 (const_string "16")))])
6372 (define_insn_and_split "*eqv<mode>3_internal1"
6373 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6376 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6377 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6380 if (vsx_register_operand (operands[0], <MODE>mode))
6381 return "xxleqv %x0,%x1,%x2";
6385 "TARGET_P8_VECTOR && reload_completed
6386 && int_reg_operand (operands[0], <MODE>mode)"
6389 rs6000_split_logical (operands, XOR, true, false, false);
6394 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6395 (const_string "vecsimple")
6396 (const_string "integer")))
6397 (set (attr "length")
6399 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6402 (match_test "TARGET_POWERPC64")
6404 (const_string "16"))))])
6406 (define_insn_and_split "*eqv<mode>3_internal2"
6407 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6410 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6411 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6414 "reload_completed && !TARGET_P8_VECTOR"
6417 rs6000_split_logical (operands, XOR, true, false, false);
6420 [(set_attr "type" "integer")
6421 (set (attr "length")
6423 (match_test "TARGET_POWERPC64")
6425 (const_string "16")))])
6427 ;; 128-bit one's complement
6428 (define_insn_and_split "*one_cmpl<mode>3_internal"
6429 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6431 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6434 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6435 return "xxlnor %x0,%x1,%x1";
6437 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6438 return "vnor %0,%1,%1";
6442 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6445 rs6000_split_logical (operands, NOT, false, false, false);
6450 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6451 (const_string "vecsimple")
6452 (const_string "integer")))
6453 (set (attr "length")
6455 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6458 (match_test "TARGET_POWERPC64")
6460 (const_string "16"))))])
6463 ;; Now define ways of moving data around.
6465 ;; Set up a register with a value from the GOT table
6467 (define_expand "movsi_got"
6468 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6469 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6470 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6471 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6474 if (GET_CODE (operands[1]) == CONST)
6476 rtx offset = const0_rtx;
6477 HOST_WIDE_INT value;
6479 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6480 value = INTVAL (offset);
6483 rtx tmp = (!can_create_pseudo_p ()
6485 : gen_reg_rtx (Pmode));
6486 emit_insn (gen_movsi_got (tmp, operands[1]));
6487 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6492 operands[2] = rs6000_got_register (operands[1]);
6495 (define_insn "*movsi_got_internal"
6496 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6497 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6498 (match_operand:SI 2 "gpc_reg_operand" "b")]
6500 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6501 "lwz %0,%a1@got(%2)"
6502 [(set_attr "type" "load")])
6504 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6505 ;; didn't get allocated to a hard register.
6507 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6508 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6509 (match_operand:SI 2 "memory_operand" "")]
6511 "DEFAULT_ABI == ABI_V4
6513 && (reload_in_progress || reload_completed)"
6514 [(set (match_dup 0) (match_dup 2))
6515 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6519 ;; For SI, we special-case integers that can't be loaded in one insn. We
6520 ;; do the load 16-bits at a time. We could do this by loading from memory,
6521 ;; and this is even supposed to be faster, but it is simpler not to get
6522 ;; integers in the TOC.
6523 (define_insn "movsi_low"
6524 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6525 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6526 (match_operand 2 "" ""))))]
6527 "TARGET_MACHO && ! TARGET_64BIT"
6528 "lwz %0,lo16(%2)(%1)"
6529 [(set_attr "type" "load")
6530 (set_attr "length" "4")])
6532 (define_insn "*movsi_internal1"
6533 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6534 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6535 "!TARGET_SINGLE_FPU &&
6536 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6549 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6550 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6552 (define_insn "*movsi_internal1_single"
6553 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6554 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6555 "TARGET_SINGLE_FPU &&
6556 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6571 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6572 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6574 ;; Split a load of a large constant into the appropriate two-insn
6578 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6579 (match_operand:SI 1 "const_int_operand" ""))]
6580 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6581 && (INTVAL (operands[1]) & 0xffff) != 0"
6585 (ior:SI (match_dup 0)
6589 if (rs6000_emit_set_const (operands[0], operands[1]))
6595 (define_insn "*mov<mode>_internal2"
6596 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6597 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6599 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6605 [(set_attr "type" "cmp,logical,cmp")
6606 (set_attr "dot" "yes")
6607 (set_attr "length" "4,4,8")])
6610 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6611 (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6613 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6615 [(set (match_dup 0) (match_dup 1))
6617 (compare:CC (match_dup 0)
6621 (define_insn "*movhi_internal"
6622 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6623 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6624 "gpc_reg_operand (operands[0], HImode)
6625 || gpc_reg_operand (operands[1], HImode)"
6634 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6636 (define_expand "mov<mode>"
6637 [(set (match_operand:INT 0 "general_operand" "")
6638 (match_operand:INT 1 "any_operand" ""))]
6640 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6642 (define_insn "*movqi_internal"
6643 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6644 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6645 "gpc_reg_operand (operands[0], QImode)
6646 || gpc_reg_operand (operands[1], QImode)"
6655 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6657 ;; Here is how to move condition codes around. When we store CC data in
6658 ;; an integer register or memory, we store just the high-order 4 bits.
6659 ;; This lets us not shift in the most common case of CR0.
6660 (define_expand "movcc"
6661 [(set (match_operand:CC 0 "nonimmediate_operand" "")
6662 (match_operand:CC 1 "nonimmediate_operand" ""))]
6666 (define_insn "*movcc_internal1"
6667 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6668 (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6669 "register_operand (operands[0], CCmode)
6670 || register_operand (operands[1], CCmode)"
6674 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6677 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6685 (cond [(eq_attr "alternative" "0,3")
6686 (const_string "cr_logical")
6687 (eq_attr "alternative" "1,2")
6688 (const_string "mtcr")
6689 (eq_attr "alternative" "6,7")
6690 (const_string "integer")
6691 (eq_attr "alternative" "8")
6692 (const_string "mfjmpr")
6693 (eq_attr "alternative" "9")
6694 (const_string "mtjmpr")
6695 (eq_attr "alternative" "10")
6696 (const_string "load")
6697 (eq_attr "alternative" "11")
6698 (const_string "store")
6699 (match_test "TARGET_MFCRF")
6700 (const_string "mfcrf")
6702 (const_string "mfcr")))
6703 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6705 ;; For floating-point, we normally deal with the floating-point registers
6706 ;; unless -msoft-float is used. The sole exception is that parameter passing
6707 ;; can produce floating-point values in fixed-point registers. Unless the
6708 ;; value is a simple constant or already in memory, we deal with this by
6709 ;; allocating memory and copying the value explicitly via that memory location.
6711 ;; Move 32-bit binary/decimal floating point
6712 (define_expand "mov<mode>"
6713 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6714 (match_operand:FMOVE32 1 "any_operand" ""))]
6716 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6719 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6720 (match_operand:FMOVE32 1 "const_double_operand" ""))]
6722 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6723 || (GET_CODE (operands[0]) == SUBREG
6724 && GET_CODE (SUBREG_REG (operands[0])) == REG
6725 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6726 [(set (match_dup 2) (match_dup 3))]
6732 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
6733 <real_value_to_target> (rv, l);
6735 if (! TARGET_POWERPC64)
6736 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6738 operands[2] = gen_lowpart (SImode, operands[0]);
6740 operands[3] = gen_int_mode (l, SImode);
6743 (define_insn "mov<mode>_hardfloat"
6744 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_sm>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h")
6745 (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_sr>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
6746 "(gpc_reg_operand (operands[0], <MODE>mode)
6747 || gpc_reg_operand (operands[1], <MODE>mode))
6748 && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6754 xscpsgndp %x0,%x1,%x1
6766 [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*")
6767 (set_attr "length" "4")])
6769 (define_insn "*mov<mode>_softfloat"
6770 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6771 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6772 "(gpc_reg_operand (operands[0], <MODE>mode)
6773 || gpc_reg_operand (operands[1], <MODE>mode))
6774 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6786 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6787 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6790 ;; Move 64-bit binary/decimal floating point
6791 (define_expand "mov<mode>"
6792 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6793 (match_operand:FMOVE64 1 "any_operand" ""))]
6795 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6798 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6799 (match_operand:FMOVE64 1 "const_int_operand" ""))]
6800 "! TARGET_POWERPC64 && reload_completed
6801 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6802 || (GET_CODE (operands[0]) == SUBREG
6803 && GET_CODE (SUBREG_REG (operands[0])) == REG
6804 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6805 [(set (match_dup 2) (match_dup 4))
6806 (set (match_dup 3) (match_dup 1))]
6809 int endian = (WORDS_BIG_ENDIAN == 0);
6810 HOST_WIDE_INT value = INTVAL (operands[1]);
6812 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6813 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6814 operands[4] = GEN_INT (value >> 32);
6815 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6819 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6820 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6821 "! TARGET_POWERPC64 && reload_completed
6822 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6823 || (GET_CODE (operands[0]) == SUBREG
6824 && GET_CODE (SUBREG_REG (operands[0])) == REG
6825 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6826 [(set (match_dup 2) (match_dup 4))
6827 (set (match_dup 3) (match_dup 5))]
6830 int endian = (WORDS_BIG_ENDIAN == 0);
6834 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
6835 <real_value_to_target> (rv, l);
6837 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6838 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6839 operands[4] = gen_int_mode (l[endian], SImode);
6840 operands[5] = gen_int_mode (l[1 - endian], SImode);
6844 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6845 (match_operand:FMOVE64 1 "const_double_operand" ""))]
6846 "TARGET_POWERPC64 && reload_completed
6847 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6848 || (GET_CODE (operands[0]) == SUBREG
6849 && GET_CODE (SUBREG_REG (operands[0])) == REG
6850 && REGNO (SUBREG_REG (operands[0])) <= 31))"
6851 [(set (match_dup 2) (match_dup 3))]
6854 int endian = (WORDS_BIG_ENDIAN == 0);
6859 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
6860 <real_value_to_target> (rv, l);
6862 operands[2] = gen_lowpart (DImode, operands[0]);
6863 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
6864 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6865 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6867 operands[3] = gen_int_mode (val, DImode);
6870 ;; Don't have reload use general registers to load a constant. It is
6871 ;; less efficient than loading the constant into an FP register, since
6872 ;; it will probably be used there.
6874 ;; The move constraints are ordered to prefer floating point registers before
6875 ;; general purpose registers to avoid doing a store and a load to get the value
6876 ;; into a floating point register when it is needed for a floating point
6877 ;; operation. Prefer traditional floating point registers over VSX registers,
6878 ;; since the D-form version of the memory instructions does not need a GPR for
6881 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6882 ;; except for 0.0 which can be created on VSX with an xor instruction.
6884 (define_insn "*mov<mode>_hardfloat32"
6885 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6886 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r"))]
6887 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6888 && (gpc_reg_operand (operands[0], <MODE>mode)
6889 || gpc_reg_operand (operands[1], <MODE>mode))"
6902 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,two,store,load,two")
6903 (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8")])
6905 (define_insn "*mov<mode>_softfloat32"
6906 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6907 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6909 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
6910 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6911 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6912 && (gpc_reg_operand (operands[0], <MODE>mode)
6913 || gpc_reg_operand (operands[1], <MODE>mode))"
6915 [(set_attr "type" "store,load,two,*,*,*")
6916 (set_attr "length" "8,8,8,8,12,16")])
6918 ; ld/std require word-aligned displacements -> 'Y' constraint.
6919 ; List Y->r and r->Y before r->r for reload.
6920 (define_insn "*mov<mode>_hardfloat64"
6921 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
6922 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6923 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6924 && (gpc_reg_operand (operands[0], <MODE>mode)
6925 || gpc_reg_operand (operands[1], <MODE>mode))"
6945 [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6946 (set_attr "length" "4")])
6948 (define_insn "*mov<mode>_softfloat64"
6949 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6950 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6951 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6952 && (gpc_reg_operand (operands[0], <MODE>mode)
6953 || gpc_reg_operand (operands[1], <MODE>mode))"
6964 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6965 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6967 (define_expand "mov<mode>"
6968 [(set (match_operand:FMOVE128 0 "general_operand" "")
6969 (match_operand:FMOVE128 1 "any_operand" ""))]
6971 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6973 ;; It's important to list Y->r and r->Y before r->r because otherwise
6974 ;; reload, given m->r, will try to pick r->r and reload it, which
6975 ;; doesn't make progress.
6977 ;; We can't split little endian direct moves of TDmode, because the words are
6978 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
6979 ;; problematical. Don't allow direct move for this case.
6981 (define_insn_and_split "*mov<mode>_64bit_dm"
6982 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r,r,wm")
6983 (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jY,r,wm,r"))]
6984 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6985 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6986 && (gpc_reg_operand (operands[0], <MODE>mode)
6987 || gpc_reg_operand (operands[1], <MODE>mode))"
6989 "&& reload_completed"
6991 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6992 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6994 (define_insn_and_split "*movtd_64bit_nodm"
6995 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
6996 (match_operand:TD 1 "input_operand" "d,m,d,j,r,jY,r"))]
6997 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6998 && (gpc_reg_operand (operands[0], TDmode)
6999 || gpc_reg_operand (operands[1], TDmode))"
7001 "&& reload_completed"
7003 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7004 [(set_attr "length" "8,8,8,8,12,12,8")])
7006 (define_insn_and_split "*mov<mode>_32bit"
7007 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
7008 (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jY,r"))]
7009 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
7010 && (gpc_reg_operand (operands[0], <MODE>mode)
7011 || gpc_reg_operand (operands[1], <MODE>mode))"
7013 "&& reload_completed"
7015 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7016 [(set_attr "length" "8,8,8,8,20,20,16")])
7018 (define_insn_and_split "*mov<mode>_softfloat"
7019 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
7020 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7021 "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
7022 && (gpc_reg_operand (operands[0], <MODE>mode)
7023 || gpc_reg_operand (operands[1], <MODE>mode))"
7025 "&& reload_completed"
7027 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7028 [(set_attr "length" "20,20,16")])
7030 (define_expand "extenddftf2"
7031 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7032 (float_extend:TF (match_operand:DF 1 "input_operand" "")))]
7034 && TARGET_HARD_FLOAT
7035 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7036 && TARGET_LONG_DOUBLE_128"
7038 if (TARGET_E500_DOUBLE)
7039 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
7041 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1]));
7045 (define_expand "extenddftf2_fprs"
7046 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
7047 (float_extend:TF (match_operand:DF 1 "input_operand" "")))
7048 (use (match_dup 2))])]
7050 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7051 && TARGET_LONG_DOUBLE_128"
7053 /* VSX can create 0.0 directly, otherwise let rs6000_emit_move create
7054 the proper constant. */
7056 operands[2] = CONST0_RTX (DFmode);
7059 operands[2] = gen_reg_rtx (DFmode);
7060 rs6000_emit_move (operands[2], CONST0_RTX (DFmode), DFmode);
7064 (define_insn_and_split "*extenddftf2_internal"
7065 [(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,ws,d,&d")
7066 (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,md")))
7067 (use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,j,m,d"))]
7069 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7070 && TARGET_LONG_DOUBLE_128"
7072 "&& reload_completed"
7075 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7076 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7077 emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
7079 emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
7084 (define_expand "extendsftf2"
7085 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7086 (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
7088 && TARGET_HARD_FLOAT
7089 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7090 && TARGET_LONG_DOUBLE_128"
7092 rtx tmp = gen_reg_rtx (DFmode);
7093 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7094 emit_insn (gen_extenddftf2 (operands[0], tmp));
7098 (define_expand "trunctfdf2"
7099 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7100 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
7102 && TARGET_HARD_FLOAT
7103 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7104 && TARGET_LONG_DOUBLE_128"
7107 (define_insn_and_split "trunctfdf2_internal1"
7108 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7109 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,d")))]
7110 "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
7111 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7115 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7118 emit_note (NOTE_INSN_DELETED);
7121 [(set_attr "type" "fp")])
7123 (define_insn "trunctfdf2_internal2"
7124 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7125 (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "d")))]
7126 "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
7127 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7128 && TARGET_LONG_DOUBLE_128"
7130 [(set_attr "type" "fp")
7131 (set_attr "fp_type" "fp_addsub_d")])
7133 (define_expand "trunctfsf2"
7134 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7135 (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))]
7137 && TARGET_HARD_FLOAT
7138 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7139 && TARGET_LONG_DOUBLE_128"
7141 if (TARGET_E500_DOUBLE)
7142 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
7144 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7148 (define_insn_and_split "trunctfsf2_fprs"
7149 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7150 (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "d")))
7151 (clobber (match_scratch:DF 2 "=d"))]
7153 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7154 && TARGET_LONG_DOUBLE_128"
7156 "&& reload_completed"
7158 (float_truncate:DF (match_dup 1)))
7160 (float_truncate:SF (match_dup 2)))]
7163 (define_expand "floatsitf2"
7164 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7165 (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))]
7167 && TARGET_HARD_FLOAT
7168 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7169 && TARGET_LONG_DOUBLE_128"
7171 rtx tmp = gen_reg_rtx (DFmode);
7172 expand_float (tmp, operands[1], false);
7173 emit_insn (gen_extenddftf2 (operands[0], tmp));
7177 ; fadd, but rounding towards zero.
7178 ; This is probably not the optimal code sequence.
7179 (define_insn "fix_trunc_helper"
7180 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7181 (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "d")]
7182 UNSPEC_FIX_TRUNC_TF))
7183 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7184 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
7185 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7186 [(set_attr "type" "fp")
7187 (set_attr "length" "20")])
7189 (define_expand "fix_trunctfsi2"
7190 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7191 (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))]
7192 "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT
7193 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7195 if (TARGET_E500_DOUBLE)
7196 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7198 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7202 (define_expand "fix_trunctfsi2_fprs"
7203 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7204 (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
7205 (clobber (match_dup 2))
7206 (clobber (match_dup 3))
7207 (clobber (match_dup 4))
7208 (clobber (match_dup 5))])]
7210 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7212 operands[2] = gen_reg_rtx (DFmode);
7213 operands[3] = gen_reg_rtx (DFmode);
7214 operands[4] = gen_reg_rtx (DImode);
7215 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7218 (define_insn_and_split "*fix_trunctfsi2_internal"
7219 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7220 (fix:SI (match_operand:TF 1 "gpc_reg_operand" "d")))
7221 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7222 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7223 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7224 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7226 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7232 emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
7234 gcc_assert (MEM_P (operands[5]));
7235 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7237 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7238 emit_move_insn (operands[5], operands[4]);
7239 emit_move_insn (operands[0], lowword);
7243 (define_expand "negtf2"
7244 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7245 (neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
7247 && TARGET_HARD_FLOAT
7248 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7249 && TARGET_LONG_DOUBLE_128"
7252 (define_insn "negtf2_internal"
7253 [(set (match_operand:TF 0 "gpc_reg_operand" "=d")
7254 (neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))]
7256 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7259 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7260 return \"fneg %L0,%L1\;fneg %0,%1\";
7262 return \"fneg %0,%1\;fneg %L0,%L1\";
7264 [(set_attr "type" "fp")
7265 (set_attr "length" "8")])
7267 (define_expand "abstf2"
7268 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7269 (abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
7271 && TARGET_HARD_FLOAT
7272 && (TARGET_FPRS || TARGET_E500_DOUBLE)
7273 && TARGET_LONG_DOUBLE_128"
7276 rtx label = gen_label_rtx ();
7277 if (TARGET_E500_DOUBLE)
7279 if (flag_finite_math_only && !flag_trapping_math)
7280 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7282 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7285 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7290 (define_expand "abstf2_internal"
7291 [(set (match_operand:TF 0 "gpc_reg_operand" "")
7292 (match_operand:TF 1 "gpc_reg_operand" ""))
7293 (set (match_dup 3) (match_dup 5))
7294 (set (match_dup 5) (abs:DF (match_dup 5)))
7295 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7296 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7297 (label_ref (match_operand 2 "" ""))
7299 (set (match_dup 6) (neg:DF (match_dup 6)))]
7301 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7302 && TARGET_LONG_DOUBLE_128"
7305 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7306 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7307 operands[3] = gen_reg_rtx (DFmode);
7308 operands[4] = gen_reg_rtx (CCFPmode);
7309 operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
7310 operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
7313 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
7314 ;; must have 3 arguments, and scratch register constraint must be a single
7317 ;; Reload patterns to support gpr load/store with misaligned mem.
7318 ;; and multiple gpr load/store at offset >= 0xfffc
7319 (define_expand "reload_<mode>_store"
7320 [(parallel [(match_operand 0 "memory_operand" "=m")
7321 (match_operand 1 "gpc_reg_operand" "r")
7322 (match_operand:GPR 2 "register_operand" "=&b")])]
7325 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7329 (define_expand "reload_<mode>_load"
7330 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7331 (match_operand 1 "memory_operand" "m")
7332 (match_operand:GPR 2 "register_operand" "=b")])]
7335 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7340 ;; Reload patterns for various types using the vector registers. We may need
7341 ;; an additional base register to convert the reg+offset addressing to reg+reg
7342 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7343 ;; index register for gpr registers.
7344 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7345 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7346 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7347 (match_operand:P 2 "register_operand" "=b")])]
7350 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7354 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7355 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7356 (match_operand:RELOAD 1 "memory_operand" "m")
7357 (match_operand:P 2 "register_operand" "=b")])]
7360 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7365 ;; Reload sometimes tries to move the address to a GPR, and can generate
7366 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
7367 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7369 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7370 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7371 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7372 (match_operand:P 2 "reg_or_cint_operand" "rI"))
7374 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7376 "&& reload_completed"
7378 (plus:P (match_dup 1)
7381 (and:P (match_dup 0)
7384 ;; Power8 merge instructions to allow direct move to/from floating point
7385 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
7386 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
7387 ;; value, since it is allocated in reload and not all of the flow information
7388 ;; is setup for it. We have two patterns to do the two moves between gprs and
7389 ;; fprs. There isn't a dependancy between the two, but we could potentially
7390 ;; schedule other instructions between the two instructions. TFmode is
7391 ;; currently limited to traditional FPR registers. If/when this is changed, we
7392 ;; will need to revist %L to make sure it works with VSX registers, or add an
7393 ;; %x version of %L.
7395 (define_insn "p8_fmrgow_<mode>"
7396 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7397 (unspec:FMOVE64X [(match_operand:TF 1 "register_operand" "d")]
7398 UNSPEC_P8V_FMRGOW))]
7399 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7401 [(set_attr "type" "vecperm")])
7403 (define_insn "p8_mtvsrwz_1"
7404 [(set (match_operand:TF 0 "register_operand" "=d")
7405 (unspec:TF [(match_operand:SI 1 "register_operand" "r")]
7406 UNSPEC_P8V_MTVSRWZ))]
7407 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7409 [(set_attr "type" "mftgpr")])
7411 (define_insn "p8_mtvsrwz_2"
7412 [(set (match_operand:TF 0 "register_operand" "+d")
7413 (unspec:TF [(match_dup 0)
7414 (match_operand:SI 1 "register_operand" "r")]
7415 UNSPEC_P8V_MTVSRWZ))]
7416 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7418 [(set_attr "type" "mftgpr")])
7420 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7421 [(set (match_operand:FMOVE64X 0 "register_operand" "=ws")
7422 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7423 UNSPEC_P8V_RELOAD_FROM_GPR))
7424 (clobber (match_operand:TF 2 "register_operand" "=d"))]
7425 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7427 "&& reload_completed"
7430 rtx dest = operands[0];
7431 rtx src = operands[1];
7432 rtx tmp = operands[2];
7433 rtx gpr_hi_reg = gen_highpart (SImode, src);
7434 rtx gpr_lo_reg = gen_lowpart (SImode, src);
7436 emit_insn (gen_p8_mtvsrwz_1 (tmp, gpr_hi_reg));
7437 emit_insn (gen_p8_mtvsrwz_2 (tmp, gpr_lo_reg));
7438 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp));
7441 [(set_attr "length" "12")
7442 (set_attr "type" "three")])
7444 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7445 (define_insn "p8_mtvsrd_1"
7446 [(set (match_operand:TF 0 "register_operand" "=ws")
7447 (unspec:TF [(match_operand:DI 1 "register_operand" "r")]
7448 UNSPEC_P8V_MTVSRD))]
7449 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7451 [(set_attr "type" "mftgpr")])
7453 (define_insn "p8_mtvsrd_2"
7454 [(set (match_operand:TF 0 "register_operand" "+ws")
7455 (unspec:TF [(match_dup 0)
7456 (match_operand:DI 1 "register_operand" "r")]
7457 UNSPEC_P8V_MTVSRD))]
7458 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7460 [(set_attr "type" "mftgpr")])
7462 (define_insn "p8_xxpermdi_<mode>"
7463 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7464 (unspec:FMOVE128_GPR [(match_operand:TF 1 "register_operand" "ws")]
7465 UNSPEC_P8V_XXPERMDI))]
7466 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7467 "xxpermdi %x0,%1,%L1,0"
7468 [(set_attr "type" "vecperm")])
7470 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7471 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7472 (unspec:FMOVE128_GPR
7473 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7474 UNSPEC_P8V_RELOAD_FROM_GPR))
7475 (clobber (match_operand:TF 2 "register_operand" "=ws"))]
7476 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7478 "&& reload_completed"
7481 rtx dest = operands[0];
7482 rtx src = operands[1];
7483 rtx tmp = operands[2];
7484 rtx gpr_hi_reg = gen_highpart (DImode, src);
7485 rtx gpr_lo_reg = gen_lowpart (DImode, src);
7487 emit_insn (gen_p8_mtvsrd_1 (tmp, gpr_hi_reg));
7488 emit_insn (gen_p8_mtvsrd_2 (tmp, gpr_lo_reg));
7489 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp));
7492 [(set_attr "length" "12")
7493 (set_attr "type" "three")])
7496 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7497 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7499 && (int_reg_operand (operands[0], <MODE>mode)
7500 || int_reg_operand (operands[1], <MODE>mode))"
7502 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7504 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
7505 ;; type is stored internally as double precision in the VSX registers, we have
7506 ;; to convert it from the vector format.
7508 (define_insn_and_split "reload_vsx_from_gprsf"
7509 [(set (match_operand:SF 0 "register_operand" "=wa")
7510 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7511 UNSPEC_P8V_RELOAD_FROM_GPR))
7512 (clobber (match_operand:DI 2 "register_operand" "=r"))]
7513 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7515 "&& reload_completed"
7518 rtx op0 = operands[0];
7519 rtx op1 = operands[1];
7520 rtx op2 = operands[2];
7521 /* Also use the destination register to hold the unconverted DImode value.
7522 This is conceptually a separate value from OP0, so we use gen_rtx_REG
7523 rather than simplify_gen_subreg. */
7524 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
7525 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7527 /* Move SF value to upper 32-bits for xscvspdpn. */
7528 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7529 emit_move_insn (op0_di, op2);
7530 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di));
7533 [(set_attr "length" "8")
7534 (set_attr "type" "two")])
7536 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7537 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7538 ;; and then doing a move of that.
7539 (define_insn "p8_mfvsrd_3_<mode>"
7540 [(set (match_operand:DF 0 "register_operand" "=r")
7541 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7542 UNSPEC_P8V_RELOAD_FROM_VSX))]
7543 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7545 [(set_attr "type" "mftgpr")])
7547 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7548 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7549 (unspec:FMOVE128_GPR
7550 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7551 UNSPEC_P8V_RELOAD_FROM_VSX))
7552 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7553 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7555 "&& reload_completed"
7558 rtx dest = operands[0];
7559 rtx src = operands[1];
7560 rtx tmp = operands[2];
7561 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7562 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7564 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7565 emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7566 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7569 [(set_attr "length" "12")
7570 (set_attr "type" "three")])
7572 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
7573 ;; type is stored internally as double precision, we have to convert it to the
7576 (define_insn_and_split "reload_gpr_from_vsxsf"
7577 [(set (match_operand:SF 0 "register_operand" "=r")
7578 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7579 UNSPEC_P8V_RELOAD_FROM_VSX))
7580 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7581 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7583 "&& reload_completed"
7586 rtx op0 = operands[0];
7587 rtx op1 = operands[1];
7588 rtx op2 = operands[2];
7589 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7591 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7592 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7593 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7596 [(set_attr "length" "12")
7597 (set_attr "type" "three")])
7599 (define_insn "p8_mfvsrd_4_disf"
7600 [(set (match_operand:DI 0 "register_operand" "=r")
7601 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7602 UNSPEC_P8V_RELOAD_FROM_VSX))]
7603 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7605 [(set_attr "type" "mftgpr")])
7608 ;; Next come the multi-word integer load and store and the load and store
7611 ;; List r->r after r->Y, otherwise reload will try to reload a
7612 ;; non-offsettable address by using r->r which won't make progress.
7613 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7614 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7615 (define_insn "*movdi_internal32"
7616 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
7617 (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
7619 && (gpc_reg_operand (operands[0], DImode)
7620 || gpc_reg_operand (operands[1], DImode))"
7629 [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
7632 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7633 (match_operand:DI 1 "const_int_operand" ""))]
7634 "! TARGET_POWERPC64 && reload_completed
7635 && gpr_or_gpr_p (operands[0], operands[1])
7636 && !direct_move_p (operands[0], operands[1])"
7637 [(set (match_dup 2) (match_dup 4))
7638 (set (match_dup 3) (match_dup 1))]
7641 HOST_WIDE_INT value = INTVAL (operands[1]);
7642 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7644 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7646 operands[4] = GEN_INT (value >> 32);
7647 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7651 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7652 (match_operand:DIFD 1 "input_operand" ""))]
7653 "reload_completed && !TARGET_POWERPC64
7654 && gpr_or_gpr_p (operands[0], operands[1])
7655 && !direct_move_p (operands[0], operands[1])"
7657 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7659 (define_insn "*movdi_internal64"
7660 [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
7661 (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
7663 && (gpc_reg_operand (operands[0], DImode)
7664 || gpc_reg_operand (operands[1], DImode))"
7683 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
7684 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
7686 ;; Generate all one-bits and clear left or right.
7687 ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
7689 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7690 (match_operand:DI 1 "mask64_operand" ""))]
7691 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7692 [(set (match_dup 0) (const_int -1))
7694 (and:DI (rotate:DI (match_dup 0)
7699 ;; Split a load of a large constant into the appropriate five-instruction
7700 ;; sequence. Handle anything in a constant number of insns.
7701 ;; When non-easy constants can go in the TOC, this should use
7702 ;; easy_fp_constant predicate.
7704 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7705 (match_operand:DI 1 "const_int_operand" ""))]
7706 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7707 [(set (match_dup 0) (match_dup 2))
7708 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7711 if (rs6000_emit_set_const (operands[0], operands[1]))
7718 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7719 (match_operand:DI 1 "const_scalar_int_operand" ""))]
7720 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7721 [(set (match_dup 0) (match_dup 2))
7722 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7725 if (rs6000_emit_set_const (operands[0], operands[1]))
7731 ;; TImode/PTImode is similar, except that we usually want to compute the
7732 ;; address into a register and use lsi/stsi (the exception is during reload).
7734 (define_insn "*mov<mode>_string"
7735 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
7736 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
7738 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
7739 && (gpc_reg_operand (operands[0], <MODE>mode)
7740 || gpc_reg_operand (operands[1], <MODE>mode))"
7743 switch (which_alternative)
7749 return \"stswi %1,%P0,16\";
7753 /* If the address is not used in the output, we can use lsi. Otherwise,
7754 fall through to generating four loads. */
7756 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
7757 return \"lswi %0,%P1,16\";
7758 /* ... fall through ... */
7765 [(set_attr "type" "store,store,load,load,*,*")
7766 (set_attr "update" "yes")
7767 (set_attr "indexed" "yes")
7768 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
7769 (const_string "always")
7770 (const_string "conditional")))])
7772 (define_insn "*mov<mode>_ppc64"
7773 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
7774 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
7775 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
7776 && (gpc_reg_operand (operands[0], <MODE>mode)
7777 || gpc_reg_operand (operands[1], <MODE>mode)))"
7779 return rs6000_output_move_128bit (operands);
7781 [(set_attr "type" "store,store,load,load,*,*")
7782 (set_attr "length" "8")])
7785 [(set (match_operand:TI2 0 "int_reg_operand" "")
7786 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
7788 && (VECTOR_MEM_NONE_P (<MODE>mode)
7789 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
7790 [(set (match_dup 2) (match_dup 4))
7791 (set (match_dup 3) (match_dup 5))]
7794 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7796 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7798 if (CONST_WIDE_INT_P (operands[1]))
7800 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
7801 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
7803 else if (CONST_INT_P (operands[1]))
7805 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
7806 operands[5] = operands[1];
7813 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
7814 (match_operand:TI2 1 "input_operand" ""))]
7816 && gpr_or_gpr_p (operands[0], operands[1])
7817 && !direct_move_p (operands[0], operands[1])
7818 && !quad_load_store_p (operands[0], operands[1])"
7820 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7822 (define_expand "load_multiple"
7823 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7824 (match_operand:SI 1 "" ""))
7825 (use (match_operand:SI 2 "" ""))])]
7826 "TARGET_STRING && !TARGET_POWERPC64"
7834 /* Support only loading a constant number of fixed-point registers from
7835 memory and only bother with this if more than two; the machine
7836 doesn't support more than eight. */
7837 if (GET_CODE (operands[2]) != CONST_INT
7838 || INTVAL (operands[2]) <= 2
7839 || INTVAL (operands[2]) > 8
7840 || GET_CODE (operands[1]) != MEM
7841 || GET_CODE (operands[0]) != REG
7842 || REGNO (operands[0]) >= 32)
7845 count = INTVAL (operands[2]);
7846 regno = REGNO (operands[0]);
7848 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
7849 op1 = replace_equiv_address (operands[1],
7850 force_reg (SImode, XEXP (operands[1], 0)));
7852 for (i = 0; i < count; i++)
7853 XVECEXP (operands[3], 0, i)
7854 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
7855 adjust_address_nv (op1, SImode, i * 4));
7858 (define_insn "*ldmsi8"
7859 [(match_parallel 0 "load_multiple_operation"
7860 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7861 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7862 (set (match_operand:SI 3 "gpc_reg_operand" "")
7863 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7864 (set (match_operand:SI 4 "gpc_reg_operand" "")
7865 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7866 (set (match_operand:SI 5 "gpc_reg_operand" "")
7867 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7868 (set (match_operand:SI 6 "gpc_reg_operand" "")
7869 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7870 (set (match_operand:SI 7 "gpc_reg_operand" "")
7871 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7872 (set (match_operand:SI 8 "gpc_reg_operand" "")
7873 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
7874 (set (match_operand:SI 9 "gpc_reg_operand" "")
7875 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
7876 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
7878 { return rs6000_output_load_multiple (operands); }"
7879 [(set_attr "type" "load")
7880 (set_attr "update" "yes")
7881 (set_attr "indexed" "yes")
7882 (set_attr "length" "32")])
7884 (define_insn "*ldmsi7"
7885 [(match_parallel 0 "load_multiple_operation"
7886 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7887 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7888 (set (match_operand:SI 3 "gpc_reg_operand" "")
7889 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7890 (set (match_operand:SI 4 "gpc_reg_operand" "")
7891 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7892 (set (match_operand:SI 5 "gpc_reg_operand" "")
7893 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7894 (set (match_operand:SI 6 "gpc_reg_operand" "")
7895 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7896 (set (match_operand:SI 7 "gpc_reg_operand" "")
7897 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7898 (set (match_operand:SI 8 "gpc_reg_operand" "")
7899 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
7900 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
7902 { return rs6000_output_load_multiple (operands); }"
7903 [(set_attr "type" "load")
7904 (set_attr "update" "yes")
7905 (set_attr "indexed" "yes")
7906 (set_attr "length" "32")])
7908 (define_insn "*ldmsi6"
7909 [(match_parallel 0 "load_multiple_operation"
7910 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7911 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7912 (set (match_operand:SI 3 "gpc_reg_operand" "")
7913 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7914 (set (match_operand:SI 4 "gpc_reg_operand" "")
7915 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7916 (set (match_operand:SI 5 "gpc_reg_operand" "")
7917 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7918 (set (match_operand:SI 6 "gpc_reg_operand" "")
7919 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7920 (set (match_operand:SI 7 "gpc_reg_operand" "")
7921 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
7922 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
7924 { return rs6000_output_load_multiple (operands); }"
7925 [(set_attr "type" "load")
7926 (set_attr "update" "yes")
7927 (set_attr "indexed" "yes")
7928 (set_attr "length" "32")])
7930 (define_insn "*ldmsi5"
7931 [(match_parallel 0 "load_multiple_operation"
7932 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7933 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7934 (set (match_operand:SI 3 "gpc_reg_operand" "")
7935 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7936 (set (match_operand:SI 4 "gpc_reg_operand" "")
7937 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7938 (set (match_operand:SI 5 "gpc_reg_operand" "")
7939 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7940 (set (match_operand:SI 6 "gpc_reg_operand" "")
7941 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
7942 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
7944 { return rs6000_output_load_multiple (operands); }"
7945 [(set_attr "type" "load")
7946 (set_attr "update" "yes")
7947 (set_attr "indexed" "yes")
7948 (set_attr "length" "32")])
7950 (define_insn "*ldmsi4"
7951 [(match_parallel 0 "load_multiple_operation"
7952 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7953 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7954 (set (match_operand:SI 3 "gpc_reg_operand" "")
7955 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7956 (set (match_operand:SI 4 "gpc_reg_operand" "")
7957 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7958 (set (match_operand:SI 5 "gpc_reg_operand" "")
7959 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
7960 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
7962 { return rs6000_output_load_multiple (operands); }"
7963 [(set_attr "type" "load")
7964 (set_attr "update" "yes")
7965 (set_attr "indexed" "yes")
7966 (set_attr "length" "32")])
7968 (define_insn "*ldmsi3"
7969 [(match_parallel 0 "load_multiple_operation"
7970 [(set (match_operand:SI 2 "gpc_reg_operand" "")
7971 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7972 (set (match_operand:SI 3 "gpc_reg_operand" "")
7973 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7974 (set (match_operand:SI 4 "gpc_reg_operand" "")
7975 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
7976 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
7978 { return rs6000_output_load_multiple (operands); }"
7979 [(set_attr "type" "load")
7980 (set_attr "update" "yes")
7981 (set_attr "indexed" "yes")
7982 (set_attr "length" "32")])
7984 (define_expand "store_multiple"
7985 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7986 (match_operand:SI 1 "" ""))
7987 (clobber (scratch:SI))
7988 (use (match_operand:SI 2 "" ""))])]
7989 "TARGET_STRING && !TARGET_POWERPC64"
7998 /* Support only storing a constant number of fixed-point registers to
7999 memory and only bother with this if more than two; the machine
8000 doesn't support more than eight. */
8001 if (GET_CODE (operands[2]) != CONST_INT
8002 || INTVAL (operands[2]) <= 2
8003 || INTVAL (operands[2]) > 8
8004 || GET_CODE (operands[0]) != MEM
8005 || GET_CODE (operands[1]) != REG
8006 || REGNO (operands[1]) >= 32)
8009 count = INTVAL (operands[2]);
8010 regno = REGNO (operands[1]);
8012 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8013 to = force_reg (SImode, XEXP (operands[0], 0));
8014 op0 = replace_equiv_address (operands[0], to);
8016 XVECEXP (operands[3], 0, 0)
8017 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8018 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8019 gen_rtx_SCRATCH (SImode));
8021 for (i = 1; i < count; i++)
8022 XVECEXP (operands[3], 0, i + 1)
8023 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8024 gen_rtx_REG (SImode, regno + i));
8027 (define_insn "*stmsi8"
8028 [(match_parallel 0 "store_multiple_operation"
8029 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8030 (match_operand:SI 2 "gpc_reg_operand" "r"))
8031 (clobber (match_scratch:SI 3 "=X"))
8032 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8033 (match_operand:SI 4 "gpc_reg_operand" "r"))
8034 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8035 (match_operand:SI 5 "gpc_reg_operand" "r"))
8036 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8037 (match_operand:SI 6 "gpc_reg_operand" "r"))
8038 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8039 (match_operand:SI 7 "gpc_reg_operand" "r"))
8040 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8041 (match_operand:SI 8 "gpc_reg_operand" "r"))
8042 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8043 (match_operand:SI 9 "gpc_reg_operand" "r"))
8044 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8045 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8046 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8048 [(set_attr "type" "store")
8049 (set_attr "update" "yes")
8050 (set_attr "indexed" "yes")
8051 (set_attr "cell_micro" "always")])
8053 (define_insn "*stmsi7"
8054 [(match_parallel 0 "store_multiple_operation"
8055 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8056 (match_operand:SI 2 "gpc_reg_operand" "r"))
8057 (clobber (match_scratch:SI 3 "=X"))
8058 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8059 (match_operand:SI 4 "gpc_reg_operand" "r"))
8060 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8061 (match_operand:SI 5 "gpc_reg_operand" "r"))
8062 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8063 (match_operand:SI 6 "gpc_reg_operand" "r"))
8064 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8065 (match_operand:SI 7 "gpc_reg_operand" "r"))
8066 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8067 (match_operand:SI 8 "gpc_reg_operand" "r"))
8068 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8069 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8070 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8072 [(set_attr "type" "store")
8073 (set_attr "update" "yes")
8074 (set_attr "indexed" "yes")
8075 (set_attr "cell_micro" "always")])
8077 (define_insn "*stmsi6"
8078 [(match_parallel 0 "store_multiple_operation"
8079 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8080 (match_operand:SI 2 "gpc_reg_operand" "r"))
8081 (clobber (match_scratch:SI 3 "=X"))
8082 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8083 (match_operand:SI 4 "gpc_reg_operand" "r"))
8084 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8085 (match_operand:SI 5 "gpc_reg_operand" "r"))
8086 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8087 (match_operand:SI 6 "gpc_reg_operand" "r"))
8088 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8089 (match_operand:SI 7 "gpc_reg_operand" "r"))
8090 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8091 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8092 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8094 [(set_attr "type" "store")
8095 (set_attr "update" "yes")
8096 (set_attr "indexed" "yes")
8097 (set_attr "cell_micro" "always")])
8099 (define_insn "*stmsi5"
8100 [(match_parallel 0 "store_multiple_operation"
8101 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8102 (match_operand:SI 2 "gpc_reg_operand" "r"))
8103 (clobber (match_scratch:SI 3 "=X"))
8104 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8105 (match_operand:SI 4 "gpc_reg_operand" "r"))
8106 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8107 (match_operand:SI 5 "gpc_reg_operand" "r"))
8108 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8109 (match_operand:SI 6 "gpc_reg_operand" "r"))
8110 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8111 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8112 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8114 [(set_attr "type" "store")
8115 (set_attr "update" "yes")
8116 (set_attr "indexed" "yes")
8117 (set_attr "cell_micro" "always")])
8119 (define_insn "*stmsi4"
8120 [(match_parallel 0 "store_multiple_operation"
8121 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8122 (match_operand:SI 2 "gpc_reg_operand" "r"))
8123 (clobber (match_scratch:SI 3 "=X"))
8124 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8125 (match_operand:SI 4 "gpc_reg_operand" "r"))
8126 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8127 (match_operand:SI 5 "gpc_reg_operand" "r"))
8128 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8129 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8130 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8132 [(set_attr "type" "store")
8133 (set_attr "update" "yes")
8134 (set_attr "indexed" "yes")
8135 (set_attr "cell_micro" "always")])
8137 (define_insn "*stmsi3"
8138 [(match_parallel 0 "store_multiple_operation"
8139 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8140 (match_operand:SI 2 "gpc_reg_operand" "r"))
8141 (clobber (match_scratch:SI 3 "=X"))
8142 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8143 (match_operand:SI 4 "gpc_reg_operand" "r"))
8144 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8145 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8146 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8148 [(set_attr "type" "store")
8149 (set_attr "update" "yes")
8150 (set_attr "indexed" "yes")
8151 (set_attr "cell_micro" "always")])
8153 (define_expand "setmemsi"
8154 [(parallel [(set (match_operand:BLK 0 "" "")
8155 (match_operand 2 "const_int_operand" ""))
8156 (use (match_operand:SI 1 "" ""))
8157 (use (match_operand:SI 3 "" ""))])]
8161 /* If value to set is not zero, use the library routine. */
8162 if (operands[2] != const0_rtx)
8165 if (expand_block_clear (operands))
8171 ;; String/block move insn.
8172 ;; Argument 0 is the destination
8173 ;; Argument 1 is the source
8174 ;; Argument 2 is the length
8175 ;; Argument 3 is the alignment
8177 (define_expand "movmemsi"
8178 [(parallel [(set (match_operand:BLK 0 "" "")
8179 (match_operand:BLK 1 "" ""))
8180 (use (match_operand:SI 2 "" ""))
8181 (use (match_operand:SI 3 "" ""))])]
8185 if (expand_block_move (operands))
8191 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
8192 ;; register allocator doesn't have a clue about allocating 8 word registers.
8193 ;; rD/rS = r5 is preferred, efficient form.
8194 (define_expand "movmemsi_8reg"
8195 [(parallel [(set (match_operand 0 "" "")
8196 (match_operand 1 "" ""))
8197 (use (match_operand 2 "" ""))
8198 (use (match_operand 3 "" ""))
8199 (clobber (reg:SI 5))
8200 (clobber (reg:SI 6))
8201 (clobber (reg:SI 7))
8202 (clobber (reg:SI 8))
8203 (clobber (reg:SI 9))
8204 (clobber (reg:SI 10))
8205 (clobber (reg:SI 11))
8206 (clobber (reg:SI 12))
8207 (clobber (match_scratch:SI 4 ""))])]
8212 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8213 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8214 (use (match_operand:SI 2 "immediate_operand" "i"))
8215 (use (match_operand:SI 3 "immediate_operand" "i"))
8216 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8217 (clobber (reg:SI 6))
8218 (clobber (reg:SI 7))
8219 (clobber (reg:SI 8))
8220 (clobber (reg:SI 9))
8221 (clobber (reg:SI 10))
8222 (clobber (reg:SI 11))
8223 (clobber (reg:SI 12))
8224 (clobber (match_scratch:SI 5 "=X"))]
8226 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8227 || INTVAL (operands[2]) == 0)
8228 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8229 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8230 && REGNO (operands[4]) == 5"
8231 "lswi %4,%1,%2\;stswi %4,%0,%2"
8232 [(set_attr "type" "store")
8233 (set_attr "update" "yes")
8234 (set_attr "indexed" "yes")
8235 (set_attr "cell_micro" "always")
8236 (set_attr "length" "8")])
8238 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
8239 ;; register allocator doesn't have a clue about allocating 6 word registers.
8240 ;; rD/rS = r5 is preferred, efficient form.
8241 (define_expand "movmemsi_6reg"
8242 [(parallel [(set (match_operand 0 "" "")
8243 (match_operand 1 "" ""))
8244 (use (match_operand 2 "" ""))
8245 (use (match_operand 3 "" ""))
8246 (clobber (reg:SI 5))
8247 (clobber (reg:SI 6))
8248 (clobber (reg:SI 7))
8249 (clobber (reg:SI 8))
8250 (clobber (reg:SI 9))
8251 (clobber (reg:SI 10))
8252 (clobber (match_scratch:SI 4 ""))])]
8257 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8258 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8259 (use (match_operand:SI 2 "immediate_operand" "i"))
8260 (use (match_operand:SI 3 "immediate_operand" "i"))
8261 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8262 (clobber (reg:SI 6))
8263 (clobber (reg:SI 7))
8264 (clobber (reg:SI 8))
8265 (clobber (reg:SI 9))
8266 (clobber (reg:SI 10))
8267 (clobber (match_scratch:SI 5 "=X"))]
8269 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8270 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8271 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8272 && REGNO (operands[4]) == 5"
8273 "lswi %4,%1,%2\;stswi %4,%0,%2"
8274 [(set_attr "type" "store")
8275 (set_attr "update" "yes")
8276 (set_attr "indexed" "yes")
8277 (set_attr "cell_micro" "always")
8278 (set_attr "length" "8")])
8280 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8281 ;; problems with TImode.
8282 ;; rD/rS = r5 is preferred, efficient form.
8283 (define_expand "movmemsi_4reg"
8284 [(parallel [(set (match_operand 0 "" "")
8285 (match_operand 1 "" ""))
8286 (use (match_operand 2 "" ""))
8287 (use (match_operand 3 "" ""))
8288 (clobber (reg:SI 5))
8289 (clobber (reg:SI 6))
8290 (clobber (reg:SI 7))
8291 (clobber (reg:SI 8))
8292 (clobber (match_scratch:SI 4 ""))])]
8297 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8298 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8299 (use (match_operand:SI 2 "immediate_operand" "i"))
8300 (use (match_operand:SI 3 "immediate_operand" "i"))
8301 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8302 (clobber (reg:SI 6))
8303 (clobber (reg:SI 7))
8304 (clobber (reg:SI 8))
8305 (clobber (match_scratch:SI 5 "=X"))]
8307 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8308 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8309 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8310 && REGNO (operands[4]) == 5"
8311 "lswi %4,%1,%2\;stswi %4,%0,%2"
8312 [(set_attr "type" "store")
8313 (set_attr "update" "yes")
8314 (set_attr "indexed" "yes")
8315 (set_attr "cell_micro" "always")
8316 (set_attr "length" "8")])
8318 ;; Move up to 8 bytes at a time.
8319 (define_expand "movmemsi_2reg"
8320 [(parallel [(set (match_operand 0 "" "")
8321 (match_operand 1 "" ""))
8322 (use (match_operand 2 "" ""))
8323 (use (match_operand 3 "" ""))
8324 (clobber (match_scratch:DI 4 ""))
8325 (clobber (match_scratch:SI 5 ""))])]
8326 "TARGET_STRING && ! TARGET_POWERPC64"
8330 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8331 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8332 (use (match_operand:SI 2 "immediate_operand" "i"))
8333 (use (match_operand:SI 3 "immediate_operand" "i"))
8334 (clobber (match_scratch:DI 4 "=&r"))
8335 (clobber (match_scratch:SI 5 "=X"))]
8336 "TARGET_STRING && ! TARGET_POWERPC64
8337 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8338 "lswi %4,%1,%2\;stswi %4,%0,%2"
8339 [(set_attr "type" "store")
8340 (set_attr "update" "yes")
8341 (set_attr "indexed" "yes")
8342 (set_attr "cell_micro" "always")
8343 (set_attr "length" "8")])
8345 ;; Move up to 4 bytes at a time.
8346 (define_expand "movmemsi_1reg"
8347 [(parallel [(set (match_operand 0 "" "")
8348 (match_operand 1 "" ""))
8349 (use (match_operand 2 "" ""))
8350 (use (match_operand 3 "" ""))
8351 (clobber (match_scratch:SI 4 ""))
8352 (clobber (match_scratch:SI 5 ""))])]
8357 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8358 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8359 (use (match_operand:SI 2 "immediate_operand" "i"))
8360 (use (match_operand:SI 3 "immediate_operand" "i"))
8361 (clobber (match_scratch:SI 4 "=&r"))
8362 (clobber (match_scratch:SI 5 "=X"))]
8363 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8364 "lswi %4,%1,%2\;stswi %4,%0,%2"
8365 [(set_attr "type" "store")
8366 (set_attr "update" "yes")
8367 (set_attr "indexed" "yes")
8368 (set_attr "cell_micro" "always")
8369 (set_attr "length" "8")])
8371 ;; Define insns that do load or store with update. Some of these we can
8372 ;; get by using pre-decrement or pre-increment, but the hardware can also
8373 ;; do cases where the increment is not the size of the object.
8375 ;; In all these cases, we use operands 0 and 1 for the register being
8376 ;; incremented because those are the operands that local-alloc will
8377 ;; tie and these are the pair most likely to be tieable (and the ones
8378 ;; that will benefit the most).
8380 (define_insn "*movdi_update1"
8381 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8382 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8383 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8384 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8385 (plus:DI (match_dup 1) (match_dup 2)))]
8386 "TARGET_POWERPC64 && TARGET_UPDATE
8387 && (!avoiding_indexed_address_p (DImode)
8388 || !gpc_reg_operand (operands[2], DImode))"
8392 [(set_attr "type" "load")
8393 (set_attr "update" "yes")
8394 (set_attr "indexed" "yes,no")])
8396 (define_insn "movdi_<mode>_update"
8397 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8398 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8399 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8400 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8401 (plus:P (match_dup 1) (match_dup 2)))]
8402 "TARGET_POWERPC64 && TARGET_UPDATE
8403 && (!avoiding_indexed_address_p (Pmode)
8404 || !gpc_reg_operand (operands[2], Pmode)
8405 || (REG_P (operands[0])
8406 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8410 [(set_attr "type" "store")
8411 (set_attr "update" "yes")
8412 (set_attr "indexed" "yes,no")])
8414 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8415 ;; needed for stack allocation, even if the user passes -mno-update.
8416 (define_insn "movdi_<mode>_update_stack"
8417 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8418 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8419 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8420 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8421 (plus:P (match_dup 1) (match_dup 2)))]
8426 [(set_attr "type" "store")
8427 (set_attr "update" "yes")
8428 (set_attr "indexed" "yes,no")])
8430 (define_insn "*movsi_update1"
8431 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8432 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8433 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8434 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8435 (plus:SI (match_dup 1) (match_dup 2)))]
8437 && (!avoiding_indexed_address_p (SImode)
8438 || !gpc_reg_operand (operands[2], SImode))"
8442 [(set_attr "type" "load")
8443 (set_attr "update" "yes")
8444 (set_attr "indexed" "yes,no")])
8446 (define_insn "*movsi_update2"
8447 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8449 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8450 (match_operand:DI 2 "gpc_reg_operand" "r")))))
8451 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8452 (plus:DI (match_dup 1) (match_dup 2)))]
8453 "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8454 && !avoiding_indexed_address_p (DImode)"
8456 [(set_attr "type" "load")
8457 (set_attr "sign_extend" "yes")
8458 (set_attr "update" "yes")
8459 (set_attr "indexed" "yes")])
8461 (define_insn "movsi_update"
8462 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8463 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8464 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8465 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8466 (plus:SI (match_dup 1) (match_dup 2)))]
8468 && (!avoiding_indexed_address_p (SImode)
8469 || !gpc_reg_operand (operands[2], SImode)
8470 || (REG_P (operands[0])
8471 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8475 [(set_attr "type" "store")
8476 (set_attr "update" "yes")
8477 (set_attr "indexed" "yes,no")])
8479 ;; This is an unconditional pattern; needed for stack allocation, even
8480 ;; if the user passes -mno-update.
8481 (define_insn "movsi_update_stack"
8482 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8483 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8484 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8485 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8486 (plus:SI (match_dup 1) (match_dup 2)))]
8491 [(set_attr "type" "store")
8492 (set_attr "update" "yes")
8493 (set_attr "indexed" "yes,no")])
8495 (define_insn "*movhi_update1"
8496 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8497 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8498 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8499 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8500 (plus:SI (match_dup 1) (match_dup 2)))]
8502 && (!avoiding_indexed_address_p (SImode)
8503 || !gpc_reg_operand (operands[2], SImode))"
8507 [(set_attr "type" "load")
8508 (set_attr "update" "yes")
8509 (set_attr "indexed" "yes,no")])
8511 (define_insn "*movhi_update2"
8512 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8514 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8515 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8516 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8517 (plus:SI (match_dup 1) (match_dup 2)))]
8519 && (!avoiding_indexed_address_p (SImode)
8520 || !gpc_reg_operand (operands[2], SImode))"
8524 [(set_attr "type" "load")
8525 (set_attr "update" "yes")
8526 (set_attr "indexed" "yes,no")])
8528 (define_insn "*movhi_update3"
8529 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8531 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8532 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8533 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8534 (plus:SI (match_dup 1) (match_dup 2)))]
8535 "TARGET_UPDATE && rs6000_gen_cell_microcode
8536 && (!avoiding_indexed_address_p (SImode)
8537 || !gpc_reg_operand (operands[2], SImode))"
8541 [(set_attr "type" "load")
8542 (set_attr "sign_extend" "yes")
8543 (set_attr "update" "yes")
8544 (set_attr "indexed" "yes,no")])
8546 (define_insn "*movhi_update4"
8547 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8548 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8549 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8550 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8551 (plus:SI (match_dup 1) (match_dup 2)))]
8553 && (!avoiding_indexed_address_p (SImode)
8554 || !gpc_reg_operand (operands[2], SImode))"
8558 [(set_attr "type" "store")
8559 (set_attr "update" "yes")
8560 (set_attr "indexed" "yes,no")])
8562 (define_insn "*movqi_update1"
8563 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8564 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8565 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8566 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8567 (plus:SI (match_dup 1) (match_dup 2)))]
8569 && (!avoiding_indexed_address_p (SImode)
8570 || !gpc_reg_operand (operands[2], SImode))"
8574 [(set_attr "type" "load")
8575 (set_attr "update" "yes")
8576 (set_attr "indexed" "yes,no")])
8578 (define_insn "*movqi_update2"
8579 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8581 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8582 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8583 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8584 (plus:SI (match_dup 1) (match_dup 2)))]
8586 && (!avoiding_indexed_address_p (SImode)
8587 || !gpc_reg_operand (operands[2], SImode))"
8591 [(set_attr "type" "load")
8592 (set_attr "update" "yes")
8593 (set_attr "indexed" "yes,no")])
8595 (define_insn "*movqi_update3"
8596 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8597 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8598 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
8599 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8600 (plus:SI (match_dup 1) (match_dup 2)))]
8602 && (!avoiding_indexed_address_p (SImode)
8603 || !gpc_reg_operand (operands[2], SImode))"
8607 [(set_attr "type" "store")
8608 (set_attr "update" "yes")
8609 (set_attr "indexed" "yes,no")])
8611 (define_insn "*movsf_update1"
8612 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
8613 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8614 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8615 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8616 (plus:SI (match_dup 1) (match_dup 2)))]
8617 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8618 && (!avoiding_indexed_address_p (SImode)
8619 || !gpc_reg_operand (operands[2], SImode))"
8623 [(set_attr "type" "fpload")
8624 (set_attr "update" "yes")
8625 (set_attr "indexed" "yes,no")])
8627 (define_insn "*movsf_update2"
8628 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8629 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8630 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
8631 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8632 (plus:SI (match_dup 1) (match_dup 2)))]
8633 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8634 && (!avoiding_indexed_address_p (SImode)
8635 || !gpc_reg_operand (operands[2], SImode))"
8639 [(set_attr "type" "fpstore")
8640 (set_attr "update" "yes")
8641 (set_attr "indexed" "yes,no")])
8643 (define_insn "*movsf_update3"
8644 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
8645 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8646 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8647 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8648 (plus:SI (match_dup 1) (match_dup 2)))]
8649 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8650 && (!avoiding_indexed_address_p (SImode)
8651 || !gpc_reg_operand (operands[2], SImode))"
8655 [(set_attr "type" "load")
8656 (set_attr "update" "yes")
8657 (set_attr "indexed" "yes,no")])
8659 (define_insn "*movsf_update4"
8660 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8661 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8662 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
8663 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8664 (plus:SI (match_dup 1) (match_dup 2)))]
8665 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8666 && (!avoiding_indexed_address_p (SImode)
8667 || !gpc_reg_operand (operands[2], SImode))"
8671 [(set_attr "type" "store")
8672 (set_attr "update" "yes")
8673 (set_attr "indexed" "yes,no")])
8675 (define_insn "*movdf_update1"
8676 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
8677 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8678 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8679 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8680 (plus:SI (match_dup 1) (match_dup 2)))]
8681 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8682 && (!avoiding_indexed_address_p (SImode)
8683 || !gpc_reg_operand (operands[2], SImode))"
8687 [(set_attr "type" "fpload")
8688 (set_attr "update" "yes")
8689 (set_attr "indexed" "yes,no")])
8691 (define_insn "*movdf_update2"
8692 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8693 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8694 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
8695 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8696 (plus:SI (match_dup 1) (match_dup 2)))]
8697 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8698 && (!avoiding_indexed_address_p (SImode)
8699 || !gpc_reg_operand (operands[2], SImode))"
8703 [(set_attr "type" "fpstore")
8704 (set_attr "update" "yes")
8705 (set_attr "indexed" "yes,no")])
8708 ;; After inserting conditional returns we can sometimes have
8709 ;; unnecessary register moves. Unfortunately we cannot have a
8710 ;; modeless peephole here, because some single SImode sets have early
8711 ;; clobber outputs. Although those sets expand to multi-ppc-insn
8712 ;; sequences, using get_attr_length here will smash the operands
8713 ;; array. Neither is there an early_cobbler_p predicate.
8714 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
8715 ;; Also this optimization interferes with scalars going into
8716 ;; altivec registers (the code does reloading through the FPRs).
8718 [(set (match_operand:DF 0 "gpc_reg_operand" "")
8719 (match_operand:DF 1 "any_operand" ""))
8720 (set (match_operand:DF 2 "gpc_reg_operand" "")
8722 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
8723 && !TARGET_UPPER_REGS_DF
8724 && peep2_reg_dead_p (2, operands[0])"
8725 [(set (match_dup 2) (match_dup 1))])
8728 [(set (match_operand:SF 0 "gpc_reg_operand" "")
8729 (match_operand:SF 1 "any_operand" ""))
8730 (set (match_operand:SF 2 "gpc_reg_operand" "")
8732 "!TARGET_UPPER_REGS_SF
8733 && peep2_reg_dead_p (2, operands[0])"
8734 [(set (match_dup 2) (match_dup 1))])
8739 ;; Mode attributes for different ABIs.
8740 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
8741 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
8742 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
8743 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
8745 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
8746 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8747 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8748 (match_operand 4 "" "g")))
8749 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8750 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8752 (clobber (reg:SI LR_REGNO))]
8753 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8755 if (TARGET_CMODEL != CMODEL_SMALL)
8756 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
8759 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
8761 "&& TARGET_TLS_MARKERS"
8763 (unspec:TLSmode [(match_dup 1)
8766 (parallel [(set (match_dup 0)
8767 (call (mem:TLSmode (match_dup 3))
8769 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8770 (clobber (reg:SI LR_REGNO))])]
8772 [(set_attr "type" "two")
8773 (set (attr "length")
8774 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8778 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
8779 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8780 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8781 (match_operand 4 "" "g")))
8782 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8783 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8785 (clobber (reg:SI LR_REGNO))]
8786 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
8790 if (TARGET_SECURE_PLT && flag_pic == 2)
8791 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
8793 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
8796 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
8798 "&& TARGET_TLS_MARKERS"
8800 (unspec:TLSmode [(match_dup 1)
8803 (parallel [(set (match_dup 0)
8804 (call (mem:TLSmode (match_dup 3))
8806 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8807 (clobber (reg:SI LR_REGNO))])]
8809 [(set_attr "type" "two")
8810 (set_attr "length" "8")])
8812 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
8813 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8814 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8815 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8817 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
8818 "addi %0,%1,%2@got@tlsgd"
8819 "&& TARGET_CMODEL != CMODEL_SMALL"
8822 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
8824 (lo_sum:TLSmode (match_dup 3)
8825 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
8828 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
8830 [(set (attr "length")
8831 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8835 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
8836 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8838 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8839 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8841 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8842 "addis %0,%1,%2@got@tlsgd@ha"
8843 [(set_attr "length" "4")])
8845 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
8846 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8847 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
8848 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
8849 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8851 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8852 "addi %0,%1,%2@got@tlsgd@l"
8853 [(set_attr "length" "4")])
8855 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
8856 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8857 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8858 (match_operand 2 "" "g")))
8859 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8861 (clobber (reg:SI LR_REGNO))]
8862 "HAVE_AS_TLS && TARGET_TLS_MARKERS
8863 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8864 "bl %z1(%3@tlsgd)\;nop"
8865 [(set_attr "type" "branch")
8866 (set_attr "length" "8")])
8868 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
8869 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8870 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8871 (match_operand 2 "" "g")))
8872 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8874 (clobber (reg:SI LR_REGNO))]
8875 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
8879 if (TARGET_SECURE_PLT && flag_pic == 2)
8880 return "bl %z1+32768(%3@tlsgd)@plt";
8881 return "bl %z1(%3@tlsgd)@plt";
8883 return "bl %z1(%3@tlsgd)";
8885 [(set_attr "type" "branch")
8886 (set_attr "length" "4")])
8888 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
8889 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8890 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
8891 (match_operand 3 "" "g")))
8892 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8894 (clobber (reg:SI LR_REGNO))]
8895 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8897 if (TARGET_CMODEL != CMODEL_SMALL)
8898 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
8901 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
8903 "&& TARGET_TLS_MARKERS"
8905 (unspec:TLSmode [(match_dup 1)]
8907 (parallel [(set (match_dup 0)
8908 (call (mem:TLSmode (match_dup 2))
8910 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
8911 (clobber (reg:SI LR_REGNO))])]
8913 [(set_attr "type" "two")
8914 (set (attr "length")
8915 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8919 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
8920 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8921 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
8922 (match_operand 3 "" "g")))
8923 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8925 (clobber (reg:SI LR_REGNO))]
8926 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
8930 if (TARGET_SECURE_PLT && flag_pic == 2)
8931 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
8933 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
8936 return "addi %0,%1,%&@got@tlsld\;bl %z2";
8938 "&& TARGET_TLS_MARKERS"
8940 (unspec:TLSmode [(match_dup 1)]
8942 (parallel [(set (match_dup 0)
8943 (call (mem:TLSmode (match_dup 2))
8945 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
8946 (clobber (reg:SI LR_REGNO))])]
8948 [(set_attr "length" "8")])
8950 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
8951 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8952 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8954 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
8955 "addi %0,%1,%&@got@tlsld"
8956 "&& TARGET_CMODEL != CMODEL_SMALL"
8959 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
8961 (lo_sum:TLSmode (match_dup 2)
8962 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
8965 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
8967 [(set (attr "length")
8968 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8972 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
8973 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8975 (unspec:TLSmode [(const_int 0)
8976 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8978 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8979 "addis %0,%1,%&@got@tlsld@ha"
8980 [(set_attr "length" "4")])
8982 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
8983 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8984 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
8985 (unspec:TLSmode [(const_int 0)
8986 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
8988 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8989 "addi %0,%1,%&@got@tlsld@l"
8990 [(set_attr "length" "4")])
8992 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
8993 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8994 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8995 (match_operand 2 "" "g")))
8996 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
8997 (clobber (reg:SI LR_REGNO))]
8998 "HAVE_AS_TLS && TARGET_TLS_MARKERS
8999 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9000 "bl %z1(%&@tlsld)\;nop"
9001 [(set_attr "type" "branch")
9002 (set_attr "length" "8")])
9004 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9005 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9006 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9007 (match_operand 2 "" "g")))
9008 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9009 (clobber (reg:SI LR_REGNO))]
9010 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9014 if (TARGET_SECURE_PLT && flag_pic == 2)
9015 return "bl %z1+32768(%&@tlsld)@plt";
9016 return "bl %z1(%&@tlsld)@plt";
9018 return "bl %z1(%&@tlsld)";
9020 [(set_attr "type" "branch")
9021 (set_attr "length" "4")])
9023 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9024 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9025 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9026 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9029 "addi %0,%1,%2@dtprel")
9031 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9032 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9033 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9034 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9035 UNSPEC_TLSDTPRELHA))]
9037 "addis %0,%1,%2@dtprel@ha")
9039 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9040 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9041 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9042 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9043 UNSPEC_TLSDTPRELLO))]
9045 "addi %0,%1,%2@dtprel@l")
9047 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9048 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9049 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9050 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9051 UNSPEC_TLSGOTDTPREL))]
9053 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9054 "&& TARGET_CMODEL != CMODEL_SMALL"
9057 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9059 (lo_sum:TLSmode (match_dup 3)
9060 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9063 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9065 [(set (attr "length")
9066 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9070 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9071 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9073 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9074 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9075 UNSPEC_TLSGOTDTPREL)))]
9076 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9077 "addis %0,%1,%2@got@dtprel@ha"
9078 [(set_attr "length" "4")])
9080 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9081 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9082 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9083 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9084 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9085 UNSPEC_TLSGOTDTPREL)))]
9086 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9087 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9088 [(set_attr "length" "4")])
9090 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9091 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9092 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9093 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9096 "addi %0,%1,%2@tprel")
9098 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9099 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9100 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9101 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9102 UNSPEC_TLSTPRELHA))]
9104 "addis %0,%1,%2@tprel@ha")
9106 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9107 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9108 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9109 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9110 UNSPEC_TLSTPRELLO))]
9112 "addi %0,%1,%2@tprel@l")
9114 ;; "b" output constraint here and on tls_tls input to support linker tls
9115 ;; optimization. The linker may edit the instructions emitted by a
9116 ;; tls_got_tprel/tls_tls pair to addis,addi.
9117 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9118 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9119 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9120 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9121 UNSPEC_TLSGOTTPREL))]
9123 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9124 "&& TARGET_CMODEL != CMODEL_SMALL"
9127 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9129 (lo_sum:TLSmode (match_dup 3)
9130 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9133 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9135 [(set (attr "length")
9136 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9140 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9141 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9143 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9144 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9145 UNSPEC_TLSGOTTPREL)))]
9146 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9147 "addis %0,%1,%2@got@tprel@ha"
9148 [(set_attr "length" "4")])
9150 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9151 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9152 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9153 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9154 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9155 UNSPEC_TLSGOTTPREL)))]
9156 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9157 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9158 [(set_attr "length" "4")])
9160 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9161 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9162 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9163 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9165 "TARGET_ELF && HAVE_AS_TLS"
9168 (define_expand "tls_get_tpointer"
9169 [(set (match_operand:SI 0 "gpc_reg_operand" "")
9170 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9171 "TARGET_XCOFF && HAVE_AS_TLS"
9174 emit_insn (gen_tls_get_tpointer_internal ());
9175 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9179 (define_insn "tls_get_tpointer_internal"
9181 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9182 (clobber (reg:SI LR_REGNO))]
9183 "TARGET_XCOFF && HAVE_AS_TLS"
9184 "bla __get_tpointer")
9186 (define_expand "tls_get_addr<mode>"
9187 [(set (match_operand:P 0 "gpc_reg_operand" "")
9188 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9189 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9190 "TARGET_XCOFF && HAVE_AS_TLS"
9193 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9194 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9195 emit_insn (gen_tls_get_addr_internal<mode> ());
9196 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9200 (define_insn "tls_get_addr_internal<mode>"
9202 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9206 (clobber (reg:P 11))
9207 (clobber (reg:CC CR0_REGNO))
9208 (clobber (reg:P LR_REGNO))]
9209 "TARGET_XCOFF && HAVE_AS_TLS"
9210 "bla __tls_get_addr")
9212 ;; Next come insns related to the calling sequence.
9214 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9215 ;; We move the back-chain and decrement the stack pointer.
9217 (define_expand "allocate_stack"
9218 [(set (match_operand 0 "gpc_reg_operand" "")
9219 (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9221 (minus (reg 1) (match_dup 1)))]
9224 { rtx chain = gen_reg_rtx (Pmode);
9225 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9227 rtx insn, par, set, mem;
9229 emit_move_insn (chain, stack_bot);
9231 /* Check stack bounds if necessary. */
9232 if (crtl->limit_stack)
9235 available = expand_binop (Pmode, sub_optab,
9236 stack_pointer_rtx, stack_limit_rtx,
9237 NULL_RTX, 1, OPTAB_WIDEN);
9238 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9241 if (GET_CODE (operands[1]) != CONST_INT
9242 || INTVAL (operands[1]) < -32767
9243 || INTVAL (operands[1]) > 32768)
9245 neg_op0 = gen_reg_rtx (Pmode);
9247 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9249 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9252 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9254 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9255 : gen_movdi_di_update_stack))
9256 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9258 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9259 it now and set the alias set/attributes. The above gen_*_update
9260 calls will generate a PARALLEL with the MEM set being the first
9262 par = PATTERN (insn);
9263 gcc_assert (GET_CODE (par) == PARALLEL);
9264 set = XVECEXP (par, 0, 0);
9265 gcc_assert (GET_CODE (set) == SET);
9266 mem = SET_DEST (set);
9267 gcc_assert (MEM_P (mem));
9268 MEM_NOTRAP_P (mem) = 1;
9269 set_mem_alias_set (mem, get_frame_alias_set ());
9271 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9275 ;; These patterns say how to save and restore the stack pointer. We need not
9276 ;; save the stack pointer at function level since we are careful to
9277 ;; preserve the backchain. At block level, we have to restore the backchain
9278 ;; when we restore the stack pointer.
9280 ;; For nonlocal gotos, we must save both the stack pointer and its
9281 ;; backchain and restore both. Note that in the nonlocal case, the
9282 ;; save area is a memory location.
9284 (define_expand "save_stack_function"
9285 [(match_operand 0 "any_operand" "")
9286 (match_operand 1 "any_operand" "")]
9290 (define_expand "restore_stack_function"
9291 [(match_operand 0 "any_operand" "")
9292 (match_operand 1 "any_operand" "")]
9296 ;; Adjust stack pointer (op0) to a new value (op1).
9297 ;; First copy old stack backchain to new location, and ensure that the
9298 ;; scheduler won't reorder the sp assignment before the backchain write.
9299 (define_expand "restore_stack_block"
9300 [(set (match_dup 2) (match_dup 3))
9301 (set (match_dup 4) (match_dup 2))
9303 (set (match_operand 0 "register_operand" "")
9304 (match_operand 1 "register_operand" ""))]
9310 operands[1] = force_reg (Pmode, operands[1]);
9311 operands[2] = gen_reg_rtx (Pmode);
9312 operands[3] = gen_frame_mem (Pmode, operands[0]);
9313 operands[4] = gen_frame_mem (Pmode, operands[1]);
9314 p = rtvec_alloc (1);
9315 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9317 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9320 (define_expand "save_stack_nonlocal"
9321 [(set (match_dup 3) (match_dup 4))
9322 (set (match_operand 0 "memory_operand" "") (match_dup 3))
9323 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9327 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9329 /* Copy the backchain to the first word, sp to the second. */
9330 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9331 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9332 operands[3] = gen_reg_rtx (Pmode);
9333 operands[4] = gen_frame_mem (Pmode, operands[1]);
9336 (define_expand "restore_stack_nonlocal"
9337 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9338 (set (match_dup 3) (match_dup 4))
9339 (set (match_dup 5) (match_dup 2))
9341 (set (match_operand 0 "register_operand" "") (match_dup 3))]
9345 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9348 /* Restore the backchain from the first word, sp from the second. */
9349 operands[2] = gen_reg_rtx (Pmode);
9350 operands[3] = gen_reg_rtx (Pmode);
9351 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9352 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9353 operands[5] = gen_frame_mem (Pmode, operands[3]);
9354 p = rtvec_alloc (1);
9355 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9357 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9360 ;; TOC register handling.
9362 ;; Code to initialize the TOC register...
9364 (define_insn "load_toc_aix_si"
9365 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9366 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9368 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9372 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9373 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9374 operands[2] = gen_rtx_REG (Pmode, 2);
9375 return \"lwz %0,%1(%2)\";
9377 [(set_attr "type" "load")
9378 (set_attr "update" "no")
9379 (set_attr "indexed" "no")])
9381 (define_insn "load_toc_aix_di"
9382 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9383 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9385 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9389 #ifdef TARGET_RELOCATABLE
9390 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9391 !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
9393 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9396 strcat (buf, \"@toc\");
9397 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9398 operands[2] = gen_rtx_REG (Pmode, 2);
9399 return \"ld %0,%1(%2)\";
9401 [(set_attr "type" "load")
9402 (set_attr "update" "no")
9403 (set_attr "indexed" "no")])
9405 (define_insn "load_toc_v4_pic_si"
9406 [(set (reg:SI LR_REGNO)
9407 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9408 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9409 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9410 [(set_attr "type" "branch")
9411 (set_attr "length" "4")])
9413 (define_expand "load_toc_v4_PIC_1"
9414 [(parallel [(set (reg:SI LR_REGNO)
9415 (match_operand:SI 0 "immediate_operand" "s"))
9416 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9417 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9418 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9421 (define_insn "load_toc_v4_PIC_1_normal"
9422 [(set (reg:SI LR_REGNO)
9423 (match_operand:SI 0 "immediate_operand" "s"))
9424 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9425 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9426 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9427 "bcl 20,31,%0\\n%0:"
9428 [(set_attr "type" "branch")
9429 (set_attr "length" "4")])
9431 (define_insn "load_toc_v4_PIC_1_476"
9432 [(set (reg:SI LR_REGNO)
9433 (match_operand:SI 0 "immediate_operand" "s"))
9434 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9435 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9436 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9440 static char templ[32];
9442 get_ppc476_thunk_name (name);
9443 sprintf (templ, \"bl %s\\n%%0:\", name);
9446 [(set_attr "type" "branch")
9447 (set_attr "length" "4")])
9449 (define_expand "load_toc_v4_PIC_1b"
9450 [(parallel [(set (reg:SI LR_REGNO)
9451 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9452 (label_ref (match_operand 1 "" ""))]
9455 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9458 (define_insn "load_toc_v4_PIC_1b_normal"
9459 [(set (reg:SI LR_REGNO)
9460 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9461 (label_ref (match_operand 1 "" ""))]
9464 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9465 "bcl 20,31,$+8\;.long %0-$"
9466 [(set_attr "type" "branch")
9467 (set_attr "length" "8")])
9469 (define_insn "load_toc_v4_PIC_1b_476"
9470 [(set (reg:SI LR_REGNO)
9471 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9472 (label_ref (match_operand 1 "" ""))]
9475 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9479 static char templ[32];
9481 get_ppc476_thunk_name (name);
9482 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9485 [(set_attr "type" "branch")
9486 (set_attr "length" "16")])
9488 (define_insn "load_toc_v4_PIC_2"
9489 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9490 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9491 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9492 (match_operand:SI 3 "immediate_operand" "s")))))]
9493 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9495 [(set_attr "type" "load")])
9497 (define_insn "load_toc_v4_PIC_3b"
9498 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9499 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9501 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9502 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9503 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9504 "addis %0,%1,%2-%3@ha")
9506 (define_insn "load_toc_v4_PIC_3c"
9507 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9508 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9509 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9510 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9511 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9512 "addi %0,%1,%2-%3@l")
9514 ;; If the TOC is shared over a translation unit, as happens with all
9515 ;; the kinds of PIC that we support, we need to restore the TOC
9516 ;; pointer only when jumping over units of translation.
9517 ;; On Darwin, we need to reload the picbase.
9519 (define_expand "builtin_setjmp_receiver"
9520 [(use (label_ref (match_operand 0 "" "")))]
9521 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9522 || (TARGET_TOC && TARGET_MINIMAL_TOC)
9523 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9527 if (DEFAULT_ABI == ABI_DARWIN)
9529 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9530 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9534 crtl->uses_pic_offset_table = 1;
9535 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9536 CODE_LABEL_NUMBER (operands[0]));
9537 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9539 emit_insn (gen_load_macho_picbase (tmplabrtx));
9540 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9541 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9545 rs6000_emit_load_toc_table (FALSE);
9550 (define_insn "*largetoc_high"
9551 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9553 (unspec [(match_operand:DI 1 "" "")
9554 (match_operand:DI 2 "gpc_reg_operand" "b")]
9556 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9557 "addis %0,%2,%1@toc@ha")
9559 (define_insn "*largetoc_high_aix<mode>"
9560 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9562 (unspec [(match_operand:P 1 "" "")
9563 (match_operand:P 2 "gpc_reg_operand" "b")]
9565 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9566 "addis %0,%1@u(%2)")
9568 (define_insn "*largetoc_high_plus"
9569 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9572 (unspec [(match_operand:DI 1 "" "")
9573 (match_operand:DI 2 "gpc_reg_operand" "b")]
9575 (match_operand:DI 3 "add_cint_operand" "n"))))]
9576 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9577 "addis %0,%2,%1+%3@toc@ha")
9579 (define_insn "*largetoc_high_plus_aix<mode>"
9580 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9583 (unspec [(match_operand:P 1 "" "")
9584 (match_operand:P 2 "gpc_reg_operand" "b")]
9586 (match_operand:P 3 "add_cint_operand" "n"))))]
9587 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9588 "addis %0,%1+%3@u(%2)")
9590 (define_insn "*largetoc_low"
9591 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9592 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9593 (match_operand:DI 2 "" "")))]
9594 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9597 (define_insn "*largetoc_low_aix<mode>"
9598 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9599 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9600 (match_operand:P 2 "" "")))]
9601 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9604 (define_insn_and_split "*tocref<mode>"
9605 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9606 (match_operand:P 1 "small_toc_ref" "R"))]
9609 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
9610 [(set (match_dup 0) (high:P (match_dup 1)))
9611 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
9613 ;; Elf specific ways of loading addresses for non-PIC code.
9614 ;; The output of this could be r0, but we make a very strong
9615 ;; preference for a base register because it will usually
9617 (define_insn "elf_high"
9618 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
9619 (high:SI (match_operand 1 "" "")))]
9620 "TARGET_ELF && ! TARGET_64BIT"
9623 (define_insn "elf_low"
9624 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9625 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9626 (match_operand 2 "" "")))]
9627 "TARGET_ELF && ! TARGET_64BIT"
9630 ;; Call and call_value insns
9631 (define_expand "call"
9632 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
9633 (match_operand 1 "" ""))
9634 (use (match_operand 2 "" ""))
9635 (clobber (reg:SI LR_REGNO))])]
9640 if (MACHOPIC_INDIRECT)
9641 operands[0] = machopic_indirect_call_target (operands[0]);
9644 gcc_assert (GET_CODE (operands[0]) == MEM);
9645 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
9647 operands[0] = XEXP (operands[0], 0);
9649 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9651 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
9655 if (GET_CODE (operands[0]) != SYMBOL_REF
9656 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
9658 if (INTVAL (operands[2]) & CALL_LONG)
9659 operands[0] = rs6000_longcall_ref (operands[0]);
9661 switch (DEFAULT_ABI)
9665 operands[0] = force_reg (Pmode, operands[0]);
9674 (define_expand "call_value"
9675 [(parallel [(set (match_operand 0 "" "")
9676 (call (mem:SI (match_operand 1 "address_operand" ""))
9677 (match_operand 2 "" "")))
9678 (use (match_operand 3 "" ""))
9679 (clobber (reg:SI LR_REGNO))])]
9684 if (MACHOPIC_INDIRECT)
9685 operands[1] = machopic_indirect_call_target (operands[1]);
9688 gcc_assert (GET_CODE (operands[1]) == MEM);
9689 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
9691 operands[1] = XEXP (operands[1], 0);
9693 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9695 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
9699 if (GET_CODE (operands[1]) != SYMBOL_REF
9700 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
9702 if (INTVAL (operands[3]) & CALL_LONG)
9703 operands[1] = rs6000_longcall_ref (operands[1]);
9705 switch (DEFAULT_ABI)
9709 operands[1] = force_reg (Pmode, operands[1]);
9718 ;; Call to function in current module. No TOC pointer reload needed.
9719 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
9720 ;; either the function was not prototyped, or it was prototyped as a
9721 ;; variable argument function. It is > 0 if FP registers were passed
9722 ;; and < 0 if they were not.
9724 (define_insn "*call_local32"
9725 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
9726 (match_operand 1 "" "g,g"))
9727 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9728 (clobber (reg:SI LR_REGNO))]
9729 "(INTVAL (operands[2]) & CALL_LONG) == 0"
9732 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9733 output_asm_insn (\"crxor 6,6,6\", operands);
9735 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9736 output_asm_insn (\"creqv 6,6,6\", operands);
9738 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9740 [(set_attr "type" "branch")
9741 (set_attr "length" "4,8")])
9743 (define_insn "*call_local64"
9744 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
9745 (match_operand 1 "" "g,g"))
9746 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9747 (clobber (reg:SI LR_REGNO))]
9748 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
9751 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9752 output_asm_insn (\"crxor 6,6,6\", operands);
9754 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9755 output_asm_insn (\"creqv 6,6,6\", operands);
9757 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9759 [(set_attr "type" "branch")
9760 (set_attr "length" "4,8")])
9762 (define_insn "*call_value_local32"
9763 [(set (match_operand 0 "" "")
9764 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
9765 (match_operand 2 "" "g,g")))
9766 (use (match_operand:SI 3 "immediate_operand" "O,n"))
9767 (clobber (reg:SI LR_REGNO))]
9768 "(INTVAL (operands[3]) & CALL_LONG) == 0"
9771 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9772 output_asm_insn (\"crxor 6,6,6\", operands);
9774 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9775 output_asm_insn (\"creqv 6,6,6\", operands);
9777 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9779 [(set_attr "type" "branch")
9780 (set_attr "length" "4,8")])
9783 (define_insn "*call_value_local64"
9784 [(set (match_operand 0 "" "")
9785 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
9786 (match_operand 2 "" "g,g")))
9787 (use (match_operand:SI 3 "immediate_operand" "O,n"))
9788 (clobber (reg:SI LR_REGNO))]
9789 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
9792 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9793 output_asm_insn (\"crxor 6,6,6\", operands);
9795 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9796 output_asm_insn (\"creqv 6,6,6\", operands);
9798 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9800 [(set_attr "type" "branch")
9801 (set_attr "length" "4,8")])
9804 ;; A function pointer under System V is just a normal pointer
9805 ;; operands[0] is the function pointer
9806 ;; operands[1] is the stack size to clean up
9807 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
9808 ;; which indicates how to set cr1
9810 (define_insn "*call_indirect_nonlocal_sysv<mode>"
9811 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
9812 (match_operand 1 "" "g,g,g,g"))
9813 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
9814 (clobber (reg:SI LR_REGNO))]
9815 "DEFAULT_ABI == ABI_V4
9816 || DEFAULT_ABI == ABI_DARWIN"
9818 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9819 output_asm_insn ("crxor 6,6,6", operands);
9821 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9822 output_asm_insn ("creqv 6,6,6", operands);
9826 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
9827 (set_attr "length" "4,4,8,8")])
9829 (define_insn_and_split "*call_nonlocal_sysv<mode>"
9830 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9831 (match_operand 1 "" "g,g"))
9832 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9833 (clobber (reg:SI LR_REGNO))]
9834 "(DEFAULT_ABI == ABI_DARWIN
9835 || (DEFAULT_ABI == ABI_V4
9836 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
9838 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9839 output_asm_insn ("crxor 6,6,6", operands);
9841 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9842 output_asm_insn ("creqv 6,6,6", operands);
9845 return output_call(insn, operands, 0, 2);
9847 if (DEFAULT_ABI == ABI_V4 && flag_pic)
9849 gcc_assert (!TARGET_SECURE_PLT);
9850 return "bl %z0@plt";
9856 "DEFAULT_ABI == ABI_V4
9857 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9858 && (INTVAL (operands[2]) & CALL_LONG) == 0"
9859 [(parallel [(call (mem:SI (match_dup 0))
9863 (clobber (reg:SI LR_REGNO))])]
9865 operands[3] = pic_offset_table_rtx;
9867 [(set_attr "type" "branch,branch")
9868 (set_attr "length" "4,8")])
9870 (define_insn "*call_nonlocal_sysv_secure<mode>"
9871 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9872 (match_operand 1 "" "g,g"))
9873 (use (match_operand:SI 2 "immediate_operand" "O,n"))
9874 (use (match_operand:SI 3 "register_operand" "r,r"))
9875 (clobber (reg:SI LR_REGNO))]
9876 "(DEFAULT_ABI == ABI_V4
9877 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9878 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
9880 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9881 output_asm_insn ("crxor 6,6,6", operands);
9883 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9884 output_asm_insn ("creqv 6,6,6", operands);
9887 /* The magic 32768 offset here and in the other sysv call insns
9888 corresponds to the offset of r30 in .got2, as given by LCTOC1.
9889 See sysv4.h:toc_section. */
9890 return "bl %z0+32768@plt";
9892 return "bl %z0@plt";
9894 [(set_attr "type" "branch,branch")
9895 (set_attr "length" "4,8")])
9897 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
9898 [(set (match_operand 0 "" "")
9899 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
9900 (match_operand 2 "" "g,g,g,g")))
9901 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
9902 (clobber (reg:SI LR_REGNO))]
9903 "DEFAULT_ABI == ABI_V4
9904 || DEFAULT_ABI == ABI_DARWIN"
9906 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9907 output_asm_insn ("crxor 6,6,6", operands);
9909 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9910 output_asm_insn ("creqv 6,6,6", operands);
9914 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
9915 (set_attr "length" "4,4,8,8")])
9917 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
9918 [(set (match_operand 0 "" "")
9919 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
9920 (match_operand 2 "" "g,g")))
9921 (use (match_operand:SI 3 "immediate_operand" "O,n"))
9922 (clobber (reg:SI LR_REGNO))]
9923 "(DEFAULT_ABI == ABI_DARWIN
9924 || (DEFAULT_ABI == ABI_V4
9925 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
9927 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9928 output_asm_insn ("crxor 6,6,6", operands);
9930 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9931 output_asm_insn ("creqv 6,6,6", operands);
9934 return output_call(insn, operands, 1, 3);
9936 if (DEFAULT_ABI == ABI_V4 && flag_pic)
9938 gcc_assert (!TARGET_SECURE_PLT);
9939 return "bl %z1@plt";
9945 "DEFAULT_ABI == ABI_V4
9946 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
9947 && (INTVAL (operands[3]) & CALL_LONG) == 0"
9948 [(parallel [(set (match_dup 0)
9949 (call (mem:SI (match_dup 1))
9953 (clobber (reg:SI LR_REGNO))])]
9955 operands[4] = pic_offset_table_rtx;
9957 [(set_attr "type" "branch,branch")
9958 (set_attr "length" "4,8")])
9960 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
9961 [(set (match_operand 0 "" "")
9962 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
9963 (match_operand 2 "" "g,g")))
9964 (use (match_operand:SI 3 "immediate_operand" "O,n"))
9965 (use (match_operand:SI 4 "register_operand" "r,r"))
9966 (clobber (reg:SI LR_REGNO))]
9967 "(DEFAULT_ABI == ABI_V4
9968 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
9969 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
9971 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9972 output_asm_insn ("crxor 6,6,6", operands);
9974 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9975 output_asm_insn ("creqv 6,6,6", operands);
9978 return "bl %z1+32768@plt";
9980 return "bl %z1@plt";
9982 [(set_attr "type" "branch,branch")
9983 (set_attr "length" "4,8")])
9986 ;; Call to AIX abi function in the same module.
9988 (define_insn "*call_local_aix<mode>"
9989 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
9990 (match_operand 1 "" "g"))
9991 (clobber (reg:P LR_REGNO))]
9992 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
9994 [(set_attr "type" "branch")
9995 (set_attr "length" "4")])
9997 (define_insn "*call_value_local_aix<mode>"
9998 [(set (match_operand 0 "" "")
9999 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10000 (match_operand 2 "" "g")))
10001 (clobber (reg:P LR_REGNO))]
10002 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10004 [(set_attr "type" "branch")
10005 (set_attr "length" "4")])
10007 ;; Call to AIX abi function which may be in another module.
10008 ;; Restore the TOC pointer (r2) after the call.
10010 (define_insn "*call_nonlocal_aix<mode>"
10011 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10012 (match_operand 1 "" "g"))
10013 (clobber (reg:P LR_REGNO))]
10014 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10016 [(set_attr "type" "branch")
10017 (set_attr "length" "8")])
10019 (define_insn "*call_value_nonlocal_aix<mode>"
10020 [(set (match_operand 0 "" "")
10021 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10022 (match_operand 2 "" "g")))
10023 (clobber (reg:P LR_REGNO))]
10024 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10026 [(set_attr "type" "branch")
10027 (set_attr "length" "8")])
10029 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10030 ;; Operand0 is the addresss of the function to call
10031 ;; Operand2 is the location in the function descriptor to load r2 from
10032 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10034 (define_insn "*call_indirect_aix<mode>"
10035 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10036 (match_operand 1 "" "g,g"))
10037 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10038 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10039 (clobber (reg:P LR_REGNO))]
10040 "DEFAULT_ABI == ABI_AIX"
10041 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10042 [(set_attr "type" "jmpreg")
10043 (set_attr "length" "12")])
10045 (define_insn "*call_value_indirect_aix<mode>"
10046 [(set (match_operand 0 "" "")
10047 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10048 (match_operand 2 "" "g,g")))
10049 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10050 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10051 (clobber (reg:P LR_REGNO))]
10052 "DEFAULT_ABI == ABI_AIX"
10053 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10054 [(set_attr "type" "jmpreg")
10055 (set_attr "length" "12")])
10057 ;; Call to indirect functions with the ELFv2 ABI.
10058 ;; Operand0 is the addresss of the function to call
10059 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10061 (define_insn "*call_indirect_elfv2<mode>"
10062 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10063 (match_operand 1 "" "g,g"))
10064 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10065 (clobber (reg:P LR_REGNO))]
10066 "DEFAULT_ABI == ABI_ELFv2"
10067 "b%T0l\;<ptrload> 2,%2(1)"
10068 [(set_attr "type" "jmpreg")
10069 (set_attr "length" "8")])
10071 (define_insn "*call_value_indirect_elfv2<mode>"
10072 [(set (match_operand 0 "" "")
10073 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10074 (match_operand 2 "" "g,g")))
10075 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10076 (clobber (reg:P LR_REGNO))]
10077 "DEFAULT_ABI == ABI_ELFv2"
10078 "b%T1l\;<ptrload> 2,%3(1)"
10079 [(set_attr "type" "jmpreg")
10080 (set_attr "length" "8")])
10083 ;; Call subroutine returning any type.
10084 (define_expand "untyped_call"
10085 [(parallel [(call (match_operand 0 "" "")
10087 (match_operand 1 "" "")
10088 (match_operand 2 "" "")])]
10094 emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx));
10096 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10098 rtx set = XVECEXP (operands[2], 0, i);
10099 emit_move_insn (SET_DEST (set), SET_SRC (set));
10102 /* The optimizer does not know that the call sets the function value
10103 registers we stored in the result block. We avoid problems by
10104 claiming that all hard registers are used and clobbered at this
10106 emit_insn (gen_blockage ());
10111 ;; sibling call patterns
10112 (define_expand "sibcall"
10113 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10114 (match_operand 1 "" ""))
10115 (use (match_operand 2 "" ""))
10116 (use (reg:SI LR_REGNO))
10122 if (MACHOPIC_INDIRECT)
10123 operands[0] = machopic_indirect_call_target (operands[0]);
10126 gcc_assert (GET_CODE (operands[0]) == MEM);
10127 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10129 operands[0] = XEXP (operands[0], 0);
10131 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10133 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10138 (define_expand "sibcall_value"
10139 [(parallel [(set (match_operand 0 "register_operand" "")
10140 (call (mem:SI (match_operand 1 "address_operand" ""))
10141 (match_operand 2 "" "")))
10142 (use (match_operand 3 "" ""))
10143 (use (reg:SI LR_REGNO))
10149 if (MACHOPIC_INDIRECT)
10150 operands[1] = machopic_indirect_call_target (operands[1]);
10153 gcc_assert (GET_CODE (operands[1]) == MEM);
10154 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10156 operands[1] = XEXP (operands[1], 0);
10158 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10160 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10165 ;; this and similar patterns must be marked as using LR, otherwise
10166 ;; dataflow will try to delete the store into it. This is true
10167 ;; even when the actual reg to jump to is in CTR, when LR was
10168 ;; saved and restored around the PIC-setting BCL.
10169 (define_insn "*sibcall_local32"
10170 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10171 (match_operand 1 "" "g,g"))
10172 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10173 (use (reg:SI LR_REGNO))
10175 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10178 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10179 output_asm_insn (\"crxor 6,6,6\", operands);
10181 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10182 output_asm_insn (\"creqv 6,6,6\", operands);
10184 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10186 [(set_attr "type" "branch")
10187 (set_attr "length" "4,8")])
10189 (define_insn "*sibcall_local64"
10190 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10191 (match_operand 1 "" "g,g"))
10192 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10193 (use (reg:SI LR_REGNO))
10195 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10198 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10199 output_asm_insn (\"crxor 6,6,6\", operands);
10201 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10202 output_asm_insn (\"creqv 6,6,6\", operands);
10204 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10206 [(set_attr "type" "branch")
10207 (set_attr "length" "4,8")])
10209 (define_insn "*sibcall_value_local32"
10210 [(set (match_operand 0 "" "")
10211 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10212 (match_operand 2 "" "g,g")))
10213 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10214 (use (reg:SI LR_REGNO))
10216 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10219 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10220 output_asm_insn (\"crxor 6,6,6\", operands);
10222 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10223 output_asm_insn (\"creqv 6,6,6\", operands);
10225 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10227 [(set_attr "type" "branch")
10228 (set_attr "length" "4,8")])
10230 (define_insn "*sibcall_value_local64"
10231 [(set (match_operand 0 "" "")
10232 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10233 (match_operand 2 "" "g,g")))
10234 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10235 (use (reg:SI LR_REGNO))
10237 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10240 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10241 output_asm_insn (\"crxor 6,6,6\", operands);
10243 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10244 output_asm_insn (\"creqv 6,6,6\", operands);
10246 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10248 [(set_attr "type" "branch")
10249 (set_attr "length" "4,8")])
10251 (define_insn "*sibcall_nonlocal_sysv<mode>"
10252 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10253 (match_operand 1 "" ""))
10254 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10255 (use (reg:SI LR_REGNO))
10257 "(DEFAULT_ABI == ABI_DARWIN
10258 || DEFAULT_ABI == ABI_V4)
10259 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10262 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10263 output_asm_insn (\"crxor 6,6,6\", operands);
10265 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10266 output_asm_insn (\"creqv 6,6,6\", operands);
10268 if (which_alternative >= 2)
10270 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10272 gcc_assert (!TARGET_SECURE_PLT);
10273 return \"b %z0@plt\";
10278 [(set_attr "type" "branch")
10279 (set_attr "length" "4,8,4,8")])
10281 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10282 [(set (match_operand 0 "" "")
10283 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10284 (match_operand 2 "" "")))
10285 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10286 (use (reg:SI LR_REGNO))
10288 "(DEFAULT_ABI == ABI_DARWIN
10289 || DEFAULT_ABI == ABI_V4)
10290 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10293 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10294 output_asm_insn (\"crxor 6,6,6\", operands);
10296 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10297 output_asm_insn (\"creqv 6,6,6\", operands);
10299 if (which_alternative >= 2)
10301 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10303 gcc_assert (!TARGET_SECURE_PLT);
10304 return \"b %z1@plt\";
10309 [(set_attr "type" "branch")
10310 (set_attr "length" "4,8,4,8")])
10312 ;; AIX ABI sibling call patterns.
10314 (define_insn "*sibcall_aix<mode>"
10315 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10316 (match_operand 1 "" "g,g"))
10318 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10322 [(set_attr "type" "branch")
10323 (set_attr "length" "4")])
10325 (define_insn "*sibcall_value_aix<mode>"
10326 [(set (match_operand 0 "" "")
10327 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10328 (match_operand 2 "" "g,g")))
10330 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10334 [(set_attr "type" "branch")
10335 (set_attr "length" "4")])
10337 (define_expand "sibcall_epilogue"
10338 [(use (const_int 0))]
10341 if (!TARGET_SCHED_PROLOG)
10342 emit_insn (gen_blockage ());
10343 rs6000_emit_epilogue (TRUE);
10347 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10348 ;; all of memory. This blocks insns from being moved across this point.
10350 (define_insn "blockage"
10351 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10355 (define_expand "probe_stack_address"
10356 [(use (match_operand 0 "address_operand"))]
10359 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10360 MEM_VOLATILE_P (operands[0]) = 1;
10363 emit_insn (gen_probe_stack_di (operands[0]));
10365 emit_insn (gen_probe_stack_si (operands[0]));
10369 (define_insn "probe_stack_<mode>"
10370 [(set (match_operand:P 0 "memory_operand" "=m")
10371 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10374 operands[1] = gen_rtx_REG (Pmode, 0);
10375 return "st<wd>%U0%X0 %1,%0";
10377 [(set_attr "type" "store")
10378 (set (attr "update")
10379 (if_then_else (match_operand 0 "update_address_mem")
10380 (const_string "yes")
10381 (const_string "no")))
10382 (set (attr "indexed")
10383 (if_then_else (match_operand 0 "indexed_address_mem")
10384 (const_string "yes")
10385 (const_string "no")))
10386 (set_attr "length" "4")])
10388 (define_insn "probe_stack_range<P:mode>"
10389 [(set (match_operand:P 0 "register_operand" "=r")
10390 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10391 (match_operand:P 2 "register_operand" "r")]
10392 UNSPECV_PROBE_STACK_RANGE))]
10394 "* return output_probe_stack_range (operands[0], operands[2]);"
10395 [(set_attr "type" "three")])
10397 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
10398 ;; signed & unsigned, and one type of branch.
10400 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10401 ;; insns, and branches.
10403 (define_expand "cbranch<mode>4"
10404 [(use (match_operator 0 "rs6000_cbranch_operator"
10405 [(match_operand:GPR 1 "gpc_reg_operand" "")
10406 (match_operand:GPR 2 "reg_or_short_operand" "")]))
10407 (use (match_operand 3 ""))]
10411 /* Take care of the possibility that operands[2] might be negative but
10412 this might be a logical operation. That insn doesn't exist. */
10413 if (GET_CODE (operands[2]) == CONST_INT
10414 && INTVAL (operands[2]) < 0)
10416 operands[2] = force_reg (<MODE>mode, operands[2]);
10417 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10418 GET_MODE (operands[0]),
10419 operands[1], operands[2]);
10422 rs6000_emit_cbranch (<MODE>mode, operands);
10426 (define_expand "cbranch<mode>4"
10427 [(use (match_operator 0 "rs6000_cbranch_operator"
10428 [(match_operand:FP 1 "gpc_reg_operand" "")
10429 (match_operand:FP 2 "gpc_reg_operand" "")]))
10430 (use (match_operand 3 ""))]
10434 rs6000_emit_cbranch (<MODE>mode, operands);
10438 (define_expand "cstore<mode>4_unsigned"
10439 [(use (match_operator 1 "unsigned_comparison_operator"
10440 [(match_operand:P 2 "gpc_reg_operand" "")
10441 (match_operand:P 3 "reg_or_short_operand" "")]))
10442 (clobber (match_operand:P 0 "register_operand"))]
10445 enum rtx_code cond_code = GET_CODE (operands[1]);
10447 rtx op0 = operands[0];
10448 rtx op1 = operands[2];
10449 rtx op2 = operands[3];
10451 if (cond_code == GEU || cond_code == LTU)
10453 cond_code = swap_condition (cond_code);
10458 if (!gpc_reg_operand (op1, <MODE>mode))
10459 op1 = force_reg (<MODE>mode, op1);
10460 if (!reg_or_short_operand (op2, <MODE>mode))
10461 op2 = force_reg (<MODE>mode, op2);
10463 rtx tmp = gen_reg_rtx (<MODE>mode);
10464 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10466 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10467 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10469 if (cond_code == LEU)
10470 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10472 emit_insn (gen_neg<mode>2 (op0, tmp2));
10477 (define_expand "cstore<mode>4_signed_imm"
10478 [(use (match_operator 1 "signed_comparison_operator"
10479 [(match_operand:GPR 2 "gpc_reg_operand")
10480 (match_operand:GPR 3 "immediate_operand")]))
10481 (clobber (match_operand:GPR 0 "register_operand"))]
10484 bool invert = false;
10486 enum rtx_code cond_code = GET_CODE (operands[1]);
10488 rtx op0 = operands[0];
10489 rtx op1 = operands[2];
10490 HOST_WIDE_INT val = INTVAL (operands[3]);
10492 if (cond_code == GE || cond_code == GT)
10494 cond_code = reverse_condition (cond_code);
10498 if (cond_code == LE)
10501 rtx tmp = gen_reg_rtx (<MODE>mode);
10502 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10503 rtx x = gen_reg_rtx (<MODE>mode);
10505 emit_insn (gen_and<mode>3 (x, op1, tmp));
10507 emit_insn (gen_ior<mode>3 (x, op1, tmp));
10511 rtx tmp = gen_reg_rtx (<MODE>mode);
10512 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10516 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10517 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10522 (define_expand "cstore<mode>4_unsigned_imm"
10523 [(use (match_operator 1 "unsigned_comparison_operator"
10524 [(match_operand:GPR 2 "gpc_reg_operand")
10525 (match_operand:GPR 3 "immediate_operand")]))
10526 (clobber (match_operand:GPR 0 "register_operand"))]
10529 bool invert = false;
10531 enum rtx_code cond_code = GET_CODE (operands[1]);
10533 rtx op0 = operands[0];
10534 rtx op1 = operands[2];
10535 HOST_WIDE_INT val = INTVAL (operands[3]);
10537 if (cond_code == GEU || cond_code == GTU)
10539 cond_code = reverse_condition (cond_code);
10543 if (cond_code == LEU)
10546 rtx tmp = gen_reg_rtx (<MODE>mode);
10547 rtx tmp2 = gen_reg_rtx (<MODE>mode);
10548 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10549 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
10550 rtx x = gen_reg_rtx (<MODE>mode);
10552 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
10554 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
10558 rtx tmp = gen_reg_rtx (<MODE>mode);
10559 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10563 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10564 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10569 (define_expand "cstore<mode>4"
10570 [(use (match_operator 1 "rs6000_cbranch_operator"
10571 [(match_operand:GPR 2 "gpc_reg_operand")
10572 (match_operand:GPR 3 "reg_or_short_operand")]))
10573 (clobber (match_operand:GPR 0 "register_operand"))]
10576 /* Use ISEL if the user asked for it. */
10578 rs6000_emit_sISEL (<MODE>mode, operands);
10580 /* Expanding EQ and NE directly to some machine instructions does not help
10581 but does hurt combine. So don't. */
10582 else if (GET_CODE (operands[1]) == EQ)
10583 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
10584 else if (<MODE>mode == Pmode
10585 && GET_CODE (operands[1]) == NE)
10586 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
10587 else if (GET_CODE (operands[1]) == NE)
10589 rtx tmp = gen_reg_rtx (<MODE>mode);
10590 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
10591 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
10594 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
10595 etc. combinations magically work out just right. */
10596 else if (<MODE>mode == Pmode
10597 && unsigned_comparison_operator (operands[1], VOIDmode))
10598 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
10599 operands[2], operands[3]));
10601 /* For signed comparisons against a constant, we can do some simple
10603 else if (signed_comparison_operator (operands[1], VOIDmode)
10604 && CONST_INT_P (operands[3]))
10605 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
10606 operands[2], operands[3]));
10608 /* And similarly for unsigned comparisons. */
10609 else if (unsigned_comparison_operator (operands[1], VOIDmode)
10610 && CONST_INT_P (operands[3]))
10611 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
10612 operands[2], operands[3]));
10614 /* Everything else, use the mfcr brute force. */
10616 rs6000_emit_sCOND (<MODE>mode, operands);
10621 (define_expand "cstore<mode>4"
10622 [(use (match_operator 1 "rs6000_cbranch_operator"
10623 [(match_operand:FP 2 "gpc_reg_operand" "")
10624 (match_operand:FP 3 "gpc_reg_operand" "")]))
10625 (clobber (match_operand:SI 0 "register_operand"))]
10628 rs6000_emit_sCOND (<MODE>mode, operands);
10633 (define_expand "stack_protect_set"
10634 [(match_operand 0 "memory_operand" "")
10635 (match_operand 1 "memory_operand" "")]
10638 #ifdef TARGET_THREAD_SSP_OFFSET
10639 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10640 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10641 operands[1] = gen_rtx_MEM (Pmode, addr);
10644 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10646 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10650 (define_insn "stack_protect_setsi"
10651 [(set (match_operand:SI 0 "memory_operand" "=m")
10652 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
10653 (set (match_scratch:SI 2 "=&r") (const_int 0))]
10655 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
10656 [(set_attr "type" "three")
10657 (set_attr "length" "12")])
10659 (define_insn "stack_protect_setdi"
10660 [(set (match_operand:DI 0 "memory_operand" "=Y")
10661 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
10662 (set (match_scratch:DI 2 "=&r") (const_int 0))]
10664 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
10665 [(set_attr "type" "three")
10666 (set_attr "length" "12")])
10668 (define_expand "stack_protect_test"
10669 [(match_operand 0 "memory_operand" "")
10670 (match_operand 1 "memory_operand" "")
10671 (match_operand 2 "" "")]
10674 rtx test, op0, op1;
10675 #ifdef TARGET_THREAD_SSP_OFFSET
10676 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10677 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10678 operands[1] = gen_rtx_MEM (Pmode, addr);
10681 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
10682 test = gen_rtx_EQ (VOIDmode, op0, op1);
10683 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
10687 (define_insn "stack_protect_testsi"
10688 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10689 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
10690 (match_operand:SI 2 "memory_operand" "m,m")]
10692 (set (match_scratch:SI 4 "=r,r") (const_int 0))
10693 (clobber (match_scratch:SI 3 "=&r,&r"))]
10696 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10697 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
10698 [(set_attr "length" "16,20")])
10700 (define_insn "stack_protect_testdi"
10701 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10702 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
10703 (match_operand:DI 2 "memory_operand" "Y,Y")]
10705 (set (match_scratch:DI 4 "=r,r") (const_int 0))
10706 (clobber (match_scratch:DI 3 "=&r,&r"))]
10709 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10710 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
10711 [(set_attr "length" "16,20")])
10714 ;; Here are the actual compare insns.
10715 (define_insn "*cmp<mode>_internal1"
10716 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
10717 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
10718 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
10720 "cmp<wd>%I2 %0,%1,%2"
10721 [(set_attr "type" "cmp")])
10723 ;; If we are comparing a register for equality with a large constant,
10724 ;; we can do this with an XOR followed by a compare. But this is profitable
10725 ;; only if the large constant is only used for the comparison (and in this
10726 ;; case we already have a register to reuse as scratch).
10728 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
10729 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
10732 [(set (match_operand:SI 0 "register_operand")
10733 (match_operand:SI 1 "logical_const_operand" ""))
10734 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
10736 (match_operand:SI 2 "logical_const_operand" "")]))
10737 (set (match_operand:CC 4 "cc_reg_operand" "")
10738 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
10741 (if_then_else (match_operator 6 "equality_operator"
10742 [(match_dup 4) (const_int 0)])
10743 (match_operand 7 "" "")
10744 (match_operand 8 "" "")))]
10745 "peep2_reg_dead_p (3, operands[0])
10746 && peep2_reg_dead_p (4, operands[4])
10747 && REGNO (operands[0]) != REGNO (operands[5])"
10748 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
10749 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
10750 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
10753 /* Get the constant we are comparing against, and see what it looks like
10754 when sign-extended from 16 to 32 bits. Then see what constant we could
10755 XOR with SEXTC to get the sign-extended value. */
10756 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
10758 operands[1], operands[2]);
10759 HOST_WIDE_INT c = INTVAL (cnst);
10760 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
10761 HOST_WIDE_INT xorv = c ^ sextc;
10763 operands[9] = GEN_INT (xorv);
10764 operands[10] = GEN_INT (sextc);
10767 (define_insn "*cmpsi_internal2"
10768 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
10769 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
10770 (match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
10772 "cmplw%I2 %0,%1,%b2"
10773 [(set_attr "type" "cmp")])
10775 (define_insn "*cmpdi_internal2"
10776 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
10777 (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
10778 (match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
10780 "cmpld%I2 %0,%1,%b2"
10781 [(set_attr "type" "cmp")])
10783 ;; The following two insns don't exist as single insns, but if we provide
10784 ;; them, we can swap an add and compare, which will enable us to overlap more
10785 ;; of the required delay between a compare and branch. We generate code for
10786 ;; them by splitting.
10789 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
10790 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
10791 (match_operand:SI 2 "short_cint_operand" "i")))
10792 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10793 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10796 [(set_attr "length" "8")])
10799 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
10800 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
10801 (match_operand:SI 2 "u_short_cint_operand" "i")))
10802 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10803 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10806 [(set_attr "length" "8")])
10809 [(set (match_operand:CC 3 "cc_reg_operand" "")
10810 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
10811 (match_operand:SI 2 "short_cint_operand" "")))
10812 (set (match_operand:SI 0 "gpc_reg_operand" "")
10813 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
10815 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
10816 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
10819 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
10820 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
10821 (match_operand:SI 2 "u_short_cint_operand" "")))
10822 (set (match_operand:SI 0 "gpc_reg_operand" "")
10823 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
10825 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
10826 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
10828 ;; Only need to compare second words if first words equal
10829 (define_insn "*cmptf_internal1"
10830 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
10831 (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
10832 (match_operand:TF 2 "gpc_reg_operand" "d")))]
10833 "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
10834 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
10835 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
10836 [(set_attr "type" "fpcompare")
10837 (set_attr "length" "12")])
10839 (define_insn_and_split "*cmptf_internal2"
10840 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
10841 (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
10842 (match_operand:TF 2 "gpc_reg_operand" "d")))
10843 (clobber (match_scratch:DF 3 "=d"))
10844 (clobber (match_scratch:DF 4 "=d"))
10845 (clobber (match_scratch:DF 5 "=d"))
10846 (clobber (match_scratch:DF 6 "=d"))
10847 (clobber (match_scratch:DF 7 "=d"))
10848 (clobber (match_scratch:DF 8 "=d"))
10849 (clobber (match_scratch:DF 9 "=d"))
10850 (clobber (match_scratch:DF 10 "=d"))
10851 (clobber (match_scratch:GPR 11 "=b"))]
10852 "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
10853 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
10855 "&& reload_completed"
10856 [(set (match_dup 3) (match_dup 14))
10857 (set (match_dup 4) (match_dup 15))
10858 (set (match_dup 9) (abs:DF (match_dup 5)))
10859 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
10860 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
10861 (label_ref (match_dup 12))
10863 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
10864 (set (pc) (label_ref (match_dup 13)))
10866 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
10867 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
10868 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
10869 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
10872 REAL_VALUE_TYPE rv;
10873 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
10874 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
10876 operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
10877 operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
10878 operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word);
10879 operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word);
10880 operands[12] = gen_label_rtx ();
10881 operands[13] = gen_label_rtx ();
10883 operands[14] = force_const_mem (DFmode,
10884 CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode));
10885 operands[15] = force_const_mem (DFmode,
10886 CONST_DOUBLE_FROM_REAL_VALUE (dconst0,
10891 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
10892 operands[14] = gen_const_mem (DFmode, tocref);
10893 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
10894 operands[15] = gen_const_mem (DFmode, tocref);
10895 set_mem_alias_set (operands[14], get_TOC_alias_set ());
10896 set_mem_alias_set (operands[15], get_TOC_alias_set ());
10900 ;; Now we have the scc insns. We can do some combinations because of the
10901 ;; way the machine works.
10903 ;; Note that this is probably faster if we can put an insn between the
10904 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
10905 ;; cases the insns below which don't use an intermediate CR field will
10906 ;; be used instead.
10908 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10909 (match_operator:SI 1 "scc_comparison_operator"
10910 [(match_operand 2 "cc_reg_operand" "y")
10913 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
10914 [(set (attr "type")
10915 (cond [(match_test "TARGET_MFCRF")
10916 (const_string "mfcrf")
10918 (const_string "mfcr")))
10919 (set_attr "length" "8")])
10921 ;; Same as above, but get the GT bit.
10922 (define_insn "move_from_CR_gt_bit"
10923 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10924 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
10925 "TARGET_HARD_FLOAT && !TARGET_FPRS"
10926 "mfcr %0\;rlwinm %0,%0,%D1,31,31"
10927 [(set_attr "type" "mfcr")
10928 (set_attr "length" "8")])
10930 ;; Same as above, but get the OV/ORDERED bit.
10931 (define_insn "move_from_CR_ov_bit"
10932 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10933 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
10936 "mfcr %0\;rlwinm %0,%0,%t1,1"
10937 [(set_attr "type" "mfcr")
10938 (set_attr "length" "8")])
10941 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10942 (match_operator:DI 1 "scc_comparison_operator"
10943 [(match_operand 2 "cc_reg_operand" "y")
10946 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
10947 [(set (attr "type")
10948 (cond [(match_test "TARGET_MFCRF")
10949 (const_string "mfcrf")
10951 (const_string "mfcr")))
10952 (set_attr "length" "8")])
10955 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
10956 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
10957 [(match_operand 2 "cc_reg_operand" "y,y")
10960 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
10961 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10964 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
10966 [(set_attr "type" "shift")
10967 (set_attr "dot" "yes")
10968 (set_attr "length" "8,16")])
10971 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
10972 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
10973 [(match_operand 2 "cc_reg_operand" "")
10976 (set (match_operand:SI 3 "gpc_reg_operand" "")
10977 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10978 "TARGET_32BIT && reload_completed"
10979 [(set (match_dup 3)
10980 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
10982 (compare:CC (match_dup 3)
10987 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10988 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
10989 [(match_operand 2 "cc_reg_operand" "y")
10991 (match_operand:SI 3 "const_int_operand" "n")))]
10995 int is_bit = ccr_bit (operands[1], 1);
10996 int put_bit = 31 - (INTVAL (operands[3]) & 31);
10999 if (is_bit >= put_bit)
11000 count = is_bit - put_bit;
11002 count = 32 - (put_bit - is_bit);
11004 operands[4] = GEN_INT (count);
11005 operands[5] = GEN_INT (put_bit);
11007 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11009 [(set (attr "type")
11010 (cond [(match_test "TARGET_MFCRF")
11011 (const_string "mfcrf")
11013 (const_string "mfcr")))
11014 (set_attr "length" "8")])
11017 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11019 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11020 [(match_operand 2 "cc_reg_operand" "y,y")
11022 (match_operand:SI 3 "const_int_operand" "n,n"))
11024 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11025 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11030 int is_bit = ccr_bit (operands[1], 1);
11031 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11034 /* Force split for non-cc0 compare. */
11035 if (which_alternative == 1)
11038 if (is_bit >= put_bit)
11039 count = is_bit - put_bit;
11041 count = 32 - (put_bit - is_bit);
11043 operands[5] = GEN_INT (count);
11044 operands[6] = GEN_INT (put_bit);
11046 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11048 [(set_attr "type" "shift")
11049 (set_attr "dot" "yes")
11050 (set_attr "length" "8,16")])
11053 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11055 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11056 [(match_operand 2 "cc_reg_operand" "")
11058 (match_operand:SI 3 "const_int_operand" ""))
11060 (set (match_operand:SI 4 "gpc_reg_operand" "")
11061 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11064 [(set (match_dup 4)
11065 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11068 (compare:CC (match_dup 4)
11072 ;; There is a 3 cycle delay between consecutive mfcr instructions
11073 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
11076 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11077 (match_operator:SI 1 "scc_comparison_operator"
11078 [(match_operand 2 "cc_reg_operand" "y")
11080 (set (match_operand:SI 3 "gpc_reg_operand" "=r")
11081 (match_operator:SI 4 "scc_comparison_operator"
11082 [(match_operand 5 "cc_reg_operand" "y")
11084 "REGNO (operands[2]) != REGNO (operands[5])"
11085 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11086 [(set_attr "type" "mfcr")
11087 (set_attr "length" "12")])
11090 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11091 (match_operator:DI 1 "scc_comparison_operator"
11092 [(match_operand 2 "cc_reg_operand" "y")
11094 (set (match_operand:DI 3 "gpc_reg_operand" "=r")
11095 (match_operator:DI 4 "scc_comparison_operator"
11096 [(match_operand 5 "cc_reg_operand" "y")
11098 "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11099 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11100 [(set_attr "type" "mfcr")
11101 (set_attr "length" "12")])
11104 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11107 (define_insn_and_split "eq<mode>3"
11108 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11109 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11110 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11111 (clobber (match_scratch:GPR 3 "=r"))
11112 (clobber (match_scratch:GPR 4 "=r"))]
11116 [(set (match_dup 4)
11117 (clz:GPR (match_dup 3)))
11119 (lshiftrt:GPR (match_dup 4)
11122 operands[3] = rs6000_emit_eqne (<MODE>mode,
11123 operands[1], operands[2], operands[3]);
11125 if (GET_CODE (operands[4]) == SCRATCH)
11126 operands[4] = gen_reg_rtx (<MODE>mode);
11128 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11130 [(set (attr "length")
11131 (if_then_else (match_test "operands[2] == const0_rtx")
11133 (const_string "12")))])
11135 (define_insn_and_split "ne<mode>3"
11136 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11137 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11138 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11139 (clobber (match_scratch:P 3 "=r"))
11140 (clobber (match_scratch:P 4 "=r"))
11141 (clobber (reg:P CA_REGNO))]
11145 [(parallel [(set (match_dup 4)
11146 (plus:P (match_dup 3)
11148 (set (reg:P CA_REGNO)
11149 (ne:P (match_dup 3)
11151 (parallel [(set (match_dup 0)
11152 (plus:P (plus:P (not:P (match_dup 4))
11155 (clobber (reg:P CA_REGNO))])]
11157 operands[3] = rs6000_emit_eqne (<MODE>mode,
11158 operands[1], operands[2], operands[3]);
11160 if (GET_CODE (operands[4]) == SCRATCH)
11161 operands[4] = gen_reg_rtx (<MODE>mode);
11163 [(set (attr "length")
11164 (if_then_else (match_test "operands[2] == const0_rtx")
11166 (const_string "12")))])
11168 (define_insn_and_split "*neg_eq_<mode>"
11169 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11170 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11171 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11172 (clobber (match_scratch:P 3 "=r"))
11173 (clobber (match_scratch:P 4 "=r"))
11174 (clobber (reg:P CA_REGNO))]
11178 [(parallel [(set (match_dup 4)
11179 (plus:P (match_dup 3)
11181 (set (reg:P CA_REGNO)
11182 (ne:P (match_dup 3)
11184 (parallel [(set (match_dup 0)
11185 (plus:P (reg:P CA_REGNO)
11187 (clobber (reg:P CA_REGNO))])]
11189 operands[3] = rs6000_emit_eqne (<MODE>mode,
11190 operands[1], operands[2], operands[3]);
11192 if (GET_CODE (operands[4]) == SCRATCH)
11193 operands[4] = gen_reg_rtx (<MODE>mode);
11195 [(set (attr "length")
11196 (if_then_else (match_test "operands[2] == const0_rtx")
11198 (const_string "12")))])
11200 (define_insn_and_split "*neg_ne_<mode>"
11201 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11202 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11203 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11204 (clobber (match_scratch:P 3 "=r"))
11205 (clobber (match_scratch:P 4 "=r"))
11206 (clobber (reg:P CA_REGNO))]
11210 [(parallel [(set (match_dup 4)
11211 (neg:P (match_dup 3)))
11212 (set (reg:P CA_REGNO)
11213 (eq:P (match_dup 3)
11215 (parallel [(set (match_dup 0)
11216 (plus:P (reg:P CA_REGNO)
11218 (clobber (reg:P CA_REGNO))])]
11220 operands[3] = rs6000_emit_eqne (<MODE>mode,
11221 operands[1], operands[2], operands[3]);
11223 if (GET_CODE (operands[4]) == SCRATCH)
11224 operands[4] = gen_reg_rtx (<MODE>mode);
11226 [(set (attr "length")
11227 (if_then_else (match_test "operands[2] == const0_rtx")
11229 (const_string "12")))])
11231 (define_insn_and_split "*plus_eq_<mode>"
11232 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11233 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11234 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11235 (match_operand:P 3 "gpc_reg_operand" "r")))
11236 (clobber (match_scratch:P 4 "=r"))
11237 (clobber (match_scratch:P 5 "=r"))
11238 (clobber (reg:P CA_REGNO))]
11242 [(parallel [(set (match_dup 5)
11243 (neg:P (match_dup 4)))
11244 (set (reg:P CA_REGNO)
11245 (eq:P (match_dup 4)
11247 (parallel [(set (match_dup 0)
11248 (plus:P (match_dup 3)
11250 (clobber (reg:P CA_REGNO))])]
11252 operands[4] = rs6000_emit_eqne (<MODE>mode,
11253 operands[1], operands[2], operands[4]);
11255 if (GET_CODE (operands[5]) == SCRATCH)
11256 operands[5] = gen_reg_rtx (<MODE>mode);
11258 [(set (attr "length")
11259 (if_then_else (match_test "operands[2] == const0_rtx")
11261 (const_string "12")))])
11263 (define_insn_and_split "*plus_ne_<mode>"
11264 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11265 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11266 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11267 (match_operand:P 3 "gpc_reg_operand" "r")))
11268 (clobber (match_scratch:P 4 "=r"))
11269 (clobber (match_scratch:P 5 "=r"))
11270 (clobber (reg:P CA_REGNO))]
11274 [(parallel [(set (match_dup 5)
11275 (plus:P (match_dup 4)
11277 (set (reg:P CA_REGNO)
11278 (ne:P (match_dup 4)
11280 (parallel [(set (match_dup 0)
11281 (plus:P (match_dup 3)
11283 (clobber (reg:P CA_REGNO))])]
11285 operands[4] = rs6000_emit_eqne (<MODE>mode,
11286 operands[1], operands[2], operands[4]);
11288 if (GET_CODE (operands[5]) == SCRATCH)
11289 operands[5] = gen_reg_rtx (<MODE>mode);
11291 [(set (attr "length")
11292 (if_then_else (match_test "operands[2] == const0_rtx")
11294 (const_string "12")))])
11296 (define_insn_and_split "*minus_eq_<mode>"
11297 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11298 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11299 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11300 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11301 (clobber (match_scratch:P 4 "=r"))
11302 (clobber (match_scratch:P 5 "=r"))
11303 (clobber (reg:P CA_REGNO))]
11307 [(parallel [(set (match_dup 5)
11308 (plus:P (match_dup 4)
11310 (set (reg:P CA_REGNO)
11311 (ne:P (match_dup 4)
11313 (parallel [(set (match_dup 0)
11314 (plus:P (plus:P (match_dup 3)
11317 (clobber (reg:P CA_REGNO))])]
11319 operands[4] = rs6000_emit_eqne (<MODE>mode,
11320 operands[1], operands[2], operands[4]);
11322 if (GET_CODE (operands[5]) == SCRATCH)
11323 operands[5] = gen_reg_rtx (<MODE>mode);
11325 [(set (attr "length")
11326 (if_then_else (match_test "operands[2] == const0_rtx")
11328 (const_string "12")))])
11330 (define_insn_and_split "*minus_ne_<mode>"
11331 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11332 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11333 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11334 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11335 (clobber (match_scratch:P 4 "=r"))
11336 (clobber (match_scratch:P 5 "=r"))
11337 (clobber (reg:P CA_REGNO))]
11341 [(parallel [(set (match_dup 5)
11342 (neg:P (match_dup 4)))
11343 (set (reg:P CA_REGNO)
11344 (eq:P (match_dup 4)
11346 (parallel [(set (match_dup 0)
11347 (plus:P (plus:P (match_dup 3)
11350 (clobber (reg:P CA_REGNO))])]
11352 operands[4] = rs6000_emit_eqne (<MODE>mode,
11353 operands[1], operands[2], operands[4]);
11355 if (GET_CODE (operands[5]) == SCRATCH)
11356 operands[5] = gen_reg_rtx (<MODE>mode);
11358 [(set (attr "length")
11359 (if_then_else (match_test "operands[2] == const0_rtx")
11361 (const_string "12")))])
11363 (define_insn_and_split "*eqsi3_ext<mode>"
11364 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11365 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11366 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11367 (clobber (match_scratch:SI 3 "=r"))
11368 (clobber (match_scratch:SI 4 "=r"))]
11372 [(set (match_dup 4)
11373 (clz:SI (match_dup 3)))
11376 (lshiftrt:SI (match_dup 4)
11379 operands[3] = rs6000_emit_eqne (SImode,
11380 operands[1], operands[2], operands[3]);
11382 if (GET_CODE (operands[4]) == SCRATCH)
11383 operands[4] = gen_reg_rtx (SImode);
11385 [(set (attr "length")
11386 (if_then_else (match_test "operands[2] == const0_rtx")
11388 (const_string "12")))])
11390 (define_insn_and_split "*nesi3_ext<mode>"
11391 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11392 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11393 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11394 (clobber (match_scratch:SI 3 "=r"))
11395 (clobber (match_scratch:SI 4 "=r"))
11396 (clobber (match_scratch:EXTSI 5 "=r"))]
11400 [(set (match_dup 4)
11401 (clz:SI (match_dup 3)))
11404 (lshiftrt:SI (match_dup 4)
11407 (xor:EXTSI (match_dup 5)
11410 operands[3] = rs6000_emit_eqne (SImode,
11411 operands[1], operands[2], operands[3]);
11413 if (GET_CODE (operands[4]) == SCRATCH)
11414 operands[4] = gen_reg_rtx (SImode);
11415 if (GET_CODE (operands[5]) == SCRATCH)
11416 operands[5] = gen_reg_rtx (<MODE>mode);
11418 [(set (attr "length")
11419 (if_then_else (match_test "operands[2] == const0_rtx")
11420 (const_string "12")
11421 (const_string "16")))])
11423 ;; Define both directions of branch and return. If we need a reload
11424 ;; register, we'd rather use CR0 since it is much easier to copy a
11425 ;; register CC value to there.
11429 (if_then_else (match_operator 1 "branch_comparison_operator"
11431 "cc_reg_operand" "y")
11433 (label_ref (match_operand 0 "" ""))
11438 return output_cbranch (operands[1], \"%l0\", 0, insn);
11440 [(set_attr "type" "branch")])
11444 (if_then_else (match_operator 0 "branch_comparison_operator"
11446 "cc_reg_operand" "y")
11453 return output_cbranch (operands[0], NULL, 0, insn);
11455 [(set_attr "type" "jmpreg")
11456 (set_attr "length" "4")])
11460 (if_then_else (match_operator 1 "branch_comparison_operator"
11462 "cc_reg_operand" "y")
11465 (label_ref (match_operand 0 "" ""))))]
11469 return output_cbranch (operands[1], \"%l0\", 1, insn);
11471 [(set_attr "type" "branch")])
11475 (if_then_else (match_operator 0 "branch_comparison_operator"
11477 "cc_reg_operand" "y")
11484 return output_cbranch (operands[0], NULL, 1, insn);
11486 [(set_attr "type" "jmpreg")
11487 (set_attr "length" "4")])
11489 ;; Logic on condition register values.
11491 ; This pattern matches things like
11492 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11493 ; (eq:SI (reg:CCFP 68) (const_int 0)))
11495 ; which are generated by the branch logic.
11496 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11498 (define_insn "*cceq_ior_compare"
11499 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11500 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11501 [(match_operator:SI 2
11502 "branch_positive_comparison_operator"
11504 "cc_reg_operand" "y,y")
11506 (match_operator:SI 4
11507 "branch_positive_comparison_operator"
11509 "cc_reg_operand" "0,y")
11513 "cr%q1 %E0,%j2,%j4"
11514 [(set_attr "type" "cr_logical,delayed_cr")])
11516 ; Why is the constant -1 here, but 1 in the previous pattern?
11517 ; Because ~1 has all but the low bit set.
11519 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11520 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11521 [(not:SI (match_operator:SI 2
11522 "branch_positive_comparison_operator"
11524 "cc_reg_operand" "y,y")
11526 (match_operator:SI 4
11527 "branch_positive_comparison_operator"
11529 "cc_reg_operand" "0,y")
11533 "cr%q1 %E0,%j2,%j4"
11534 [(set_attr "type" "cr_logical,delayed_cr")])
11536 (define_insn "*cceq_rev_compare"
11537 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11538 (compare:CCEQ (match_operator:SI 1
11539 "branch_positive_comparison_operator"
11541 "cc_reg_operand" "0,y")
11546 [(set_attr "type" "cr_logical,delayed_cr")])
11548 ;; If we are comparing the result of two comparisons, this can be done
11549 ;; using creqv or crxor.
11551 (define_insn_and_split ""
11552 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
11553 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
11554 [(match_operand 2 "cc_reg_operand" "y")
11556 (match_operator 3 "branch_comparison_operator"
11557 [(match_operand 4 "cc_reg_operand" "y")
11562 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
11566 int positive_1, positive_2;
11568 positive_1 = branch_positive_comparison_operator (operands[1],
11569 GET_MODE (operands[1]));
11570 positive_2 = branch_positive_comparison_operator (operands[3],
11571 GET_MODE (operands[3]));
11574 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
11575 GET_CODE (operands[1])),
11577 operands[2], const0_rtx);
11578 else if (GET_MODE (operands[1]) != SImode)
11579 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
11580 operands[2], const0_rtx);
11583 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
11584 GET_CODE (operands[3])),
11586 operands[4], const0_rtx);
11587 else if (GET_MODE (operands[3]) != SImode)
11588 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
11589 operands[4], const0_rtx);
11591 if (positive_1 == positive_2)
11593 operands[1] = gen_rtx_NOT (SImode, operands[1]);
11594 operands[5] = constm1_rtx;
11598 operands[5] = const1_rtx;
11602 ;; Unconditional branch and return.
11604 (define_insn "jump"
11606 (label_ref (match_operand 0 "" "")))]
11609 [(set_attr "type" "branch")])
11611 (define_insn "<return_str>return"
11615 [(set_attr "type" "jmpreg")])
11617 (define_expand "indirect_jump"
11618 [(set (pc) (match_operand 0 "register_operand" ""))])
11620 (define_insn "*indirect_jump<mode>"
11621 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
11626 [(set_attr "type" "jmpreg")])
11628 ;; Table jump for switch statements:
11629 (define_expand "tablejump"
11630 [(use (match_operand 0 "" ""))
11631 (use (label_ref (match_operand 1 "" "")))]
11636 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
11638 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
11642 (define_expand "tablejumpsi"
11643 [(set (match_dup 3)
11644 (plus:SI (match_operand:SI 0 "" "")
11646 (parallel [(set (pc) (match_dup 3))
11647 (use (label_ref (match_operand 1 "" "")))])]
11650 { operands[0] = force_reg (SImode, operands[0]);
11651 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
11652 operands[3] = gen_reg_rtx (SImode);
11655 (define_expand "tablejumpdi"
11656 [(set (match_dup 4)
11657 (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
11659 (plus:DI (match_dup 4)
11661 (parallel [(set (pc) (match_dup 3))
11662 (use (label_ref (match_operand 1 "" "")))])]
11665 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
11666 operands[3] = gen_reg_rtx (DImode);
11667 operands[4] = gen_reg_rtx (DImode);
11670 (define_insn "*tablejump<mode>_internal1"
11672 (match_operand:P 0 "register_operand" "c,*l"))
11673 (use (label_ref (match_operand 1 "" "")))]
11678 [(set_attr "type" "jmpreg")])
11681 [(unspec [(const_int 0)] UNSPEC_NOP)]
11685 (define_insn "group_ending_nop"
11686 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
11690 if (rs6000_cpu_attr == CPU_POWER6)
11691 return \"ori 1,1,0\";
11692 return \"ori 2,2,0\";
11695 ;; Define the subtract-one-and-jump insns, starting with the template
11696 ;; so loop.c knows what to generate.
11698 (define_expand "doloop_end"
11699 [(use (match_operand 0 "" "")) ; loop pseudo
11700 (use (match_operand 1 "" ""))] ; label
11706 if (GET_MODE (operands[0]) != DImode)
11708 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
11712 if (GET_MODE (operands[0]) != SImode)
11714 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
11719 (define_expand "ctr<mode>"
11720 [(parallel [(set (pc)
11721 (if_then_else (ne (match_operand:P 0 "register_operand" "")
11723 (label_ref (match_operand 1 "" ""))
11726 (plus:P (match_dup 0)
11728 (clobber (match_scratch:CC 2 ""))
11729 (clobber (match_scratch:P 3 ""))])]
11733 ;; We need to be able to do this for any operand, including MEM, or we
11734 ;; will cause reload to blow up since we don't allow output reloads on
11736 ;; For the length attribute to be calculated correctly, the
11737 ;; label MUST be operand 0.
11739 (define_insn "*ctr<mode>_internal1"
11741 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11743 (label_ref (match_operand 0 "" ""))
11745 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11746 (plus:P (match_dup 1)
11748 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11749 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11753 if (which_alternative != 0)
11755 else if (get_attr_length (insn) == 4)
11756 return \"bdnz %l0\";
11758 return \"bdz $+8\;b %l0\";
11760 [(set_attr "type" "branch")
11761 (set_attr "length" "*,16,20,20")])
11763 (define_insn "*ctr<mode>_internal2"
11765 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11768 (label_ref (match_operand 0 "" ""))))
11769 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11770 (plus:P (match_dup 1)
11772 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11773 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11777 if (which_alternative != 0)
11779 else if (get_attr_length (insn) == 4)
11780 return \"bdz %l0\";
11782 return \"bdnz $+8\;b %l0\";
11784 [(set_attr "type" "branch")
11785 (set_attr "length" "*,16,20,20")])
11787 ;; Similar but use EQ
11789 (define_insn "*ctr<mode>_internal5"
11791 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11793 (label_ref (match_operand 0 "" ""))
11795 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11796 (plus:P (match_dup 1)
11798 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11799 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11803 if (which_alternative != 0)
11805 else if (get_attr_length (insn) == 4)
11806 return \"bdz %l0\";
11808 return \"bdnz $+8\;b %l0\";
11810 [(set_attr "type" "branch")
11811 (set_attr "length" "*,16,20,20")])
11813 (define_insn "*ctr<mode>_internal6"
11815 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11818 (label_ref (match_operand 0 "" ""))))
11819 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11820 (plus:P (match_dup 1)
11822 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11823 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11827 if (which_alternative != 0)
11829 else if (get_attr_length (insn) == 4)
11830 return \"bdnz %l0\";
11832 return \"bdz $+8\;b %l0\";
11834 [(set_attr "type" "branch")
11835 (set_attr "length" "*,16,20,20")])
11837 ;; Now the splitters if we could not allocate the CTR register
11841 (if_then_else (match_operator 2 "comparison_operator"
11842 [(match_operand:P 1 "gpc_reg_operand" "")
11844 (match_operand 5 "" "")
11845 (match_operand 6 "" "")))
11846 (set (match_operand:P 0 "gpc_reg_operand" "")
11847 (plus:P (match_dup 1) (const_int -1)))
11848 (clobber (match_scratch:CC 3 ""))
11849 (clobber (match_scratch:P 4 ""))]
11851 [(set (match_dup 3)
11852 (compare:CC (match_dup 1)
11855 (plus:P (match_dup 1)
11857 (set (pc) (if_then_else (match_dup 7)
11861 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
11862 operands[3], const0_rtx); }")
11866 (if_then_else (match_operator 2 "comparison_operator"
11867 [(match_operand:P 1 "gpc_reg_operand" "")
11869 (match_operand 5 "" "")
11870 (match_operand 6 "" "")))
11871 (set (match_operand:P 0 "nonimmediate_operand" "")
11872 (plus:P (match_dup 1) (const_int -1)))
11873 (clobber (match_scratch:CC 3 ""))
11874 (clobber (match_scratch:P 4 ""))]
11875 "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
11876 [(set (match_dup 3)
11877 (compare:CC (match_dup 1)
11880 (plus:P (match_dup 1)
11884 (set (pc) (if_then_else (match_dup 7)
11888 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
11889 operands[3], const0_rtx); }")
11891 (define_insn "trap"
11892 [(trap_if (const_int 1) (const_int 0))]
11895 [(set_attr "type" "trap")])
11897 (define_expand "ctrap<mode>4"
11898 [(trap_if (match_operator 0 "ordered_comparison_operator"
11899 [(match_operand:GPR 1 "register_operand")
11900 (match_operand:GPR 2 "reg_or_short_operand")])
11901 (match_operand 3 "zero_constant" ""))]
11906 [(trap_if (match_operator 0 "ordered_comparison_operator"
11907 [(match_operand:GPR 1 "register_operand" "r")
11908 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
11911 "t<wd>%V0%I2 %1,%2"
11912 [(set_attr "type" "trap")])
11914 ;; Insns related to generating the function prologue and epilogue.
11916 (define_expand "prologue"
11917 [(use (const_int 0))]
11920 rs6000_emit_prologue ();
11921 if (!TARGET_SCHED_PROLOG)
11922 emit_insn (gen_blockage ());
11926 (define_insn "*movesi_from_cr_one"
11927 [(match_parallel 0 "mfcr_operation"
11928 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
11929 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
11930 (match_operand 3 "immediate_operand" "n")]
11931 UNSPEC_MOVESI_FROM_CR))])]
11937 for (i = 0; i < XVECLEN (operands[0], 0); i++)
11939 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
11940 operands[4] = GEN_INT (mask);
11941 output_asm_insn (\"mfcr %1,%4\", operands);
11945 [(set_attr "type" "mfcrf")])
11947 (define_insn "movesi_from_cr"
11948 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11949 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
11950 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
11951 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
11952 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
11953 UNSPEC_MOVESI_FROM_CR))]
11956 [(set_attr "type" "mfcr")])
11958 (define_insn "*crsave"
11959 [(match_parallel 0 "crsave_operation"
11960 [(set (match_operand:SI 1 "memory_operand" "=m")
11961 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
11964 [(set_attr "type" "store")])
11966 (define_insn "*stmw"
11967 [(match_parallel 0 "stmw_operation"
11968 [(set (match_operand:SI 1 "memory_operand" "=m")
11969 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
11972 [(set_attr "type" "store")
11973 (set_attr "update" "yes")
11974 (set_attr "indexed" "yes")])
11976 ; The following comment applies to:
11980 ; return_and_restore_gpregs*
11981 ; return_and_restore_fpregs*
11982 ; return_and_restore_fpregs_aix*
11984 ; The out-of-line save / restore functions expects one input argument.
11985 ; Since those are not standard call_insn's, we must avoid using
11986 ; MATCH_OPERAND for that argument. That way the register rename
11987 ; optimization will not try to rename this register.
11988 ; Each pattern is repeated for each possible register number used in
11989 ; various ABIs (r11, r1, and for some functions r12)
11991 (define_insn "*save_gpregs_<mode>_r11"
11992 [(match_parallel 0 "any_parallel_operand"
11993 [(clobber (reg:P 65))
11994 (use (match_operand:P 1 "symbol_ref_operand" "s"))
11996 (set (match_operand:P 2 "memory_operand" "=m")
11997 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12000 [(set_attr "type" "branch")
12001 (set_attr "length" "4")])
12003 (define_insn "*save_gpregs_<mode>_r12"
12004 [(match_parallel 0 "any_parallel_operand"
12005 [(clobber (reg:P 65))
12006 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12008 (set (match_operand:P 2 "memory_operand" "=m")
12009 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12012 [(set_attr "type" "branch")
12013 (set_attr "length" "4")])
12015 (define_insn "*save_gpregs_<mode>_r1"
12016 [(match_parallel 0 "any_parallel_operand"
12017 [(clobber (reg:P 65))
12018 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12020 (set (match_operand:P 2 "memory_operand" "=m")
12021 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12024 [(set_attr "type" "branch")
12025 (set_attr "length" "4")])
12027 (define_insn "*save_fpregs_<mode>_r11"
12028 [(match_parallel 0 "any_parallel_operand"
12029 [(clobber (reg:P 65))
12030 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12032 (set (match_operand:DF 2 "memory_operand" "=m")
12033 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12036 [(set_attr "type" "branch")
12037 (set_attr "length" "4")])
12039 (define_insn "*save_fpregs_<mode>_r12"
12040 [(match_parallel 0 "any_parallel_operand"
12041 [(clobber (reg:P 65))
12042 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12044 (set (match_operand:DF 2 "memory_operand" "=m")
12045 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12048 [(set_attr "type" "branch")
12049 (set_attr "length" "4")])
12051 (define_insn "*save_fpregs_<mode>_r1"
12052 [(match_parallel 0 "any_parallel_operand"
12053 [(clobber (reg:P 65))
12054 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12056 (set (match_operand:DF 2 "memory_operand" "=m")
12057 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12060 [(set_attr "type" "branch")
12061 (set_attr "length" "4")])
12063 ; This is to explain that changes to the stack pointer should
12064 ; not be moved over loads from or stores to stack memory.
12065 (define_insn "stack_tie"
12066 [(match_parallel 0 "tie_operand"
12067 [(set (mem:BLK (reg 1)) (const_int 0))])]
12070 [(set_attr "length" "0")])
12072 (define_expand "epilogue"
12073 [(use (const_int 0))]
12076 if (!TARGET_SCHED_PROLOG)
12077 emit_insn (gen_blockage ());
12078 rs6000_emit_epilogue (FALSE);
12082 ; On some processors, doing the mtcrf one CC register at a time is
12083 ; faster (like on the 604e). On others, doing them all at once is
12084 ; faster; for instance, on the 601 and 750.
12086 (define_expand "movsi_to_cr_one"
12087 [(set (match_operand:CC 0 "cc_reg_operand" "")
12088 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12089 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12091 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12093 (define_insn "*movsi_to_cr"
12094 [(match_parallel 0 "mtcrf_operation"
12095 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12096 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12097 (match_operand 3 "immediate_operand" "n")]
12098 UNSPEC_MOVESI_TO_CR))])]
12104 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12105 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12106 operands[4] = GEN_INT (mask);
12107 return \"mtcrf %4,%2\";
12109 [(set_attr "type" "mtcr")])
12111 (define_insn "*mtcrfsi"
12112 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12113 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12114 (match_operand 2 "immediate_operand" "n")]
12115 UNSPEC_MOVESI_TO_CR))]
12116 "GET_CODE (operands[0]) == REG
12117 && CR_REGNO_P (REGNO (operands[0]))
12118 && GET_CODE (operands[2]) == CONST_INT
12119 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12121 [(set_attr "type" "mtcr")])
12123 ; The load-multiple instructions have similar properties.
12124 ; Note that "load_multiple" is a name known to the machine-independent
12125 ; code that actually corresponds to the PowerPC load-string.
12127 (define_insn "*lmw"
12128 [(match_parallel 0 "lmw_operation"
12129 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12130 (match_operand:SI 2 "memory_operand" "m"))])]
12133 [(set_attr "type" "load")
12134 (set_attr "update" "yes")
12135 (set_attr "indexed" "yes")
12136 (set_attr "cell_micro" "always")])
12138 (define_insn "*return_internal_<mode>"
12140 (use (match_operand:P 0 "register_operand" "lc"))]
12143 [(set_attr "type" "jmpreg")])
12145 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12146 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
12148 ; The following comment applies to:
12152 ; return_and_restore_gpregs*
12153 ; return_and_restore_fpregs*
12154 ; return_and_restore_fpregs_aix*
12156 ; The out-of-line save / restore functions expects one input argument.
12157 ; Since those are not standard call_insn's, we must avoid using
12158 ; MATCH_OPERAND for that argument. That way the register rename
12159 ; optimization will not try to rename this register.
12160 ; Each pattern is repeated for each possible register number used in
12161 ; various ABIs (r11, r1, and for some functions r12)
12163 (define_insn "*restore_gpregs_<mode>_r11"
12164 [(match_parallel 0 "any_parallel_operand"
12165 [(clobber (match_operand:P 1 "register_operand" "=l"))
12166 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12168 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12169 (match_operand:P 4 "memory_operand" "m"))])]
12172 [(set_attr "type" "branch")
12173 (set_attr "length" "4")])
12175 (define_insn "*restore_gpregs_<mode>_r12"
12176 [(match_parallel 0 "any_parallel_operand"
12177 [(clobber (match_operand:P 1 "register_operand" "=l"))
12178 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12180 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12181 (match_operand:P 4 "memory_operand" "m"))])]
12184 [(set_attr "type" "branch")
12185 (set_attr "length" "4")])
12187 (define_insn "*restore_gpregs_<mode>_r1"
12188 [(match_parallel 0 "any_parallel_operand"
12189 [(clobber (match_operand:P 1 "register_operand" "=l"))
12190 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12192 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12193 (match_operand:P 4 "memory_operand" "m"))])]
12196 [(set_attr "type" "branch")
12197 (set_attr "length" "4")])
12199 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12200 [(match_parallel 0 "any_parallel_operand"
12202 (clobber (match_operand:P 1 "register_operand" "=l"))
12203 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12205 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12206 (match_operand:P 4 "memory_operand" "m"))])]
12209 [(set_attr "type" "branch")
12210 (set_attr "length" "4")])
12212 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12213 [(match_parallel 0 "any_parallel_operand"
12215 (clobber (match_operand:P 1 "register_operand" "=l"))
12216 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12218 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12219 (match_operand:P 4 "memory_operand" "m"))])]
12222 [(set_attr "type" "branch")
12223 (set_attr "length" "4")])
12225 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12226 [(match_parallel 0 "any_parallel_operand"
12228 (clobber (match_operand:P 1 "register_operand" "=l"))
12229 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12231 (set (match_operand:P 3 "gpc_reg_operand" "=r")
12232 (match_operand:P 4 "memory_operand" "m"))])]
12235 [(set_attr "type" "branch")
12236 (set_attr "length" "4")])
12238 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12239 [(match_parallel 0 "any_parallel_operand"
12241 (clobber (match_operand:P 1 "register_operand" "=l"))
12242 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12244 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12245 (match_operand:DF 4 "memory_operand" "m"))])]
12248 [(set_attr "type" "branch")
12249 (set_attr "length" "4")])
12251 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12252 [(match_parallel 0 "any_parallel_operand"
12254 (clobber (match_operand:P 1 "register_operand" "=l"))
12255 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12257 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12258 (match_operand:DF 4 "memory_operand" "m"))])]
12261 [(set_attr "type" "branch")
12262 (set_attr "length" "4")])
12264 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12265 [(match_parallel 0 "any_parallel_operand"
12267 (clobber (match_operand:P 1 "register_operand" "=l"))
12268 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12270 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12271 (match_operand:DF 4 "memory_operand" "m"))])]
12274 [(set_attr "type" "branch")
12275 (set_attr "length" "4")])
12277 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12278 [(match_parallel 0 "any_parallel_operand"
12280 (use (match_operand:P 1 "register_operand" "l"))
12281 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12283 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12284 (match_operand:DF 4 "memory_operand" "m"))])]
12287 [(set_attr "type" "branch")
12288 (set_attr "length" "4")])
12290 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12291 [(match_parallel 0 "any_parallel_operand"
12293 (use (match_operand:P 1 "register_operand" "l"))
12294 (use (match_operand:P 2 "symbol_ref_operand" "s"))
12296 (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12297 (match_operand:DF 4 "memory_operand" "m"))])]
12300 [(set_attr "type" "branch")
12301 (set_attr "length" "4")])
12303 ; This is used in compiling the unwind routines.
12304 (define_expand "eh_return"
12305 [(use (match_operand 0 "general_operand" ""))]
12310 emit_insn (gen_eh_set_lr_si (operands[0]));
12312 emit_insn (gen_eh_set_lr_di (operands[0]));
12316 ; We can't expand this before we know where the link register is stored.
12317 (define_insn "eh_set_lr_<mode>"
12318 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12320 (clobber (match_scratch:P 1 "=&b"))]
12325 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12326 (clobber (match_scratch 1 ""))]
12331 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12335 (define_insn "prefetch"
12336 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12337 (match_operand:SI 1 "const_int_operand" "n")
12338 (match_operand:SI 2 "const_int_operand" "n"))]
12342 if (GET_CODE (operands[0]) == REG)
12343 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12344 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12346 [(set_attr "type" "load")])
12348 (define_insn "bpermd_<mode>"
12349 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12350 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12351 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12354 [(set_attr "type" "popcnt")])
12357 ;; Builtin fma support. Handle
12358 ;; Note that the conditions for expansion are in the FMA_F iterator.
12360 (define_expand "fma<mode>4"
12361 [(set (match_operand:FMA_F 0 "register_operand" "")
12363 (match_operand:FMA_F 1 "register_operand" "")
12364 (match_operand:FMA_F 2 "register_operand" "")
12365 (match_operand:FMA_F 3 "register_operand" "")))]
12369 (define_insn "*fma<mode>4_fpr"
12370 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
12372 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>,<Fv>")
12373 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
12374 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))]
12375 "TARGET_<MODE>_FPR"
12377 fmadd<Ftrad> %0,%1,%2,%3
12378 xsmadda<Fvsx> %x0,%x1,%x2
12379 xsmaddm<Fvsx> %x0,%x1,%x3"
12380 [(set_attr "type" "fp")
12381 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12383 ; Altivec only has fma and nfms.
12384 (define_expand "fms<mode>4"
12385 [(set (match_operand:FMA_F 0 "register_operand" "")
12387 (match_operand:FMA_F 1 "register_operand" "")
12388 (match_operand:FMA_F 2 "register_operand" "")
12389 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12390 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12393 (define_insn "*fms<mode>4_fpr"
12394 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
12396 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
12397 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
12398 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
12399 "TARGET_<MODE>_FPR"
12401 fmsub<Ftrad> %0,%1,%2,%3
12402 xsmsuba<Fvsx> %x0,%x1,%x2
12403 xsmsubm<Fvsx> %x0,%x1,%x3"
12404 [(set_attr "type" "fp")
12405 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12407 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12408 (define_expand "fnma<mode>4"
12409 [(set (match_operand:FMA_F 0 "register_operand" "")
12412 (match_operand:FMA_F 1 "register_operand" "")
12413 (match_operand:FMA_F 2 "register_operand" "")
12414 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12415 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12418 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12419 (define_expand "fnms<mode>4"
12420 [(set (match_operand:FMA_F 0 "register_operand" "")
12423 (match_operand:FMA_F 1 "register_operand" "")
12424 (match_operand:FMA_F 2 "register_operand" "")
12425 (match_operand:FMA_F 3 "register_operand" ""))))]
12426 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12429 ; Not an official optab name, but used from builtins.
12430 (define_expand "nfma<mode>4"
12431 [(set (match_operand:FMA_F 0 "register_operand" "")
12434 (match_operand:FMA_F 1 "register_operand" "")
12435 (match_operand:FMA_F 2 "register_operand" "")
12436 (match_operand:FMA_F 3 "register_operand" ""))))]
12437 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12440 (define_insn "*nfma<mode>4_fpr"
12441 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
12444 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
12445 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
12446 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
12447 "TARGET_<MODE>_FPR"
12449 fnmadd<Ftrad> %0,%1,%2,%3
12450 xsnmadda<Fvsx> %x0,%x1,%x2
12451 xsnmaddm<Fvsx> %x0,%x1,%x3"
12452 [(set_attr "type" "fp")
12453 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12455 ; Not an official optab name, but used from builtins.
12456 (define_expand "nfms<mode>4"
12457 [(set (match_operand:FMA_F 0 "register_operand" "")
12460 (match_operand:FMA_F 1 "register_operand" "")
12461 (match_operand:FMA_F 2 "register_operand" "")
12462 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12466 (define_insn "*nfmssf4_fpr"
12467 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
12470 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
12471 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
12473 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))))]
12474 "TARGET_<MODE>_FPR"
12476 fnmsub<Ftrad> %0,%1,%2,%3
12477 xsnmsuba<Fvsx> %x0,%x1,%x2
12478 xsnmsubm<Fvsx> %x0,%x1,%x3"
12479 [(set_attr "type" "fp")
12480 (set_attr "fp_type" "fp_maddsub_<Fs>")])
12483 (define_expand "rs6000_get_timebase"
12484 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
12487 if (TARGET_POWERPC64)
12488 emit_insn (gen_rs6000_mftb_di (operands[0]));
12490 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
12494 (define_insn "rs6000_get_timebase_ppc32"
12495 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12496 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
12497 (clobber (match_scratch:SI 1 "=r"))
12498 (clobber (match_scratch:CC 2 "=y"))]
12499 "!TARGET_POWERPC64"
12501 if (WORDS_BIG_ENDIAN)
12504 return "mfspr %0,269\;"
12512 return "mftbu %0\;"
12521 return "mfspr %L0,269\;"
12529 return "mftbu %L0\;"
12536 [(set_attr "length" "20")])
12538 (define_insn "rs6000_mftb_<mode>"
12539 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12540 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
12544 return "mfspr %0,268";
12550 (define_insn "rs6000_mffs"
12551 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
12552 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
12553 "TARGET_HARD_FLOAT && TARGET_FPRS"
12556 (define_insn "rs6000_mtfsf"
12557 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
12558 (match_operand:DF 1 "gpc_reg_operand" "d")]
12560 "TARGET_HARD_FLOAT && TARGET_FPRS"
12564 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
12565 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
12566 ;; register that is being loaded. The fused ops must be physically adjacent.
12568 ;; Find cases where the addis that feeds into a load instruction is either used
12569 ;; once or is the same as the target register, and replace it with the fusion
12573 [(set (match_operand:P 0 "base_reg_operand" "")
12574 (match_operand:P 1 "fusion_gpr_addis" ""))
12575 (set (match_operand:INT1 2 "base_reg_operand" "")
12576 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
12578 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
12582 expand_fusion_gpr_load (operands);
12586 ;; Fusion insn, created by the define_peephole2 above (and eventually by
12589 (define_insn "fusion_gpr_load_<mode>"
12590 [(set (match_operand:INT1 0 "base_reg_operand" "=&b")
12591 (unspec:INT1 [(match_operand:INT1 1 "fusion_gpr_mem_combo" "")]
12592 UNSPEC_FUSION_GPR))]
12595 return emit_fusion_gpr_load (operands[0], operands[1]);
12597 [(set_attr "type" "load")
12598 (set_attr "length" "8")])
12601 ;; Miscellaneous ISA 2.06 (power7) instructions
12602 (define_insn "addg6s"
12603 [(set (match_operand:SI 0 "register_operand" "=r")
12604 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
12605 (match_operand:SI 2 "register_operand" "r")]
12609 [(set_attr "type" "integer")
12610 (set_attr "length" "4")])
12612 (define_insn "cdtbcd"
12613 [(set (match_operand:SI 0 "register_operand" "=r")
12614 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
12618 [(set_attr "type" "integer")
12619 (set_attr "length" "4")])
12621 (define_insn "cbcdtd"
12622 [(set (match_operand:SI 0 "register_operand" "=r")
12623 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
12627 [(set_attr "type" "integer")
12628 (set_attr "length" "4")])
12630 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
12635 (define_int_attr div_extend [(UNSPEC_DIVE "e")
12636 (UNSPEC_DIVEO "eo")
12637 (UNSPEC_DIVEU "eu")
12638 (UNSPEC_DIVEUO "euo")])
12640 (define_insn "div<div_extend>_<mode>"
12641 [(set (match_operand:GPR 0 "register_operand" "=r")
12642 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
12643 (match_operand:GPR 2 "register_operand" "r")]
12644 UNSPEC_DIV_EXTEND))]
12646 "div<wd><div_extend> %0,%1,%2"
12647 [(set_attr "type" "div")
12648 (set_attr "size" "<bits>")])
12651 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
12653 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
12654 (define_mode_attr FP128_64 [(TF "DF") (TD "DI")])
12656 (define_expand "unpack<mode>"
12657 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
12659 [(match_operand:FMOVE128 1 "register_operand" "")
12660 (match_operand:QI 2 "const_0_to_1_operand" "")]
12661 UNSPEC_UNPACK_128BIT))]
12665 (define_insn_and_split "unpack<mode>_dm"
12666 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
12668 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
12669 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
12670 UNSPEC_UNPACK_128BIT))]
12671 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
12673 "&& reload_completed"
12674 [(set (match_dup 0) (match_dup 3))]
12676 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
12678 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
12680 emit_note (NOTE_INSN_DELETED);
12684 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
12686 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
12687 (set_attr "length" "4")])
12689 (define_insn_and_split "unpack<mode>_nodm"
12690 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
12692 [(match_operand:FMOVE128 1 "register_operand" "d,d")
12693 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
12694 UNSPEC_UNPACK_128BIT))]
12695 "!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE"
12697 "&& reload_completed"
12698 [(set (match_dup 0) (match_dup 3))]
12700 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
12702 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
12704 emit_note (NOTE_INSN_DELETED);
12708 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
12710 [(set_attr "type" "fp,fpstore")
12711 (set_attr "length" "4")])
12713 (define_insn_and_split "pack<mode>"
12714 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
12716 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
12717 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
12718 UNSPEC_PACK_128BIT))]
12723 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
12724 [(set (match_dup 3) (match_dup 1))
12725 (set (match_dup 4) (match_dup 2))]
12727 unsigned dest_hi = REGNO (operands[0]);
12728 unsigned dest_lo = dest_hi + 1;
12730 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
12731 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
12733 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
12734 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
12736 [(set_attr "type" "fp,fp")
12737 (set_attr "length" "4,8")])
12739 (define_insn "unpackv1ti"
12740 [(set (match_operand:DI 0 "register_operand" "=d,d")
12741 (unspec:DI [(match_operand:V1TI 1 "register_operand" "0,wa")
12742 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
12743 UNSPEC_UNPACK_128BIT))]
12746 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
12747 return ASM_COMMENT_START " xxpermdi to same register";
12749 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
12750 return "xxpermdi %x0,%x1,%x1,%3";
12752 [(set_attr "type" "vecperm")
12753 (set_attr "length" "4")])
12755 (define_insn "packv1ti"
12756 [(set (match_operand:V1TI 0 "register_operand" "=wa")
12758 [(match_operand:DI 1 "register_operand" "d")
12759 (match_operand:DI 2 "register_operand" "d")]
12760 UNSPEC_PACK_128BIT))]
12762 "xxpermdi %x0,%x1,%x2,0"
12763 [(set_attr "type" "vecperm")
12764 (set_attr "length" "4")])
12768 (include "sync.md")
12769 (include "vector.md")
12771 (include "altivec.md")
12774 (include "paired.md")
12775 (include "crypto.md")