PR target/68609
[official-gcc.git] / gcc / config / rs6000 / rs6000.md
blobd8834a2731413b4d1726e0e3623b0438526f6db2
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2016 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.
24 ;; REGNOS
27 (define_constants
28   [(FIRST_GPR_REGNO             0)
29    (STACK_POINTER_REGNUM        1)
30    (TOC_REGNUM                  2)
31    (STATIC_CHAIN_REGNUM         11)
32    (HARD_FRAME_POINTER_REGNUM   31)
33    (LAST_GPR_REGNO              31)
34    (FIRST_FPR_REGNO             32)
35    (LAST_FPR_REGNO              63)
36    (LR_REGNO                    65)
37    (CTR_REGNO                   66)
38    (ARG_POINTER_REGNUM          67)
39    (CR0_REGNO                   68)
40    (CR1_REGNO                   69)
41    (CR2_REGNO                   70)
42    (CR3_REGNO                   71)
43    (CR4_REGNO                   72)
44    (CR5_REGNO                   73)
45    (CR6_REGNO                   74)
46    (CR7_REGNO                   75)
47    (MAX_CR_REGNO                75)
48    (CA_REGNO                    76)
49    (FIRST_ALTIVEC_REGNO         77)
50    (LAST_ALTIVEC_REGNO          108)
51    (VRSAVE_REGNO                109)
52    (VSCR_REGNO                  110)
53    (SPE_ACC_REGNO               111)
54    (SPEFSCR_REGNO               112)
55    (FRAME_POINTER_REGNUM        113)
56    (TFHAR_REGNO                 114)
57    (TFIAR_REGNO                 115)
58    (TEXASR_REGNO                116)
59    (FIRST_SPE_HIGH_REGNO        117)
60    (LAST_SPE_HIGH_REGNO         148)
61   ])
64 ;; UNSPEC usage
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
73    UNSPEC_MOVSI_GOT
74    UNSPEC_MV_CR_OV              ; move_from_CR_ov_bit
75    UNSPEC_FCTIWZ
76    UNSPEC_FRIM
77    UNSPEC_FRIN
78    UNSPEC_FRIP
79    UNSPEC_FRIZ
80    UNSPEC_XSRDPI
81    UNSPEC_LD_MPIC               ; load_macho_picbase
82    UNSPEC_RELD_MPIC             ; re-load_macho_picbase
83    UNSPEC_MPIC_CORRECT          ; macho_correct_pic
84    UNSPEC_TLSGD
85    UNSPEC_TLSLD
86    UNSPEC_MOVESI_FROM_CR
87    UNSPEC_MOVESI_TO_CR
88    UNSPEC_TLSDTPREL
89    UNSPEC_TLSDTPRELHA
90    UNSPEC_TLSDTPRELLO
91    UNSPEC_TLSGOTDTPREL
92    UNSPEC_TLSTPREL
93    UNSPEC_TLSTPRELHA
94    UNSPEC_TLSTPRELLO
95    UNSPEC_TLSGOTTPREL
96    UNSPEC_TLSTLS
97    UNSPEC_FIX_TRUNC_TF          ; fadd, rounding towards zero
98    UNSPEC_MV_CR_GT              ; move_from_CR_gt_bit
99    UNSPEC_STFIWX
100    UNSPEC_POPCNTB
101    UNSPEC_FRES
102    UNSPEC_SP_SET
103    UNSPEC_SP_TEST
104    UNSPEC_SYNC
105    UNSPEC_LWSYNC
106    UNSPEC_SYNC_OP
107    UNSPEC_ATOMIC
108    UNSPEC_CMPXCHG
109    UNSPEC_XCHG
110    UNSPEC_AND
111    UNSPEC_DLMZB
112    UNSPEC_DLMZB_CR
113    UNSPEC_DLMZB_STRLEN
114    UNSPEC_RSQRT
115    UNSPEC_TOCREL
116    UNSPEC_MACHOPIC_OFFSET
117    UNSPEC_BPERM
118    UNSPEC_COPYSIGN
119    UNSPEC_PARITY
120    UNSPEC_FCTIW
121    UNSPEC_FCTID
122    UNSPEC_LFIWAX
123    UNSPEC_LFIWZX
124    UNSPEC_FCTIWUZ
125    UNSPEC_NOP
126    UNSPEC_GRP_END_NOP
127    UNSPEC_P8V_FMRGOW
128    UNSPEC_P8V_MTVSRWZ
129    UNSPEC_P8V_RELOAD_FROM_GPR
130    UNSPEC_P8V_MTVSRD
131    UNSPEC_P8V_XXPERMDI
132    UNSPEC_P8V_RELOAD_FROM_VSX
133    UNSPEC_ADDG6S
134    UNSPEC_CDTBCD
135    UNSPEC_CBCDTD
136    UNSPEC_DIVE
137    UNSPEC_DIVEO
138    UNSPEC_DIVEU
139    UNSPEC_DIVEUO
140    UNSPEC_UNPACK_128BIT
141    UNSPEC_PACK_128BIT
142    UNSPEC_LSQ
143    UNSPEC_FUSION_GPR
144    UNSPEC_STACK_CHECK
145    UNSPEC_FUSION_P9
146    UNSPEC_FUSION_ADDIS
147    UNSPEC_ROUND_TO_ODD
148    UNSPEC_IEEE128_MOVE
149    UNSPEC_IEEE128_CONVERT
150   ])
153 ;; UNSPEC_VOLATILE usage
156 (define_c_enum "unspecv"
157   [UNSPECV_BLOCK
158    UNSPECV_LL                   ; load-locked
159    UNSPECV_SC                   ; store-conditional
160    UNSPECV_PROBE_STACK_RANGE    ; probe range of stack addresses
161    UNSPECV_EH_RR                ; eh_reg_restore
162    UNSPECV_ISYNC                ; isync instruction
163    UNSPECV_MFTB                 ; move from time base
164    UNSPECV_NLGR                 ; non-local goto receiver
165    UNSPECV_MFFS                 ; Move from FPSCR
166    UNSPECV_MTFSF                ; Move to FPSCR Fields
167    UNSPECV_SPLIT_STACK_RETURN   ; A camouflaged return
168   ])
171 ;; Define an insn type attribute.  This is used in function unit delay
172 ;; computations.
173 (define_attr "type"
174   "integer,two,three,
175    add,logical,shift,insert,
176    mul,halfmul,div,
177    exts,cntlz,popcnt,isel,
178    load,store,fpload,fpstore,vecload,vecstore,
179    cmp,
180    branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
181    cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
182    fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,
183    brinc,
184    vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
185    vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
186    htm"
187   (const_string "integer"))
189 ;; What data size does this instruction work on?
190 ;; This is used for insert, mul.
191 (define_attr "size" "8,16,32,64" (const_string "32"))
193 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
194 ;; This is used for add, logical, shift, exts, mul.
195 (define_attr "dot" "no,yes" (const_string "no"))
197 ;; Does this instruction sign-extend its result?
198 ;; This is used for load insns.
199 (define_attr "sign_extend" "no,yes" (const_string "no"))
201 ;; Does this instruction use indexed (that is, reg+reg) addressing?
202 ;; This is used for load and store insns.  If operand 0 or 1 is a MEM
203 ;; it is automatically set based on that.  If a load or store instruction
204 ;; has fewer than two operands it needs to set this attribute manually
205 ;; or the compiler will crash.
206 (define_attr "indexed" "no,yes"
207   (if_then_else (ior (match_operand 0 "indexed_address_mem")
208                      (match_operand 1 "indexed_address_mem"))
209                 (const_string "yes")
210                 (const_string "no")))
212 ;; Does this instruction use update addressing?
213 ;; This is used for load and store insns.  See the comments for "indexed".
214 (define_attr "update" "no,yes"
215   (if_then_else (ior (match_operand 0 "update_address_mem")
216                      (match_operand 1 "update_address_mem"))
217                 (const_string "yes")
218                 (const_string "no")))
220 ;; Is this instruction using operands[2] as shift amount, and can that be a
221 ;; register?
222 ;; This is used for shift insns.
223 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
225 ;; Is this instruction using a shift amount from a register?
226 ;; This is used for shift insns.
227 (define_attr "var_shift" "no,yes"
228   (if_then_else (and (eq_attr "type" "shift")
229                      (eq_attr "maybe_var_shift" "yes"))
230                 (if_then_else (match_operand 2 "gpc_reg_operand")
231                               (const_string "yes")
232                               (const_string "no"))
233                 (const_string "no")))
235 ;; Is copying of this instruction disallowed?
236 (define_attr "cannot_copy" "no,yes" (const_string "no"))
238 ;; Define floating point instruction sub-types for use with Xfpu.md
239 (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"))
241 ;; Length (in bytes).
242 ; '(pc)' in the following doesn't include the instruction itself; it is
243 ; calculated as if the instruction had zero size.
244 (define_attr "length" ""
245   (if_then_else (eq_attr "type" "branch")
246                 (if_then_else (and (ge (minus (match_dup 0) (pc))
247                                        (const_int -32768))
248                                    (lt (minus (match_dup 0) (pc))
249                                        (const_int 32764)))
250                               (const_int 4)
251                               (const_int 8))
252                 (const_int 4)))
254 ;; Processor type -- this attribute must exactly match the processor_type
255 ;; enumeration in rs6000-opts.h.
256 (define_attr "cpu"
257   "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
258    ppc750,ppc7400,ppc7450,
259    ppc403,ppc405,ppc440,ppc476,
260    ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
261    power4,power5,power6,power7,power8,power9,
262    rs64a,mpccore,cell,ppca2,titan"
263   (const (symbol_ref "rs6000_cpu_attr")))
266 ;; If this instruction is microcoded on the CELL processor
267 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
268 (define_attr "cell_micro" "not,conditional,always"
269   (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
270                           (eq_attr "dot" "yes"))
271                      (and (eq_attr "type" "load")
272                           (eq_attr "sign_extend" "yes"))
273                      (and (eq_attr "type" "shift")
274                           (eq_attr "var_shift" "yes")))
275                 (const_string "always")
276                 (const_string "not")))
278 (automata_option "ndfa")
280 (include "rs64.md")
281 (include "mpc.md")
282 (include "40x.md")
283 (include "440.md")
284 (include "476.md")
285 (include "601.md")
286 (include "603.md")
287 (include "6xx.md")
288 (include "7xx.md")
289 (include "7450.md")
290 (include "8540.md")
291 (include "e300c2c3.md")
292 (include "e500mc.md")
293 (include "e500mc64.md")
294 (include "e5500.md")
295 (include "e6500.md")
296 (include "power4.md")
297 (include "power5.md")
298 (include "power6.md")
299 (include "power7.md")
300 (include "power8.md")
301 (include "cell.md")
302 (include "xfpu.md")
303 (include "a2.md")
304 (include "titan.md")
306 (include "predicates.md")
307 (include "constraints.md")
309 (include "darwin.md")
312 ;; Mode iterators
314 ; This mode iterator allows :GPR to be used to indicate the allowable size
315 ; of whole values in GPRs.
316 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
318 ; Any supported integer mode.
319 (define_mode_iterator INT [QI HI SI DI TI PTI])
321 ; Any supported integer mode that fits in one register.
322 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
324 ; Everything we can extend QImode to.
325 (define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")])
327 ; Everything we can extend HImode to.
328 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
330 ; Everything we can extend SImode to.
331 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
333 ; QImode or HImode for small atomic ops
334 (define_mode_iterator QHI [QI HI])
336 ; QImode, HImode, SImode for fused ops only for GPR loads
337 (define_mode_iterator QHSI [QI HI SI])
339 ; HImode or SImode for sign extended fusion ops
340 (define_mode_iterator HSI [HI SI])
342 ; SImode or DImode, even if DImode doesn't fit in GPRs.
343 (define_mode_iterator SDI [SI DI])
345 ; Types that can be fused with an ADDIS instruction to load or store a GPR
346 ; register that has reg+offset addressing.
347 (define_mode_iterator GPR_FUSION [QI
348                                   HI
349                                   SI
350                                   (DI   "TARGET_POWERPC64")
351                                   SF
352                                   (DF   "TARGET_POWERPC64")])
354 ; Types that can be fused with an ADDIS instruction to load or store a FPR
355 ; register that has reg+offset addressing.
356 (define_mode_iterator FPR_FUSION [DI SF DF])
358 ; The size of a pointer.  Also, the size of the value that a record-condition
359 ; (one with a '.') will compare; and the size used for arithmetic carries.
360 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
362 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
363 ; PTImode is GPR only)
364 (define_mode_iterator TI2 [TI PTI])
366 ; Any hardware-supported floating-point mode
367 (define_mode_iterator FP [
368   (SF "TARGET_HARD_FLOAT 
369    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
370   (DF "TARGET_HARD_FLOAT 
371    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
372   (TF "TARGET_HARD_FLOAT
373    && (TARGET_FPRS || TARGET_E500_DOUBLE)
374    && TARGET_LONG_DOUBLE_128")
375   (IF "TARGET_FLOAT128")
376   (KF "TARGET_FLOAT128")
377   (DD "TARGET_DFP")
378   (TD "TARGET_DFP")])
380 ; Any fma capable floating-point mode.
381 (define_mode_iterator FMA_F [
382   (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
383   (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
384        || VECTOR_UNIT_VSX_P (DFmode)")
385   (V2SF "TARGET_PAIRED_FLOAT")
386   (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
387   (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
388   (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
389   (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
390   ])
392 ; Floating point move iterators to combine binary and decimal moves
393 (define_mode_iterator FMOVE32 [SF SD])
394 (define_mode_iterator FMOVE64 [DF DD])
395 (define_mode_iterator FMOVE64X [DI DF DD])
396 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
397                                 (IF "TARGET_LONG_DOUBLE_128")
398                                 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
400 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
401                                     (IF "FLOAT128_2REG_P (IFmode)")
402                                     (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
404 ; Iterators for 128 bit types for direct move
405 (define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
406                                     (V16QI "")
407                                     (V8HI  "")
408                                     (V4SI  "")
409                                     (V4SF  "")
410                                     (V2DI  "")
411                                     (V2DF  "")
412                                     (V1TI  "")
413                                     (KF    "FLOAT128_VECTOR_P (KFmode)")
414                                     (TF    "FLOAT128_VECTOR_P (TFmode)")])
416 ; Iterator for 128-bit VSX types for pack/unpack
417 (define_mode_iterator FMOVE128_VSX [V1TI KF])
419 ; Whether a floating point move is ok, don't allow SD without hardware FP
420 (define_mode_attr fmove_ok [(SF "")
421                             (DF "")
422                             (SD "TARGET_HARD_FLOAT && TARGET_FPRS")
423                             (DD "")])
425 ; Convert REAL_VALUE to the appropriate bits
426 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
427                                         (DF "REAL_VALUE_TO_TARGET_DOUBLE")
428                                         (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
429                                         (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
431 ; Definitions for load to 32-bit fpr register
432 (define_mode_attr f32_lr  [(SF "f")               (SD "wz")])
433 (define_mode_attr f32_lr2 [(SF "wb")              (SD "wn")])
434 (define_mode_attr f32_lm  [(SF "m")               (SD "Z")])
435 (define_mode_attr f32_lm2 [(SF "o")               (SD "wn")])
436 (define_mode_attr f32_li  [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
437 (define_mode_attr f32_li2 [(SF "lxssp %0,%1")     (SD "lfiwzx %0,%y1")])
438 (define_mode_attr f32_lv  [(SF "lxsspx %x0,%y1")  (SD "lxsiwzx %x0,%y1")])
440 ; Definitions for store from 32-bit fpr register
441 (define_mode_attr f32_sr  [(SF "f")                (SD "wx")])
442 (define_mode_attr f32_sr2 [(SF "wb")               (SD "wn")])
443 (define_mode_attr f32_sm  [(SF "m")                (SD "Z")])
444 (define_mode_attr f32_sm2 [(SF "o")                (SD "wn")])
445 (define_mode_attr f32_si  [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
446 (define_mode_attr f32_si2 [(SF "stxssp %1,%0")     (SD "stfiwx %1,%y0")])
447 (define_mode_attr f32_sv  [(SF "stxsspx %x1,%y0")  (SD "stxsiwzx %x1,%y0")])
449 ; Definitions for 32-bit fpr direct move
450 ; At present, the decimal modes are not allowed in the traditional altivec
451 ; registers, so restrict the constraints to just the traditional FPRs.
452 (define_mode_attr f32_dm [(SF "wn") (SD "wh")])
454 ; Definitions for 32-bit VSX
455 (define_mode_attr f32_vsx [(SF "ww") (SD "wn")])
457 ; Definitions for 32-bit use of altivec registers
458 (define_mode_attr f32_av  [(SF "wu") (SD "wn")])
460 ; Definitions for 64-bit VSX
461 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
463 ; Definitions for 64-bit direct move
464 (define_mode_attr f64_dm  [(DF "wk") (DD "wh")])
466 ; Definitions for 64-bit use of altivec registers
467 (define_mode_attr f64_av  [(DF "wv") (DD "wn")])
469 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
470 (define_mode_attr f64_p9  [(DF "wb") (DD "wn")])
472 ; These modes do not fit in integer registers in 32-bit mode.
473 ; but on e500v2, the gpr are 64 bit registers
474 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
476 ; Iterator for reciprocal estimate instructions
477 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
479 ; Iterator for just SF/DF
480 (define_mode_iterator SFDF [SF DF])
482 ; Iterator for 128-bit floating point that uses the IBM double-double format
483 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
484                               (TF "FLOAT128_IBM_P (TFmode)")])
486 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
487 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
488                                (TF "FLOAT128_IEEE_P (TFmode)")])
490 ; Iterator for 128-bit floating point
491 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
492                                 (IF "TARGET_FLOAT128")
493                                 (TF "TARGET_LONG_DOUBLE_128")])
495 ; SF/DF suffix for traditional floating instructions
496 (define_mode_attr Ftrad         [(SF "s") (DF "")])
498 ; SF/DF suffix for VSX instructions
499 (define_mode_attr Fvsx          [(SF "sp") (DF  "dp")])
501 ; SF/DF constraint for arithmetic on traditional floating point registers
502 (define_mode_attr Ff            [(SF "f") (DF "d") (DI "d")])
504 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
505 ; ISA 2.06 (power7).  This includes instructions that normally target DF mode,
506 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
507 ; format.
508 (define_mode_attr Fv            [(SF "ww") (DF "ws") (DI "wi")])
510 ; SF/DF constraint for arithmetic on VSX registers.  This is intended to be
511 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
512 ; instructions added in ISA 2.07 (power8)
513 (define_mode_attr Fv2           [(SF "wy") (DF "ws") (DI "wi")])
515 ; SF/DF constraint for arithmetic on altivec registers
516 (define_mode_attr Fa            [(SF "wu") (DF "wv")])
518 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
519 (define_mode_attr Fs            [(SF "s")  (DF "d")])
521 ; FRE/FRES support
522 (define_mode_attr Ffre          [(SF "fres") (DF "fre")])
523 (define_mode_attr FFRE          [(SF "FRES") (DF "FRE")])
525 ; Conditional returns.
526 (define_code_iterator any_return [return simple_return])
527 (define_code_attr return_pred [(return "direct_return ()")
528                                (simple_return "1")])
529 (define_code_attr return_str [(return "") (simple_return "simple_")])
531 ; Logical operators.
532 (define_code_iterator iorxor [ior xor])
534 ; Signed/unsigned variants of ops.
535 (define_code_iterator any_extend        [sign_extend zero_extend])
536 (define_code_iterator any_fix           [fix unsigned_fix])
537 (define_code_iterator any_float         [float unsigned_float])
539 (define_code_attr u  [(sign_extend      "")
540                       (zero_extend      "u")])
542 (define_code_attr su [(sign_extend      "s")
543                       (zero_extend      "u")
544                       (fix              "s")
545                       (unsigned_fix     "s")
546                       (float            "s")
547                       (unsigned_float   "u")])
549 (define_code_attr az [(sign_extend      "a")
550                       (zero_extend      "z")
551                       (fix              "a")
552                       (unsigned_fix     "z")
553                       (float            "a")
554                       (unsigned_float   "z")])
556 (define_code_attr uns [(fix             "")
557                        (unsigned_fix    "uns")
558                        (float           "")
559                        (unsigned_float  "uns")])
561 ; Various instructions that come in SI and DI forms.
562 ; A generic w/d attribute, for things like cmpw/cmpd.
563 (define_mode_attr wd [(QI    "b")
564                       (HI    "h")
565                       (SI    "w")
566                       (DI    "d")
567                       (V16QI "b")
568                       (V8HI  "h")
569                       (V4SI  "w")
570                       (V2DI  "d")])
572 ;; How many bits in this mode?
573 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
575 ; DImode bits
576 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
578 ;; ISEL/ISEL64 target selection
579 (define_mode_attr sel [(SI "") (DI "64")])
581 ;; Bitmask for shift instructions
582 (define_mode_attr hH [(SI "h") (DI "H")])
584 ;; A mode twice the size of the given mode
585 (define_mode_attr dmode [(SI "di") (DI "ti")])
586 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
588 ;; Suffix for reload patterns
589 (define_mode_attr ptrsize [(SI "32bit")
590                            (DI "64bit")])
592 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
593                             (DI "TARGET_64BIT")])
595 (define_mode_attr mptrsize [(SI "si")
596                             (DI "di")])
598 (define_mode_attr ptrload [(SI "lwz")
599                            (DI "ld")])
601 (define_mode_attr ptrm [(SI "m")
602                         (DI "Y")])
604 (define_mode_attr rreg [(SF   "f")
605                         (DF   "ws")
606                         (TF   "f")
607                         (TD   "f")
608                         (V4SF "wf")
609                         (V2DF "wd")])
611 (define_mode_attr rreg2 [(SF   "f")
612                          (DF   "d")])
614 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
615                                  (DF "TARGET_FCFID")])
617 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
618                                 (DF "TARGET_E500_DOUBLE")])
620 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
621                                 (DF "TARGET_DOUBLE_FLOAT")])
623 ;; Mode iterator for logical operations on 128-bit types
624 (define_mode_iterator BOOL_128          [TI
625                                          PTI
626                                          (V16QI "TARGET_ALTIVEC")
627                                          (V8HI  "TARGET_ALTIVEC")
628                                          (V4SI  "TARGET_ALTIVEC")
629                                          (V4SF  "TARGET_ALTIVEC")
630                                          (V2DI  "TARGET_ALTIVEC")
631                                          (V2DF  "TARGET_ALTIVEC")
632                                          (V1TI  "TARGET_ALTIVEC")])
634 ;; For the GPRs we use 3 constraints for register outputs, two that are the
635 ;; same as the output register, and a third where the output register is an
636 ;; early clobber, so we don't have to deal with register overlaps.  For the
637 ;; vector types, we prefer to use the vector registers.  For TI mode, allow
638 ;; either.
640 ;; Mode attribute for boolean operation register constraints for output
641 (define_mode_attr BOOL_REGS_OUTPUT      [(TI    "&r,r,r,wt,v")
642                                          (PTI   "&r,r,r")
643                                          (V16QI "wa,v,&?r,?r,?r")
644                                          (V8HI  "wa,v,&?r,?r,?r")
645                                          (V4SI  "wa,v,&?r,?r,?r")
646                                          (V4SF  "wa,v,&?r,?r,?r")
647                                          (V2DI  "wa,v,&?r,?r,?r")
648                                          (V2DF  "wa,v,&?r,?r,?r")
649                                          (V1TI  "wa,v,&?r,?r,?r")])
651 ;; Mode attribute for boolean operation register constraints for operand1
652 (define_mode_attr BOOL_REGS_OP1         [(TI    "r,0,r,wt,v")
653                                          (PTI   "r,0,r")
654                                          (V16QI "wa,v,r,0,r")
655                                          (V8HI  "wa,v,r,0,r")
656                                          (V4SI  "wa,v,r,0,r")
657                                          (V4SF  "wa,v,r,0,r")
658                                          (V2DI  "wa,v,r,0,r")
659                                          (V2DF  "wa,v,r,0,r")
660                                          (V1TI  "wa,v,r,0,r")])
662 ;; Mode attribute for boolean operation register constraints for operand2
663 (define_mode_attr BOOL_REGS_OP2         [(TI    "r,r,0,wt,v")
664                                          (PTI   "r,r,0")
665                                          (V16QI "wa,v,r,r,0")
666                                          (V8HI  "wa,v,r,r,0")
667                                          (V4SI  "wa,v,r,r,0")
668                                          (V4SF  "wa,v,r,r,0")
669                                          (V2DI  "wa,v,r,r,0")
670                                          (V2DF  "wa,v,r,r,0")
671                                          (V1TI  "wa,v,r,r,0")])
673 ;; Mode attribute for boolean operation register constraints for operand1
674 ;; for one_cmpl.  To simplify things, we repeat the constraint where 0
675 ;; is used for operand1 or operand2
676 (define_mode_attr BOOL_REGS_UNARY       [(TI    "r,0,0,wt,v")
677                                          (PTI   "r,0,0")
678                                          (V16QI "wa,v,r,0,0")
679                                          (V8HI  "wa,v,r,0,0")
680                                          (V4SI  "wa,v,r,0,0")
681                                          (V4SF  "wa,v,r,0,0")
682                                          (V2DI  "wa,v,r,0,0")
683                                          (V2DF  "wa,v,r,0,0")
684                                          (V1TI  "wa,v,r,0,0")])
686 ;; Reload iterator for creating the function to allocate a base register to
687 ;; supplement addressing modes.
688 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
689                               SF SD SI DF DD DI TI PTI KF IF TF])
692 ;; Start with fixed-point load and store insns.  Here we put only the more
693 ;; complex forms.  Basic data transfer is done later.
695 (define_insn "zero_extendqi<mode>2"
696   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
697         (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
698   ""
699   "@
700    lbz%U1%X1 %0,%1
701    rlwinm %0,%1,0,0xff"
702   [(set_attr "type" "load,shift")])
704 (define_insn_and_split "*zero_extendqi<mode>2_dot"
705   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
706         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
707                     (const_int 0)))
708    (clobber (match_scratch:EXTQI 0 "=r,r"))]
709   "rs6000_gen_cell_microcode"
710   "@
711    andi. %0,%1,0xff
712    #"
713   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
714   [(set (match_dup 0)
715         (zero_extend:EXTQI (match_dup 1)))
716    (set (match_dup 2)
717         (compare:CC (match_dup 0)
718                     (const_int 0)))]
719   ""
720   [(set_attr "type" "logical")
721    (set_attr "dot" "yes")
722    (set_attr "length" "4,8")])
724 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
725   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
726         (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
727                     (const_int 0)))
728    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
729         (zero_extend:EXTQI (match_dup 1)))]
730   "rs6000_gen_cell_microcode"
731   "@
732    andi. %0,%1,0xff
733    #"
734   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
735   [(set (match_dup 0)
736         (zero_extend:EXTQI (match_dup 1)))
737    (set (match_dup 2)
738         (compare:CC (match_dup 0)
739                     (const_int 0)))]
740   ""
741   [(set_attr "type" "logical")
742    (set_attr "dot" "yes")
743    (set_attr "length" "4,8")])
746 (define_insn "zero_extendhi<mode>2"
747   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
748         (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
749   ""
750   "@
751    lhz%U1%X1 %0,%1
752    rlwinm %0,%1,0,0xffff"
753   [(set_attr "type" "load,shift")])
755 (define_insn_and_split "*zero_extendhi<mode>2_dot"
756   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
757         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
758                     (const_int 0)))
759    (clobber (match_scratch:EXTHI 0 "=r,r"))]
760   "rs6000_gen_cell_microcode"
761   "@
762    andi. %0,%1,0xffff
763    #"
764   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
765   [(set (match_dup 0)
766         (zero_extend:EXTHI (match_dup 1)))
767    (set (match_dup 2)
768         (compare:CC (match_dup 0)
769                     (const_int 0)))]
770   ""
771   [(set_attr "type" "logical")
772    (set_attr "dot" "yes")
773    (set_attr "length" "4,8")])
775 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
776   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
777         (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
778                     (const_int 0)))
779    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
780         (zero_extend:EXTHI (match_dup 1)))]
781   "rs6000_gen_cell_microcode"
782   "@
783    andi. %0,%1,0xffff
784    #"
785   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
786   [(set (match_dup 0)
787         (zero_extend:EXTHI (match_dup 1)))
788    (set (match_dup 2)
789         (compare:CC (match_dup 0)
790                     (const_int 0)))]
791   ""
792   [(set_attr "type" "logical")
793    (set_attr "dot" "yes")
794    (set_attr "length" "4,8")])
797 (define_insn "zero_extendsi<mode>2"
798   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
799         (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
800   ""
801   "@
802    lwz%U1%X1 %0,%1
803    rldicl %0,%1,0,32
804    mtvsrwz %x0,%1
805    lfiwzx %0,%y1
806    lxsiwzx %x0,%y1"
807   [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
809 (define_insn_and_split "*zero_extendsi<mode>2_dot"
810   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
811         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
812                     (const_int 0)))
813    (clobber (match_scratch:EXTSI 0 "=r,r"))]
814   "rs6000_gen_cell_microcode"
815   "@
816    rldicl. %0,%1,0,32
817    #"
818   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
819   [(set (match_dup 0)
820         (zero_extend:DI (match_dup 1)))
821    (set (match_dup 2)
822         (compare:CC (match_dup 0)
823                     (const_int 0)))]
824   ""
825   [(set_attr "type" "shift")
826    (set_attr "dot" "yes")
827    (set_attr "length" "4,8")])
829 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
830   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
831         (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
832                     (const_int 0)))
833    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
834         (zero_extend:EXTSI (match_dup 1)))]
835   "rs6000_gen_cell_microcode"
836   "@
837    rldicl. %0,%1,0,32
838    #"
839   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
840   [(set (match_dup 0)
841         (zero_extend:EXTSI (match_dup 1)))
842    (set (match_dup 2)
843         (compare:CC (match_dup 0)
844                     (const_int 0)))]
845   ""
846   [(set_attr "type" "shift")
847    (set_attr "dot" "yes")
848    (set_attr "length" "4,8")])
851 (define_insn "extendqi<mode>2"
852   [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
853         (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
854   ""
855   "extsb %0,%1"
856   [(set_attr "type" "exts")])
858 (define_insn_and_split "*extendqi<mode>2_dot"
859   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
860         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
861                     (const_int 0)))
862    (clobber (match_scratch:EXTQI 0 "=r,r"))]
863   "rs6000_gen_cell_microcode"
864   "@
865    extsb. %0,%1
866    #"
867   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
868   [(set (match_dup 0)
869         (sign_extend:EXTQI (match_dup 1)))
870    (set (match_dup 2)
871         (compare:CC (match_dup 0)
872                     (const_int 0)))]
873   ""
874   [(set_attr "type" "exts")
875    (set_attr "dot" "yes")
876    (set_attr "length" "4,8")])
878 (define_insn_and_split "*extendqi<mode>2_dot2"
879   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
880         (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
881                     (const_int 0)))
882    (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
883         (sign_extend:EXTQI (match_dup 1)))]
884   "rs6000_gen_cell_microcode"
885   "@
886    extsb. %0,%1
887    #"
888   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
889   [(set (match_dup 0)
890         (sign_extend:EXTQI (match_dup 1)))
891    (set (match_dup 2)
892         (compare:CC (match_dup 0)
893                     (const_int 0)))]
894   ""
895   [(set_attr "type" "exts")
896    (set_attr "dot" "yes")
897    (set_attr "length" "4,8")])
900 (define_expand "extendhi<mode>2"
901   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
902         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
903   ""
904   "")
906 (define_insn "*extendhi<mode>2"
907   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
908         (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
909   "rs6000_gen_cell_microcode"
910   "@
911    lha%U1%X1 %0,%1
912    extsh %0,%1"
913   [(set_attr "type" "load,exts")
914    (set_attr "sign_extend" "yes")])
916 (define_insn "*extendhi<mode>2_noload"
917   [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
918         (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
919   "!rs6000_gen_cell_microcode"
920   "extsh %0,%1"
921   [(set_attr "type" "exts")])
923 (define_insn_and_split "*extendhi<mode>2_dot"
924   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
925         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
926                     (const_int 0)))
927    (clobber (match_scratch:EXTHI 0 "=r,r"))]
928   "rs6000_gen_cell_microcode"
929   "@
930    extsh. %0,%1
931    #"
932   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
933   [(set (match_dup 0)
934         (sign_extend:EXTHI (match_dup 1)))
935    (set (match_dup 2)
936         (compare:CC (match_dup 0)
937                     (const_int 0)))]
938   ""
939   [(set_attr "type" "exts")
940    (set_attr "dot" "yes")
941    (set_attr "length" "4,8")])
943 (define_insn_and_split "*extendhi<mode>2_dot2"
944   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
945         (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
946                     (const_int 0)))
947    (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
948         (sign_extend:EXTHI (match_dup 1)))]
949   "rs6000_gen_cell_microcode"
950   "@
951    extsh. %0,%1
952    #"
953   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
954   [(set (match_dup 0)
955         (sign_extend:EXTHI (match_dup 1)))
956    (set (match_dup 2)
957         (compare:CC (match_dup 0)
958                     (const_int 0)))]
959   ""
960   [(set_attr "type" "exts")
961    (set_attr "dot" "yes")
962    (set_attr "length" "4,8")])
965 (define_insn "extendsi<mode>2"
966   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
967         (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
968   ""
969   "@
970    lwa%U1%X1 %0,%1
971    extsw %0,%1
972    mtvsrwa %x0,%1
973    lfiwax %0,%y1
974    lxsiwax %x0,%y1"
975   [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
976    (set_attr "sign_extend" "yes")])
978 (define_insn_and_split "*extendsi<mode>2_dot"
979   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
981                     (const_int 0)))
982    (clobber (match_scratch:EXTSI 0 "=r,r"))]
983   "rs6000_gen_cell_microcode"
984   "@
985    extsw. %0,%1
986    #"
987   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
988   [(set (match_dup 0)
989         (sign_extend:EXTSI (match_dup 1)))
990    (set (match_dup 2)
991         (compare:CC (match_dup 0)
992                     (const_int 0)))]
993   ""
994   [(set_attr "type" "exts")
995    (set_attr "dot" "yes")
996    (set_attr "length" "4,8")])
998 (define_insn_and_split "*extendsi<mode>2_dot2"
999   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1000         (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1001                     (const_int 0)))
1002    (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1003         (sign_extend:EXTSI (match_dup 1)))]
1004   "rs6000_gen_cell_microcode"
1005   "@
1006    extsw. %0,%1
1007    #"
1008   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1009   [(set (match_dup 0)
1010         (sign_extend:EXTSI (match_dup 1)))
1011    (set (match_dup 2)
1012         (compare:CC (match_dup 0)
1013                     (const_int 0)))]
1014   ""
1015   [(set_attr "type" "exts")
1016    (set_attr "dot" "yes")
1017    (set_attr "length" "4,8")])
1019 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1021 (define_insn "*macchwc"
1022   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1023         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1024                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1025                                        (const_int 16))
1026                                       (sign_extend:SI
1027                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1028                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1029                     (const_int 0)))
1030    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1031         (plus:SI (mult:SI (ashiftrt:SI
1032                            (match_dup 2)
1033                            (const_int 16))
1034                           (sign_extend:SI
1035                            (match_dup 1)))
1036                  (match_dup 4)))]
1037   "TARGET_MULHW"
1038   "macchw. %0,%1,%2"
1039   [(set_attr "type" "halfmul")])
1041 (define_insn "*macchw"
1042   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1043         (plus:SI (mult:SI (ashiftrt:SI
1044                            (match_operand:SI 2 "gpc_reg_operand" "r")
1045                            (const_int 16))
1046                           (sign_extend:SI
1047                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1048                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1049   "TARGET_MULHW"
1050   "macchw %0,%1,%2"
1051   [(set_attr "type" "halfmul")])
1053 (define_insn "*macchwuc"
1054   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1055         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1056                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1057                                        (const_int 16))
1058                                       (zero_extend:SI
1059                                        (match_operand:HI 1 "gpc_reg_operand" "r")))
1060                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1061                     (const_int 0)))
1062    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1063         (plus:SI (mult:SI (lshiftrt:SI
1064                            (match_dup 2)
1065                            (const_int 16))
1066                           (zero_extend:SI
1067                            (match_dup 1)))
1068                  (match_dup 4)))]
1069   "TARGET_MULHW"
1070   "macchwu. %0,%1,%2"
1071   [(set_attr "type" "halfmul")])
1073 (define_insn "*macchwu"
1074   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1075         (plus:SI (mult:SI (lshiftrt:SI
1076                            (match_operand:SI 2 "gpc_reg_operand" "r")
1077                            (const_int 16))
1078                           (zero_extend:SI
1079                            (match_operand:HI 1 "gpc_reg_operand" "r")))
1080                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1081   "TARGET_MULHW"
1082   "macchwu %0,%1,%2"
1083   [(set_attr "type" "halfmul")])
1085 (define_insn "*machhwc"
1086   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1087         (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1088                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1089                                        (const_int 16))
1090                                       (ashiftrt:SI
1091                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1092                                        (const_int 16)))
1093                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1094                     (const_int 0)))
1095    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1096         (plus:SI (mult:SI (ashiftrt:SI
1097                            (match_dup 1)
1098                            (const_int 16))
1099                           (ashiftrt:SI
1100                            (match_dup 2)
1101                            (const_int 16)))
1102                  (match_dup 4)))]
1103   "TARGET_MULHW"
1104   "machhw. %0,%1,%2"
1105   [(set_attr "type" "halfmul")])
1107 (define_insn "*machhw"
1108   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1109         (plus:SI (mult:SI (ashiftrt:SI
1110                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1111                            (const_int 16))
1112                           (ashiftrt:SI
1113                            (match_operand:SI 2 "gpc_reg_operand" "r")
1114                            (const_int 16)))
1115                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1116   "TARGET_MULHW"
1117   "machhw %0,%1,%2"
1118   [(set_attr "type" "halfmul")])
1120 (define_insn "*machhwuc"
1121   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1122         (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1123                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1124                                        (const_int 16))
1125                                       (lshiftrt:SI
1126                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1127                                        (const_int 16)))
1128                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1129                     (const_int 0)))
1130    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1131         (plus:SI (mult:SI (lshiftrt:SI
1132                            (match_dup 1)
1133                            (const_int 16))
1134                           (lshiftrt:SI
1135                            (match_dup 2)
1136                            (const_int 16)))
1137                  (match_dup 4)))]
1138   "TARGET_MULHW"
1139   "machhwu. %0,%1,%2"
1140   [(set_attr "type" "halfmul")])
1142 (define_insn "*machhwu"
1143   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1144         (plus:SI (mult:SI (lshiftrt:SI
1145                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1146                            (const_int 16))
1147                           (lshiftrt:SI
1148                            (match_operand:SI 2 "gpc_reg_operand" "r")
1149                            (const_int 16)))
1150                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1151   "TARGET_MULHW"
1152   "machhwu %0,%1,%2"
1153   [(set_attr "type" "halfmul")])
1155 (define_insn "*maclhwc"
1156   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1157         (compare:CC (plus:SI (mult:SI (sign_extend:SI
1158                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1159                                       (sign_extend:SI
1160                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1161                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1162                     (const_int 0)))
1163    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1164         (plus:SI (mult:SI (sign_extend:SI
1165                            (match_dup 1))
1166                           (sign_extend:SI
1167                            (match_dup 2)))
1168                  (match_dup 4)))]
1169   "TARGET_MULHW"
1170   "maclhw. %0,%1,%2"
1171   [(set_attr "type" "halfmul")])
1173 (define_insn "*maclhw"
1174   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1175         (plus:SI (mult:SI (sign_extend:SI
1176                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1177                           (sign_extend:SI
1178                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1179                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1180   "TARGET_MULHW"
1181   "maclhw %0,%1,%2"
1182   [(set_attr "type" "halfmul")])
1184 (define_insn "*maclhwuc"
1185   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1186         (compare:CC (plus:SI (mult:SI (zero_extend:SI
1187                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1188                                       (zero_extend:SI
1189                                        (match_operand:HI 2 "gpc_reg_operand" "r")))
1190                              (match_operand:SI 4 "gpc_reg_operand" "0"))
1191                     (const_int 0)))
1192    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1193         (plus:SI (mult:SI (zero_extend:SI
1194                            (match_dup 1))
1195                           (zero_extend:SI
1196                            (match_dup 2)))
1197                  (match_dup 4)))]
1198   "TARGET_MULHW"
1199   "maclhwu. %0,%1,%2"
1200   [(set_attr "type" "halfmul")])
1202 (define_insn "*maclhwu"
1203   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1204         (plus:SI (mult:SI (zero_extend:SI
1205                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1206                           (zero_extend:SI
1207                            (match_operand:HI 2 "gpc_reg_operand" "r")))
1208                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
1209   "TARGET_MULHW"
1210   "maclhwu %0,%1,%2"
1211   [(set_attr "type" "halfmul")])
1213 (define_insn "*nmacchwc"
1214   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1215         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1216                               (mult:SI (ashiftrt:SI
1217                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1218                                         (const_int 16))
1219                                        (sign_extend:SI
1220                                         (match_operand:HI 1 "gpc_reg_operand" "r"))))
1221                     (const_int 0)))
1222    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1223         (minus:SI (match_dup 4)
1224                   (mult:SI (ashiftrt:SI
1225                             (match_dup 2)
1226                             (const_int 16))
1227                            (sign_extend:SI
1228                             (match_dup 1)))))]
1229   "TARGET_MULHW"
1230   "nmacchw. %0,%1,%2"
1231   [(set_attr "type" "halfmul")])
1233 (define_insn "*nmacchw"
1234   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1235         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1236                   (mult:SI (ashiftrt:SI
1237                             (match_operand:SI 2 "gpc_reg_operand" "r")
1238                             (const_int 16))
1239                            (sign_extend:SI
1240                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1241   "TARGET_MULHW"
1242   "nmacchw %0,%1,%2"
1243   [(set_attr "type" "halfmul")])
1245 (define_insn "*nmachhwc"
1246   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1247         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1248                               (mult:SI (ashiftrt:SI
1249                                         (match_operand:SI 1 "gpc_reg_operand" "%r")
1250                                         (const_int 16))
1251                                        (ashiftrt:SI
1252                                         (match_operand:SI 2 "gpc_reg_operand" "r")
1253                                         (const_int 16))))
1254                     (const_int 0)))
1255    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1256         (minus:SI (match_dup 4)
1257                   (mult:SI (ashiftrt:SI
1258                             (match_dup 1)
1259                             (const_int 16))
1260                            (ashiftrt:SI
1261                             (match_dup 2)
1262                             (const_int 16)))))]
1263   "TARGET_MULHW"
1264   "nmachhw. %0,%1,%2"
1265   [(set_attr "type" "halfmul")])
1267 (define_insn "*nmachhw"
1268   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1269         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1270                   (mult:SI (ashiftrt:SI
1271                             (match_operand:SI 1 "gpc_reg_operand" "%r")
1272                             (const_int 16))
1273                            (ashiftrt:SI
1274                             (match_operand:SI 2 "gpc_reg_operand" "r")
1275                             (const_int 16)))))]
1276   "TARGET_MULHW"
1277   "nmachhw %0,%1,%2"
1278   [(set_attr "type" "halfmul")])
1280 (define_insn "*nmaclhwc"
1281   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1282         (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1283                               (mult:SI (sign_extend:SI
1284                                         (match_operand:HI 1 "gpc_reg_operand" "%r"))
1285                                        (sign_extend:SI
1286                                         (match_operand:HI 2 "gpc_reg_operand" "r"))))
1287                     (const_int 0)))
1288    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1289         (minus:SI (match_dup 4)
1290                   (mult:SI (sign_extend:SI
1291                             (match_dup 1))
1292                            (sign_extend:SI
1293                             (match_dup 2)))))]
1294   "TARGET_MULHW"
1295   "nmaclhw. %0,%1,%2"
1296   [(set_attr "type" "halfmul")])
1298 (define_insn "*nmaclhw"
1299   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1300         (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1301                   (mult:SI (sign_extend:SI
1302                             (match_operand:HI 1 "gpc_reg_operand" "%r"))
1303                            (sign_extend:SI
1304                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1305   "TARGET_MULHW"
1306   "nmaclhw %0,%1,%2"
1307   [(set_attr "type" "halfmul")])
1309 (define_insn "*mulchwc"
1310   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1311         (compare:CC (mult:SI (ashiftrt:SI
1312                               (match_operand:SI 2 "gpc_reg_operand" "r")
1313                               (const_int 16))
1314                              (sign_extend:SI
1315                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1316                     (const_int 0)))
1317    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1318         (mult:SI (ashiftrt:SI
1319                   (match_dup 2)
1320                   (const_int 16))
1321                  (sign_extend:SI
1322                   (match_dup 1))))]
1323   "TARGET_MULHW"
1324   "mulchw. %0,%1,%2"
1325   [(set_attr "type" "halfmul")])
1327 (define_insn "*mulchw"
1328   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1329         (mult:SI (ashiftrt:SI
1330                   (match_operand:SI 2 "gpc_reg_operand" "r")
1331                   (const_int 16))
1332                  (sign_extend:SI
1333                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1334   "TARGET_MULHW"
1335   "mulchw %0,%1,%2"
1336   [(set_attr "type" "halfmul")])
1338 (define_insn "*mulchwuc"
1339   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1340         (compare:CC (mult:SI (lshiftrt:SI
1341                               (match_operand:SI 2 "gpc_reg_operand" "r")
1342                               (const_int 16))
1343                              (zero_extend:SI
1344                               (match_operand:HI 1 "gpc_reg_operand" "r")))
1345                     (const_int 0)))
1346    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347         (mult:SI (lshiftrt:SI
1348                   (match_dup 2)
1349                   (const_int 16))
1350                  (zero_extend:SI
1351                   (match_dup 1))))]
1352   "TARGET_MULHW"
1353   "mulchwu. %0,%1,%2"
1354   [(set_attr "type" "halfmul")])
1356 (define_insn "*mulchwu"
1357   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1358         (mult:SI (lshiftrt:SI
1359                   (match_operand:SI 2 "gpc_reg_operand" "r")
1360                   (const_int 16))
1361                  (zero_extend:SI
1362                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1363   "TARGET_MULHW"
1364   "mulchwu %0,%1,%2"
1365   [(set_attr "type" "halfmul")])
1367 (define_insn "*mulhhwc"
1368   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1369         (compare:CC (mult:SI (ashiftrt:SI
1370                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1371                               (const_int 16))
1372                              (ashiftrt:SI
1373                               (match_operand:SI 2 "gpc_reg_operand" "r")
1374                               (const_int 16)))
1375                     (const_int 0)))
1376    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1377         (mult:SI (ashiftrt:SI
1378                   (match_dup 1)
1379                   (const_int 16))
1380                  (ashiftrt:SI
1381                   (match_dup 2)
1382                   (const_int 16))))]
1383   "TARGET_MULHW"
1384   "mulhhw. %0,%1,%2"
1385   [(set_attr "type" "halfmul")])
1387 (define_insn "*mulhhw"
1388   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1389         (mult:SI (ashiftrt:SI
1390                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1391                   (const_int 16))
1392                  (ashiftrt:SI
1393                   (match_operand:SI 2 "gpc_reg_operand" "r")
1394                   (const_int 16))))]
1395   "TARGET_MULHW"
1396   "mulhhw %0,%1,%2"
1397   [(set_attr "type" "halfmul")])
1399 (define_insn "*mulhhwuc"
1400   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1401         (compare:CC (mult:SI (lshiftrt:SI
1402                               (match_operand:SI 1 "gpc_reg_operand" "%r")
1403                               (const_int 16))
1404                              (lshiftrt:SI
1405                               (match_operand:SI 2 "gpc_reg_operand" "r")
1406                               (const_int 16)))
1407                     (const_int 0)))
1408    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1409         (mult:SI (lshiftrt:SI
1410                   (match_dup 1)
1411                   (const_int 16))
1412                  (lshiftrt:SI
1413                   (match_dup 2)
1414                   (const_int 16))))]
1415   "TARGET_MULHW"
1416   "mulhhwu. %0,%1,%2"
1417   [(set_attr "type" "halfmul")])
1419 (define_insn "*mulhhwu"
1420   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1421         (mult:SI (lshiftrt:SI
1422                   (match_operand:SI 1 "gpc_reg_operand" "%r")
1423                   (const_int 16))
1424                  (lshiftrt:SI
1425                   (match_operand:SI 2 "gpc_reg_operand" "r")
1426                   (const_int 16))))]
1427   "TARGET_MULHW"
1428   "mulhhwu %0,%1,%2"
1429   [(set_attr "type" "halfmul")])
1431 (define_insn "*mullhwc"
1432   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1433         (compare:CC (mult:SI (sign_extend:SI
1434                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1435                              (sign_extend:SI
1436                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1437                     (const_int 0)))
1438    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1439         (mult:SI (sign_extend:SI
1440                   (match_dup 1))
1441                  (sign_extend:SI
1442                   (match_dup 2))))]
1443   "TARGET_MULHW"
1444   "mullhw. %0,%1,%2"
1445   [(set_attr "type" "halfmul")])
1447 (define_insn "*mullhw"
1448   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1449         (mult:SI (sign_extend:SI
1450                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1451                  (sign_extend:SI
1452                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1453   "TARGET_MULHW"
1454   "mullhw %0,%1,%2"
1455   [(set_attr "type" "halfmul")])
1457 (define_insn "*mullhwuc"
1458   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1459         (compare:CC (mult:SI (zero_extend:SI
1460                               (match_operand:HI 1 "gpc_reg_operand" "%r"))
1461                              (zero_extend:SI
1462                               (match_operand:HI 2 "gpc_reg_operand" "r")))
1463                     (const_int 0)))
1464    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1465         (mult:SI (zero_extend:SI
1466                   (match_dup 1))
1467                  (zero_extend:SI
1468                   (match_dup 2))))]
1469   "TARGET_MULHW"
1470   "mullhwu. %0,%1,%2"
1471   [(set_attr "type" "halfmul")])
1473 (define_insn "*mullhwu"
1474   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1475         (mult:SI (zero_extend:SI
1476                   (match_operand:HI 1 "gpc_reg_operand" "%r"))
1477                  (zero_extend:SI
1478                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1479   "TARGET_MULHW"
1480   "mullhwu %0,%1,%2"
1481   [(set_attr "type" "halfmul")])
1483 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1484 (define_insn "dlmzb"
1485   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1486         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1487                     (match_operand:SI 2 "gpc_reg_operand" "r")]
1488                    UNSPEC_DLMZB_CR))
1489    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1490         (unspec:SI [(match_dup 1)
1491                     (match_dup 2)]
1492                    UNSPEC_DLMZB))]
1493   "TARGET_DLMZB"
1494   "dlmzb. %0,%1,%2")
1496 (define_expand "strlensi"
1497   [(set (match_operand:SI 0 "gpc_reg_operand" "")
1498         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1499                     (match_operand:QI 2 "const_int_operand" "")
1500                     (match_operand 3 "const_int_operand" "")]
1501                    UNSPEC_DLMZB_STRLEN))
1502    (clobber (match_scratch:CC 4 "=x"))]
1503   "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1505   rtx result = operands[0];
1506   rtx src = operands[1];
1507   rtx search_char = operands[2];
1508   rtx align = operands[3];
1509   rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1510   rtx loop_label, end_label, mem, cr0, cond;
1511   if (search_char != const0_rtx
1512       || GET_CODE (align) != CONST_INT
1513       || INTVAL (align) < 8)
1514         FAIL;
1515   word1 = gen_reg_rtx (SImode);
1516   word2 = gen_reg_rtx (SImode);
1517   scratch_dlmzb = gen_reg_rtx (SImode);
1518   scratch_string = gen_reg_rtx (Pmode);
1519   loop_label = gen_label_rtx ();
1520   end_label = gen_label_rtx ();
1521   addr = force_reg (Pmode, XEXP (src, 0));
1522   emit_move_insn (scratch_string, addr);
1523   emit_label (loop_label);
1524   mem = change_address (src, SImode, scratch_string);
1525   emit_move_insn (word1, mem);
1526   emit_move_insn (word2, adjust_address (mem, SImode, 4));
1527   cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1528   emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1529   cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1530   emit_jump_insn (gen_rtx_SET (pc_rtx,
1531                                gen_rtx_IF_THEN_ELSE (VOIDmode,
1532                                                      cond,
1533                                                      gen_rtx_LABEL_REF
1534                                                        (VOIDmode,
1535                                                         end_label),
1536                                                      pc_rtx)));
1537   emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1538   emit_jump_insn (gen_rtx_SET (pc_rtx,
1539                                gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1540   emit_barrier ();
1541   emit_label (end_label);
1542   emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1543   emit_insn (gen_subsi3 (result, scratch_string, addr));
1544   emit_insn (gen_addsi3 (result, result, constm1_rtx));
1545   DONE;
1548 ;; Fixed-point arithmetic insns.
1550 (define_expand "add<mode>3"
1551   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1552         (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1553                   (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1554   ""
1556   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1557     {
1558       rtx lo0 = gen_lowpart (SImode, operands[0]);
1559       rtx lo1 = gen_lowpart (SImode, operands[1]);
1560       rtx lo2 = gen_lowpart (SImode, operands[2]);
1561       rtx hi0 = gen_highpart (SImode, operands[0]);
1562       rtx hi1 = gen_highpart (SImode, operands[1]);
1563       rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1565       if (!reg_or_short_operand (lo2, SImode))
1566         lo2 = force_reg (SImode, lo2);
1567       if (!adde_operand (hi2, SImode))
1568         hi2 = force_reg (SImode, hi2);
1570       emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1571       emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1572       DONE;
1573     }
1575   if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1576     {
1577       rtx tmp = ((!can_create_pseudo_p ()
1578                   || rtx_equal_p (operands[0], operands[1]))
1579                  ? operands[0] : gen_reg_rtx (<MODE>mode));
1581       HOST_WIDE_INT val = INTVAL (operands[2]);
1582       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1583       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1585       if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1586         FAIL;
1588       /* The ordering here is important for the prolog expander.
1589          When space is allocated from the stack, adding 'low' first may
1590          produce a temporary deallocation (which would be bad).  */
1591       emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1592       emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1593       DONE;
1594     }
1597 (define_insn "*add<mode>3"
1598   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1599         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1600                   (match_operand:GPR 2 "add_operand" "r,I,L")))]
1601   ""
1602   "@
1603    add %0,%1,%2
1604    addi %0,%1,%2
1605    addis %0,%1,%v2"
1606   [(set_attr "type" "add")])
1608 (define_insn "addsi3_high"
1609   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1610         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1611                  (high:SI (match_operand 2 "" ""))))]
1612   "TARGET_MACHO && !TARGET_64BIT"
1613   "addis %0,%1,ha16(%2)"
1614   [(set_attr "type" "add")])
1616 (define_insn_and_split "*add<mode>3_dot"
1617   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1618         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1619                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1620                     (const_int 0)))
1621    (clobber (match_scratch:GPR 0 "=r,r"))]
1622   "<MODE>mode == Pmode"
1623   "@
1624    add. %0,%1,%2
1625    #"
1626   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1627   [(set (match_dup 0)
1628         (plus:GPR (match_dup 1)
1629                  (match_dup 2)))
1630    (set (match_dup 3)
1631         (compare:CC (match_dup 0)
1632                     (const_int 0)))]
1633   ""
1634   [(set_attr "type" "add")
1635    (set_attr "dot" "yes")
1636    (set_attr "length" "4,8")])
1638 (define_insn_and_split "*add<mode>3_dot2"
1639   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1640         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1641                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1642                     (const_int 0)))
1643    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1644         (plus:GPR (match_dup 1)
1645                   (match_dup 2)))]
1646   "<MODE>mode == Pmode"
1647   "@
1648    add. %0,%1,%2
1649    #"
1650   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1651   [(set (match_dup 0)
1652         (plus:GPR (match_dup 1)
1653                   (match_dup 2)))
1654    (set (match_dup 3)
1655         (compare:CC (match_dup 0)
1656                     (const_int 0)))]
1657   ""
1658   [(set_attr "type" "add")
1659    (set_attr "dot" "yes")
1660    (set_attr "length" "4,8")])
1662 (define_insn_and_split "*add<mode>3_imm_dot"
1663   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1664         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1665                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1666                     (const_int 0)))
1667    (clobber (match_scratch:GPR 0 "=r,r"))
1668    (clobber (reg:GPR CA_REGNO))]
1669   "<MODE>mode == Pmode"
1670   "@
1671    addic. %0,%1,%2
1672    #"
1673   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1674   [(set (match_dup 0)
1675         (plus:GPR (match_dup 1)
1676                   (match_dup 2)))
1677    (set (match_dup 3)
1678         (compare:CC (match_dup 0)
1679                     (const_int 0)))]
1680   ""
1681   [(set_attr "type" "add")
1682    (set_attr "dot" "yes")
1683    (set_attr "length" "4,8")])
1685 (define_insn_and_split "*add<mode>3_imm_dot2"
1686   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1687         (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1688                               (match_operand:GPR 2 "short_cint_operand" "I,I"))
1689                     (const_int 0)))
1690    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1691         (plus:GPR (match_dup 1)
1692                   (match_dup 2)))
1693    (clobber (reg:GPR CA_REGNO))]
1694   "<MODE>mode == Pmode"
1695   "@
1696    addic. %0,%1,%2
1697    #"
1698   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1699   [(set (match_dup 0)
1700         (plus:GPR (match_dup 1)
1701                   (match_dup 2)))
1702    (set (match_dup 3)
1703         (compare:CC (match_dup 0)
1704                     (const_int 0)))]
1705   ""
1706   [(set_attr "type" "add")
1707    (set_attr "dot" "yes")
1708    (set_attr "length" "4,8")])
1710 ;; Split an add that we can't do in one insn into two insns, each of which
1711 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
1712 ;; add should be last in case the result gets used in an address.
1714 (define_split
1715   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1716         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1717                   (match_operand:GPR 2 "non_add_cint_operand" "")))]
1718   ""
1719   [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1720    (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1722   HOST_WIDE_INT val = INTVAL (operands[2]);
1723   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1724   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1726   operands[4] = GEN_INT (low);
1727   if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1728     operands[3] = GEN_INT (rest);
1729   else if (can_create_pseudo_p ())
1730     {
1731       operands[3] = gen_reg_rtx (DImode);
1732       emit_move_insn (operands[3], operands[2]);
1733       emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1734       DONE;
1735     }
1736   else
1737     FAIL;
1741 (define_insn "add<mode>3_carry"
1742   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1743         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1744                 (match_operand:P 2 "reg_or_short_operand" "rI")))
1745    (set (reg:P CA_REGNO)
1746         (ltu:P (plus:P (match_dup 1)
1747                        (match_dup 2))
1748                (match_dup 1)))]
1749   ""
1750   "add%I2c %0,%1,%2"
1751   [(set_attr "type" "add")])
1753 (define_insn "*add<mode>3_imm_carry_pos"
1754   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1755         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1756                 (match_operand:P 2 "short_cint_operand" "n")))
1757    (set (reg:P CA_REGNO)
1758         (geu:P (match_dup 1)
1759                (match_operand:P 3 "const_int_operand" "n")))]
1760   "INTVAL (operands[2]) > 0
1761    && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1762   "addic %0,%1,%2"
1763   [(set_attr "type" "add")])
1765 (define_insn "*add<mode>3_imm_carry_0"
1766   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1767         (match_operand:P 1 "gpc_reg_operand" "r"))
1768    (set (reg:P CA_REGNO)
1769         (const_int 0))]
1770   ""
1771   "addic %0,%1,0"
1772   [(set_attr "type" "add")])
1774 (define_insn "*add<mode>3_imm_carry_m1"
1775   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1776         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1777                 (const_int -1)))
1778    (set (reg:P CA_REGNO)
1779         (ne:P (match_dup 1)
1780               (const_int 0)))]
1781   ""
1782   "addic %0,%1,-1"
1783   [(set_attr "type" "add")])
1785 (define_insn "*add<mode>3_imm_carry_neg"
1786   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1787         (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1788                 (match_operand:P 2 "short_cint_operand" "n")))
1789    (set (reg:P CA_REGNO)
1790         (gtu:P (match_dup 1)
1791                (match_operand:P 3 "const_int_operand" "n")))]
1792   "INTVAL (operands[2]) < 0
1793    && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1794   "addic %0,%1,%2"
1795   [(set_attr "type" "add")])
1798 (define_expand "add<mode>3_carry_in"
1799   [(parallel [
1800      (set (match_operand:GPR 0 "gpc_reg_operand")
1801           (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1802                               (match_operand:GPR 2 "adde_operand"))
1803                     (reg:GPR CA_REGNO)))
1804      (clobber (reg:GPR CA_REGNO))])]
1805   ""
1807   if (operands[2] == const0_rtx)
1808     {
1809       emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1810       DONE;
1811     }
1812   if (operands[2] == constm1_rtx)
1813     {
1814       emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1815       DONE;
1816     }
1819 (define_insn "*add<mode>3_carry_in_internal"
1820   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1821         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1822                             (match_operand:GPR 2 "gpc_reg_operand" "r"))
1823                   (reg:GPR CA_REGNO)))
1824    (clobber (reg:GPR CA_REGNO))]
1825   ""
1826   "adde %0,%1,%2"
1827   [(set_attr "type" "add")])
1829 (define_insn "add<mode>3_carry_in_0"
1830   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1831         (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1832                   (reg:GPR CA_REGNO)))
1833    (clobber (reg:GPR CA_REGNO))]
1834   ""
1835   "addze %0,%1"
1836   [(set_attr "type" "add")])
1838 (define_insn "add<mode>3_carry_in_m1"
1839   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1840         (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1841                             (reg:GPR CA_REGNO))
1842                   (const_int -1)))
1843    (clobber (reg:GPR CA_REGNO))]
1844   ""
1845   "addme %0,%1"
1846   [(set_attr "type" "add")])
1849 (define_expand "one_cmpl<mode>2"
1850   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1851         (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1852   ""
1854   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1855     {
1856       rs6000_split_logical (operands, NOT, false, false, false);
1857       DONE;
1858     }
1861 (define_insn "*one_cmpl<mode>2"
1862   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1863         (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1864   ""
1865   "not %0,%1")
1867 (define_insn_and_split "*one_cmpl<mode>2_dot"
1868   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1869         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1870                     (const_int 0)))
1871    (clobber (match_scratch:GPR 0 "=r,r"))]
1872   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1873   "@
1874    not. %0,%1
1875    #"
1876   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1877   [(set (match_dup 0)
1878         (not:GPR (match_dup 1)))
1879    (set (match_dup 2)
1880         (compare:CC (match_dup 0)
1881                     (const_int 0)))]
1882   ""
1883   [(set_attr "type" "logical")
1884    (set_attr "dot" "yes")
1885    (set_attr "length" "4,8")])
1887 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1888   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1889         (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1890                     (const_int 0)))
1891    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1892         (not:GPR (match_dup 1)))]
1893   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
1894   "@
1895    not. %0,%1
1896    #"
1897   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1898   [(set (match_dup 0)
1899         (not:GPR (match_dup 1)))
1900    (set (match_dup 2)
1901         (compare:CC (match_dup 0)
1902                     (const_int 0)))]
1903   ""
1904   [(set_attr "type" "logical")
1905    (set_attr "dot" "yes")
1906    (set_attr "length" "4,8")])
1909 (define_expand "sub<mode>3"
1910   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1911         (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1912                    (match_operand:SDI 2 "gpc_reg_operand" "")))]
1913   ""
1915   if (<MODE>mode == DImode && !TARGET_POWERPC64)
1916     {
1917       rtx lo0 = gen_lowpart (SImode, operands[0]);
1918       rtx lo1 = gen_lowpart (SImode, operands[1]);
1919       rtx lo2 = gen_lowpart (SImode, operands[2]);
1920       rtx hi0 = gen_highpart (SImode, operands[0]);
1921       rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
1922       rtx hi2 = gen_highpart (SImode, operands[2]);
1924       if (!reg_or_short_operand (lo1, SImode))
1925         lo1 = force_reg (SImode, lo1);
1926       if (!adde_operand (hi1, SImode))
1927         hi1 = force_reg (SImode, hi1);
1929       emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
1930       emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
1931       DONE;
1932     }
1934   if (short_cint_operand (operands[1], <MODE>mode))
1935     {
1936       emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
1937       DONE;
1938     }
1941 (define_insn "*subf<mode>3"
1942   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1943         (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
1944                    (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1945   ""
1946   "subf %0,%1,%2"
1947   [(set_attr "type" "add")])
1949 (define_insn_and_split "*subf<mode>3_dot"
1950   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1951         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1952                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1953                     (const_int 0)))
1954    (clobber (match_scratch:GPR 0 "=r,r"))]
1955   "<MODE>mode == Pmode"
1956   "@
1957    subf. %0,%1,%2
1958    #"
1959   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1960   [(set (match_dup 0)
1961         (minus:GPR (match_dup 2)
1962                    (match_dup 1)))
1963    (set (match_dup 3)
1964         (compare:CC (match_dup 0)
1965                     (const_int 0)))]
1966   ""
1967   [(set_attr "type" "add")
1968    (set_attr "dot" "yes")
1969    (set_attr "length" "4,8")])
1971 (define_insn_and_split "*subf<mode>3_dot2"
1972   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1973         (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
1974                                (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1975                     (const_int 0)))
1976    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1977         (minus:GPR (match_dup 2)
1978                    (match_dup 1)))]
1979   "<MODE>mode == Pmode"
1980   "@
1981    subf. %0,%1,%2
1982    #"
1983   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1984   [(set (match_dup 0)
1985         (minus:GPR (match_dup 2)
1986                    (match_dup 1)))
1987    (set (match_dup 3)
1988         (compare:CC (match_dup 0)
1989                     (const_int 0)))]
1990   ""
1991   [(set_attr "type" "add")
1992    (set_attr "dot" "yes")
1993    (set_attr "length" "4,8")])
1995 (define_insn "subf<mode>3_imm"
1996   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1997         (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
1998                    (match_operand:GPR 1 "gpc_reg_operand" "r")))
1999    (clobber (reg:GPR CA_REGNO))]
2000   ""
2001   "subfic %0,%1,%2"
2002   [(set_attr "type" "add")])
2005 (define_insn "subf<mode>3_carry"
2006   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2007         (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2008                  (match_operand:P 1 "gpc_reg_operand" "r")))
2009    (set (reg:P CA_REGNO)
2010         (leu:P (match_dup 1)
2011                (match_dup 2)))]
2012   ""
2013   "subf%I2c %0,%1,%2"
2014   [(set_attr "type" "add")])
2016 (define_insn "*subf<mode>3_imm_carry_0"
2017   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2018         (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2019    (set (reg:P CA_REGNO)
2020         (eq:P (match_dup 1)
2021               (const_int 0)))]
2022   ""
2023   "subfic %0,%1,0"
2024   [(set_attr "type" "add")])
2026 (define_insn "*subf<mode>3_imm_carry_m1"
2027   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2028         (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2029    (set (reg:P CA_REGNO)
2030         (const_int 1))]
2031   ""
2032   "subfic %0,%1,-1"
2033   [(set_attr "type" "add")])
2036 (define_expand "subf<mode>3_carry_in"
2037   [(parallel [
2038      (set (match_operand:GPR 0 "gpc_reg_operand")
2039           (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2040                               (reg:GPR CA_REGNO))
2041                     (match_operand:GPR 2 "adde_operand")))
2042      (clobber (reg:GPR CA_REGNO))])]
2043   ""
2045   if (operands[2] == const0_rtx)
2046     {
2047       emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2048       DONE;
2049     }
2050   if (operands[2] == constm1_rtx)
2051     {
2052       emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2053       DONE;
2054     }
2057 (define_insn "*subf<mode>3_carry_in_internal"
2058   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2059         (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2060                             (reg:GPR CA_REGNO))
2061                   (match_operand:GPR 2 "gpc_reg_operand" "r")))
2062    (clobber (reg:GPR CA_REGNO))]
2063   ""
2064   "subfe %0,%1,%2"
2065   [(set_attr "type" "add")])
2067 (define_insn "subf<mode>3_carry_in_0"
2068   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2069         (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2070                   (reg:GPR CA_REGNO)))
2071    (clobber (reg:GPR CA_REGNO))]
2072   ""
2073   "subfze %0,%1"
2074   [(set_attr "type" "add")])
2076 (define_insn "subf<mode>3_carry_in_m1"
2077   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2078         (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2079                              (match_operand:GPR 1 "gpc_reg_operand" "r"))
2080                   (const_int -2)))
2081    (clobber (reg:GPR CA_REGNO))]
2082   ""
2083   "subfme %0,%1"
2084   [(set_attr "type" "add")])
2086 (define_insn "subf<mode>3_carry_in_xx"
2087   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2088         (plus:GPR (reg:GPR CA_REGNO)
2089                   (const_int -1)))
2090    (clobber (reg:GPR CA_REGNO))]
2091   ""
2092   "subfe %0,%0,%0"
2093   [(set_attr "type" "add")])
2096 (define_insn "neg<mode>2"
2097   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2098         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2099   ""
2100   "neg %0,%1"
2101   [(set_attr "type" "add")])
2103 (define_insn_and_split "*neg<mode>2_dot"
2104   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2105         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2106                     (const_int 0)))
2107    (clobber (match_scratch:GPR 0 "=r,r"))]
2108   "<MODE>mode == Pmode"
2109   "@
2110    neg. %0,%1
2111    #"
2112   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2113   [(set (match_dup 0)
2114         (neg:GPR (match_dup 1)))
2115    (set (match_dup 2)
2116         (compare:CC (match_dup 0)
2117                     (const_int 0)))]
2118   ""
2119   [(set_attr "type" "add")
2120    (set_attr "dot" "yes")
2121    (set_attr "length" "4,8")])
2123 (define_insn_and_split "*neg<mode>2_dot2"
2124   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2125         (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2126                     (const_int 0)))
2127    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2128         (neg:GPR (match_dup 1)))]
2129   "<MODE>mode == Pmode"
2130   "@
2131    neg. %0,%1
2132    #"
2133   "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2134   [(set (match_dup 0)
2135         (neg:GPR (match_dup 1)))
2136    (set (match_dup 2)
2137         (compare:CC (match_dup 0)
2138                     (const_int 0)))]
2139   ""
2140   [(set_attr "type" "add")
2141    (set_attr "dot" "yes")
2142    (set_attr "length" "4,8")])
2145 (define_insn "clz<mode>2"
2146   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2147         (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2148   ""
2149   "cntlz<wd> %0,%1"
2150   [(set_attr "type" "cntlz")])
2152 (define_expand "ctz<mode>2"
2153   [(set (match_dup 2)
2154         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2155    (set (match_dup 3)
2156         (and:GPR (match_dup 1)
2157                  (match_dup 2)))
2158    (set (match_dup 4)
2159         (clz:GPR (match_dup 3)))
2160    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2161                    (minus:GPR (match_dup 5)
2162                               (match_dup 4)))
2163               (clobber (reg:GPR CA_REGNO))])]
2164   ""
2166   if (TARGET_CTZ)
2167     {
2168       emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2169       DONE;
2170     }
2172   operands[2] = gen_reg_rtx (<MODE>mode);
2173   operands[3] = gen_reg_rtx (<MODE>mode);
2174   operands[4] = gen_reg_rtx (<MODE>mode);
2175   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2178 (define_insn "ctz<mode>2_hw"
2179   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2180         (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2181   "TARGET_CTZ"
2182   "cnttz<wd> %0,%1"
2183   [(set_attr "type" "cntlz")])
2185 (define_expand "ffs<mode>2"
2186   [(set (match_dup 2)
2187         (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
2188    (set (match_dup 3)
2189         (and:GPR (match_dup 1)
2190                  (match_dup 2)))
2191    (set (match_dup 4)
2192         (clz:GPR (match_dup 3)))
2193    (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2194                    (minus:GPR (match_dup 5)
2195                               (match_dup 4)))
2196               (clobber (reg:GPR CA_REGNO))])]
2197   ""
2199   operands[2] = gen_reg_rtx (<MODE>mode);
2200   operands[3] = gen_reg_rtx (<MODE>mode);
2201   operands[4] = gen_reg_rtx (<MODE>mode);
2202   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2206 (define_expand "popcount<mode>2"
2207   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2208         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2209   "TARGET_POPCNTB || TARGET_POPCNTD"
2211   rs6000_emit_popcount (operands[0], operands[1]);
2212   DONE;
2215 (define_insn "popcntb<mode>2"
2216   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2217         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2218                     UNSPEC_POPCNTB))]
2219   "TARGET_POPCNTB"
2220   "popcntb %0,%1"
2221   [(set_attr "type" "popcnt")])
2223 (define_insn "popcntd<mode>2"
2224   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2225         (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2226   "TARGET_POPCNTD"
2227   "popcnt<wd> %0,%1"
2228   [(set_attr "type" "popcnt")])
2231 (define_expand "parity<mode>2"
2232   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2233         (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2234   "TARGET_POPCNTB"
2236   rs6000_emit_parity (operands[0], operands[1]);
2237   DONE;
2240 (define_insn "parity<mode>2_cmpb"
2241   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2242         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2243   "TARGET_CMPB && TARGET_POPCNTB"
2244   "prty<wd> %0,%1"
2245   [(set_attr "type" "popcnt")])
2248 ;; Since the hardware zeros the upper part of the register, save generating the
2249 ;; AND immediate if we are converting to unsigned
2250 (define_insn "*bswaphi2_extenddi"
2251   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2252         (zero_extend:DI
2253          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2254   "TARGET_POWERPC64"
2255   "lhbrx %0,%y1"
2256   [(set_attr "length" "4")
2257    (set_attr "type" "load")])
2259 (define_insn "*bswaphi2_extendsi"
2260   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2261         (zero_extend:SI
2262          (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2263   ""
2264   "lhbrx %0,%y1"
2265   [(set_attr "length" "4")
2266    (set_attr "type" "load")])
2268 (define_expand "bswaphi2"
2269   [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
2270                    (bswap:HI
2271                     (match_operand:HI 1 "reg_or_mem_operand" "")))
2272               (clobber (match_scratch:SI 2 ""))])]
2273   ""
2275   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2276     operands[1] = force_reg (HImode, operands[1]);
2279 (define_insn "bswaphi2_internal"
2280   [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
2281         (bswap:HI
2282          (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
2283    (clobber (match_scratch:SI 2 "=X,X,&r"))]
2284   ""
2285   "@
2286    lhbrx %0,%y1
2287    sthbrx %1,%y0
2288    #"
2289   [(set_attr "length" "4,4,12")
2290    (set_attr "type" "load,store,*")])
2292 (define_split
2293   [(set (match_operand:HI 0 "gpc_reg_operand" "")
2294         (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
2295    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2296   "reload_completed"
2297   [(set (match_dup 3)
2298         (and:SI (lshiftrt:SI (match_dup 4)
2299                              (const_int 8))
2300                 (const_int 255)))
2301    (set (match_dup 2)
2302         (and:SI (ashift:SI (match_dup 4)
2303                            (const_int 8))
2304                 (const_int 65280)))             ;; 0xff00
2305    (set (match_dup 3)
2306         (ior:SI (match_dup 3)
2307                 (match_dup 2)))]
2308   "
2310   operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2311   operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2314 (define_insn "*bswapsi2_extenddi"
2315   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2316         (zero_extend:DI
2317          (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
2318   "TARGET_POWERPC64"
2319   "lwbrx %0,%y1"
2320   [(set_attr "length" "4")
2321    (set_attr "type" "load")])
2323 (define_expand "bswapsi2"
2324   [(set (match_operand:SI 0 "reg_or_mem_operand" "")
2325         (bswap:SI
2326          (match_operand:SI 1 "reg_or_mem_operand" "")))]
2327   ""
2329   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2330     operands[1] = force_reg (SImode, operands[1]);
2333 (define_insn "*bswapsi2_internal"
2334   [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
2335         (bswap:SI
2336          (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
2337   ""
2338   "@
2339    lwbrx %0,%y1
2340    stwbrx %1,%y0
2341    #"
2342   [(set_attr "length" "4,4,12")
2343    (set_attr "type" "load,store,*")])
2345 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2346 ;; zero_extract insns do not change for -mlittle.
2347 (define_split
2348   [(set (match_operand:SI 0 "gpc_reg_operand" "")
2349         (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
2350   "reload_completed"
2351   [(set (match_dup 0)                                   ; DABC
2352         (rotate:SI (match_dup 1)
2353                    (const_int 24)))
2354    (set (match_dup 0)                                   ; DCBC
2355         (ior:SI (and:SI (ashift:SI (match_dup 1)
2356                                    (const_int 8))
2357                         (const_int 16711680))
2358                 (and:SI (match_dup 0)
2359                         (const_int -16711681))))
2360    (set (match_dup 0)                                   ; DCBA
2361         (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2362                                      (const_int 24))
2363                         (const_int 255))
2364                 (and:SI (match_dup 0)
2365                         (const_int -256))))
2367   ]
2368   "")
2370 (define_expand "bswapdi2"
2371   [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2372                    (bswap:DI
2373                     (match_operand:DI 1 "reg_or_mem_operand" "")))
2374               (clobber (match_scratch:DI 2 ""))
2375               (clobber (match_scratch:DI 3 ""))])]
2376   ""
2378   if (!REG_P (operands[0]) && !REG_P (operands[1]))
2379     operands[1] = force_reg (DImode, operands[1]);
2381   if (!TARGET_POWERPC64)
2382     {
2383       /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2384          that uses 64-bit registers needs the same scratch registers as 64-bit
2385          mode.  */
2386       emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
2387       DONE;
2388     }
2391 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2392 (define_insn "*bswapdi2_ldbrx"
2393   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2394         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2395    (clobber (match_scratch:DI 2 "=X,X,&r"))
2396    (clobber (match_scratch:DI 3 "=X,X,&r"))]
2397   "TARGET_POWERPC64 && TARGET_LDBRX
2398    && (REG_P (operands[0]) || REG_P (operands[1]))"
2399   "@
2400    ldbrx %0,%y1
2401    stdbrx %1,%y0
2402    #"
2403   [(set_attr "length" "4,4,36")
2404    (set_attr "type" "load,store,*")])
2406 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2407 (define_insn "*bswapdi2_64bit"
2408   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2409         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2410    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2411    (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2412   "TARGET_POWERPC64 && !TARGET_LDBRX
2413    && (REG_P (operands[0]) || REG_P (operands[1]))
2414    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2415    && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2416   "#"
2417   [(set_attr "length" "16,12,36")])
2419 (define_split
2420   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2421         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2422    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2423    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2424   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2425   [(const_int 0)]
2426   "
2428   rtx dest   = operands[0];
2429   rtx src    = operands[1];
2430   rtx op2    = operands[2];
2431   rtx op3    = operands[3];
2432   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2433                                     BYTES_BIG_ENDIAN ? 4 : 0);
2434   rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2435                                      BYTES_BIG_ENDIAN ? 4 : 0);
2436   rtx addr1;
2437   rtx addr2;
2438   rtx word1;
2439   rtx word2;
2441   addr1 = XEXP (src, 0);
2442   if (GET_CODE (addr1) == PLUS)
2443     {
2444       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2445       if (TARGET_AVOID_XFORM)
2446         {
2447           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2448           addr2 = op2;
2449         }
2450       else
2451         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2452     }
2453   else if (TARGET_AVOID_XFORM)
2454     {
2455       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2456       addr2 = op2;
2457     }
2458   else
2459     {
2460       emit_move_insn (op2, GEN_INT (4));
2461       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2462     }
2464   word1 = change_address (src, SImode, addr1);
2465   word2 = change_address (src, SImode, addr2);
2467   if (BYTES_BIG_ENDIAN)
2468     {
2469       emit_insn (gen_bswapsi2 (op3_32, word2));
2470       emit_insn (gen_bswapsi2 (dest_32, word1));
2471     }
2472   else
2473     {
2474       emit_insn (gen_bswapsi2 (op3_32, word1));
2475       emit_insn (gen_bswapsi2 (dest_32, word2));
2476     }
2478   emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2479   emit_insn (gen_iordi3 (dest, dest, op3));
2480   DONE;
2483 (define_split
2484   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2485         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2486    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2487    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2488   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2489   [(const_int 0)]
2490   "
2492   rtx dest   = operands[0];
2493   rtx src    = operands[1];
2494   rtx op2    = operands[2];
2495   rtx op3    = operands[3];
2496   rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2497                                     BYTES_BIG_ENDIAN ? 4 : 0);
2498   rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2499                                     BYTES_BIG_ENDIAN ? 4 : 0);
2500   rtx addr1;
2501   rtx addr2;
2502   rtx word1;
2503   rtx word2;
2505   addr1 = XEXP (dest, 0);
2506   if (GET_CODE (addr1) == PLUS)
2507     {
2508       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2509       if (TARGET_AVOID_XFORM)
2510         {
2511           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2512           addr2 = op2;
2513         }
2514       else
2515         addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2516     }
2517   else if (TARGET_AVOID_XFORM)
2518     {
2519       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2520       addr2 = op2;
2521     }
2522   else
2523     {
2524       emit_move_insn (op2, GEN_INT (4));
2525       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2526     }
2528   word1 = change_address (dest, SImode, addr1);
2529   word2 = change_address (dest, SImode, addr2);
2531   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2533   if (BYTES_BIG_ENDIAN)
2534     {
2535       emit_insn (gen_bswapsi2 (word1, src_si));
2536       emit_insn (gen_bswapsi2 (word2, op3_si));
2537     }
2538   else
2539     {
2540       emit_insn (gen_bswapsi2 (word2, src_si));
2541       emit_insn (gen_bswapsi2 (word1, op3_si));
2542     }
2543   DONE;
2546 (define_split
2547   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2548         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2549    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2550    (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2551   "TARGET_POWERPC64 && reload_completed"
2552   [(const_int 0)]
2553   "
2555   rtx dest    = operands[0];
2556   rtx src     = operands[1];
2557   rtx op2     = operands[2];
2558   rtx op3     = operands[3];
2559   int lo_off  = BYTES_BIG_ENDIAN ? 4 : 0;
2560   rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2561   rtx src_si  = simplify_gen_subreg (SImode, src, DImode, lo_off);
2562   rtx op2_si  = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2563   rtx op3_si  = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2565   emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2566   emit_insn (gen_bswapsi2 (dest_si, src_si));
2567   emit_insn (gen_bswapsi2 (op3_si, op2_si));
2568   emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2569   emit_insn (gen_iordi3 (dest, dest, op3));
2570   DONE;
2573 (define_insn "bswapdi2_32bit"
2574   [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2575         (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2576    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2577   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2578   "#"
2579   [(set_attr "length" "16,12,36")])
2581 (define_split
2582   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2583         (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2584    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2585   "!TARGET_POWERPC64 && reload_completed"
2586   [(const_int 0)]
2587   "
2589   rtx dest  = operands[0];
2590   rtx src   = operands[1];
2591   rtx op2   = operands[2];
2592   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2593   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2594   rtx addr1;
2595   rtx addr2;
2596   rtx word1;
2597   rtx word2;
2599   addr1 = XEXP (src, 0);
2600   if (GET_CODE (addr1) == PLUS)
2601     {
2602       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2603       if (TARGET_AVOID_XFORM
2604           || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2605         {
2606           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2607           addr2 = op2;
2608         }
2609       else
2610         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2611     }
2612   else if (TARGET_AVOID_XFORM
2613            || REGNO (addr1) == REGNO (dest2))
2614     {
2615       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2616       addr2 = op2;
2617     }
2618   else
2619     {
2620       emit_move_insn (op2, GEN_INT (4));
2621       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2622     }
2624   word1 = change_address (src, SImode, addr1);
2625   word2 = change_address (src, SImode, addr2);
2627   emit_insn (gen_bswapsi2 (dest2, word1));
2628   /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2629      thus allowing us to omit an early clobber on the output.  */
2630   emit_insn (gen_bswapsi2 (dest1, word2));
2631   DONE;
2634 (define_split
2635   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2636         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2637    (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2638   "!TARGET_POWERPC64 && reload_completed"
2639   [(const_int 0)]
2640   "
2642   rtx dest = operands[0];
2643   rtx src  = operands[1];
2644   rtx op2  = operands[2];
2645   rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2646   rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2647   rtx addr1;
2648   rtx addr2;
2649   rtx word1;
2650   rtx word2;
2652   addr1 = XEXP (dest, 0);
2653   if (GET_CODE (addr1) == PLUS)
2654     {
2655       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2656       if (TARGET_AVOID_XFORM)
2657         {
2658           emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2659           addr2 = op2;
2660         }
2661       else
2662         addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2663     }
2664   else if (TARGET_AVOID_XFORM)
2665     {
2666       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2667       addr2 = op2;
2668     }
2669   else
2670     {
2671       emit_move_insn (op2, GEN_INT (4));
2672       addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2673     }
2675   word1 = change_address (dest, SImode, addr1);
2676   word2 = change_address (dest, SImode, addr2);
2678   emit_insn (gen_bswapsi2 (word2, src1));
2679   emit_insn (gen_bswapsi2 (word1, src2));
2680   DONE;
2683 (define_split
2684   [(set (match_operand:DI 0 "gpc_reg_operand" "")
2685         (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2686    (clobber (match_operand:SI 2 "" ""))]
2687   "!TARGET_POWERPC64 && reload_completed"
2688   [(const_int 0)]
2689   "
2691   rtx dest  = operands[0];
2692   rtx src   = operands[1];
2693   rtx src1  = simplify_gen_subreg (SImode, src, DImode, 0);
2694   rtx src2  = simplify_gen_subreg (SImode, src, DImode, 4);
2695   rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2696   rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2698   emit_insn (gen_bswapsi2 (dest1, src2));
2699   emit_insn (gen_bswapsi2 (dest2, src1));
2700   DONE;
2704 (define_insn "mul<mode>3"
2705   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2706         (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2707                   (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2708   ""
2709   "@
2710    mull<wd> %0,%1,%2
2711    mulli %0,%1,%2"
2712    [(set_attr "type" "mul")
2713     (set (attr "size")
2714       (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2715                 (const_string "8")
2716              (match_operand:GPR 2 "short_cint_operand" "")
2717                 (const_string "16")]
2718         (const_string "<bits>")))])
2720 (define_insn_and_split "*mul<mode>3_dot"
2721   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2722         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2723                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2724                     (const_int 0)))
2725    (clobber (match_scratch:GPR 0 "=r,r"))]
2726   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2727   "@
2728    mull<wd>. %0,%1,%2
2729    #"
2730   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2731   [(set (match_dup 0)
2732         (mult:GPR (match_dup 1)
2733                   (match_dup 2)))
2734    (set (match_dup 3)
2735         (compare:CC (match_dup 0)
2736                     (const_int 0)))]
2737   ""
2738   [(set_attr "type" "mul")
2739    (set_attr "size" "<bits>")
2740    (set_attr "dot" "yes")
2741    (set_attr "length" "4,8")])
2743 (define_insn_and_split "*mul<mode>3_dot2"
2744   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2745         (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2746                               (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2747                     (const_int 0)))
2748    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2749         (mult:GPR (match_dup 1)
2750                   (match_dup 2)))]
2751   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
2752   "@
2753    mull<wd>. %0,%1,%2
2754    #"
2755   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2756   [(set (match_dup 0)
2757         (mult:GPR (match_dup 1)
2758                   (match_dup 2)))
2759    (set (match_dup 3)
2760         (compare:CC (match_dup 0)
2761                     (const_int 0)))]
2762   ""
2763   [(set_attr "type" "mul")
2764    (set_attr "size" "<bits>")
2765    (set_attr "dot" "yes")
2766    (set_attr "length" "4,8")])
2769 (define_expand "<su>mul<mode>3_highpart"
2770   [(set (match_operand:GPR 0 "gpc_reg_operand")
2771         (subreg:GPR
2772           (mult:<DMODE> (any_extend:<DMODE>
2773                           (match_operand:GPR 1 "gpc_reg_operand"))
2774                         (any_extend:<DMODE>
2775                           (match_operand:GPR 2 "gpc_reg_operand")))
2776          0))]
2777   ""
2779   if (<MODE>mode == SImode && TARGET_POWERPC64)
2780     {
2781       emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2782                                              operands[2]));
2783       DONE;
2784     }
2786   if (!WORDS_BIG_ENDIAN)
2787     {
2788       emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2789                                                  operands[2]));
2790       DONE;
2791     }
2794 (define_insn "*<su>mul<mode>3_highpart"
2795   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2796         (subreg:GPR
2797           (mult:<DMODE> (any_extend:<DMODE>
2798                           (match_operand:GPR 1 "gpc_reg_operand" "r"))
2799                         (any_extend:<DMODE>
2800                           (match_operand:GPR 2 "gpc_reg_operand" "r")))
2801          0))]
2802   "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2803   "mulh<wd><u> %0,%1,%2"
2804   [(set_attr "type" "mul")
2805    (set_attr "size" "<bits>")])
2807 (define_insn "<su>mulsi3_highpart_le"
2808   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2809         (subreg:SI
2810           (mult:DI (any_extend:DI
2811                      (match_operand:SI 1 "gpc_reg_operand" "r"))
2812                    (any_extend:DI
2813                      (match_operand:SI 2 "gpc_reg_operand" "r")))
2814          4))]
2815   "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2816   "mulhw<u> %0,%1,%2"
2817   [(set_attr "type" "mul")])
2819 (define_insn "<su>muldi3_highpart_le"
2820   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2821         (subreg:DI
2822           (mult:TI (any_extend:TI
2823                      (match_operand:DI 1 "gpc_reg_operand" "r"))
2824                    (any_extend:TI
2825                      (match_operand:DI 2 "gpc_reg_operand" "r")))
2826          8))]
2827   "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2828   "mulhd<u> %0,%1,%2"
2829   [(set_attr "type" "mul")
2830    (set_attr "size" "64")])
2832 (define_insn "<su>mulsi3_highpart_64"
2833   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2834         (truncate:SI
2835           (lshiftrt:DI
2836             (mult:DI (any_extend:DI
2837                        (match_operand:SI 1 "gpc_reg_operand" "r"))
2838                      (any_extend:DI
2839                        (match_operand:SI 2 "gpc_reg_operand" "r")))
2840             (const_int 32))))]
2841   "TARGET_POWERPC64"
2842   "mulhw<u> %0,%1,%2"
2843   [(set_attr "type" "mul")])
2845 (define_expand "<u>mul<mode><dmode>3"
2846   [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
2847         (mult:<DMODE> (any_extend:<DMODE>
2848                         (match_operand:GPR 1 "gpc_reg_operand"))
2849                       (any_extend:<DMODE>
2850                         (match_operand:GPR 2 "gpc_reg_operand"))))]
2851   "!(<MODE>mode == SImode && TARGET_POWERPC64)"
2853   rtx l = gen_reg_rtx (<MODE>mode);
2854   rtx h = gen_reg_rtx (<MODE>mode);
2855   emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
2856   emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
2857   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
2858   emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
2859   DONE;
2862 (define_insn "*maddld4"
2863   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2864         (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
2865                           (match_operand:DI 2 "gpc_reg_operand" "r"))
2866                  (match_operand:DI 3 "gpc_reg_operand" "r")))]
2867   "TARGET_MADDLD"
2868   "maddld %0,%1,%2,%3"
2869   [(set_attr "type" "mul")])
2871 (define_insn "udiv<mode>3"
2872   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2873         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2874                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2875   ""
2876   "div<wd>u %0,%1,%2"
2877   [(set_attr "type" "div")
2878    (set_attr "size" "<bits>")])
2881 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
2882 ;; modulus.  If it isn't a power of two, force operands into register and do
2883 ;; a normal divide.
2884 (define_expand "div<mode>3"
2885   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2886         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2887                  (match_operand:GPR 2 "reg_or_cint_operand" "")))]
2888   ""
2890   if (CONST_INT_P (operands[2])
2891       && INTVAL (operands[2]) > 0
2892       && exact_log2 (INTVAL (operands[2])) >= 0)
2893     {
2894       emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
2895       DONE;
2896     }
2898   operands[2] = force_reg (<MODE>mode, operands[2]);
2901 (define_insn "*div<mode>3"
2902   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2903         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2904                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
2905   ""
2906   "div<wd> %0,%1,%2"
2907   [(set_attr "type" "div")
2908    (set_attr "size" "<bits>")])
2910 (define_insn "div<mode>3_sra"
2911   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2912         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2913                  (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
2914    (clobber (reg:GPR CA_REGNO))]
2915   ""
2916   "sra<wd>i %0,%1,%p2\;addze %0,%0"
2917   [(set_attr "type" "two")
2918    (set_attr "length" "8")])
2920 (define_insn_and_split "*div<mode>3_sra_dot"
2921   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2922         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2923                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2924                     (const_int 0)))
2925    (clobber (match_scratch:GPR 0 "=r,r"))
2926    (clobber (reg:GPR CA_REGNO))]
2927   "<MODE>mode == Pmode"
2928   "@
2929    sra<wd>i %0,%1,%p2\;addze. %0,%0
2930    #"
2931   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2932   [(parallel [(set (match_dup 0)
2933                    (div:GPR (match_dup 1)
2934                             (match_dup 2)))
2935               (clobber (reg:GPR CA_REGNO))])
2936    (set (match_dup 3)
2937         (compare:CC (match_dup 0)
2938                     (const_int 0)))]
2939   ""
2940   [(set_attr "type" "two")
2941    (set_attr "length" "8,12")
2942    (set_attr "cell_micro" "not")])
2944 (define_insn_and_split "*div<mode>3_sra_dot2"
2945   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2946         (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2947                              (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
2948                     (const_int 0)))
2949    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2950         (div:GPR (match_dup 1)
2951                  (match_dup 2)))
2952    (clobber (reg:GPR CA_REGNO))]
2953   "<MODE>mode == Pmode"
2954   "@
2955    sra<wd>i %0,%1,%p2\;addze. %0,%0
2956    #"
2957   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2958   [(parallel [(set (match_dup 0)
2959                    (div:GPR (match_dup 1)
2960                             (match_dup 2)))
2961               (clobber (reg:GPR CA_REGNO))])
2962    (set (match_dup 3)
2963         (compare:CC (match_dup 0)
2964                     (const_int 0)))]
2965   ""
2966   [(set_attr "type" "two")
2967    (set_attr "length" "8,12")
2968    (set_attr "cell_micro" "not")])
2970 (define_expand "mod<mode>3"
2971   [(set (match_operand:GPR 0 "gpc_reg_operand")
2972         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
2973                  (match_operand:GPR 2 "reg_or_cint_operand")))]
2974   ""
2976   int i;
2977   rtx temp1;
2978   rtx temp2;
2980   if (GET_CODE (operands[2]) != CONST_INT
2981       || INTVAL (operands[2]) <= 0
2982       || (i = exact_log2 (INTVAL (operands[2]))) < 0)
2983     {
2984       if (!TARGET_MODULO)
2985         FAIL;
2987       operands[2] = force_reg (<MODE>mode, operands[2]);
2988     }
2989   else
2990     {
2991       temp1 = gen_reg_rtx (<MODE>mode);
2992       temp2 = gen_reg_rtx (<MODE>mode);
2994       emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
2995       emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
2996       emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
2997       DONE;
2998     }
3001 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3002 ;; mod, prefer putting the result of mod into a different register
3003 (define_insn "*mod<mode>3"
3004   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3005         (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3006                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3007   "TARGET_MODULO"
3008   "mods<wd> %0,%1,%2"
3009   [(set_attr "type" "div")
3010    (set_attr "size" "<bits>")])
3013 (define_insn "umod<mode>3"
3014   [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3015         (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3016                   (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3017   "TARGET_MODULO"
3018   "modu<wd> %0,%1,%2"
3019   [(set_attr "type" "div")
3020    (set_attr "size" "<bits>")])
3022 ;; On machines with modulo support, do a combined div/mod the old fashioned
3023 ;; method, since the multiply/subtract is faster than doing the mod instruction
3024 ;; after a divide.
3026 (define_peephole2
3027   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3028         (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3029                  (match_operand:GPR 2 "gpc_reg_operand" "")))
3030    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3031         (mod:GPR (match_dup 1)
3032                  (match_dup 2)))]
3033   "TARGET_MODULO
3034    && ! reg_mentioned_p (operands[0], operands[1])
3035    && ! reg_mentioned_p (operands[0], operands[2])
3036    && ! reg_mentioned_p (operands[3], operands[1])
3037    && ! reg_mentioned_p (operands[3], operands[2])"
3038   [(set (match_dup 0)
3039         (div:GPR (match_dup 1)
3040                  (match_dup 2)))
3041    (set (match_dup 3)
3042         (mult:GPR (match_dup 0)
3043                   (match_dup 2)))
3044    (set (match_dup 3)
3045         (minus:GPR (match_dup 1)
3046                    (match_dup 3)))])
3048 (define_peephole2
3049   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3050         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3051                   (match_operand:GPR 2 "gpc_reg_operand" "")))
3052    (set (match_operand:GPR 3 "gpc_reg_operand" "")
3053         (umod:GPR (match_dup 1)
3054                   (match_dup 2)))]
3055   "TARGET_MODULO
3056    && ! reg_mentioned_p (operands[0], operands[1])
3057    && ! reg_mentioned_p (operands[0], operands[2])
3058    && ! reg_mentioned_p (operands[3], operands[1])
3059    && ! reg_mentioned_p (operands[3], operands[2])"
3060   [(set (match_dup 0)
3061         (div:GPR (match_dup 1)
3062                  (match_dup 2)))
3063    (set (match_dup 3)
3064         (mult:GPR (match_dup 0)
3065                   (match_dup 2)))
3066    (set (match_dup 3)
3067         (minus:GPR (match_dup 1)
3068                    (match_dup 3)))])
3071 ;; Logical instructions
3072 ;; The logical instructions are mostly combined by using match_operator,
3073 ;; but the plain AND insns are somewhat different because there is no
3074 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3075 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
3077 (define_expand "and<mode>3"
3078   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3079         (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3080                  (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3081   ""
3083   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3084     {
3085       rs6000_split_logical (operands, AND, false, false, false);
3086       DONE;
3087     }
3089   if (CONST_INT_P (operands[2]))
3090     {
3091       if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3092         {
3093           emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3094           DONE;
3095         }
3097       if (logical_const_operand (operands[2], <MODE>mode)
3098           && rs6000_gen_cell_microcode)
3099         {
3100           emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3101           DONE;
3102         }
3104       if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3105         {
3106           rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3107           DONE;
3108         }
3110       operands[2] = force_reg (<MODE>mode, operands[2]);
3111     }
3115 (define_insn "and<mode>3_imm"
3116   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3117         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3118                  (match_operand:GPR 2 "logical_const_operand" "n")))
3119    (clobber (match_scratch:CC 3 "=x"))]
3120   "rs6000_gen_cell_microcode
3121    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3122   "andi%e2. %0,%1,%u2"
3123   [(set_attr "type" "logical")
3124    (set_attr "dot" "yes")])
3126 (define_insn_and_split "*and<mode>3_imm_dot"
3127   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3128         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3129                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3130                     (const_int 0)))
3131    (clobber (match_scratch:GPR 0 "=r,r"))
3132    (clobber (match_scratch:CC 4 "=X,x"))]
3133   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3134    && rs6000_gen_cell_microcode
3135    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3136   "@
3137    andi%e2. %0,%1,%u2
3138    #"
3139   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3140   [(parallel [(set (match_dup 0)
3141                    (and:GPR (match_dup 1)
3142                             (match_dup 2)))
3143               (clobber (match_dup 4))])
3144    (set (match_dup 3)
3145         (compare:CC (match_dup 0)
3146                     (const_int 0)))]
3147   ""
3148   [(set_attr "type" "logical")
3149    (set_attr "dot" "yes")
3150    (set_attr "length" "4,8")])
3152 (define_insn_and_split "*and<mode>3_imm_dot2"
3153   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3154         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3155                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3156                     (const_int 0)))
3157    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3158         (and:GPR (match_dup 1)
3159                  (match_dup 2)))
3160    (clobber (match_scratch:CC 4 "=X,x"))]
3161   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3162    && rs6000_gen_cell_microcode
3163    && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3164   "@
3165    andi%e2. %0,%1,%u2
3166    #"
3167   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3168   [(parallel [(set (match_dup 0)
3169                    (and:GPR (match_dup 1)
3170                             (match_dup 2)))
3171               (clobber (match_dup 4))])
3172    (set (match_dup 3)
3173         (compare:CC (match_dup 0)
3174                     (const_int 0)))]
3175   ""
3176   [(set_attr "type" "logical")
3177    (set_attr "dot" "yes")
3178    (set_attr "length" "4,8")])
3180 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3181   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3182         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3183                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3184                     (const_int 0)))
3185    (clobber (match_scratch:GPR 0 "=r,r"))]
3186   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3187    && rs6000_gen_cell_microcode"
3188   "@
3189    andi%e2. %0,%1,%u2
3190    #"
3191   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3192   [(set (match_dup 0)
3193         (and:GPR (match_dup 1)
3194                  (match_dup 2)))
3195    (set (match_dup 3)
3196         (compare:CC (match_dup 0)
3197                     (const_int 0)))]
3198   ""
3199   [(set_attr "type" "logical")
3200    (set_attr "dot" "yes")
3201    (set_attr "length" "4,8")])
3203 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3204   [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3205         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3206                              (match_operand:GPR 2 "logical_const_operand" "n,n"))
3207                     (const_int 0)))
3208    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3209         (and:GPR (match_dup 1)
3210                  (match_dup 2)))]
3211   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3212    && rs6000_gen_cell_microcode"
3213   "@
3214    andi%e2. %0,%1,%u2
3215    #"
3216   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3217   [(set (match_dup 0)
3218         (and:GPR (match_dup 1)
3219                  (match_dup 2)))
3220    (set (match_dup 3)
3221         (compare:CC (match_dup 0)
3222                     (const_int 0)))]
3223   ""
3224   [(set_attr "type" "logical")
3225    (set_attr "dot" "yes")
3226    (set_attr "length" "4,8")])
3228 (define_insn "*and<mode>3_imm_dot_shifted"
3229   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3230         (compare:CC
3231           (and:GPR
3232             (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3233                           (match_operand:SI 4 "const_int_operand" "n"))
3234             (match_operand:GPR 2 "const_int_operand" "n"))
3235           (const_int 0)))
3236    (clobber (match_scratch:GPR 0 "=r"))]
3237   "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3238                                    << INTVAL (operands[4])),
3239                           DImode)
3240    && (<MODE>mode == Pmode
3241        || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)
3242    && rs6000_gen_cell_microcode"
3244   operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3245   return "andi%e2. %0,%1,%u2";
3247   [(set_attr "type" "logical")
3248    (set_attr "dot" "yes")])
3251 (define_insn "and<mode>3_mask"
3252   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3253         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3254                  (match_operand:GPR 2 "const_int_operand" "n")))]
3255   "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3257   return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3259   [(set_attr "type" "shift")])
3261 (define_insn_and_split "*and<mode>3_mask_dot"
3262   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3263         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3264                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3265                     (const_int 0)))
3266    (clobber (match_scratch:GPR 0 "=r,r"))]
3267   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3268    && rs6000_gen_cell_microcode
3269    && !logical_const_operand (operands[2], <MODE>mode)
3270    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3272   if (which_alternative == 0)
3273     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3274   else
3275     return "#";
3277   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3278   [(set (match_dup 0)
3279         (and:GPR (match_dup 1)
3280                  (match_dup 2)))
3281    (set (match_dup 3)
3282         (compare:CC (match_dup 0)
3283                     (const_int 0)))]
3284   ""
3285   [(set_attr "type" "shift")
3286    (set_attr "dot" "yes")
3287    (set_attr "length" "4,8")])
3289 (define_insn_and_split "*and<mode>3_mask_dot2"
3290   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3291         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3292                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3293                     (const_int 0)))
3294    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3295         (and:GPR (match_dup 1)
3296                  (match_dup 2)))]
3297   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3298    && rs6000_gen_cell_microcode
3299    && !logical_const_operand (operands[2], <MODE>mode)
3300    && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3302   if (which_alternative == 0)
3303     return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3304   else
3305     return "#";
3307   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3308   [(set (match_dup 0)
3309         (and:GPR (match_dup 1)
3310                  (match_dup 2)))
3311    (set (match_dup 3)
3312         (compare:CC (match_dup 0)
3313                     (const_int 0)))]
3314   ""
3315   [(set_attr "type" "shift")
3316    (set_attr "dot" "yes")
3317    (set_attr "length" "4,8")])
3320 (define_insn_and_split "*and<mode>3_2insn"
3321   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3322         (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3323                  (match_operand:GPR 2 "const_int_operand" "n")))]
3324   "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3325    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3326         || (logical_const_operand (operands[2], <MODE>mode)
3327             && rs6000_gen_cell_microcode))"
3328   "#"
3329   "&& 1"
3330   [(pc)]
3332   rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3333   DONE;
3335   [(set_attr "type" "shift")
3336    (set_attr "length" "8")])
3338 (define_insn_and_split "*and<mode>3_2insn_dot"
3339   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3340         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3341                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3342                     (const_int 0)))
3343    (clobber (match_scratch:GPR 0 "=r,r"))]
3344   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3345    && rs6000_gen_cell_microcode
3346    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3347    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3348         || (logical_const_operand (operands[2], <MODE>mode)
3349             && rs6000_gen_cell_microcode))"
3350   "#"
3351   "&& reload_completed"
3352   [(pc)]
3354   rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3355   DONE;
3357   [(set_attr "type" "shift")
3358    (set_attr "dot" "yes")
3359    (set_attr "length" "8,12")])
3361 (define_insn_and_split "*and<mode>3_2insn_dot2"
3362   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3363         (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3364                              (match_operand:GPR 2 "const_int_operand" "n,n"))
3365                     (const_int 0)))
3366    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3367         (and:GPR (match_dup 1)
3368                  (match_dup 2)))]
3369   "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3370    && rs6000_gen_cell_microcode
3371    && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3372    && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3373         || (logical_const_operand (operands[2], <MODE>mode)
3374             && rs6000_gen_cell_microcode))"
3375   "#"
3376   "&& reload_completed"
3377   [(pc)]
3379   rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3380   DONE;
3382   [(set_attr "type" "shift")
3383    (set_attr "dot" "yes")
3384    (set_attr "length" "8,12")])
3387 (define_expand "<code><mode>3"
3388   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3389         (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3390                     (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3391   ""
3393   if (<MODE>mode == DImode && !TARGET_POWERPC64)
3394     {
3395       rs6000_split_logical (operands, <CODE>, false, false, false);
3396       DONE;
3397     }
3399   if (non_logical_cint_operand (operands[2], <MODE>mode))
3400     {
3401       rtx tmp = ((!can_create_pseudo_p ()
3402                   || rtx_equal_p (operands[0], operands[1]))
3403                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3405       HOST_WIDE_INT value = INTVAL (operands[2]);
3406       HOST_WIDE_INT lo = value & 0xffff;
3407       HOST_WIDE_INT hi = value - lo;
3409       emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3410       emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3411       DONE;
3412     }
3414   if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3415     operands[2] = force_reg (<MODE>mode, operands[2]);
3418 (define_split
3419   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3420         (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3421                     (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3422   ""
3423   [(set (match_dup 3)
3424         (iorxor:GPR (match_dup 1)
3425                     (match_dup 4)))
3426    (set (match_dup 0)
3427         (iorxor:GPR (match_dup 3)
3428                     (match_dup 5)))]
3430   operands[3] = ((!can_create_pseudo_p ()
3431                   || rtx_equal_p (operands[0], operands[1]))
3432                  ? operands[0] : gen_reg_rtx (<MODE>mode));
3434   HOST_WIDE_INT value = INTVAL (operands[2]);
3435   HOST_WIDE_INT lo = value & 0xffff;
3436   HOST_WIDE_INT hi = value - lo;
3438   operands[4] = GEN_INT (hi);
3439   operands[5] = GEN_INT (lo);
3442 (define_insn "*bool<mode>3_imm"
3443   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3444         (match_operator:GPR 3 "boolean_or_operator"
3445          [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3446           (match_operand:GPR 2 "logical_const_operand" "n")]))]
3447   ""
3448   "%q3i%e2 %0,%1,%u2"
3449   [(set_attr "type" "logical")])
3451 (define_insn "*bool<mode>3"
3452   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3453         (match_operator:GPR 3 "boolean_operator"
3454          [(match_operand:GPR 1 "gpc_reg_operand" "r")
3455           (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3456   ""
3457   "%q3 %0,%1,%2"
3458   [(set_attr "type" "logical")])
3460 (define_insn_and_split "*bool<mode>3_dot"
3461   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3462         (compare:CC (match_operator:GPR 3 "boolean_operator"
3463          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3464           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3465          (const_int 0)))
3466    (clobber (match_scratch:GPR 0 "=r,r"))]
3467   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3468   "@
3469    %q3. %0,%1,%2
3470    #"
3471   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3472   [(set (match_dup 0)
3473         (match_dup 3))
3474    (set (match_dup 4)
3475         (compare:CC (match_dup 0)
3476                     (const_int 0)))]
3477   ""
3478   [(set_attr "type" "logical")
3479    (set_attr "dot" "yes")
3480    (set_attr "length" "4,8")])
3482 (define_insn_and_split "*bool<mode>3_dot2"
3483   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3484         (compare:CC (match_operator:GPR 3 "boolean_operator"
3485          [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3486           (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3487          (const_int 0)))
3488    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3489         (match_dup 3))]
3490   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3491   "@
3492    %q3. %0,%1,%2
3493    #"
3494   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3495   [(set (match_dup 0)
3496         (match_dup 3))
3497    (set (match_dup 4)
3498         (compare:CC (match_dup 0)
3499                     (const_int 0)))]
3500   ""
3501   [(set_attr "type" "logical")
3502    (set_attr "dot" "yes")
3503    (set_attr "length" "4,8")])
3506 (define_insn "*boolc<mode>3"
3507   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3508         (match_operator:GPR 3 "boolean_operator"
3509          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3510           (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3511   ""
3512   "%q3 %0,%1,%2"
3513   [(set_attr "type" "logical")])
3515 (define_insn_and_split "*boolc<mode>3_dot"
3516   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3517         (compare:CC (match_operator:GPR 3 "boolean_operator"
3518          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3519           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3520          (const_int 0)))
3521    (clobber (match_scratch:GPR 0 "=r,r"))]
3522   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3523   "@
3524    %q3. %0,%1,%2
3525    #"
3526   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3527   [(set (match_dup 0)
3528         (match_dup 3))
3529    (set (match_dup 4)
3530         (compare:CC (match_dup 0)
3531                     (const_int 0)))]
3532   ""
3533   [(set_attr "type" "logical")
3534    (set_attr "dot" "yes")
3535    (set_attr "length" "4,8")])
3537 (define_insn_and_split "*boolc<mode>3_dot2"
3538   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3539         (compare:CC (match_operator:GPR 3 "boolean_operator"
3540          [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3541           (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3542          (const_int 0)))
3543    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3544         (match_dup 3))]
3545   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3546   "@
3547    %q3. %0,%1,%2
3548    #"
3549   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3550   [(set (match_dup 0)
3551         (match_dup 3))
3552    (set (match_dup 4)
3553         (compare:CC (match_dup 0)
3554                     (const_int 0)))]
3555   ""
3556   [(set_attr "type" "logical")
3557    (set_attr "dot" "yes")
3558    (set_attr "length" "4,8")])
3561 (define_insn "*boolcc<mode>3"
3562   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3563         (match_operator:GPR 3 "boolean_operator"
3564          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3565           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3566   ""
3567   "%q3 %0,%1,%2"
3568   [(set_attr "type" "logical")])
3570 (define_insn_and_split "*boolcc<mode>3_dot"
3571   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3572         (compare:CC (match_operator:GPR 3 "boolean_operator"
3573          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3574           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3575          (const_int 0)))
3576    (clobber (match_scratch:GPR 0 "=r,r"))]
3577   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3578   "@
3579    %q3. %0,%1,%2
3580    #"
3581   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3582   [(set (match_dup 0)
3583         (match_dup 3))
3584    (set (match_dup 4)
3585         (compare:CC (match_dup 0)
3586                     (const_int 0)))]
3587   ""
3588   [(set_attr "type" "logical")
3589    (set_attr "dot" "yes")
3590    (set_attr "length" "4,8")])
3592 (define_insn_and_split "*boolcc<mode>3_dot2"
3593   [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3594         (compare:CC (match_operator:GPR 3 "boolean_operator"
3595          [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3596           (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3597          (const_int 0)))
3598    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3599         (match_dup 3))]
3600   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3601   "@
3602    %q3. %0,%1,%2
3603    #"
3604   "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3605   [(set (match_dup 0)
3606         (match_dup 3))
3607    (set (match_dup 4)
3608         (compare:CC (match_dup 0)
3609                     (const_int 0)))]
3610   ""
3611   [(set_attr "type" "logical")
3612    (set_attr "dot" "yes")
3613    (set_attr "length" "4,8")])
3616 ;; TODO: Should have dots of this as well.
3617 (define_insn "*eqv<mode>3"
3618   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3619         (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3620                           (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3621   ""
3622   "eqv %0,%1,%2"
3623   [(set_attr "type" "logical")])
3625 ;; Rotate-and-mask and insert.
3627 (define_insn "*rotl<mode>3_mask"
3628   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3629         (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3630                   [(match_operand:GPR 1 "gpc_reg_operand" "r")
3631                    (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3632                  (match_operand:GPR 3 "const_int_operand" "n")))]
3633   "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3635   return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3637   [(set_attr "type" "shift")
3638    (set_attr "maybe_var_shift" "yes")])
3640 (define_insn_and_split "*rotl<mode>3_mask_dot"
3641   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3642         (compare:CC
3643           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3644                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3645                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3646                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3647           (const_int 0)))
3648    (clobber (match_scratch:GPR 0 "=r,r"))]
3649   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3650    && rs6000_gen_cell_microcode
3651    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3653   if (which_alternative == 0)
3654     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3655   else
3656     return "#";
3658   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3659   [(set (match_dup 0)
3660         (and:GPR (match_dup 4)
3661                  (match_dup 3)))
3662    (set (match_dup 5)
3663         (compare:CC (match_dup 0)
3664                     (const_int 0)))]
3665   ""
3666   [(set_attr "type" "shift")
3667    (set_attr "maybe_var_shift" "yes")
3668    (set_attr "dot" "yes")
3669    (set_attr "length" "4,8")])
3671 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3672   [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3673         (compare:CC
3674           (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3675                     [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3676                      (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3677                    (match_operand:GPR 3 "const_int_operand" "n,n"))
3678           (const_int 0)))
3679    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3680         (and:GPR (match_dup 4)
3681                  (match_dup 3)))]
3682   "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3683    && rs6000_gen_cell_microcode
3684    && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3686   if (which_alternative == 0)
3687     return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3688   else
3689     return "#";
3691   "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3692   [(set (match_dup 0)
3693         (and:GPR (match_dup 4)
3694                  (match_dup 3)))
3695    (set (match_dup 5)
3696         (compare:CC (match_dup 0)
3697                     (const_int 0)))]
3698   ""
3699   [(set_attr "type" "shift")
3700    (set_attr "maybe_var_shift" "yes")
3701    (set_attr "dot" "yes")
3702    (set_attr "length" "4,8")])
3704 ; Special case for less-than-0.  We can do it with just one machine
3705 ; instruction, but the generic optimizers do not realise it is cheap.
3706 (define_insn "*lt0_disi"
3707   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3708         (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r")
3709                (const_int 0)))]
3710   "TARGET_POWERPC64"
3711   "rlwinm %0,%1,1,31,31"
3712   [(set_attr "type" "shift")])
3716 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3717 ; both are an AND so are the same precedence).
3718 (define_insn "*rotl<mode>3_insert"
3719   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3720         (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3721                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3722                             (match_operand:SI 2 "const_int_operand" "n")])
3723                           (match_operand:GPR 3 "const_int_operand" "n"))
3724                  (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3725                           (match_operand:GPR 6 "const_int_operand" "n"))))]
3726   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3727    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3729   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3731   [(set_attr "type" "insert")])
3732 ; FIXME: this needs an attr "size", so that the scheduler can see the
3733 ; difference between rlwimi and rldimi.  We also might want dot forms,
3734 ; but not for rlwimi on POWER4 and similar processors.
3736 (define_insn "*rotl<mode>3_insert_2"
3737   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3738         (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3739                           (match_operand:GPR 6 "const_int_operand" "n"))
3740                  (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3741                            [(match_operand:GPR 1 "gpc_reg_operand" "r")
3742                             (match_operand:SI 2 "const_int_operand" "n")])
3743                           (match_operand:GPR 3 "const_int_operand" "n"))))]
3744   "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3745    && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3747   return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3749   [(set_attr "type" "insert")])
3751 ; There are also some forms without one of the ANDs.
3752 (define_insn "*rotl<mode>3_insert_3"
3753   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3754         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3755                           (match_operand:GPR 4 "const_int_operand" "n"))
3756                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3757                              (match_operand:SI 2 "const_int_operand" "n"))))]
3758   "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3760   if (<MODE>mode == SImode)
3761     return "rlwimi %0,%1,%h2,0,31-%h2";
3762   else
3763     return "rldimi %0,%1,%H2,0";
3765   [(set_attr "type" "insert")])
3767 (define_insn "*rotl<mode>3_insert_4"
3768   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3769         (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3770                           (match_operand:GPR 4 "const_int_operand" "n"))
3771                  (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3772                                (match_operand:SI 2 "const_int_operand" "n"))))]
3773   "<MODE>mode == SImode &&
3774    GET_MODE_PRECISION (<MODE>mode)
3775    == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3777   operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3778                          - INTVAL (operands[2]));
3779   if (<MODE>mode == SImode)
3780     return "rlwimi %0,%1,%h2,32-%h2,31";
3781   else
3782     return "rldimi %0,%1,%H2,64-%H2";
3784   [(set_attr "type" "insert")])
3787 ; This handles the important case of multiple-precision shifts.  There is
3788 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3789 (define_split
3790   [(set (match_operand:GPR 0 "gpc_reg_operand")
3791         (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3792                              (match_operand:SI 3 "const_int_operand"))
3793                  (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3794                                (match_operand:SI 4 "const_int_operand"))))]
3795   "can_create_pseudo_p ()
3796    && INTVAL (operands[3]) + INTVAL (operands[4])
3797       >= GET_MODE_PRECISION (<MODE>mode)"
3798   [(set (match_dup 5)
3799         (lshiftrt:GPR (match_dup 2)
3800                       (match_dup 4)))
3801    (set (match_dup 0)
3802         (ior:GPR (and:GPR (match_dup 5)
3803                           (match_dup 6))
3804                  (ashift:GPR (match_dup 1)
3805                              (match_dup 3))))]
3807   unsigned HOST_WIDE_INT mask = 1;
3808   mask = (mask << INTVAL (operands[3])) - 1;
3809   operands[5] = gen_reg_rtx (<MODE>mode);
3810   operands[6] = GEN_INT (mask);
3813 (define_split
3814   [(set (match_operand:GPR 0 "gpc_reg_operand")
3815         (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3816                                (match_operand:SI 4 "const_int_operand"))
3817                  (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3818                              (match_operand:SI 3 "const_int_operand"))))]
3819   "can_create_pseudo_p ()
3820    && INTVAL (operands[3]) + INTVAL (operands[4])
3821       >= GET_MODE_PRECISION (<MODE>mode)"
3822   [(set (match_dup 5)
3823         (lshiftrt:GPR (match_dup 2)
3824                       (match_dup 4)))
3825    (set (match_dup 0)
3826         (ior:GPR (and:GPR (match_dup 5)
3827                           (match_dup 6))
3828                  (ashift:GPR (match_dup 1)
3829                              (match_dup 3))))]
3831   unsigned HOST_WIDE_INT mask = 1;
3832   mask = (mask << INTVAL (operands[3])) - 1;
3833   operands[5] = gen_reg_rtx (<MODE>mode);
3834   operands[6] = GEN_INT (mask);
3838 ; Another important case is setting some bits to 1; we can do that with
3839 ; an insert instruction, in many cases.
3840 (define_insn_and_split "*ior<mode>_mask"
3841   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3842         (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
3843                  (match_operand:GPR 2 "const_int_operand" "n")))
3844    (clobber (match_scratch:GPR 3 "=r"))]
3845   "!logical_const_operand (operands[2], <MODE>mode)
3846    && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
3847   "#"
3848   "&& 1"
3849   [(set (match_dup 3)
3850         (const_int -1))
3851    (set (match_dup 0)
3852         (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
3853                                       (match_dup 4))
3854                           (match_dup 2))
3855                  (and:GPR (match_dup 1)
3856                           (match_dup 5))))]
3858   int nb, ne;
3859   rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
3860   if (GET_CODE (operands[3]) == SCRATCH)
3861     operands[3] = gen_reg_rtx (<MODE>mode);
3862   operands[4] = GEN_INT (ne);
3863   operands[5] = GEN_INT (~UINTVAL (operands[2]));
3865   [(set_attr "type" "two")
3866    (set_attr "length" "8")])
3869 ;; Now the simple shifts.
3871 (define_insn "rotl<mode>3"
3872   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3873         (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3874                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3875   ""
3876   "rotl<wd>%I2 %0,%1,%<hH>2"
3877   [(set_attr "type" "shift")
3878    (set_attr "maybe_var_shift" "yes")])
3880 (define_insn "*rotlsi3_64"
3881   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3882         (zero_extend:DI
3883             (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3884                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3885   "TARGET_POWERPC64"
3886   "rotlw%I2 %0,%1,%h2"
3887   [(set_attr "type" "shift")
3888    (set_attr "maybe_var_shift" "yes")])
3890 (define_insn_and_split "*rotl<mode>3_dot"
3891   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3892         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3893                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3894                     (const_int 0)))
3895    (clobber (match_scratch:GPR 0 "=r,r"))]
3896   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3897   "@
3898    rotl<wd>%I2. %0,%1,%<hH>2
3899    #"
3900   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3901   [(set (match_dup 0)
3902         (rotate:GPR (match_dup 1)
3903                     (match_dup 2)))
3904    (set (match_dup 3)
3905         (compare:CC (match_dup 0)
3906                     (const_int 0)))]
3907   ""
3908   [(set_attr "type" "shift")
3909    (set_attr "maybe_var_shift" "yes")
3910    (set_attr "dot" "yes")
3911    (set_attr "length" "4,8")])
3913 (define_insn_and_split "*rotl<mode>3_dot2"
3914   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3915         (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3916                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3917                     (const_int 0)))
3918    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3919         (rotate:GPR (match_dup 1)
3920                     (match_dup 2)))]
3921   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3922   "@
3923    rotl<wd>%I2. %0,%1,%<hH>2
3924    #"
3925   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3926   [(set (match_dup 0)
3927         (rotate:GPR (match_dup 1)
3928                     (match_dup 2)))
3929    (set (match_dup 3)
3930         (compare:CC (match_dup 0)
3931                     (const_int 0)))]
3932   ""
3933   [(set_attr "type" "shift")
3934    (set_attr "maybe_var_shift" "yes")
3935    (set_attr "dot" "yes")
3936    (set_attr "length" "4,8")])
3939 (define_insn "ashl<mode>3"
3940   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3941         (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3942                     (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
3943   ""
3944   "sl<wd>%I2 %0,%1,%<hH>2"
3945   [(set_attr "type" "shift")
3946    (set_attr "maybe_var_shift" "yes")])
3948 (define_insn "*ashlsi3_64"
3949   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3950         (zero_extend:DI
3951             (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
3952                        (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
3953   "TARGET_POWERPC64"
3954   "slw%I2 %0,%1,%h2"
3955   [(set_attr "type" "shift")
3956    (set_attr "maybe_var_shift" "yes")])
3958 (define_insn_and_split "*ashl<mode>3_dot"
3959   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3960         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3961                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3962                     (const_int 0)))
3963    (clobber (match_scratch:GPR 0 "=r,r"))]
3964   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3965   "@
3966    sl<wd>%I2. %0,%1,%<hH>2
3967    #"
3968   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3969   [(set (match_dup 0)
3970         (ashift:GPR (match_dup 1)
3971                     (match_dup 2)))
3972    (set (match_dup 3)
3973         (compare:CC (match_dup 0)
3974                     (const_int 0)))]
3975   ""
3976   [(set_attr "type" "shift")
3977    (set_attr "maybe_var_shift" "yes")
3978    (set_attr "dot" "yes")
3979    (set_attr "length" "4,8")])
3981 (define_insn_and_split "*ashl<mode>3_dot2"
3982   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3983         (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3984                                 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
3985                     (const_int 0)))
3986    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3987         (ashift:GPR (match_dup 1)
3988                     (match_dup 2)))]
3989   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
3990   "@
3991    sl<wd>%I2. %0,%1,%<hH>2
3992    #"
3993   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3994   [(set (match_dup 0)
3995         (ashift:GPR (match_dup 1)
3996                     (match_dup 2)))
3997    (set (match_dup 3)
3998         (compare:CC (match_dup 0)
3999                     (const_int 0)))]
4000   ""
4001   [(set_attr "type" "shift")
4002    (set_attr "maybe_var_shift" "yes")
4003    (set_attr "dot" "yes")
4004    (set_attr "length" "4,8")])
4006 ;; Pretend we have a memory form of extswsli until register allocation is done
4007 ;; so that we use LWZ to load the value from memory, instead of LWA.
4008 (define_insn_and_split "ashdi3_extswsli"
4009   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4010         (ashift:DI
4011          (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4012          (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4013   "TARGET_EXTSWSLI"
4014   "@
4015    extswsli %0,%1,%2
4016    #"
4017   "&& reload_completed && MEM_P (operands[1])"
4018   [(set (match_dup 3)
4019         (match_dup 1))
4020    (set (match_dup 0)
4021         (ashift:DI (sign_extend:DI (match_dup 3))
4022                    (match_dup 2)))]
4024   operands[3] = gen_lowpart (SImode, operands[0]);
4026   [(set_attr "type" "shift")
4027    (set_attr "maybe_var_shift" "no")])
4030 (define_insn_and_split "ashdi3_extswsli_dot"
4031   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4032         (compare:CC
4033          (ashift:DI
4034           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4035           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4036          (const_int 0)))
4037    (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4038   "TARGET_EXTSWSLI"
4039   "@
4040    extswsli. %0,%1,%2
4041    #
4042    #
4043    #"
4044   "&& reload_completed
4045    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4046        || memory_operand (operands[1], SImode))"
4047   [(pc)]
4049   rtx dest = operands[0];
4050   rtx src = operands[1];
4051   rtx shift = operands[2];
4052   rtx cr = operands[3];
4053   rtx src2;
4055   if (!MEM_P (src))
4056     src2 = src;
4057   else
4058     {
4059       src2 = gen_lowpart (SImode, dest);
4060       emit_move_insn (src2, src);
4061     }
4063   if (REGNO (cr) == CR0_REGNO)
4064     {
4065       emit_insn (gen_ashdi3_extswsli_dot (dest, src2, shift, cr));
4066       DONE;
4067     }
4069   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4070   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4071   DONE;
4073   [(set_attr "type" "shift")
4074    (set_attr "maybe_var_shift" "no")
4075    (set_attr "dot" "yes")
4076    (set_attr "length" "4,8,8,12")])
4078 (define_insn_and_split "ashdi3_extswsli_dot2"
4079   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4080         (compare:CC
4081          (ashift:DI
4082           (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4083           (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4084          (const_int 0)))
4085    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4086         (ashift:DI (sign_extend:DI (match_dup 1))
4087                    (match_dup 2)))]
4088   "TARGET_EXTSWSLI"
4089   "@
4090    extswsli. %0,%1,%2
4091    #
4092    #
4093    #"
4094   "&& reload_completed
4095    && (cc_reg_not_cr0_operand (operands[3], CCmode)
4096        || memory_operand (operands[1], SImode))"
4097   [(pc)]
4099   rtx dest = operands[0];
4100   rtx src = operands[1];
4101   rtx shift = operands[2];
4102   rtx cr = operands[3];
4103   rtx src2;
4105   if (!MEM_P (src))
4106     src2 = src;
4107   else
4108     {
4109       src2 = gen_lowpart (SImode, dest);
4110       emit_move_insn (src2, src);
4111     }
4113   if (REGNO (cr) == CR0_REGNO)
4114     {
4115       emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4116       DONE;
4117     }
4119   emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4120   emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4121   DONE;
4123   [(set_attr "type" "shift")
4124    (set_attr "maybe_var_shift" "no")
4125    (set_attr "dot" "yes")
4126    (set_attr "length" "4,8,8,12")])
4128 (define_insn "lshr<mode>3"
4129   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4130         (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4131                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4132   ""
4133   "sr<wd>%I2 %0,%1,%<hH>2"
4134   [(set_attr "type" "shift")
4135    (set_attr "maybe_var_shift" "yes")])
4137 (define_insn "*lshrsi3_64"
4138   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4139         (zero_extend:DI
4140             (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4141                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4142   "TARGET_POWERPC64"
4143   "srw%I2 %0,%1,%h2"
4144   [(set_attr "type" "shift")
4145    (set_attr "maybe_var_shift" "yes")])
4147 (define_insn_and_split "*lshr<mode>3_dot"
4148   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4149         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4150                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4151                     (const_int 0)))
4152    (clobber (match_scratch:GPR 0 "=r,r"))]
4153   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4154   "@
4155    sr<wd>%I2. %0,%1,%<hH>2
4156    #"
4157   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4158   [(set (match_dup 0)
4159         (lshiftrt:GPR (match_dup 1)
4160                       (match_dup 2)))
4161    (set (match_dup 3)
4162         (compare:CC (match_dup 0)
4163                     (const_int 0)))]
4164   ""
4165   [(set_attr "type" "shift")
4166    (set_attr "maybe_var_shift" "yes")
4167    (set_attr "dot" "yes")
4168    (set_attr "length" "4,8")])
4170 (define_insn_and_split "*lshr<mode>3_dot2"
4171   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4172         (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4173                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4174                     (const_int 0)))
4175    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4176         (lshiftrt:GPR (match_dup 1)
4177                       (match_dup 2)))]
4178   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4179   "@
4180    sr<wd>%I2. %0,%1,%<hH>2
4181    #"
4182   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4183   [(set (match_dup 0)
4184         (lshiftrt:GPR (match_dup 1)
4185                       (match_dup 2)))
4186    (set (match_dup 3)
4187         (compare:CC (match_dup 0)
4188                     (const_int 0)))]
4189   ""
4190   [(set_attr "type" "shift")
4191    (set_attr "maybe_var_shift" "yes")
4192    (set_attr "dot" "yes")
4193    (set_attr "length" "4,8")])
4196 (define_insn "ashr<mode>3"
4197   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4198         (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4199                       (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4200    (clobber (reg:GPR CA_REGNO))]
4201   ""
4202   "sra<wd>%I2 %0,%1,%<hH>2"
4203   [(set_attr "type" "shift")
4204    (set_attr "maybe_var_shift" "yes")])
4206 (define_insn "*ashrsi3_64"
4207   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4208         (sign_extend:DI
4209             (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4210                          (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4211    (clobber (reg:SI CA_REGNO))]
4212   "TARGET_POWERPC64"
4213   "sraw%I2 %0,%1,%h2"
4214   [(set_attr "type" "shift")
4215    (set_attr "maybe_var_shift" "yes")])
4217 (define_insn_and_split "*ashr<mode>3_dot"
4218   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4219         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4220                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4221                     (const_int 0)))
4222    (clobber (match_scratch:GPR 0 "=r,r"))
4223    (clobber (reg:GPR CA_REGNO))]
4224   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4225   "@
4226    sra<wd>%I2. %0,%1,%<hH>2
4227    #"
4228   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4229   [(parallel [(set (match_dup 0)
4230                    (ashiftrt:GPR (match_dup 1)
4231                                  (match_dup 2)))
4232               (clobber (reg:GPR CA_REGNO))])
4233    (set (match_dup 3)
4234         (compare:CC (match_dup 0)
4235                     (const_int 0)))]
4236   ""
4237   [(set_attr "type" "shift")
4238    (set_attr "maybe_var_shift" "yes")
4239    (set_attr "dot" "yes")
4240    (set_attr "length" "4,8")])
4242 (define_insn_and_split "*ashr<mode>3_dot2"
4243   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4244         (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4245                                   (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4246                     (const_int 0)))
4247    (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4248         (ashiftrt:GPR (match_dup 1)
4249                       (match_dup 2)))
4250    (clobber (reg:GPR CA_REGNO))]
4251   "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
4252   "@
4253    sra<wd>%I2. %0,%1,%<hH>2
4254    #"
4255   "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4256   [(parallel [(set (match_dup 0)
4257                    (ashiftrt:GPR (match_dup 1)
4258                                  (match_dup 2)))
4259               (clobber (reg:GPR CA_REGNO))])
4260    (set (match_dup 3)
4261         (compare:CC (match_dup 0)
4262                     (const_int 0)))]
4263   ""
4264   [(set_attr "type" "shift")
4265    (set_attr "maybe_var_shift" "yes")
4266    (set_attr "dot" "yes")
4267    (set_attr "length" "4,8")])
4269 ;; Builtins to replace a division to generate FRE reciprocal estimate
4270 ;; instructions and the necessary fixup instructions
4271 (define_expand "recip<mode>3"
4272   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4273    (match_operand:RECIPF 1 "gpc_reg_operand" "")
4274    (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4275   "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4277    rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4278    DONE;
4281 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4282 ;; hardware division.  This is only done before register allocation and with
4283 ;; -ffast-math.  This must appear before the divsf3/divdf3 insns.
4284 (define_split
4285   [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4286         (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4287                     (match_operand 2 "gpc_reg_operand" "")))]
4288   "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4289    && can_create_pseudo_p () && optimize_insn_for_speed_p ()
4290    && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
4291   [(const_int 0)]
4293   rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4294   DONE;
4297 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4298 ;; appropriate fixup.
4299 (define_expand "rsqrt<mode>2"
4300   [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4301    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4302   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4304   rs6000_emit_swsqrt (operands[0], operands[1], 1);
4305   DONE;
4308 ;; Floating-point insns, excluding normal data motion.  We combine the SF/DF
4309 ;; modes here, and also add in conditional vsx/power8-vector support to access
4310 ;; values in the traditional Altivec registers if the appropriate
4311 ;; -mupper-regs-{df,sf} option is enabled.
4313 (define_expand "abs<mode>2"
4314   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4315         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4316   "TARGET_<MODE>_INSN"
4317   "")
4319 (define_insn "*abs<mode>2_fpr"
4320   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4321         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4322   "TARGET_<MODE>_FPR"
4323   "@
4324    fabs %0,%1
4325    xsabsdp %x0,%x1"
4326   [(set_attr "type" "fp")
4327    (set_attr "fp_type" "fp_addsub_<Fs>")])
4329 (define_insn "*nabs<mode>2_fpr"
4330   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4331         (neg:SFDF
4332          (abs:SFDF
4333           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4334   "TARGET_<MODE>_FPR"
4335   "@
4336    fnabs %0,%1
4337    xsnabsdp %x0,%x1"
4338   [(set_attr "type" "fp")
4339    (set_attr "fp_type" "fp_addsub_<Fs>")])
4341 (define_expand "neg<mode>2"
4342   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4343         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4344   "TARGET_<MODE>_INSN"
4345   "")
4347 (define_insn "*neg<mode>2_fpr"
4348   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4349         (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4350   "TARGET_<MODE>_FPR"
4351   "@
4352    fneg %0,%1
4353    xsnegdp %x0,%x1"
4354   [(set_attr "type" "fp")
4355    (set_attr "fp_type" "fp_addsub_<Fs>")])
4357 (define_expand "add<mode>3"
4358   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4359         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4360                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4361   "TARGET_<MODE>_INSN"
4362   "")
4364 (define_insn "*add<mode>3_fpr"
4365   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4366         (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4367                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4368   "TARGET_<MODE>_FPR"
4369   "@
4370    fadd<Ftrad> %0,%1,%2
4371    xsadd<Fvsx> %x0,%x1,%x2"
4372   [(set_attr "type" "fp")
4373    (set_attr "fp_type" "fp_addsub_<Fs>")])
4375 (define_expand "sub<mode>3"
4376   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4377         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4378                     (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4379   "TARGET_<MODE>_INSN"
4380   "")
4382 (define_insn "*sub<mode>3_fpr"
4383   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4384         (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4385                     (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4386   "TARGET_<MODE>_FPR"
4387   "@
4388    fsub<Ftrad> %0,%1,%2
4389    xssub<Fvsx> %x0,%x1,%x2"
4390   [(set_attr "type" "fp")
4391    (set_attr "fp_type" "fp_addsub_<Fs>")])
4393 (define_expand "mul<mode>3"
4394   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4395         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4396                    (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4397   "TARGET_<MODE>_INSN"
4398   "")
4400 (define_insn "*mul<mode>3_fpr"
4401   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4402         (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4403                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4404   "TARGET_<MODE>_FPR"
4405   "@
4406    fmul<Ftrad> %0,%1,%2
4407    xsmul<Fvsx> %x0,%x1,%x2"
4408   [(set_attr "type" "dmul")
4409    (set_attr "fp_type" "fp_mul_<Fs>")])
4411 (define_expand "div<mode>3"
4412   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4413         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4414                   (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4415   "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4416   "")
4418 (define_insn "*div<mode>3_fpr"
4419   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4420         (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4421                   (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4422   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4423   "@
4424    fdiv<Ftrad> %0,%1,%2
4425    xsdiv<Fvsx> %x0,%x1,%x2"
4426   [(set_attr "type" "<Fs>div")
4427    (set_attr "fp_type" "fp_div_<Fs>")])
4429 (define_insn "*sqrt<mode>2_internal"
4430   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4431         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4432   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4433    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4434   "@
4435    fsqrt<Ftrad> %0,%1
4436    xssqrt<Fvsx> %x0,%x1"
4437   [(set_attr "type" "<Fs>sqrt")
4438    (set_attr "fp_type" "fp_sqrt_<Fs>")])
4440 (define_expand "sqrt<mode>2"
4441   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4442         (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4443   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4444    && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4446   if (<MODE>mode == SFmode
4447       && TARGET_RECIP_PRECISION
4448       && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4449       && !optimize_function_for_size_p (cfun)
4450       && flag_finite_math_only && !flag_trapping_math
4451       && flag_unsafe_math_optimizations)
4452     {
4453       rs6000_emit_swsqrt (operands[0], operands[1], 0);
4454       DONE;
4455     }
4458 ;; Floating point reciprocal approximation
4459 (define_insn "fre<Fs>"
4460   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4461         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4462                      UNSPEC_FRES))]
4463   "TARGET_<FFRE>"
4464   "@
4465    fre<Ftrad> %0,%1
4466    xsre<Fvsx> %x0,%x1"
4467   [(set_attr "type" "fp")])
4469 (define_insn "*rsqrt<mode>2"
4470   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4471         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4472                      UNSPEC_RSQRT))]
4473   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4474   "@
4475    frsqrte<Ftrad> %0,%1
4476    xsrsqrte<Fvsx> %x0,%x1"
4477   [(set_attr "type" "fp")])
4479 ;; Floating point comparisons
4480 (define_insn "*cmp<mode>_fpr"
4481   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4482         (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4483                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4484   "TARGET_<MODE>_FPR"
4485   "@
4486    fcmpu %0,%1,%2
4487    xscmpudp %0,%x1,%x2"
4488   [(set_attr "type" "fpcompare")])
4490 ;; Floating point conversions
4491 (define_expand "extendsfdf2"
4492   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4493         (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4494   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4495   "")
4497 (define_insn_and_split "*extendsfdf2_fpr"
4498   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4499         (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,o")))]
4500   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4501   "@
4502    #
4503    fmr %0,%1
4504    lfs%U1%X1 %0,%1
4505    #
4506    xscpsgndp %x0,%x1,%x1
4507    lxsspx %x0,%y1
4508    lxssp %0,%1"
4509   "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4510   [(const_int 0)]
4512   emit_note (NOTE_INSN_DELETED);
4513   DONE;
4515   [(set_attr "type" "fp,fp,fpload,fp,fp,fpload,fpload")])
4517 (define_expand "truncdfsf2"
4518   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4519         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4520   "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
4521   "")
4523 (define_insn "*truncdfsf2_fpr"
4524   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4525         (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4526   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4527   "@
4528    frsp %0,%1
4529    xsrsp %x0,%x1"
4530   [(set_attr "type" "fp")])
4532 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4533 ;; builtins.c and optabs.c that are not correct for IBM long double
4534 ;; when little-endian.
4535 (define_expand "signbit<mode>2"
4536   [(set (match_dup 2)
4537         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "")))
4538    (set (match_dup 3)
4539         (subreg:DI (match_dup 2) 0))
4540    (set (match_dup 4)
4541         (match_dup 5))
4542    (set (match_operand:SI 0 "gpc_reg_operand" "")
4543         (match_dup 6))]
4544   "TARGET_HARD_FLOAT
4545    && (TARGET_FPRS || TARGET_E500_DOUBLE)"
4547   operands[2] = gen_reg_rtx (DFmode);
4548   operands[3] = gen_reg_rtx (DImode);
4549   if (TARGET_POWERPC64)
4550     {
4551       operands[4] = gen_reg_rtx (DImode);
4552       operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4553       operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4554                                     WORDS_BIG_ENDIAN ? 4 : 0);
4555     }
4556   else
4557     {
4558       operands[4] = gen_reg_rtx (SImode);
4559       operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4560                                     WORDS_BIG_ENDIAN ? 0 : 4);
4561       operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4562     }
4565 (define_expand "copysign<mode>3"
4566   [(set (match_dup 3)
4567         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4568    (set (match_dup 4)
4569         (neg:SFDF (abs:SFDF (match_dup 1))))
4570    (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4571         (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4572                                (match_dup 5))
4573                          (match_dup 3)
4574                          (match_dup 4)))]
4575   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
4576    && ((TARGET_PPC_GFXOPT
4577         && !HONOR_NANS (<MODE>mode)
4578         && !HONOR_SIGNED_ZEROS (<MODE>mode))
4579        || TARGET_CMPB
4580        || VECTOR_UNIT_VSX_P (<MODE>mode))"
4582   if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4583     {
4584       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4585                                              operands[2]));
4586       DONE;
4587     }
4589    operands[3] = gen_reg_rtx (<MODE>mode);
4590    operands[4] = gen_reg_rtx (<MODE>mode);
4591    operands[5] = CONST0_RTX (<MODE>mode);
4592   })
4594 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4595 ;; compiler from optimizing -0.0
4596 (define_insn "copysign<mode>3_fcpsgn"
4597   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4598         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4599                       (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4600                      UNSPEC_COPYSIGN))]
4601   "TARGET_<MODE>_FPR && TARGET_CMPB"
4602   "@
4603    fcpsgn %0,%2,%1
4604    xscpsgndp %x0,%x2,%x1"
4605   [(set_attr "type" "fp")])
4607 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4608 ;; fsel instruction and some auxiliary computations.  Then we just have a
4609 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4610 ;; combine.
4611 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4612 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4613 ;; computations.  Then we just have a single DEFINE_INSN for fsel and the
4614 ;; define_splits to make them if made by combine.  On VSX machines we have the
4615 ;; min/max instructions.
4617 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4618 ;; to allow either DF/SF to use only traditional registers.
4620 (define_expand "smax<mode>3"
4621   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4622         (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4623                                (match_operand:SFDF 2 "gpc_reg_operand" ""))
4624                            (match_dup 1)
4625                            (match_dup 2)))]
4626   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4628   rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
4629   DONE;
4632 (define_insn "*smax<mode>3_vsx"
4633   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4634         (smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4635                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4636   "TARGET_<MODE>_FPR && TARGET_VSX"
4637   "xsmaxdp %x0,%x1,%x2"
4638   [(set_attr "type" "fp")])
4640 (define_expand "smin<mode>3"
4641   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4642         (if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
4643                                (match_operand:SFDF 2 "gpc_reg_operand" ""))
4644                            (match_dup 2)
4645                            (match_dup 1)))]
4646   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
4648   rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
4649   DONE;
4652 (define_insn "*smin<mode>3_vsx"
4653   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4654         (smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
4655                    (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
4656   "TARGET_<MODE>_FPR && TARGET_VSX"
4657   "xsmindp %x0,%x1,%x2"
4658   [(set_attr "type" "fp")])
4660 (define_split
4661   [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4662         (match_operator:SFDF 3 "min_max_operator"
4663          [(match_operand:SFDF 1 "gpc_reg_operand" "")
4664           (match_operand:SFDF 2 "gpc_reg_operand" "")]))]
4665   "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
4666    && !TARGET_VSX"
4667   [(const_int 0)]
4669   rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
4670                       operands[2]);
4671   DONE;
4674 (define_split
4675   [(set (match_operand:SF 0 "gpc_reg_operand" "")
4676         (match_operator:SF 3 "min_max_operator"
4677          [(match_operand:SF 1 "gpc_reg_operand" "")
4678           (match_operand:SF 2 "gpc_reg_operand" "")]))]
4679   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS 
4680    && TARGET_SINGLE_FLOAT && !flag_trapping_math"
4681   [(const_int 0)]
4682   "
4683 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4684                       operands[1], operands[2]);
4685   DONE;
4688 (define_expand "mov<mode>cc"
4689    [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4690          (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4691                            (match_operand:GPR 2 "gpc_reg_operand" "")
4692                            (match_operand:GPR 3 "gpc_reg_operand" "")))]
4693   "TARGET_ISEL<sel>"
4694   "
4696   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4697     DONE;
4698   else
4699     FAIL;
4702 ;; We use the BASE_REGS for the isel input operands because, if rA is
4703 ;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
4704 ;; because we may switch the operands and rB may end up being rA.
4706 ;; We need 2 patterns: an unsigned and a signed pattern.  We could
4707 ;; leave out the mode in operand 4 and use one pattern, but reload can
4708 ;; change the mode underneath our feet and then gets confused trying
4709 ;; to reload the value.
4710 (define_insn "isel_signed_<mode>"
4711   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4712         (if_then_else:GPR
4713          (match_operator 1 "scc_comparison_operator"
4714                          [(match_operand:CC 4 "cc_reg_operand" "y,y")
4715                           (const_int 0)])
4716          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4717          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4718   "TARGET_ISEL<sel>"
4719   "*
4720 { return output_isel (operands); }"
4721   [(set_attr "type" "isel")
4722    (set_attr "length" "4")])
4724 (define_insn "isel_unsigned_<mode>"
4725   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4726         (if_then_else:GPR
4727          (match_operator 1 "scc_comparison_operator"
4728                          [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4729                           (const_int 0)])
4730          (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
4731          (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4732   "TARGET_ISEL<sel>"
4733   "*
4734 { return output_isel (operands); }"
4735   [(set_attr "type" "isel")
4736    (set_attr "length" "4")])
4738 ;; These patterns can be useful for combine; they let combine know that
4739 ;; isel can handle reversed comparisons so long as the operands are
4740 ;; registers.
4742 (define_insn "*isel_reversed_signed_<mode>"
4743   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4744         (if_then_else:GPR
4745          (match_operator 1 "scc_rev_comparison_operator"
4746                          [(match_operand:CC 4 "cc_reg_operand" "y")
4747                           (const_int 0)])
4748          (match_operand:GPR 2 "gpc_reg_operand" "b")
4749          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4750   "TARGET_ISEL<sel>"
4751   "*
4752 { return output_isel (operands); }"
4753   [(set_attr "type" "isel")
4754    (set_attr "length" "4")])
4756 (define_insn "*isel_reversed_unsigned_<mode>"
4757   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4758         (if_then_else:GPR
4759          (match_operator 1 "scc_rev_comparison_operator"
4760                          [(match_operand:CCUNS 4 "cc_reg_operand" "y")
4761                           (const_int 0)])
4762          (match_operand:GPR 2 "gpc_reg_operand" "b")
4763          (match_operand:GPR 3 "gpc_reg_operand" "b")))]
4764   "TARGET_ISEL<sel>"
4765   "*
4766 { return output_isel (operands); }"
4767   [(set_attr "type" "isel")
4768    (set_attr "length" "4")])
4770 (define_expand "movsfcc"
4771    [(set (match_operand:SF 0 "gpc_reg_operand" "")
4772          (if_then_else:SF (match_operand 1 "comparison_operator" "")
4773                           (match_operand:SF 2 "gpc_reg_operand" "")
4774                           (match_operand:SF 3 "gpc_reg_operand" "")))]
4775   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4776   "
4778   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4779     DONE;
4780   else
4781     FAIL;
4784 (define_insn "*fselsfsf4"
4785   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4786         (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4787                              (match_operand:SF 4 "zero_fp_constant" "F"))
4788                          (match_operand:SF 2 "gpc_reg_operand" "f")
4789                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
4790   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
4791   "fsel %0,%1,%2,%3"
4792   [(set_attr "type" "fp")])
4794 (define_insn "*fseldfsf4"
4795   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4796         (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4797                              (match_operand:DF 4 "zero_fp_constant" "F"))
4798                          (match_operand:SF 2 "gpc_reg_operand" "f")
4799                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
4800   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4801   "fsel %0,%1,%2,%3"
4802   [(set_attr "type" "fp")])
4804 ;; The conditional move instructions allow us to perform max and min
4805 ;; operations even when
4807 (define_split
4808   [(set (match_operand:DF 0 "gpc_reg_operand" "")
4809         (match_operator:DF 3 "min_max_operator"
4810          [(match_operand:DF 1 "gpc_reg_operand" "")
4811           (match_operand:DF 2 "gpc_reg_operand" "")]))]
4812   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
4813    && !flag_trapping_math"
4814   [(const_int 0)]
4815   "
4816 { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
4817                       operands[1], operands[2]);
4818   DONE;
4821 (define_expand "movdfcc"
4822    [(set (match_operand:DF 0 "gpc_reg_operand" "")
4823          (if_then_else:DF (match_operand 1 "comparison_operator" "")
4824                           (match_operand:DF 2 "gpc_reg_operand" "")
4825                           (match_operand:DF 3 "gpc_reg_operand" "")))]
4826   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4827   "
4829   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4830     DONE;
4831   else
4832     FAIL;
4835 (define_insn "*fseldfdf4"
4836   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4837         (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
4838                              (match_operand:DF 4 "zero_fp_constant" "F"))
4839                          (match_operand:DF 2 "gpc_reg_operand" "d")
4840                          (match_operand:DF 3 "gpc_reg_operand" "d")))]
4841   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
4842   "fsel %0,%1,%2,%3"
4843   [(set_attr "type" "fp")])
4845 (define_insn "*fselsfdf4"
4846   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
4847         (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
4848                              (match_operand:SF 4 "zero_fp_constant" "F"))
4849                          (match_operand:DF 2 "gpc_reg_operand" "d")
4850                          (match_operand:DF 3 "gpc_reg_operand" "d")))]
4851   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
4852   "fsel %0,%1,%2,%3"
4853   [(set_attr "type" "fp")])
4855 ;; Conversions to and from floating-point.
4857 ; We don't define lfiwax/lfiwzx with the normal definition, because we
4858 ; don't want to support putting SImode in FPR registers.
4859 (define_insn "lfiwax"
4860   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4861         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4862                    UNSPEC_LFIWAX))]
4863   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
4864   "@
4865    lfiwax %0,%y1
4866    lxsiwax %x0,%y1
4867    mtvsrwa %x0,%1"
4868   [(set_attr "type" "fpload,fpload,mffgpr")])
4870 ; This split must be run before register allocation because it allocates the
4871 ; memory slot that is needed to move values to/from the FPR.  We don't allocate
4872 ; it earlier to allow for the combiner to merge insns together where it might
4873 ; not be needed and also in case the insns are deleted as dead code.
4875 (define_insn_and_split "floatsi<mode>2_lfiwax"
4876   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4877         (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4878    (clobber (match_scratch:DI 2 "=wj"))]
4879   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4880    && <SI_CONVERT_FP> && can_create_pseudo_p ()"
4881   "#"
4882   ""
4883   [(pc)]
4884   "
4886   rtx dest = operands[0];
4887   rtx src = operands[1];
4888   rtx tmp;
4890   if (!MEM_P (src) && TARGET_POWERPC64
4891       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4892     tmp = convert_to_mode (DImode, src, false);
4893   else
4894     {
4895       tmp = operands[2];
4896       if (GET_CODE (tmp) == SCRATCH)
4897         tmp = gen_reg_rtx (DImode);
4898       if (MEM_P (src))
4899         {
4900           src = rs6000_address_for_fpconvert (src);
4901           emit_insn (gen_lfiwax (tmp, src));
4902         }
4903       else
4904         {
4905           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4906           emit_move_insn (stack, src);
4907           emit_insn (gen_lfiwax (tmp, stack));
4908         }
4909     }
4910   emit_insn (gen_floatdi<mode>2 (dest, tmp));
4911   DONE;
4913   [(set_attr "length" "12")
4914    (set_attr "type" "fpload")])
4916 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
4917   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4918         (float:SFDF
4919          (sign_extend:DI
4920           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4921    (clobber (match_scratch:DI 2 "=0,d"))]
4922   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
4923    && <SI_CONVERT_FP>"
4924   "#"
4925   ""
4926   [(pc)]
4927   "
4929   operands[1] = rs6000_address_for_fpconvert (operands[1]);
4930   if (GET_CODE (operands[2]) == SCRATCH)
4931     operands[2] = gen_reg_rtx (DImode);
4932   emit_insn (gen_lfiwax (operands[2], operands[1]));
4933   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
4934   DONE;
4936   [(set_attr "length" "8")
4937    (set_attr "type" "fpload")])
4939 (define_insn "lfiwzx"
4940   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj")
4941         (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")]
4942                    UNSPEC_LFIWZX))]
4943   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
4944   "@
4945    lfiwzx %0,%y1
4946    lxsiwzx %x0,%y1
4947    mtvsrwz %x0,%1"
4948   [(set_attr "type" "fpload,fpload,mftgpr")])
4950 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
4951   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
4952         (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
4953    (clobber (match_scratch:DI 2 "=wj"))]
4954   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4955    && <SI_CONVERT_FP>"
4956   "#"
4957   ""
4958   [(pc)]
4959   "
4961   rtx dest = operands[0];
4962   rtx src = operands[1];
4963   rtx tmp;
4965   if (!MEM_P (src) && TARGET_POWERPC64
4966       && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
4967     tmp = convert_to_mode (DImode, src, true);
4968   else
4969     {
4970       tmp = operands[2];
4971       if (GET_CODE (tmp) == SCRATCH)
4972         tmp = gen_reg_rtx (DImode);
4973       if (MEM_P (src))
4974         {
4975           src = rs6000_address_for_fpconvert (src);
4976           emit_insn (gen_lfiwzx (tmp, src));
4977         }
4978       else
4979         {
4980           rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
4981           emit_move_insn (stack, src);
4982           emit_insn (gen_lfiwzx (tmp, stack));
4983         }
4984     }
4985   emit_insn (gen_floatdi<mode>2 (dest, tmp));
4986   DONE;
4988   [(set_attr "length" "12")
4989    (set_attr "type" "fpload")])
4991 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
4992   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>")
4993         (unsigned_float:SFDF
4994          (zero_extend:DI
4995           (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
4996    (clobber (match_scratch:DI 2 "=0,d"))]
4997   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
4998    && <SI_CONVERT_FP>"
4999   "#"
5000   ""
5001   [(pc)]
5002   "
5004   operands[1] = rs6000_address_for_fpconvert (operands[1]);
5005   if (GET_CODE (operands[2]) == SCRATCH)
5006     operands[2] = gen_reg_rtx (DImode);
5007   emit_insn (gen_lfiwzx (operands[2], operands[1]));
5008   emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5009   DONE;
5011   [(set_attr "length" "8")
5012    (set_attr "type" "fpload")])
5014 ; For each of these conversions, there is a define_expand, a define_insn
5015 ; with a '#' template, and a define_split (with C code).  The idea is
5016 ; to allow constant folding with the template of the define_insn,
5017 ; then to have the insns split later (between sched1 and final).
5019 (define_expand "floatsidf2"
5020   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5021                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5022               (use (match_dup 2))
5023               (use (match_dup 3))
5024               (clobber (match_dup 4))
5025               (clobber (match_dup 5))
5026               (clobber (match_dup 6))])]
5027   "TARGET_HARD_FLOAT 
5028    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5029   "
5031   if (TARGET_E500_DOUBLE)
5032     {
5033       if (!REG_P (operands[1]))
5034         operands[1] = force_reg (SImode, operands[1]);
5035       emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5036       DONE;
5037     }
5038   else if (TARGET_LFIWAX && TARGET_FCFID)
5039     {
5040       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5041       DONE;
5042     }
5043   else if (TARGET_FCFID)
5044     {
5045       rtx dreg = operands[1];
5046       if (!REG_P (dreg))
5047         dreg = force_reg (SImode, dreg);
5048       dreg = convert_to_mode (DImode, dreg, false);
5049       emit_insn (gen_floatdidf2 (operands[0], dreg));
5050       DONE;
5051     }
5053   if (!REG_P (operands[1]))
5054     operands[1] = force_reg (SImode, operands[1]);
5055   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5056   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5057   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5058   operands[5] = gen_reg_rtx (DFmode);
5059   operands[6] = gen_reg_rtx (SImode);
5062 (define_insn_and_split "*floatsidf2_internal"
5063   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5064         (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5065    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5066    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5067    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5068    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5069    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5070   "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5071   "#"
5072   ""
5073   [(pc)]
5074   "
5076   rtx lowword, highword;
5077   gcc_assert (MEM_P (operands[4]));
5078   highword = adjust_address (operands[4], SImode, 0);
5079   lowword = adjust_address (operands[4], SImode, 4);
5080   if (! WORDS_BIG_ENDIAN)
5081     std::swap (lowword, highword);
5083   emit_insn (gen_xorsi3 (operands[6], operands[1],
5084                          GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5085   emit_move_insn (lowword, operands[6]);
5086   emit_move_insn (highword, operands[2]);
5087   emit_move_insn (operands[5], operands[4]);
5088   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5089   DONE;
5091   [(set_attr "length" "24")
5092    (set_attr "type" "fp")])
5094 ;; If we don't have a direct conversion to single precision, don't enable this
5095 ;; conversion for 32-bit without fast math, because we don't have the insn to
5096 ;; generate the fixup swizzle to avoid double rounding problems.
5097 (define_expand "floatunssisf2"
5098   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5099         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5100   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5101    && (!TARGET_FPRS
5102        || (TARGET_FPRS
5103            && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5104                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5105                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5106   "
5108   if (!TARGET_FPRS)
5109     {
5110       if (!REG_P (operands[1]))
5111         operands[1] = force_reg (SImode, operands[1]);
5112     }
5113   else if (TARGET_LFIWZX && TARGET_FCFIDUS)
5114     {
5115       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5116       DONE;
5117     }
5118   else
5119     {
5120       rtx dreg = operands[1];
5121       if (!REG_P (dreg))
5122         dreg = force_reg (SImode, dreg);
5123       dreg = convert_to_mode (DImode, dreg, true);
5124       emit_insn (gen_floatdisf2 (operands[0], dreg));
5125       DONE;
5126     }
5129 (define_expand "floatunssidf2"
5130   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5131                    (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5132               (use (match_dup 2))
5133               (use (match_dup 3))
5134               (clobber (match_dup 4))
5135               (clobber (match_dup 5))])]
5136   "TARGET_HARD_FLOAT
5137    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
5138   "
5140   if (TARGET_E500_DOUBLE)
5141     {
5142       if (!REG_P (operands[1]))
5143         operands[1] = force_reg (SImode, operands[1]);
5144       emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5145       DONE;
5146     }
5147   else if (TARGET_LFIWZX && TARGET_FCFID)
5148     {
5149       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5150       DONE;
5151     }
5152   else if (TARGET_FCFID)
5153     {
5154       rtx dreg = operands[1];
5155       if (!REG_P (dreg))
5156         dreg = force_reg (SImode, dreg);
5157       dreg = convert_to_mode (DImode, dreg, true);
5158       emit_insn (gen_floatdidf2 (operands[0], dreg));
5159       DONE;
5160     }
5162   if (!REG_P (operands[1]))
5163     operands[1] = force_reg (SImode, operands[1]);
5164   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5165   operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5166   operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5167   operands[5] = gen_reg_rtx (DFmode);
5170 (define_insn_and_split "*floatunssidf2_internal"
5171   [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5172         (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5173    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5174    (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5175    (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5176    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5177   "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5178    && !(TARGET_FCFID && TARGET_POWERPC64)"
5179   "#"
5180   ""
5181   [(pc)]
5182   "
5184   rtx lowword, highword;
5185   gcc_assert (MEM_P (operands[4]));
5186   highword = adjust_address (operands[4], SImode, 0);
5187   lowword = adjust_address (operands[4], SImode, 4);
5188   if (! WORDS_BIG_ENDIAN)
5189     std::swap (lowword, highword);
5191   emit_move_insn (lowword, operands[1]);
5192   emit_move_insn (highword, operands[2]);
5193   emit_move_insn (operands[5], operands[4]);
5194   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5195   DONE;
5197   [(set_attr "length" "20")
5198    (set_attr "type" "fp")])
5200 (define_expand "fix_trunc<mode>si2"
5201   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5202         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5203   "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
5204   "
5206   if (!<E500_CONVERT>)
5207     {
5208       rtx tmp, stack;
5210       if (TARGET_STFIWX)
5211         emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5212       else
5213         {
5214           tmp = gen_reg_rtx (DImode);
5215           stack = rs6000_allocate_stack_temp (DImode, true, false);
5216           emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
5217                                                       tmp, stack));
5218         }
5219       DONE;
5220     }
5223 ; Like the convert to float patterns, this insn must be split before
5224 ; register allocation so that it can allocate the memory slot if it
5225 ; needed
5226 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5227   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5228         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5229    (clobber (match_scratch:DI 2 "=d"))]
5230   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5231    && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5232    && TARGET_STFIWX && can_create_pseudo_p ()"
5233   "#"
5234   ""
5235   [(pc)]
5237   rtx dest = operands[0];
5238   rtx src = operands[1];
5239   rtx tmp = operands[2];
5241   if (GET_CODE (tmp) == SCRATCH)
5242     tmp = gen_reg_rtx (DImode);
5244   emit_insn (gen_fctiwz_<mode> (tmp, src));
5245   if (MEM_P (dest))
5246     {
5247       dest = rs6000_address_for_fpconvert (dest);
5248       emit_insn (gen_stfiwx (dest, tmp));
5249       DONE;
5250     }
5251   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5252     {
5253       dest = gen_lowpart (DImode, dest);
5254       emit_move_insn (dest, tmp);
5255       DONE;
5256     }
5257   else
5258     {
5259       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5260       emit_insn (gen_stfiwx (stack, tmp));
5261       emit_move_insn (dest, stack);
5262       DONE;
5263     }
5265   [(set_attr "length" "12")
5266    (set_attr "type" "fp")])
5268 (define_insn_and_split "fix_trunc<mode>si2_internal"
5269   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5270         (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5271    (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5272    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5273   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5274   "#"
5275   ""
5276   [(pc)]
5277   "
5279   rtx lowword;
5280   gcc_assert (MEM_P (operands[3]));
5281   lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5283   emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5284   emit_move_insn (operands[3], operands[2]);
5285   emit_move_insn (operands[0], lowword);
5286   DONE;
5288   [(set_attr "length" "16")
5289    (set_attr "type" "fp")])
5291 (define_expand "fix_trunc<mode>di2"
5292   [(set (match_operand:DI 0 "gpc_reg_operand" "")
5293         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5294   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5295    && TARGET_FCFID"
5296   "")
5298 (define_insn "*fix_trunc<mode>di2_fctidz"
5299   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5300         (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5301   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5302     && TARGET_FCFID"
5303   "@
5304    fctidz %0,%1
5305    xscvdpsxds %x0,%x1"
5306   [(set_attr "type" "fp")])
5308 (define_expand "fixuns_trunc<mode>si2"
5309   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5310         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5311   "TARGET_HARD_FLOAT
5312    && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
5313        || <E500_CONVERT>)"
5314   "
5316   if (!<E500_CONVERT>)
5317     {
5318       emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5319       DONE;
5320     }
5323 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5324   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5325         (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5326    (clobber (match_scratch:DI 2 "=d"))]
5327   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
5328    && TARGET_STFIWX && can_create_pseudo_p ()"
5329   "#"
5330   ""
5331   [(pc)]
5333   rtx dest = operands[0];
5334   rtx src = operands[1];
5335   rtx tmp = operands[2];
5337   if (GET_CODE (tmp) == SCRATCH)
5338     tmp = gen_reg_rtx (DImode);
5340   emit_insn (gen_fctiwuz_<mode> (tmp, src));
5341   if (MEM_P (dest))
5342     {
5343       dest = rs6000_address_for_fpconvert (dest);
5344       emit_insn (gen_stfiwx (dest, tmp));
5345       DONE;
5346     }
5347   else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5348     {
5349       dest = gen_lowpart (DImode, dest);
5350       emit_move_insn (dest, tmp);
5351       DONE;
5352     }
5353   else
5354     {
5355       rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5356       emit_insn (gen_stfiwx (stack, tmp));
5357       emit_move_insn (dest, stack);
5358       DONE;
5359     }
5361   [(set_attr "length" "12")
5362    (set_attr "type" "fp")])
5364 (define_expand "fixuns_trunc<mode>di2"
5365   [(set (match_operand:DI 0 "register_operand" "")
5366         (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
5367   "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
5368   "")
5370 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
5371   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5372         (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
5373   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
5374     && TARGET_FCTIDUZ"
5375   "@
5376    fctiduz %0,%1
5377    xscvdpuxds %x0,%x1"
5378   [(set_attr "type" "fp")])
5380 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5381 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
5382 ; because the first makes it clear that operand 0 is not live
5383 ; before the instruction.
5384 (define_insn "fctiwz_<mode>"
5385   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5386         (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5387                    UNSPEC_FCTIWZ))]
5388   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
5389   "@
5390    fctiwz %0,%1
5391    xscvdpsxws %x0,%x1"
5392   [(set_attr "type" "fp")])
5394 (define_insn "fctiwuz_<mode>"
5395   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5396         (unspec:DI [(unsigned_fix:SI
5397                      (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5398                    UNSPEC_FCTIWUZ))]
5399   "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5400   "@
5401    fctiwuz %0,%1
5402    xscvdpuxws %x0,%x1"
5403   [(set_attr "type" "fp")])
5405 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5406 ;; since the friz instruction does not truncate the value if the floating
5407 ;; point value is < LONG_MIN or > LONG_MAX.
5408 (define_insn "*friz"
5409   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5410         (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5411   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5412    && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5413   "@
5414    friz %0,%1
5415    xsrdpiz %x0,%x1"
5416   [(set_attr "type" "fp")])
5418 ;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
5419 ;; load to properly sign extend the value, but at least doing a store, load
5420 ;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
5421 ;; if we have 32-bit memory ops
5422 (define_insn_and_split "*round32<mode>2_fprs"
5423   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5424         (float:SFDF
5425          (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5426    (clobber (match_scratch:DI 2 "=d"))
5427    (clobber (match_scratch:DI 3 "=d"))]
5428   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5429    && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5430    && can_create_pseudo_p ()"
5431   "#"
5432   ""
5433   [(pc)]
5435   rtx dest = operands[0];
5436   rtx src = operands[1];
5437   rtx tmp1 = operands[2];
5438   rtx tmp2 = operands[3];
5439   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5441   if (GET_CODE (tmp1) == SCRATCH)
5442     tmp1 = gen_reg_rtx (DImode);
5443   if (GET_CODE (tmp2) == SCRATCH)
5444     tmp2 = gen_reg_rtx (DImode);
5446   emit_insn (gen_fctiwz_<mode> (tmp1, src));
5447   emit_insn (gen_stfiwx (stack, tmp1));
5448   emit_insn (gen_lfiwax (tmp2, stack));
5449   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5450   DONE;
5452   [(set_attr "type" "fpload")
5453    (set_attr "length" "16")])
5455 (define_insn_and_split "*roundu32<mode>2_fprs"
5456   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5457         (unsigned_float:SFDF
5458          (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5459    (clobber (match_scratch:DI 2 "=d"))
5460    (clobber (match_scratch:DI 3 "=d"))]
5461   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5462    && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
5463    && can_create_pseudo_p ()"
5464   "#"
5465   ""
5466   [(pc)]
5468   rtx dest = operands[0];
5469   rtx src = operands[1];
5470   rtx tmp1 = operands[2];
5471   rtx tmp2 = operands[3];
5472   rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5474   if (GET_CODE (tmp1) == SCRATCH)
5475     tmp1 = gen_reg_rtx (DImode);
5476   if (GET_CODE (tmp2) == SCRATCH)
5477     tmp2 = gen_reg_rtx (DImode);
5479   emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5480   emit_insn (gen_stfiwx (stack, tmp1));
5481   emit_insn (gen_lfiwzx (tmp2, stack));
5482   emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5483   DONE;
5485   [(set_attr "type" "fpload")
5486    (set_attr "length" "16")])
5488 ;; No VSX equivalent to fctid
5489 (define_insn "lrint<mode>di2"
5490   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5491         (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5492                    UNSPEC_FCTID))]
5493   "TARGET_<MODE>_FPR && TARGET_FPRND"
5494   "fctid %0,%1"
5495   [(set_attr "type" "fp")])
5497 (define_insn "btrunc<mode>2"
5498   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5499         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5500                      UNSPEC_FRIZ))]
5501   "TARGET_<MODE>_FPR && TARGET_FPRND"
5502   "@
5503    friz %0,%1
5504    xsrdpiz %x0,%x1"
5505   [(set_attr "type" "fp")
5506    (set_attr "fp_type" "fp_addsub_<Fs>")])
5508 (define_insn "ceil<mode>2"
5509   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5510         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5511                      UNSPEC_FRIP))]
5512   "TARGET_<MODE>_FPR && TARGET_FPRND"
5513   "@
5514    frip %0,%1
5515    xsrdpip %x0,%x1"
5516   [(set_attr "type" "fp")
5517    (set_attr "fp_type" "fp_addsub_<Fs>")])
5519 (define_insn "floor<mode>2"
5520   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5521         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5522                      UNSPEC_FRIM))]
5523   "TARGET_<MODE>_FPR && TARGET_FPRND"
5524   "@
5525    frim %0,%1
5526    xsrdpim %x0,%x1"
5527   [(set_attr "type" "fp")
5528    (set_attr "fp_type" "fp_addsub_<Fs>")])
5530 ;; No VSX equivalent to frin
5531 (define_insn "round<mode>2"
5532   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5533         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5534                      UNSPEC_FRIN))]
5535   "TARGET_<MODE>_FPR && TARGET_FPRND"
5536   "frin %0,%1"
5537   [(set_attr "type" "fp")
5538    (set_attr "fp_type" "fp_addsub_<Fs>")])
5540 (define_insn "*xsrdpi<mode>2"
5541   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5542         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5543                      UNSPEC_XSRDPI))]
5544   "TARGET_<MODE>_FPR && TARGET_VSX"
5545   "xsrdpi %x0,%x1"
5546   [(set_attr "type" "fp")
5547    (set_attr "fp_type" "fp_addsub_<Fs>")])
5549 (define_expand "lround<mode>di2"
5550   [(set (match_dup 2)
5551         (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
5552                      UNSPEC_XSRDPI))
5553    (set (match_operand:DI 0 "gpc_reg_operand" "")
5554         (unspec:DI [(match_dup 2)]
5555                    UNSPEC_FCTID))]
5556   "TARGET_<MODE>_FPR && TARGET_VSX"
5558   operands[2] = gen_reg_rtx (<MODE>mode);
5561 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5562 (define_insn "stfiwx"
5563   [(set (match_operand:SI 0 "memory_operand" "=Z")
5564         (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
5565                    UNSPEC_STFIWX))]
5566   "TARGET_PPC_GFXOPT"
5567   "stfiwx %1,%y0"
5568   [(set_attr "type" "fpstore")])
5570 ;; If we don't have a direct conversion to single precision, don't enable this
5571 ;; conversion for 32-bit without fast math, because we don't have the insn to
5572 ;; generate the fixup swizzle to avoid double rounding problems.
5573 (define_expand "floatsisf2"
5574   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5575         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5576   "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5577    && (!TARGET_FPRS
5578        || (TARGET_FPRS
5579            && ((TARGET_FCFIDS && TARGET_LFIWAX)
5580                || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5581                    && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
5582   "
5584   if (!TARGET_FPRS)
5585     {
5586       if (!REG_P (operands[1]))
5587         operands[1] = force_reg (SImode, operands[1]);
5588     }
5589   else if (TARGET_FCFIDS && TARGET_LFIWAX)
5590     {
5591       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
5592       DONE;
5593     }
5594   else if (TARGET_FCFID && TARGET_LFIWAX)
5595     {
5596       rtx dfreg = gen_reg_rtx (DFmode);
5597       emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
5598       emit_insn (gen_truncdfsf2 (operands[0], dfreg));
5599       DONE;
5600     }
5601   else
5602     {
5603       rtx dreg = operands[1];
5604       if (!REG_P (dreg))
5605         dreg = force_reg (SImode, dreg);
5606       dreg = convert_to_mode (DImode, dreg, false);
5607       emit_insn (gen_floatdisf2 (operands[0], dreg));
5608       DONE;
5609     }
5612 (define_expand "floatdidf2"
5613   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5614         (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
5615   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5616   "")
5618 (define_insn "*floatdidf2_fpr"
5619   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5620         (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5621   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
5622   "@
5623    fcfid %0,%1
5624    xscvsxddp %x0,%x1"
5625   [(set_attr "type" "fp")])
5627 ; Allow the combiner to merge source memory operands to the conversion so that
5628 ; the optimizer/register allocator doesn't try to load the value too early in a
5629 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
5630 ; hit.  We will split after reload to avoid the trip through the GPRs
5632 (define_insn_and_split "*floatdidf2_mem"
5633   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5634         (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5635    (clobber (match_scratch:DI 2 "=d,wi"))]
5636   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
5637   "#"
5638   "&& reload_completed"
5639   [(set (match_dup 2) (match_dup 1))
5640    (set (match_dup 0) (float:DF (match_dup 2)))]
5641   ""
5642   [(set_attr "length" "8")
5643    (set_attr "type" "fpload")])
5645 (define_expand "floatunsdidf2"
5646   [(set (match_operand:DF 0 "gpc_reg_operand" "")
5647         (unsigned_float:DF
5648          (match_operand:DI 1 "gpc_reg_operand" "")))]
5649   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5650   "")
5652 (define_insn "*floatunsdidf2_fcfidu"
5653   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5654         (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5655   "TARGET_HARD_FLOAT && TARGET_FCFIDU"
5656   "@
5657    fcfidu %0,%1
5658    xscvuxddp %x0,%x1"
5659   [(set_attr "type" "fp")
5660    (set_attr "length" "4")])
5662 (define_insn_and_split "*floatunsdidf2_mem"
5663   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5664         (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
5665    (clobber (match_scratch:DI 2 "=d,wi"))]
5666   "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
5667   "#"
5668   "&& reload_completed"
5669   [(set (match_dup 2) (match_dup 1))
5670    (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
5671   ""
5672   [(set_attr "length" "8")
5673    (set_attr "type" "fpload")])
5675 (define_expand "floatdisf2"
5676   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5677         (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5678   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5679    && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
5680   "
5682   if (!TARGET_FCFIDS)
5683     {
5684       rtx val = operands[1];
5685       if (!flag_unsafe_math_optimizations)
5686         {
5687           rtx label = gen_label_rtx ();
5688           val = gen_reg_rtx (DImode);
5689           emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5690           emit_label (label);
5691         }
5692       emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5693       DONE;
5694     }
5697 (define_insn "floatdisf2_fcfids"
5698   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
5699         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5700   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5701    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5702   "@
5703    fcfids %0,%1
5704    xscvsxdsp %x0,%x1"
5705   [(set_attr "type" "fp")])
5707 (define_insn_and_split "*floatdisf2_mem"
5708   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5709         (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5710    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5711   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5712    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
5713   "#"
5714   "&& reload_completed"
5715   [(pc)]
5716   "
5718   emit_move_insn (operands[2], operands[1]);
5719   emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
5720   DONE;
5722   [(set_attr "length" "8")])
5724 ;; This is not IEEE compliant if rounding mode is "round to nearest".
5725 ;; If the DI->DF conversion is inexact, then it's possible to suffer
5726 ;; from double rounding.
5727 ;; Instead of creating a new cpu type for two FP operations, just use fp
5728 (define_insn_and_split "floatdisf2_internal1"
5729   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5730         (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
5731    (clobber (match_scratch:DF 2 "=d"))]
5732   "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5733    && !TARGET_FCFIDS"
5734   "#"
5735   "&& reload_completed"
5736   [(set (match_dup 2)
5737         (float:DF (match_dup 1)))
5738    (set (match_dup 0)
5739         (float_truncate:SF (match_dup 2)))]
5740   ""
5741   [(set_attr "length" "8")
5742    (set_attr "type" "fp")])
5744 ;; Twiddles bits to avoid double rounding.
5745 ;; Bits that might be truncated when converting to DFmode are replaced
5746 ;; by a bit that won't be lost at that stage, but is below the SFmode
5747 ;; rounding position.
5748 (define_expand "floatdisf2_internal2"
5749   [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
5750                                               (const_int 53)))
5751               (clobber (reg:DI CA_REGNO))])
5752    (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
5753                                            (const_int 2047)))
5754    (set (match_dup 3) (plus:DI (match_dup 3)
5755                                (const_int 1)))
5756    (set (match_dup 0) (plus:DI (match_dup 0)
5757                                (const_int 2047)))
5758    (set (match_dup 4) (compare:CCUNS (match_dup 3)
5759                                      (const_int 2)))
5760    (set (match_dup 0) (ior:DI (match_dup 0)
5761                               (match_dup 1)))
5762    (set (match_dup 0) (and:DI (match_dup 0)
5763                               (const_int -2048)))
5764    (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
5765                            (label_ref (match_operand:DI 2 "" ""))
5766                            (pc)))
5767    (set (match_dup 0) (match_dup 1))]
5768   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5769    && !TARGET_FCFIDS"
5770   "
5772   operands[3] = gen_reg_rtx (DImode);
5773   operands[4] = gen_reg_rtx (CCUNSmode);
5776 (define_expand "floatunsdisf2"
5777   [(set (match_operand:SF 0 "gpc_reg_operand" "")
5778         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5779   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5780    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5781   "")
5783 (define_insn "floatunsdisf2_fcfidus"
5784   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
5785         (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
5786   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5787    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5788   "@
5789    fcfidus %0,%1
5790    xscvuxdsp %x0,%x1"
5791   [(set_attr "type" "fp")])
5793 (define_insn_and_split "*floatunsdisf2_mem"
5794   [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
5795         (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
5796    (clobber (match_scratch:DI 2 "=d,d,wi"))]
5797   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
5798    && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
5799   "#"
5800   "&& reload_completed"
5801   [(pc)]
5802   "
5804   emit_move_insn (operands[2], operands[1]);
5805   emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
5806   DONE;
5808   [(set_attr "length" "8")
5809    (set_attr "type" "fpload")])
5811 ;; Define the TImode operations that can be done in a small number
5812 ;; of instructions.  The & constraints are to prevent the register
5813 ;; allocator from allocating registers that overlap with the inputs
5814 ;; (for example, having an input in 7,8 and an output in 6,7).  We
5815 ;; also allow for the output being the same as one of the inputs.
5817 (define_expand "addti3"
5818   [(set (match_operand:TI 0 "gpc_reg_operand" "")
5819         (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
5820                  (match_operand:TI 2 "reg_or_short_operand" "")))]
5821   "TARGET_64BIT"
5823   rtx lo0 = gen_lowpart (DImode, operands[0]);
5824   rtx lo1 = gen_lowpart (DImode, operands[1]);
5825   rtx lo2 = gen_lowpart (DImode, operands[2]);
5826   rtx hi0 = gen_highpart (DImode, operands[0]);
5827   rtx hi1 = gen_highpart (DImode, operands[1]);
5828   rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
5830   if (!reg_or_short_operand (lo2, DImode))
5831     lo2 = force_reg (DImode, lo2);
5832   if (!adde_operand (hi2, DImode))
5833     hi2 = force_reg (DImode, hi2);
5835   emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
5836   emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
5837   DONE;
5840 (define_expand "subti3"
5841   [(set (match_operand:TI 0 "gpc_reg_operand" "")
5842         (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
5843                   (match_operand:TI 2 "gpc_reg_operand" "")))]
5844   "TARGET_64BIT"
5846   rtx lo0 = gen_lowpart (DImode, operands[0]);
5847   rtx lo1 = gen_lowpart (DImode, operands[1]);
5848   rtx lo2 = gen_lowpart (DImode, operands[2]);
5849   rtx hi0 = gen_highpart (DImode, operands[0]);
5850   rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
5851   rtx hi2 = gen_highpart (DImode, operands[2]);
5853   if (!reg_or_short_operand (lo1, DImode))
5854     lo1 = force_reg (DImode, lo1);
5855   if (!adde_operand (hi1, DImode))
5856     hi1 = force_reg (DImode, hi1);
5858   emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
5859   emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
5860   DONE;
5863 ;; 128-bit logical operations expanders
5865 (define_expand "and<mode>3"
5866   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5867         (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5868                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5869   ""
5870   "")
5872 (define_expand "ior<mode>3"
5873   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5874         (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5875                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5876   ""
5877   "")
5879 (define_expand "xor<mode>3"
5880   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5881         (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5882                       (match_operand:BOOL_128 2 "vlogical_operand" "")))]
5883   ""
5884   "")
5886 (define_expand "one_cmpl<mode>2"
5887   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5888         (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5889   ""
5890   "")
5892 (define_expand "nor<mode>3"
5893   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5894         (and:BOOL_128
5895          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5896          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5897   ""
5898   "")
5900 (define_expand "andc<mode>3"
5901   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5902         (and:BOOL_128
5903          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5904          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5905   ""
5906   "")
5908 ;; Power8 vector logical instructions.
5909 (define_expand "eqv<mode>3"
5910   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5911         (not:BOOL_128
5912          (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
5913                        (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5914   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5915   "")
5917 ;; Rewrite nand into canonical form
5918 (define_expand "nand<mode>3"
5919   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5920         (ior:BOOL_128
5921          (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
5922          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
5923   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5924   "")
5926 ;; The canonical form is to have the negated element first, so we need to
5927 ;; reverse arguments.
5928 (define_expand "orc<mode>3"
5929   [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
5930         (ior:BOOL_128
5931          (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
5932          (match_operand:BOOL_128 1 "vlogical_operand" "")))]
5933   "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
5934   "")
5936 ;; 128-bit logical operations insns and split operations
5937 (define_insn_and_split "*and<mode>3_internal"
5938   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5939         (and:BOOL_128
5940          (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5941          (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
5942   ""
5944   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5945     return "xxland %x0,%x1,%x2";
5947   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5948     return "vand %0,%1,%2";
5950   return "#";
5952   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
5953   [(const_int 0)]
5955   rs6000_split_logical (operands, AND, false, false, false);
5956   DONE;
5958   [(set (attr "type")
5959       (if_then_else
5960         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5961         (const_string "vecsimple")
5962         (const_string "integer")))
5963    (set (attr "length")
5964       (if_then_else
5965         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5966         (const_string "4")
5967         (if_then_else
5968          (match_test "TARGET_POWERPC64")
5969          (const_string "8")
5970          (const_string "16"))))])
5972 ;; 128-bit IOR/XOR
5973 (define_insn_and_split "*bool<mode>3_internal"
5974   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
5975         (match_operator:BOOL_128 3 "boolean_or_operator"
5976          [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
5977           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
5978   ""
5980   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
5981     return "xxl%q3 %x0,%x1,%x2";
5983   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
5984     return "v%q3 %0,%1,%2";
5986   return "#";
5988   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
5989   [(const_int 0)]
5991   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
5992   DONE;
5994   [(set (attr "type")
5995       (if_then_else
5996         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
5997         (const_string "vecsimple")
5998         (const_string "integer")))
5999    (set (attr "length")
6000       (if_then_else
6001         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6002         (const_string "4")
6003         (if_then_else
6004          (match_test "TARGET_POWERPC64")
6005          (const_string "8")
6006          (const_string "16"))))])
6008 ;; 128-bit ANDC/ORC
6009 (define_insn_and_split "*boolc<mode>3_internal1"
6010   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6011         (match_operator:BOOL_128 3 "boolean_operator"
6012          [(not:BOOL_128
6013            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6014           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6015   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6017   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6018     return "xxl%q3 %x0,%x1,%x2";
6020   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6021     return "v%q3 %0,%1,%2";
6023   return "#";
6025   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6026    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6027   [(const_int 0)]
6029   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6030   DONE;
6032   [(set (attr "type")
6033       (if_then_else
6034         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6035         (const_string "vecsimple")
6036         (const_string "integer")))
6037    (set (attr "length")
6038       (if_then_else
6039         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6040         (const_string "4")
6041         (if_then_else
6042          (match_test "TARGET_POWERPC64")
6043          (const_string "8")
6044          (const_string "16"))))])
6046 (define_insn_and_split "*boolc<mode>3_internal2"
6047   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6048         (match_operator:TI2 3 "boolean_operator"
6049          [(not:TI2
6050            (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6051           (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6052   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6053   "#"
6054   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6055   [(const_int 0)]
6057   rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6058   DONE;
6060   [(set_attr "type" "integer")
6061    (set (attr "length")
6062         (if_then_else
6063          (match_test "TARGET_POWERPC64")
6064          (const_string "8")
6065          (const_string "16")))])
6067 ;; 128-bit NAND/NOR
6068 (define_insn_and_split "*boolcc<mode>3_internal1"
6069   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6070         (match_operator:BOOL_128 3 "boolean_operator"
6071          [(not:BOOL_128
6072            (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6073           (not:BOOL_128
6074            (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6075   "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6077   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6078     return "xxl%q3 %x0,%x1,%x2";
6080   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6081     return "v%q3 %0,%1,%2";
6083   return "#";
6085   "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6086    && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6087   [(const_int 0)]
6089   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6090   DONE;
6092   [(set (attr "type")
6093       (if_then_else
6094         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6095         (const_string "vecsimple")
6096         (const_string "integer")))
6097    (set (attr "length")
6098       (if_then_else
6099         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6100         (const_string "4")
6101         (if_then_else
6102          (match_test "TARGET_POWERPC64")
6103          (const_string "8")
6104          (const_string "16"))))])
6106 (define_insn_and_split "*boolcc<mode>3_internal2"
6107   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6108         (match_operator:TI2 3 "boolean_operator"
6109          [(not:TI2
6110            (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6111           (not:TI2
6112            (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6113   "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6114   "#"
6115   "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6116   [(const_int 0)]
6118   rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6119   DONE;
6121   [(set_attr "type" "integer")
6122    (set (attr "length")
6123         (if_then_else
6124          (match_test "TARGET_POWERPC64")
6125          (const_string "8")
6126          (const_string "16")))])
6129 ;; 128-bit EQV
6130 (define_insn_and_split "*eqv<mode>3_internal1"
6131   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6132         (not:BOOL_128
6133          (xor:BOOL_128
6134           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6135           (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6136   "TARGET_P8_VECTOR"
6138   if (vsx_register_operand (operands[0], <MODE>mode))
6139     return "xxleqv %x0,%x1,%x2";
6141   return "#";
6143   "TARGET_P8_VECTOR && reload_completed
6144    && int_reg_operand (operands[0], <MODE>mode)"
6145   [(const_int 0)]
6147   rs6000_split_logical (operands, XOR, true, false, false);
6148   DONE;
6150   [(set (attr "type")
6151       (if_then_else
6152         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6153         (const_string "vecsimple")
6154         (const_string "integer")))
6155    (set (attr "length")
6156       (if_then_else
6157         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6158         (const_string "4")
6159         (if_then_else
6160          (match_test "TARGET_POWERPC64")
6161          (const_string "8")
6162          (const_string "16"))))])
6164 (define_insn_and_split "*eqv<mode>3_internal2"
6165   [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6166         (not:TI2
6167          (xor:TI2
6168           (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6169           (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6170   "!TARGET_P8_VECTOR"
6171   "#"
6172   "reload_completed && !TARGET_P8_VECTOR"
6173   [(const_int 0)]
6175   rs6000_split_logical (operands, XOR, true, false, false);
6176   DONE;
6178   [(set_attr "type" "integer")
6179    (set (attr "length")
6180         (if_then_else
6181          (match_test "TARGET_POWERPC64")
6182          (const_string "8")
6183          (const_string "16")))])
6185 ;; 128-bit one's complement
6186 (define_insn_and_split "*one_cmpl<mode>3_internal"
6187   [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6188         (not:BOOL_128
6189           (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6190   ""
6192   if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6193     return "xxlnor %x0,%x1,%x1";
6195   if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6196     return "vnor %0,%1,%1";
6198   return "#";
6200   "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6201   [(const_int 0)]
6203   rs6000_split_logical (operands, NOT, false, false, false);
6204   DONE;
6206   [(set (attr "type")
6207       (if_then_else
6208         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6209         (const_string "vecsimple")
6210         (const_string "integer")))
6211    (set (attr "length")
6212       (if_then_else
6213         (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6214         (const_string "4")
6215         (if_then_else
6216          (match_test "TARGET_POWERPC64")
6217          (const_string "8")
6218          (const_string "16"))))])
6221 ;; Now define ways of moving data around.
6223 ;; Set up a register with a value from the GOT table
6225 (define_expand "movsi_got"
6226   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6227         (unspec:SI [(match_operand:SI 1 "got_operand" "")
6228                     (match_dup 2)] UNSPEC_MOVSI_GOT))]
6229   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6230   "
6232   if (GET_CODE (operands[1]) == CONST)
6233     {
6234       rtx offset = const0_rtx;
6235       HOST_WIDE_INT value;
6237       operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6238       value = INTVAL (offset);
6239       if (value != 0)
6240         {
6241           rtx tmp = (!can_create_pseudo_p ()
6242                      ? operands[0]
6243                      : gen_reg_rtx (Pmode));
6244           emit_insn (gen_movsi_got (tmp, operands[1]));
6245           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6246           DONE;
6247         }
6248     }
6250   operands[2] = rs6000_got_register (operands[1]);
6253 (define_insn "*movsi_got_internal"
6254   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6255         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6256                     (match_operand:SI 2 "gpc_reg_operand" "b")]
6257                    UNSPEC_MOVSI_GOT))]
6258   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6259   "lwz %0,%a1@got(%2)"
6260   [(set_attr "type" "load")])
6262 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6263 ;; didn't get allocated to a hard register.
6264 (define_split
6265   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6266         (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6267                     (match_operand:SI 2 "memory_operand" "")]
6268                    UNSPEC_MOVSI_GOT))]
6269   "DEFAULT_ABI == ABI_V4
6270     && flag_pic == 1
6271     && (reload_in_progress || reload_completed)"
6272   [(set (match_dup 0) (match_dup 2))
6273    (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6274                                  UNSPEC_MOVSI_GOT))]
6275   "")
6277 ;; For SI, we special-case integers that can't be loaded in one insn.  We
6278 ;; do the load 16-bits at a time.  We could do this by loading from memory,
6279 ;; and this is even supposed to be faster, but it is simpler not to get
6280 ;; integers in the TOC.
6281 (define_insn "movsi_low"
6282   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6283         (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6284                            (match_operand 2 "" ""))))]
6285   "TARGET_MACHO && ! TARGET_64BIT"
6286   "lwz %0,lo16(%2)(%1)"
6287   [(set_attr "type" "load")
6288    (set_attr "length" "4")])
6290 (define_insn "*movsi_internal1"
6291   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h")
6292         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))]
6293   "!TARGET_SINGLE_FPU &&
6294    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6295   "@
6296    mr %0,%1
6297    la %0,%a1
6298    lwz%U1%X1 %0,%1
6299    stw%U0%X0 %1,%0
6300    li %0,%1
6301    lis %0,%v1
6302    #
6303    mf%1 %0
6304    mt%0 %1
6305    mt%0 %1
6306    nop"
6307   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
6308    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
6310 (define_insn "*movsi_internal1_single"
6311   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6312         (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6313   "TARGET_SINGLE_FPU &&
6314    (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6315   "@
6316    mr %0,%1
6317    la %0,%a1
6318    lwz%U1%X1 %0,%1
6319    stw%U0%X0 %1,%0
6320    li %0,%1
6321    lis %0,%v1
6322    #
6323    mf%1 %0
6324    mt%0 %1
6325    mt%0 %1
6326    nop
6327    stfs%U0%X0 %1,%0
6328    lfs%U1%X1 %0,%1"
6329   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6330    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6332 ;; Split a load of a large constant into the appropriate two-insn
6333 ;; sequence.
6335 (define_split
6336   [(set (match_operand:SI 0 "gpc_reg_operand" "")
6337         (match_operand:SI 1 "const_int_operand" ""))]
6338   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6339    && (INTVAL (operands[1]) & 0xffff) != 0"
6340   [(set (match_dup 0)
6341         (match_dup 2))
6342    (set (match_dup 0)
6343         (ior:SI (match_dup 0)
6344                 (match_dup 3)))]
6345   "
6347   if (rs6000_emit_set_const (operands[0], operands[1]))
6348     DONE;
6349   else
6350     FAIL;
6353 (define_insn "*mov<mode>_internal2"
6354   [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6355         (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6356                     (const_int 0)))
6357    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6358   ""
6359   "@
6360    cmp<wd>i %2,%0,0
6361    mr. %0,%1
6362    #"
6363   [(set_attr "type" "cmp,logical,cmp")
6364    (set_attr "dot" "yes")
6365    (set_attr "length" "4,4,8")])
6367 (define_split
6368   [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
6369         (compare:CC (match_operand:P 1 "gpc_reg_operand" "")
6370                     (const_int 0)))
6371    (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
6372   "reload_completed"
6373   [(set (match_dup 0) (match_dup 1))
6374    (set (match_dup 2)
6375         (compare:CC (match_dup 0)
6376                     (const_int 0)))]
6377   "")
6379 (define_insn "*movhi_internal"
6380   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6381         (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6382   "gpc_reg_operand (operands[0], HImode)
6383    || gpc_reg_operand (operands[1], HImode)"
6384   "@
6385    mr %0,%1
6386    lhz%U1%X1 %0,%1
6387    sth%U0%X0 %1,%0
6388    li %0,%w1
6389    mf%1 %0
6390    mt%0 %1
6391    nop"
6392   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6394 (define_expand "mov<mode>"
6395   [(set (match_operand:INT 0 "general_operand" "")
6396         (match_operand:INT 1 "any_operand" ""))]
6397   ""
6398   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6400 (define_insn "*movqi_internal"
6401   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h")
6402         (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))]
6403   "gpc_reg_operand (operands[0], QImode)
6404    || gpc_reg_operand (operands[1], QImode)"
6405   "@
6406    mr %0,%1
6407    lbz%U1%X1 %0,%1
6408    stb%U0%X0 %1,%0
6409    li %0,%1
6410    mf%1 %0
6411    mt%0 %1
6412    nop"
6413   [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
6415 ;; Here is how to move condition codes around.  When we store CC data in
6416 ;; an integer register or memory, we store just the high-order 4 bits.
6417 ;; This lets us not shift in the most common case of CR0.
6418 (define_expand "movcc"
6419   [(set (match_operand:CC 0 "nonimmediate_operand" "")
6420         (match_operand:CC 1 "nonimmediate_operand" ""))]
6421   ""
6422   "")
6424 (define_insn "*movcc_internal1"
6425   [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m")
6426         (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))]
6427   "register_operand (operands[0], CCmode)
6428    || register_operand (operands[1], CCmode)"
6429   "@
6430    mcrf %0,%1
6431    mtcrf 128,%1
6432    rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
6433    crxor %0,%0,%0
6434    mfcr %0%Q1
6435    mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
6436    mr %0,%1
6437    li %0,%1
6438    mf%1 %0
6439    mt%0 %1
6440    lwz%U1%X1 %0,%1
6441    stw%U0%X0 %1,%0"
6442   [(set (attr "type")
6443      (cond [(eq_attr "alternative" "0,3")
6444                 (const_string "cr_logical")
6445             (eq_attr "alternative" "1,2")
6446                 (const_string "mtcr")
6447             (eq_attr "alternative" "6,7")
6448                 (const_string "integer")
6449             (eq_attr "alternative" "8")
6450                 (const_string "mfjmpr")
6451             (eq_attr "alternative" "9")
6452                 (const_string "mtjmpr")
6453             (eq_attr "alternative" "10")
6454                 (const_string "load")
6455             (eq_attr "alternative" "11")
6456                 (const_string "store")
6457             (match_test "TARGET_MFCRF")
6458                 (const_string "mfcrf")
6459            ]
6460         (const_string "mfcr")))
6461    (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
6463 ;; For floating-point, we normally deal with the floating-point registers
6464 ;; unless -msoft-float is used.  The sole exception is that parameter passing
6465 ;; can produce floating-point values in fixed-point registers.  Unless the
6466 ;; value is a simple constant or already in memory, we deal with this by
6467 ;; allocating memory and copying the value explicitly via that memory location.
6469 ;; Move 32-bit binary/decimal floating point
6470 (define_expand "mov<mode>"
6471   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
6472         (match_operand:FMOVE32 1 "any_operand" ""))]
6473   "<fmove_ok>"
6474   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6476 (define_split
6477   [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
6478         (match_operand:FMOVE32 1 "const_double_operand" ""))]
6479   "reload_completed
6480    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6481        || (GET_CODE (operands[0]) == SUBREG
6482            && GET_CODE (SUBREG_REG (operands[0])) == REG
6483            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6484   [(set (match_dup 2) (match_dup 3))]
6485   "
6487   long l;
6489   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6491   if (! TARGET_POWERPC64)
6492     operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
6493   else
6494     operands[2] = gen_lowpart (SImode, operands[0]);
6496   operands[3] = gen_int_mode (l, SImode);
6499 (define_insn "mov<mode>_hardfloat"
6500   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_lr2>,<f32_sm>,<f32_sm2>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h")
6501         (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
6502   "(gpc_reg_operand (operands[0], <MODE>mode)
6503    || gpc_reg_operand (operands[1], <MODE>mode))
6504    && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
6505   "@
6506    mr %0,%1
6507    lwz%U1%X1 %0,%1
6508    stw%U0%X0 %1,%0
6509    fmr %0,%1
6510    xscpsgndp %x0,%x1,%x1
6511    xxlxor %x0,%x0,%x0
6512    li %0,0
6513    <f32_li>
6514    <f32_li2>
6515    <f32_si>
6516    <f32_si2>
6517    <f32_lv>
6518    <f32_sv>
6519    mtvsrwz %x0,%1
6520    mfvsrwz %0,%x1
6521    mt%0 %1
6522    mf%1 %0
6523    nop"
6524   [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*")
6525    (set_attr "length" "4")])
6527 (define_insn "*mov<mode>_softfloat"
6528   [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
6529         (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
6530   "(gpc_reg_operand (operands[0], <MODE>mode)
6531    || gpc_reg_operand (operands[1], <MODE>mode))
6532    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
6533   "@
6534    mr %0,%1
6535    mt%0 %1
6536    mf%1 %0
6537    lwz%U1%X1 %0,%1
6538    stw%U0%X0 %1,%0
6539    li %0,%1
6540    lis %0,%v1
6541    #
6542    #
6543    nop"
6544   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
6545    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
6548 ;; Move 64-bit binary/decimal floating point
6549 (define_expand "mov<mode>"
6550   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
6551         (match_operand:FMOVE64 1 "any_operand" ""))]
6552   ""
6553   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6555 (define_split
6556   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6557         (match_operand:FMOVE64 1 "const_int_operand" ""))]
6558   "! TARGET_POWERPC64 && reload_completed
6559    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6560        || (GET_CODE (operands[0]) == SUBREG
6561            && GET_CODE (SUBREG_REG (operands[0])) == REG
6562            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6563   [(set (match_dup 2) (match_dup 4))
6564    (set (match_dup 3) (match_dup 1))]
6565   "
6567   int endian = (WORDS_BIG_ENDIAN == 0);
6568   HOST_WIDE_INT value = INTVAL (operands[1]);
6570   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6571   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6572   operands[4] = GEN_INT (value >> 32);
6573   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
6576 (define_split
6577   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6578         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6579   "! TARGET_POWERPC64 && reload_completed
6580    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6581        || (GET_CODE (operands[0]) == SUBREG
6582            && GET_CODE (SUBREG_REG (operands[0])) == REG
6583            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6584   [(set (match_dup 2) (match_dup 4))
6585    (set (match_dup 3) (match_dup 5))]
6586   "
6588   int endian = (WORDS_BIG_ENDIAN == 0);
6589   long l[2];
6591   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6593   operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
6594   operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
6595   operands[4] = gen_int_mode (l[endian], SImode);
6596   operands[5] = gen_int_mode (l[1 - endian], SImode);
6599 (define_split
6600   [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
6601         (match_operand:FMOVE64 1 "const_double_operand" ""))]
6602   "TARGET_POWERPC64 && reload_completed
6603    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
6604        || (GET_CODE (operands[0]) == SUBREG
6605            && GET_CODE (SUBREG_REG (operands[0])) == REG
6606            && REGNO (SUBREG_REG (operands[0])) <= 31))"
6607   [(set (match_dup 2) (match_dup 3))]
6608   "
6610   int endian = (WORDS_BIG_ENDIAN == 0);
6611   long l[2];
6612   HOST_WIDE_INT val;
6614   <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
6616   operands[2] = gen_lowpart (DImode, operands[0]);
6617   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
6618   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
6619          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
6621   operands[3] = gen_int_mode (val, DImode);
6624 ;; Don't have reload use general registers to load a constant.  It is
6625 ;; less efficient than loading the constant into an FP register, since
6626 ;; it will probably be used there.
6628 ;; The move constraints are ordered to prefer floating point registers before
6629 ;; general purpose registers to avoid doing a store and a load to get the value
6630 ;; into a floating point register when it is needed for a floating point
6631 ;; operation.  Prefer traditional floating point registers over VSX registers,
6632 ;; since the D-form version of the memory instructions does not need a GPR for
6633 ;; reloading.  ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
6634 ;; registers.
6636 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
6637 ;; except for 0.0 which can be created on VSX with an xor instruction.
6639 (define_insn "*mov<mode>_hardfloat32"
6640   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,o,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
6641         (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,o,<f64_p9>,<f64_vsx>,j,j,r,Y,r"))]
6642   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
6643    && (gpc_reg_operand (operands[0], <MODE>mode)
6644        || gpc_reg_operand (operands[1], <MODE>mode))"
6645   "@
6646    stfd%U0%X0 %1,%0
6647    lfd%U1%X1 %0,%1
6648    fmr %0,%1
6649    lxsd%U1x %x0,%y1
6650    stxsd%U0x %x1,%y0
6651    lxsd %0,%1
6652    stxsd %1,%0
6653    xxlor %x0,%x1,%x1
6654    xxlxor %x0,%x0,%x0
6655    #
6656    #
6657    #
6658    #"
6659   [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,two,store,load,two")
6660    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
6662 (define_insn "*mov<mode>_softfloat32"
6663   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
6664         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
6665   "! TARGET_POWERPC64 
6666    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 
6667        || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
6668        || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
6669    && (gpc_reg_operand (operands[0], <MODE>mode)
6670        || gpc_reg_operand (operands[1], <MODE>mode))"
6671   "#"
6672   [(set_attr "type" "store,load,two,*,*,*")
6673    (set_attr "length" "8,8,8,8,12,16")])
6675 ; ld/std require word-aligned displacements -> 'Y' constraint.
6676 ; List Y->r and r->Y before r->r for reload.
6677 (define_insn "*mov<mode>_hardfloat64"
6678   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,o,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
6679         (match_operand:FMOVE64 1 "input_operand" "d,m,d,o,<f64_p9>,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
6680   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6681    && (gpc_reg_operand (operands[0], <MODE>mode)
6682        || gpc_reg_operand (operands[1], <MODE>mode))"
6683   "@
6684    stfd%U0%X0 %1,%0
6685    lfd%U1%X1 %0,%1
6686    fmr %0,%1
6687    lxsd %0,%1
6688    stxsd %1,%0
6689    lxsd%U1x %x0,%y1
6690    stxsd%U0x %x1,%y0
6691    xxlor %x0,%x1,%x1
6692    xxlxor %x0,%x0,%x0
6693    li %0,0
6694    std%U0%X0 %1,%0
6695    ld%U1%X1 %0,%1
6696    mr %0,%1
6697    mt%0 %1
6698    mf%1 %0
6699    nop
6700    mftgpr %0,%1
6701    mffgpr %0,%1
6702    mfvsrd %0,%x1
6703    mtvsrd %x0,%1"
6704   [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
6705    (set_attr "length" "4")])
6707 (define_insn "*mov<mode>_softfloat64"
6708   [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
6709         (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
6710   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6711    && (gpc_reg_operand (operands[0], <MODE>mode)
6712        || gpc_reg_operand (operands[1], <MODE>mode))"
6713   "@
6714    std%U0%X0 %1,%0
6715    ld%U1%X1 %0,%1
6716    mr %0,%1
6717    mt%0 %1
6718    mf%1 %0
6719    #
6720    #
6721    #
6722    nop"
6723   [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
6724    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
6726 (define_expand "mov<mode>"
6727   [(set (match_operand:FMOVE128 0 "general_operand" "")
6728         (match_operand:FMOVE128 1 "any_operand" ""))]
6729   ""
6730   "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
6732 ;; It's important to list Y->r and r->Y before r->r because otherwise
6733 ;; reload, given m->r, will try to pick r->r and reload it, which
6734 ;; doesn't make progress.
6736 ;; We can't split little endian direct moves of TDmode, because the words are
6737 ;; not swapped like they are for TImode or TFmode.  Subregs therefore are
6738 ;; problematical.  Don't allow direct move for this case.
6740 (define_insn_and_split "*mov<mode>_64bit_dm"
6741   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r,r,wm")
6742         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,j,r,jY,r,wm,r"))]
6743   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
6744    && FLOAT128_2REG_P (<MODE>mode)
6745    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
6746    && (gpc_reg_operand (operands[0], <MODE>mode)
6747        || gpc_reg_operand (operands[1], <MODE>mode))"
6748   "#"
6749   "&& reload_completed"
6750   [(pc)]
6751 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6752   [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
6754 (define_insn_and_split "*movtd_64bit_nodm"
6755   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
6756         (match_operand:TD 1 "input_operand" "d,m,d,j,r,jY,r"))]
6757   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
6758    && (gpc_reg_operand (operands[0], TDmode)
6759        || gpc_reg_operand (operands[1], TDmode))"
6760   "#"
6761   "&& reload_completed"
6762   [(pc)]
6763 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6764   [(set_attr "length" "8,8,8,8,12,12,8")])
6766 (define_insn_and_split "*mov<mode>_32bit"
6767   [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
6768         (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,j,r,jY,r"))]
6769   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
6770    && (FLOAT128_2REG_P (<MODE>mode)
6771        || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
6772        || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
6773    && (gpc_reg_operand (operands[0], <MODE>mode)
6774        || gpc_reg_operand (operands[1], <MODE>mode))"
6775   "#"
6776   "&& reload_completed"
6777   [(pc)]
6778 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6779   [(set_attr "length" "8,8,8,8,20,20,16")])
6781 (define_insn_and_split "*mov<mode>_softfloat"
6782   [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r")
6783         (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
6784   "(TARGET_SOFT_FLOAT || !TARGET_FPRS)
6785    && (gpc_reg_operand (operands[0], <MODE>mode)
6786        || gpc_reg_operand (operands[1], <MODE>mode))"
6787   "#"
6788   "&& reload_completed"
6789   [(pc)]
6790 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
6791   [(set_attr "length" "20,20,16")])
6793 (define_expand "extenddf<mode>2"
6794   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6795         (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
6796   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
6797    && TARGET_LONG_DOUBLE_128"
6799   if (FLOAT128_IEEE_P (<MODE>mode))
6800     rs6000_expand_float128_convert (operands[0], operands[1], false);
6801   else if (TARGET_E500_DOUBLE)
6802     {
6803       gcc_assert (<MODE>mode == TFmode);
6804       emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
6805     }
6806   else if (TARGET_VSX)
6807     {
6808       if (<MODE>mode == TFmode)
6809         emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
6810       else if (<MODE>mode == IFmode)
6811         emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
6812       else
6813         gcc_unreachable ();
6814     }
6815    else
6816     {
6817       rtx zero = gen_reg_rtx (DFmode);
6818       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
6820       if (<MODE>mode == TFmode)
6821         emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
6822       else if (<MODE>mode == IFmode)
6823         emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
6824       else
6825         gcc_unreachable ();
6826     }
6827   DONE;
6830 ;; Allow memory operands for the source to be created by the combiner.
6831 (define_insn_and_split "extenddf<mode>2_fprs"
6832   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
6833         (float_extend:IBM128
6834          (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
6835    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
6836   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6837    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6838   "#"
6839   "&& reload_completed"
6840   [(set (match_dup 3) (match_dup 1))
6841    (set (match_dup 4) (match_dup 2))]
6843   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6844   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6846   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6847   operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6850 (define_insn_and_split "extenddf<mode>2_vsx"
6851   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
6852         (float_extend:IBM128
6853          (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
6854   "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
6855   "#"
6856   "&& reload_completed"
6857   [(set (match_dup 2) (match_dup 1))
6858    (set (match_dup 3) (match_dup 4))]
6860   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
6861   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
6863   operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
6864   operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
6865   operands[4] = CONST0_RTX (DFmode);
6868 (define_expand "extendsf<mode>2"
6869   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6870         (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
6871   "TARGET_HARD_FLOAT
6872    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6873    && TARGET_LONG_DOUBLE_128"
6875   if (FLOAT128_IEEE_P (<MODE>mode))
6876     rs6000_expand_float128_convert (operands[0], operands[1], false);
6877   else
6878     {
6879       rtx tmp = gen_reg_rtx (DFmode);
6880       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
6881       emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
6882     }
6883   DONE;
6886 (define_expand "trunc<mode>df2"
6887   [(set (match_operand:DF 0 "gpc_reg_operand" "")
6888         (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6889   "TARGET_HARD_FLOAT
6890    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6891    && TARGET_LONG_DOUBLE_128"
6893   if (FLOAT128_IEEE_P (<MODE>mode))
6894     {
6895       rs6000_expand_float128_convert (operands[0], operands[1], false);
6896       DONE;
6897     }
6900 (define_insn_and_split "trunc<mode>df2_internal1"
6901   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
6902         (float_truncate:DF
6903          (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
6904   "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
6905    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
6906   "@
6907    #
6908    fmr %0,%1"
6909   "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
6910   [(const_int 0)]
6912   emit_note (NOTE_INSN_DELETED);
6913   DONE;
6915   [(set_attr "type" "fp")])
6917 (define_insn "trunc<mode>df2_internal2"
6918   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6919         (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
6920   "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
6921    && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
6922   "fadd %0,%1,%L1"
6923   [(set_attr "type" "fp")
6924    (set_attr "fp_type" "fp_addsub_d")])
6926 (define_expand "trunc<mode>sf2"
6927   [(set (match_operand:SF 0 "gpc_reg_operand" "")
6928         (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
6929   "TARGET_HARD_FLOAT
6930    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6931    && TARGET_LONG_DOUBLE_128"
6933   if (FLOAT128_IEEE_P (<MODE>mode))
6934     rs6000_expand_float128_convert (operands[0], operands[1], false);
6935   else if (TARGET_E500_DOUBLE)
6936     {
6937       gcc_assert (<MODE>mode == TFmode);
6938       emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
6939     }
6940   else if (<MODE>mode == TFmode)
6941     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
6942   else if (<MODE>mode == IFmode)
6943     emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
6944   else
6945     gcc_unreachable ();
6946   DONE;
6949 (define_insn_and_split "trunc<mode>sf2_fprs"
6950   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6951         (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
6952    (clobber (match_scratch:DF 2 "=d"))]
6953   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
6954    && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
6955   "#"
6956   "&& reload_completed"
6957   [(set (match_dup 2)
6958         (float_truncate:DF (match_dup 1)))
6959    (set (match_dup 0)
6960         (float_truncate:SF (match_dup 2)))]
6961   "")
6963 (define_expand "floatsi<mode>2"
6964   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
6965         (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
6966   "TARGET_HARD_FLOAT
6967    && (TARGET_FPRS || TARGET_E500_DOUBLE)
6968    && TARGET_LONG_DOUBLE_128"
6970   if (FLOAT128_IEEE_P (<MODE>mode))
6971     rs6000_expand_float128_convert (operands[0], operands[1], false);
6972   else
6973     {
6974       rtx tmp = gen_reg_rtx (DFmode);
6975       expand_float (tmp, operands[1], false);
6976       if (<MODE>mode == TFmode)
6977         emit_insn (gen_extenddftf2 (operands[0], tmp));
6978       else if (<MODE>mode == IFmode)
6979         emit_insn (gen_extenddfif2 (operands[0], tmp));
6980       else
6981         gcc_unreachable ();
6982     }
6983   DONE;
6986 ; fadd, but rounding towards zero.
6987 ; This is probably not the optimal code sequence.
6988 (define_insn "fix_trunc_helper<mode>"
6989   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6990         (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
6991                    UNSPEC_FIX_TRUNC_TF))
6992    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
6993   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6994    && FLOAT128_IBM_P (<MODE>mode)"
6995   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
6996   [(set_attr "type" "fp")
6997    (set_attr "length" "20")])
6999 (define_expand "fix_trunc<mode>si2"
7000   [(set (match_operand:SI 0 "gpc_reg_operand" "")
7001         (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7002   "TARGET_HARD_FLOAT
7003    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
7005   if (FLOAT128_IEEE_P (<MODE>mode))
7006     rs6000_expand_float128_convert (operands[0], operands[1], false);
7007   else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7008     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
7009   else if (<MODE>mode == TFmode)
7010     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
7011   else if (<MODE>mode == IFmode)
7012     emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
7013   else
7014     gcc_unreachable ();
7015   DONE;
7018 (define_expand "fix_trunc<mode>si2_fprs"
7019   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7020                    (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7021               (clobber (match_dup 2))
7022               (clobber (match_dup 3))
7023               (clobber (match_dup 4))
7024               (clobber (match_dup 5))])]
7025   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7027   operands[2] = gen_reg_rtx (DFmode);
7028   operands[3] = gen_reg_rtx (DFmode);
7029   operands[4] = gen_reg_rtx (DImode);
7030   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7033 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7034   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7035         (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7036    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7037    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7038    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7039    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7040   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
7041   "#"
7042   ""
7043   [(pc)]
7045   rtx lowword;
7046   emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7047                                          operands[3]));
7049   gcc_assert (MEM_P (operands[5]));
7050   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7052   emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7053   emit_move_insn (operands[5], operands[4]);
7054   emit_move_insn (operands[0], lowword);
7055   DONE;
7058 (define_expand "fix_trunc<mode>di2"
7059   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7060         (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7061   "TARGET_FLOAT128"
7063   rs6000_expand_float128_convert (operands[0], operands[1], false);
7064   DONE;
7067 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7068   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7069         (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7070   "TARGET_FLOAT128"
7072   rs6000_expand_float128_convert (operands[0], operands[1], true);
7073   DONE;
7076 (define_expand "floatdi<mode>2"
7077   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7078         (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7079   "TARGET_FLOAT128"
7081   rs6000_expand_float128_convert (operands[0], operands[1], false);
7082   DONE;
7085 (define_expand "floatuns<SDI:mode><IEEE128:mode>2"
7086   [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7087         (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
7088   "TARGET_FLOAT128"
7090   rs6000_expand_float128_convert (operands[0], operands[1], true);
7091   DONE;
7094 (define_expand "neg<mode>2"
7095   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7096         (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7097   "FLOAT128_IEEE_P (<MODE>mode)
7098    || (FLOAT128_IBM_P (<MODE>mode)
7099        && TARGET_HARD_FLOAT
7100        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7101   "
7103   if (FLOAT128_IEEE_P (<MODE>mode))
7104     {
7105       if (TARGET_FLOAT128_HW)
7106         {
7107           if (<MODE>mode == TFmode)
7108             emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7109           else if (<MODE>mode == KFmode)
7110             emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7111           else
7112             gcc_unreachable ();
7113         }
7114       else if (TARGET_FLOAT128)
7115         {
7116           if (<MODE>mode == TFmode)
7117             emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7118           else if (<MODE>mode == KFmode)
7119             emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7120           else
7121             gcc_unreachable ();
7122         }
7123       else
7124         {
7125           rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7126           rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7127                                                 <MODE>mode, 1,
7128                                                 operands[1], <MODE>mode);
7130           if (target && !rtx_equal_p (target, operands[0]))
7131             emit_move_insn (operands[0], target);
7132         }
7133       DONE;
7134     }
7137 (define_insn "neg<mode>2_internal"
7138   [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7139         (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7140   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
7141   "*
7143   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7144     return \"fneg %L0,%L1\;fneg %0,%1\";
7145   else
7146     return \"fneg %0,%1\;fneg %L0,%L1\";
7148   [(set_attr "type" "fp")
7149    (set_attr "length" "8")])
7151 (define_expand "abs<mode>2"
7152   [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7153         (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7154   "FLOAT128_IEEE_P (<MODE>mode)
7155    || (FLOAT128_IBM_P (<MODE>mode)
7156        && TARGET_HARD_FLOAT
7157        && (TARGET_FPRS || TARGET_E500_DOUBLE))"
7158   "
7160   rtx label;
7162   if (FLOAT128_IEEE_P (<MODE>mode))
7163     {
7164       if (TARGET_FLOAT128_HW)
7165         {
7166           if (<MODE>mode == TFmode)
7167             emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7168           else if (<MODE>mode == KFmode)
7169             emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7170           else
7171             FAIL;
7172           DONE;
7173         }
7174       else if (TARGET_FLOAT128)
7175         {
7176           if (<MODE>mode == TFmode)
7177             emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7178           else if (<MODE>mode == KFmode)
7179             emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7180           else
7181             FAIL;
7182           DONE;
7183         }
7184       else
7185         FAIL;
7186     }
7188   label = gen_label_rtx ();
7189   if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
7190     {
7191       if (flag_finite_math_only && !flag_trapping_math)
7192         emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
7193       else
7194         emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
7195     }
7196   else if (<MODE>mode == TFmode)
7197     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7198   else if (<MODE>mode == TFmode)
7199     emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7200   else
7201     FAIL;
7202   emit_label (label);
7203   DONE;
7206 (define_expand "abs<mode>2_internal"
7207   [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
7208         (match_operand:IBM128 1 "gpc_reg_operand" ""))
7209    (set (match_dup 3) (match_dup 5))
7210    (set (match_dup 5) (abs:DF (match_dup 5)))
7211    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7212    (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7213                            (label_ref (match_operand 2 "" ""))
7214                            (pc)))
7215    (set (match_dup 6) (neg:DF (match_dup 6)))]
7216   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
7217    && TARGET_LONG_DOUBLE_128"
7218   "
7220   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7221   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7222   operands[3] = gen_reg_rtx (DFmode);
7223   operands[4] = gen_reg_rtx (CCFPmode);
7224   operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7225   operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7229 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7230 ;; register
7232 (define_expand "ieee_128bit_negative_zero"
7233   [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
7234   "TARGET_FLOAT128"
7236   rtvec v = rtvec_alloc (16);
7237   int i, high;
7239   for (i = 0; i < 16; i++)
7240     RTVEC_ELT (v, i) = const0_rtx;
7242   high = (BYTES_BIG_ENDIAN) ? 0 : 15;
7243   RTVEC_ELT (v, high) = GEN_INT (0x80);
7245   rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
7246   DONE;
7249 ;; IEEE 128-bit negate
7251 ;; We have 2 insns here for negate and absolute value.  The first uses
7252 ;; match_scratch so that phases like combine can recognize neg/abs as generic
7253 ;; insns, and second insn after the first split pass loads up the bit to
7254 ;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
7255 ;; neg/abs to create the constant just once.
7257 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
7258   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7259         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7260    (clobber (match_scratch:V16QI 2 "=v"))]
7261   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7262   "#"
7263   "&& 1"
7264   [(parallel [(set (match_dup 0)
7265                    (neg:IEEE128 (match_dup 1)))
7266               (use (match_dup 2))])]
7268   if (GET_CODE (operands[2]) == SCRATCH)
7269     operands[2] = gen_reg_rtx (V16QImode);
7271   operands[3] = gen_reg_rtx (V16QImode);
7272   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7274   [(set_attr "length" "8")
7275    (set_attr "type" "vecsimple")])
7277 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
7278   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7279         (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7280    (use (match_operand:V16QI 2 "register_operand" "=v"))]
7281   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7282   "xxlxor %x0,%x1,%x2"
7283   [(set_attr "type" "vecsimple")])
7285 ;; IEEE 128-bit absolute value
7286 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
7287   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7288         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7289    (clobber (match_scratch:V16QI 2 "=v"))]
7290   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7291   "#"
7292   "&& 1"
7293   [(parallel [(set (match_dup 0)
7294                    (abs:IEEE128 (match_dup 1)))
7295               (use (match_dup 2))])]
7297   if (GET_CODE (operands[2]) == SCRATCH)
7298     operands[2] = gen_reg_rtx (V16QImode);
7300   operands[3] = gen_reg_rtx (V16QImode);
7301   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7303   [(set_attr "length" "8")
7304    (set_attr "type" "vecsimple")])
7306 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
7307   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7308         (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
7309    (use (match_operand:V16QI 2 "register_operand" "=v"))]
7310   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7311   "xxlandc %x0,%x1,%x2"
7312   [(set_attr "type" "vecsimple")])
7314 ;; IEEE 128-bit negative absolute value
7315 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
7316   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7317         (neg:IEEE128
7318          (abs:IEEE128
7319           (match_operand:IEEE128 1 "register_operand" "wa"))))
7320    (clobber (match_scratch:V16QI 2 "=v"))]
7321   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
7322   "#"
7323   "&& 1"
7324   [(parallel [(set (match_dup 0)
7325                    (abs:IEEE128 (match_dup 1)))
7326               (use (match_dup 2))])]
7328   if (GET_CODE (operands[2]) == SCRATCH)
7329     operands[2] = gen_reg_rtx (V16QImode);
7331   operands[3] = gen_reg_rtx (V16QImode);
7332   emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
7334   [(set_attr "length" "8")
7335    (set_attr "type" "vecsimple")])
7337 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
7338   [(set (match_operand:IEEE128 0 "register_operand" "=wa")
7339         (neg:IEEE128
7340          (abs:IEEE128
7341           (match_operand:IEEE128 1 "register_operand" "wa"))))
7342    (use (match_operand:V16QI 2 "register_operand" "=v"))]
7343   "TARGET_FLOAT128 && !TARGET_FLOAT128_HW"
7344   "xxlor %x0,%x1,%x2"
7345   [(set_attr "type" "vecsimple")])
7347 ;; Float128 conversion functions.  These expand to library function calls.
7348 ;; We use expand to convert from IBM double double to IEEE 128-bit
7349 ;; and trunc for the opposite.
7350 (define_expand "extendiftf2"
7351   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7352         (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
7353   "TARGET_FLOAT128"
7355   rs6000_expand_float128_convert (operands[0], operands[1], false);
7356   DONE;
7359 (define_expand "extendifkf2"
7360   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7361         (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
7362   "TARGET_FLOAT128"
7364   rs6000_expand_float128_convert (operands[0], operands[1], false);
7365   DONE;
7368 (define_expand "extendtfkf2"
7369   [(set (match_operand:KF 0 "gpc_reg_operand" "")
7370         (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
7371   "TARGET_FLOAT128"
7373   rs6000_expand_float128_convert (operands[0], operands[1], false);
7374   DONE;
7377 (define_expand "trunciftf2"
7378   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7379         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7380   "TARGET_FLOAT128"
7382   rs6000_expand_float128_convert (operands[0], operands[1], false);
7383   DONE;
7386 (define_expand "truncifkf2"
7387   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7388         (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
7389   "TARGET_FLOAT128"
7391   rs6000_expand_float128_convert (operands[0], operands[1], false);
7392   DONE;
7395 (define_expand "trunckftf2"
7396   [(set (match_operand:TF 0 "gpc_reg_operand" "")
7397         (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
7398   "TARGET_FLOAT128"
7400   rs6000_expand_float128_convert (operands[0], operands[1], false);
7401   DONE;
7404 (define_expand "trunctfif2"
7405   [(set (match_operand:IF 0 "gpc_reg_operand" "")
7406         (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
7407   "TARGET_FLOAT128"
7409   rs6000_expand_float128_convert (operands[0], operands[1], false);
7410   DONE;
7414 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
7415 ;; must have 3 arguments, and scratch register constraint must be a single
7416 ;; constraint.
7418 ;; Reload patterns to support gpr load/store with misaligned mem.
7419 ;; and multiple gpr load/store at offset >= 0xfffc
7420 (define_expand "reload_<mode>_store"
7421   [(parallel [(match_operand 0 "memory_operand" "=m")
7422               (match_operand 1 "gpc_reg_operand" "r")
7423               (match_operand:GPR 2 "register_operand" "=&b")])]
7424   ""
7426   rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
7427   DONE;
7430 (define_expand "reload_<mode>_load"
7431   [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
7432               (match_operand 1 "memory_operand" "m")
7433               (match_operand:GPR 2 "register_operand" "=b")])]
7434   ""
7436   rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
7437   DONE;
7441 ;; Reload patterns for various types using the vector registers.  We may need
7442 ;; an additional base register to convert the reg+offset addressing to reg+reg
7443 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
7444 ;; index register for gpr registers.
7445 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
7446   [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
7447               (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
7448               (match_operand:P 2 "register_operand" "=b")])]
7449   "<P:tptrsize>"
7451   rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
7452   DONE;
7455 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
7456   [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
7457               (match_operand:RELOAD 1 "memory_operand" "m")
7458               (match_operand:P 2 "register_operand" "=b")])]
7459   "<P:tptrsize>"
7461   rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
7462   DONE;
7466 ;; Reload sometimes tries to move the address to a GPR, and can generate
7467 ;; invalid RTL for addresses involving AND -16.  Allow addresses involving
7468 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
7470 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
7471   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
7472         (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
7473                        (match_operand:P 2 "reg_or_cint_operand" "rI"))
7474                (const_int -16)))]
7475   "TARGET_ALTIVEC && (reload_in_progress || reload_completed)"
7476   "#"
7477   "&& reload_completed"
7478   [(set (match_dup 0)
7479         (plus:P (match_dup 1)
7480                 (match_dup 2)))
7481    (set (match_dup 0)
7482         (and:P (match_dup 0)
7483                (const_int -16)))])
7485 ;; Power8 merge instructions to allow direct move to/from floating point
7486 ;; registers in 32-bit mode.  We use TF mode to get two registers to move the
7487 ;; individual 32-bit parts across.  Subreg doesn't work too well on the TF
7488 ;; value, since it is allocated in reload and not all of the flow information
7489 ;; is setup for it.  We have two patterns to do the two moves between gprs and
7490 ;; fprs.  There isn't a dependancy between the two, but we could potentially
7491 ;; schedule other instructions between the two instructions.  TFmode is
7492 ;; currently limited to traditional FPR registers.  If/when this is changed, we
7493 ;; will need to revist %L to make sure it works with VSX registers, or add an
7494 ;; %x version of %L.
7496 (define_insn "p8_fmrgow_<mode>"
7497   [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
7498         (unspec:FMOVE64X [(match_operand:TF 1 "register_operand" "d")]
7499                          UNSPEC_P8V_FMRGOW))]
7500   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7501   "fmrgow %0,%1,%L1"
7502   [(set_attr "type" "vecperm")])
7504 (define_insn "p8_mtvsrwz_1"
7505   [(set (match_operand:TF 0 "register_operand" "=d")
7506         (unspec:TF [(match_operand:SI 1 "register_operand" "r")]
7507                    UNSPEC_P8V_MTVSRWZ))]
7508   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7509   "mtvsrwz %x0,%1"
7510   [(set_attr "type" "mftgpr")])
7512 (define_insn "p8_mtvsrwz_2"
7513   [(set (match_operand:TF 0 "register_operand" "+d")
7514         (unspec:TF [(match_dup 0)
7515                     (match_operand:SI 1 "register_operand" "r")]
7516                    UNSPEC_P8V_MTVSRWZ))]
7517   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7518   "mtvsrwz %L0,%1"
7519   [(set_attr "type" "mftgpr")])
7521 (define_insn_and_split "reload_fpr_from_gpr<mode>"
7522   [(set (match_operand:FMOVE64X 0 "register_operand" "=ws")
7523         (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
7524                          UNSPEC_P8V_RELOAD_FROM_GPR))
7525    (clobber (match_operand:TF 2 "register_operand" "=d"))]
7526   "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7527   "#"
7528   "&& reload_completed"
7529   [(const_int 0)]
7531   rtx dest = operands[0];
7532   rtx src = operands[1];
7533   rtx tmp = operands[2];
7534   rtx gpr_hi_reg = gen_highpart (SImode, src);
7535   rtx gpr_lo_reg = gen_lowpart (SImode, src);
7537   emit_insn (gen_p8_mtvsrwz_1 (tmp, gpr_hi_reg));
7538   emit_insn (gen_p8_mtvsrwz_2 (tmp, gpr_lo_reg));
7539   emit_insn (gen_p8_fmrgow_<mode> (dest, tmp));
7540   DONE;
7542   [(set_attr "length" "12")
7543    (set_attr "type" "three")])
7545 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
7546 (define_insn "p8_mtvsrd_1"
7547   [(set (match_operand:TF 0 "register_operand" "=ws")
7548         (unspec:TF [(match_operand:DI 1 "register_operand" "r")]
7549                    UNSPEC_P8V_MTVSRD))]
7550   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7551   "mtvsrd %0,%1"
7552   [(set_attr "type" "mftgpr")])
7554 (define_insn "p8_mtvsrd_2"
7555   [(set (match_operand:TF 0 "register_operand" "+ws")
7556         (unspec:TF [(match_dup 0)
7557                     (match_operand:DI 1 "register_operand" "r")]
7558                    UNSPEC_P8V_MTVSRD))]
7559   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7560   "mtvsrd %L0,%1"
7561   [(set_attr "type" "mftgpr")])
7563 (define_insn "p8_xxpermdi_<mode>"
7564   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7565         (unspec:FMOVE128_GPR [(match_operand:TF 1 "register_operand" "ws")]
7566                              UNSPEC_P8V_XXPERMDI))]
7567   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7568   "xxpermdi %x0,%1,%L1,0"
7569   [(set_attr "type" "vecperm")])
7571 (define_insn_and_split "reload_vsx_from_gpr<mode>"
7572   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
7573         (unspec:FMOVE128_GPR
7574          [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
7575          UNSPEC_P8V_RELOAD_FROM_GPR))
7576    (clobber (match_operand:TF 2 "register_operand" "=ws"))]
7577   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7578   "#"
7579   "&& reload_completed"
7580   [(const_int 0)]
7582   rtx dest = operands[0];
7583   rtx src = operands[1];
7584   rtx tmp = operands[2];
7585   rtx gpr_hi_reg = gen_highpart (DImode, src);
7586   rtx gpr_lo_reg = gen_lowpart (DImode, src);
7588   emit_insn (gen_p8_mtvsrd_1 (tmp, gpr_hi_reg));
7589   emit_insn (gen_p8_mtvsrd_2 (tmp, gpr_lo_reg));
7590   emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp));
7591   DONE;
7593   [(set_attr "length" "12")
7594    (set_attr "type" "three")])
7596 (define_split
7597   [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
7598         (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
7599   "reload_completed
7600    && (int_reg_operand (operands[0], <MODE>mode)
7601        || int_reg_operand (operands[1], <MODE>mode))
7602    && (!TARGET_DIRECT_MOVE_128
7603        || (!vsx_register_operand (operands[0], <MODE>mode)
7604            && !vsx_register_operand (operands[1], <MODE>mode)))"
7605   [(pc)]
7606 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7608 ;; Move SFmode to a VSX from a GPR register.  Because scalar floating point
7609 ;; type is stored internally as double precision in the VSX registers, we have
7610 ;; to convert it from the vector format.
7612 (define_insn_and_split "reload_vsx_from_gprsf"
7613   [(set (match_operand:SF 0 "register_operand" "=wa")
7614         (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
7615                    UNSPEC_P8V_RELOAD_FROM_GPR))
7616    (clobber (match_operand:DI 2 "register_operand" "=r"))]
7617   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7618   "#"
7619   "&& reload_completed"
7620   [(const_int 0)]
7622   rtx op0 = operands[0];
7623   rtx op1 = operands[1];
7624   rtx op2 = operands[2];
7625   /* Also use the destination register to hold the unconverted DImode value.
7626      This is conceptually a separate value from OP0, so we use gen_rtx_REG
7627      rather than simplify_gen_subreg.  */
7628   rtx op0_di = gen_rtx_REG (DImode, REGNO (op0));
7629   rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
7631   /* Move SF value to upper 32-bits for xscvspdpn.  */
7632   emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7633   emit_move_insn (op0_di, op2);
7634   emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di));
7635   DONE;
7637   [(set_attr "length" "8")
7638    (set_attr "type" "two")])
7640 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
7641 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
7642 ;; and then doing a move of that.
7643 (define_insn "p8_mfvsrd_3_<mode>"
7644   [(set (match_operand:DF 0 "register_operand" "=r")
7645         (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7646                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7647   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7648   "mfvsrd %0,%x1"
7649   [(set_attr "type" "mftgpr")])
7651 (define_insn_and_split "reload_gpr_from_vsx<mode>"
7652   [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
7653         (unspec:FMOVE128_GPR
7654          [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
7655          UNSPEC_P8V_RELOAD_FROM_VSX))
7656    (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
7657   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7658   "#"
7659   "&& reload_completed"
7660   [(const_int 0)]
7662   rtx dest = operands[0];
7663   rtx src = operands[1];
7664   rtx tmp = operands[2];
7665   rtx gpr_hi_reg = gen_highpart (DFmode, dest);
7666   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
7668   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
7669   emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
7670   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
7671   DONE;
7673   [(set_attr "length" "12")
7674    (set_attr "type" "three")])
7676 ;; Move SFmode to a GPR from a VSX register.  Because scalar floating point
7677 ;; type is stored internally as double precision, we have to convert it to the
7678 ;; vector format.
7680 (define_insn_and_split "reload_gpr_from_vsxsf"
7681   [(set (match_operand:SF 0 "register_operand" "=r")
7682         (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
7683                    UNSPEC_P8V_RELOAD_FROM_VSX))
7684    (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
7685   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7686   "#"
7687   "&& reload_completed"
7688   [(const_int 0)]
7690   rtx op0 = operands[0];
7691   rtx op1 = operands[1];
7692   rtx op2 = operands[2];
7693   rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0);
7695   emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7696   emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2));
7697   emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32)));
7698   DONE;
7700   [(set_attr "length" "12")
7701    (set_attr "type" "three")])
7703 (define_insn "p8_mfvsrd_4_disf"
7704   [(set (match_operand:DI 0 "register_operand" "=r")
7705         (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")]
7706                    UNSPEC_P8V_RELOAD_FROM_VSX))]
7707   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
7708   "mfvsrd %0,%x1"
7709   [(set_attr "type" "mftgpr")])
7712 ;; Next come the multi-word integer load and store and the load and store
7713 ;; multiple insns.
7715 ;; List r->r after r->Y, otherwise reload will try to reload a
7716 ;; non-offsettable address by using r->r which won't make progress.
7717 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
7718 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
7719 (define_insn "*movdi_internal32"
7720   [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r")
7721         (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))]
7722   "! TARGET_POWERPC64
7723    && (gpc_reg_operand (operands[0], DImode)
7724        || gpc_reg_operand (operands[1], DImode))"
7725   "@
7726    #
7727    #
7728    #
7729    stfd%U0%X0 %1,%0
7730    lfd%U1%X1 %0,%1
7731    fmr %0,%1
7732    #"
7733   [(set_attr "type" "store,load,*,fpstore,fpload,fp,*")])
7735 (define_split
7736   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7737         (match_operand:DI 1 "const_int_operand" ""))]
7738   "! TARGET_POWERPC64 && reload_completed
7739    && gpr_or_gpr_p (operands[0], operands[1])
7740    && !direct_move_p (operands[0], operands[1])"
7741   [(set (match_dup 2) (match_dup 4))
7742    (set (match_dup 3) (match_dup 1))]
7743   "
7745   HOST_WIDE_INT value = INTVAL (operands[1]);
7746   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7747                                        DImode);
7748   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7749                                        DImode);
7750   operands[4] = GEN_INT (value >> 32);
7751   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7754 (define_split
7755   [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
7756         (match_operand:DIFD 1 "input_operand" ""))]
7757   "reload_completed && !TARGET_POWERPC64
7758    && gpr_or_gpr_p (operands[0], operands[1])
7759    && !direct_move_p (operands[0], operands[1])"
7760   [(pc)]
7761 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7763 (define_insn "*movdi_internal64"
7764   [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi")
7765         (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))]
7766   "TARGET_POWERPC64
7767    && (gpc_reg_operand (operands[0], DImode)
7768        || gpc_reg_operand (operands[1], DImode))"
7769   "@
7770    std%U0%X0 %1,%0
7771    ld%U1%X1 %0,%1
7772    mr %0,%1
7773    li %0,%1
7774    lis %0,%v1
7775    #
7776    stfd%U0%X0 %1,%0
7777    lfd%U1%X1 %0,%1
7778    fmr %0,%1
7779    mf%1 %0
7780    mt%0 %1
7781    nop
7782    mftgpr %0,%1
7783    mffgpr %0,%1
7784    mfvsrd %0,%x1
7785    mtvsrd %x0,%1
7786    xxlxor %x0,%x0,%x0"
7787   [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
7788    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
7790 ; Some DImode loads are best done as a load of -1 followed by a mask
7791 ; instruction.
7792 (define_split
7793   [(set (match_operand:DI 0 "gpc_reg_operand")
7794         (match_operand:DI 1 "const_int_operand"))]
7795   "TARGET_POWERPC64
7796    && num_insns_constant (operands[1], DImode) > 1
7797    && rs6000_is_valid_and_mask (operands[1], DImode)"
7798   [(set (match_dup 0)
7799         (const_int -1))
7800    (set (match_dup 0)
7801         (and:DI (match_dup 0)
7802                 (match_dup 1)))]
7803   "")
7805 ;; Split a load of a large constant into the appropriate five-instruction
7806 ;; sequence.  Handle anything in a constant number of insns.
7807 ;; When non-easy constants can go in the TOC, this should use
7808 ;; easy_fp_constant predicate.
7809 (define_split
7810   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7811         (match_operand:DI 1 "const_int_operand" ""))]
7812   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7813   [(set (match_dup 0) (match_dup 2))
7814    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7815   "
7817   if (rs6000_emit_set_const (operands[0], operands[1]))
7818     DONE;
7819   else
7820     FAIL;
7823 (define_split
7824   [(set (match_operand:DI 0 "gpc_reg_operand" "")
7825         (match_operand:DI 1 "const_scalar_int_operand" ""))]
7826   "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
7827   [(set (match_dup 0) (match_dup 2))
7828    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
7829   "
7831   if (rs6000_emit_set_const (operands[0], operands[1]))
7832     DONE;
7833   else
7834     FAIL;
7837 ;; TImode/PTImode is similar, except that we usually want to compute the
7838 ;; address into a register and use lsi/stsi (the exception is during reload).
7840 (define_insn "*mov<mode>_string"
7841   [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
7842         (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
7843   "! TARGET_POWERPC64
7844    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
7845    && (gpc_reg_operand (operands[0], <MODE>mode)
7846        || gpc_reg_operand (operands[1], <MODE>mode))"
7847   "*
7849   switch (which_alternative)
7850     {
7851     default:
7852       gcc_unreachable ();
7853     case 0:
7854       if (TARGET_STRING)
7855         return \"stswi %1,%P0,16\";
7856     case 1:
7857       return \"#\";
7858     case 2:
7859       /* If the address is not used in the output, we can use lsi.  Otherwise,
7860          fall through to generating four loads.  */
7861       if (TARGET_STRING
7862           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
7863         return \"lswi %0,%P1,16\";
7864       /* ... fall through ...  */
7865     case 3:
7866     case 4:
7867     case 5:
7868       return \"#\";
7869     }
7871   [(set_attr "type" "store,store,load,load,*,*")
7872    (set_attr "update" "yes")
7873    (set_attr "indexed" "yes")
7874    (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
7875                                           (const_string "always")
7876                                           (const_string "conditional")))])
7878 (define_insn "*mov<mode>_ppc64"
7879   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
7880         (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
7881   "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
7882    && (gpc_reg_operand (operands[0], <MODE>mode)
7883        || gpc_reg_operand (operands[1], <MODE>mode)))"
7885   return rs6000_output_move_128bit (operands);
7887   [(set_attr "type" "store,store,load,load,*,*")
7888    (set_attr "length" "8")])
7890 (define_split
7891   [(set (match_operand:TI2 0 "int_reg_operand" "")
7892         (match_operand:TI2 1 "const_scalar_int_operand" ""))]
7893   "TARGET_POWERPC64
7894    && (VECTOR_MEM_NONE_P (<MODE>mode)
7895        || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
7896   [(set (match_dup 2) (match_dup 4))
7897    (set (match_dup 3) (match_dup 5))]
7898   "
7900   operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
7901                                        <MODE>mode);
7902   operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
7903                                        <MODE>mode);
7904   if (CONST_WIDE_INT_P (operands[1]))
7905     {
7906       operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
7907       operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
7908     }
7909   else if (CONST_INT_P (operands[1]))
7910     {
7911       operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
7912       operands[5] = operands[1];
7913     }
7914   else
7915     FAIL;
7918 (define_split
7919   [(set (match_operand:TI2 0 "nonimmediate_operand" "")
7920         (match_operand:TI2 1 "input_operand" ""))]
7921   "reload_completed
7922    && gpr_or_gpr_p (operands[0], operands[1])
7923    && !direct_move_p (operands[0], operands[1])
7924    && !quad_load_store_p (operands[0], operands[1])"
7925   [(pc)]
7926 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
7928 (define_expand "load_multiple"
7929   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7930                           (match_operand:SI 1 "" ""))
7931                      (use (match_operand:SI 2 "" ""))])]
7932   "TARGET_STRING && !TARGET_POWERPC64"
7933   "
7935   int regno;
7936   int count;
7937   rtx op1;
7938   int i;
7940   /* Support only loading a constant number of fixed-point registers from
7941      memory and only bother with this if more than two; the machine
7942      doesn't support more than eight.  */
7943   if (GET_CODE (operands[2]) != CONST_INT
7944       || INTVAL (operands[2]) <= 2
7945       || INTVAL (operands[2]) > 8
7946       || GET_CODE (operands[1]) != MEM
7947       || GET_CODE (operands[0]) != REG
7948       || REGNO (operands[0]) >= 32)
7949     FAIL;
7951   count = INTVAL (operands[2]);
7952   regno = REGNO (operands[0]);
7954   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
7955   op1 = replace_equiv_address (operands[1],
7956                                force_reg (SImode, XEXP (operands[1], 0)));
7958   for (i = 0; i < count; i++)
7959     XVECEXP (operands[3], 0, i)
7960       = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
7961                      adjust_address_nv (op1, SImode, i * 4));
7964 (define_insn "*ldmsi8"
7965   [(match_parallel 0 "load_multiple_operation"
7966     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7967           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7968      (set (match_operand:SI 3 "gpc_reg_operand" "")
7969           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7970      (set (match_operand:SI 4 "gpc_reg_operand" "")
7971           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7972      (set (match_operand:SI 5 "gpc_reg_operand" "")
7973           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
7974      (set (match_operand:SI 6 "gpc_reg_operand" "")
7975           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
7976      (set (match_operand:SI 7 "gpc_reg_operand" "")
7977           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
7978      (set (match_operand:SI 8 "gpc_reg_operand" "")
7979           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
7980      (set (match_operand:SI 9 "gpc_reg_operand" "")
7981           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
7982   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
7983   "*
7984 { return rs6000_output_load_multiple (operands); }"
7985   [(set_attr "type" "load")
7986    (set_attr "update" "yes")
7987    (set_attr "indexed" "yes")
7988    (set_attr "length" "32")])
7990 (define_insn "*ldmsi7"
7991   [(match_parallel 0 "load_multiple_operation"
7992     [(set (match_operand:SI 2 "gpc_reg_operand" "")
7993           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
7994      (set (match_operand:SI 3 "gpc_reg_operand" "")
7995           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
7996      (set (match_operand:SI 4 "gpc_reg_operand" "")
7997           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
7998      (set (match_operand:SI 5 "gpc_reg_operand" "")
7999           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8000      (set (match_operand:SI 6 "gpc_reg_operand" "")
8001           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8002      (set (match_operand:SI 7 "gpc_reg_operand" "")
8003           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8004      (set (match_operand:SI 8 "gpc_reg_operand" "")
8005           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8006   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8007   "*
8008 { return rs6000_output_load_multiple (operands); }"
8009   [(set_attr "type" "load")
8010    (set_attr "update" "yes")
8011    (set_attr "indexed" "yes")
8012    (set_attr "length" "32")])
8014 (define_insn "*ldmsi6"
8015   [(match_parallel 0 "load_multiple_operation"
8016     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8017           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8018      (set (match_operand:SI 3 "gpc_reg_operand" "")
8019           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8020      (set (match_operand:SI 4 "gpc_reg_operand" "")
8021           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8022      (set (match_operand:SI 5 "gpc_reg_operand" "")
8023           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8024      (set (match_operand:SI 6 "gpc_reg_operand" "")
8025           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8026      (set (match_operand:SI 7 "gpc_reg_operand" "")
8027           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8028   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8029   "*
8030 { return rs6000_output_load_multiple (operands); }"
8031   [(set_attr "type" "load")
8032    (set_attr "update" "yes")
8033    (set_attr "indexed" "yes")
8034    (set_attr "length" "32")])
8036 (define_insn "*ldmsi5"
8037   [(match_parallel 0 "load_multiple_operation"
8038     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8039           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8040      (set (match_operand:SI 3 "gpc_reg_operand" "")
8041           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8042      (set (match_operand:SI 4 "gpc_reg_operand" "")
8043           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8044      (set (match_operand:SI 5 "gpc_reg_operand" "")
8045           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8046      (set (match_operand:SI 6 "gpc_reg_operand" "")
8047           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8048   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8049   "*
8050 { return rs6000_output_load_multiple (operands); }"
8051   [(set_attr "type" "load")
8052    (set_attr "update" "yes")
8053    (set_attr "indexed" "yes")
8054    (set_attr "length" "32")])
8056 (define_insn "*ldmsi4"
8057   [(match_parallel 0 "load_multiple_operation"
8058     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8059           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8060      (set (match_operand:SI 3 "gpc_reg_operand" "")
8061           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8062      (set (match_operand:SI 4 "gpc_reg_operand" "")
8063           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8064      (set (match_operand:SI 5 "gpc_reg_operand" "")
8065           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8066   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8067   "*
8068 { return rs6000_output_load_multiple (operands); }"
8069   [(set_attr "type" "load")
8070    (set_attr "update" "yes")
8071    (set_attr "indexed" "yes")
8072    (set_attr "length" "32")])
8074 (define_insn "*ldmsi3"
8075   [(match_parallel 0 "load_multiple_operation"
8076     [(set (match_operand:SI 2 "gpc_reg_operand" "")
8077           (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8078      (set (match_operand:SI 3 "gpc_reg_operand" "")
8079           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8080      (set (match_operand:SI 4 "gpc_reg_operand" "")
8081           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8082   "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8083   "*
8084 { return rs6000_output_load_multiple (operands); }"
8085   [(set_attr "type" "load")
8086    (set_attr "update" "yes")
8087    (set_attr "indexed" "yes")
8088    (set_attr "length" "32")])
8090 (define_expand "store_multiple"
8091   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8092                           (match_operand:SI 1 "" ""))
8093                      (clobber (scratch:SI))
8094                      (use (match_operand:SI 2 "" ""))])]
8095   "TARGET_STRING && !TARGET_POWERPC64"
8096   "
8098   int regno;
8099   int count;
8100   rtx to;
8101   rtx op0;
8102   int i;
8104   /* Support only storing a constant number of fixed-point registers to
8105      memory and only bother with this if more than two; the machine
8106      doesn't support more than eight.  */
8107   if (GET_CODE (operands[2]) != CONST_INT
8108       || INTVAL (operands[2]) <= 2
8109       || INTVAL (operands[2]) > 8
8110       || GET_CODE (operands[0]) != MEM
8111       || GET_CODE (operands[1]) != REG
8112       || REGNO (operands[1]) >= 32)
8113     FAIL;
8115   count = INTVAL (operands[2]);
8116   regno = REGNO (operands[1]);
8118   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
8119   to = force_reg (SImode, XEXP (operands[0], 0));
8120   op0 = replace_equiv_address (operands[0], to);
8122   XVECEXP (operands[3], 0, 0)
8123     = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
8124   XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
8125                                                  gen_rtx_SCRATCH (SImode));
8127   for (i = 1; i < count; i++)
8128     XVECEXP (operands[3], 0, i + 1)
8129       = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
8130                      gen_rtx_REG (SImode, regno + i));
8133 (define_insn "*stmsi8"
8134   [(match_parallel 0 "store_multiple_operation"
8135     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8136           (match_operand:SI 2 "gpc_reg_operand" "r"))
8137      (clobber (match_scratch:SI 3 "=X"))
8138      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8139           (match_operand:SI 4 "gpc_reg_operand" "r"))
8140      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8141           (match_operand:SI 5 "gpc_reg_operand" "r"))
8142      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8143           (match_operand:SI 6 "gpc_reg_operand" "r"))
8144      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8145           (match_operand:SI 7 "gpc_reg_operand" "r"))
8146      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8147           (match_operand:SI 8 "gpc_reg_operand" "r"))
8148      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8149           (match_operand:SI 9 "gpc_reg_operand" "r"))
8150      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
8151           (match_operand:SI 10 "gpc_reg_operand" "r"))])]
8152   "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
8153   "stswi %2,%1,%O0"
8154   [(set_attr "type" "store")
8155    (set_attr "update" "yes")
8156    (set_attr "indexed" "yes")
8157    (set_attr "cell_micro" "always")])
8159 (define_insn "*stmsi7"
8160   [(match_parallel 0 "store_multiple_operation"
8161     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8162           (match_operand:SI 2 "gpc_reg_operand" "r"))
8163      (clobber (match_scratch:SI 3 "=X"))
8164      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8165           (match_operand:SI 4 "gpc_reg_operand" "r"))
8166      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8167           (match_operand:SI 5 "gpc_reg_operand" "r"))
8168      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8169           (match_operand:SI 6 "gpc_reg_operand" "r"))
8170      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8171           (match_operand:SI 7 "gpc_reg_operand" "r"))
8172      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8173           (match_operand:SI 8 "gpc_reg_operand" "r"))
8174      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
8175           (match_operand:SI 9 "gpc_reg_operand" "r"))])]
8176   "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8177   "stswi %2,%1,%O0"
8178   [(set_attr "type" "store")
8179    (set_attr "update" "yes")
8180    (set_attr "indexed" "yes")
8181    (set_attr "cell_micro" "always")])
8183 (define_insn "*stmsi6"
8184   [(match_parallel 0 "store_multiple_operation"
8185     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8186           (match_operand:SI 2 "gpc_reg_operand" "r"))
8187      (clobber (match_scratch:SI 3 "=X"))
8188      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8189           (match_operand:SI 4 "gpc_reg_operand" "r"))
8190      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8191           (match_operand:SI 5 "gpc_reg_operand" "r"))
8192      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8193           (match_operand:SI 6 "gpc_reg_operand" "r"))
8194      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8195           (match_operand:SI 7 "gpc_reg_operand" "r"))
8196      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
8197           (match_operand:SI 8 "gpc_reg_operand" "r"))])]
8198   "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8199   "stswi %2,%1,%O0"
8200   [(set_attr "type" "store")
8201    (set_attr "update" "yes")
8202    (set_attr "indexed" "yes")
8203    (set_attr "cell_micro" "always")])
8205 (define_insn "*stmsi5"
8206   [(match_parallel 0 "store_multiple_operation"
8207     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8208           (match_operand:SI 2 "gpc_reg_operand" "r"))
8209      (clobber (match_scratch:SI 3 "=X"))
8210      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8211           (match_operand:SI 4 "gpc_reg_operand" "r"))
8212      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8213           (match_operand:SI 5 "gpc_reg_operand" "r"))
8214      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8215           (match_operand:SI 6 "gpc_reg_operand" "r"))
8216      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
8217           (match_operand:SI 7 "gpc_reg_operand" "r"))])]
8218   "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8219   "stswi %2,%1,%O0"
8220   [(set_attr "type" "store")
8221    (set_attr "update" "yes")
8222    (set_attr "indexed" "yes")
8223    (set_attr "cell_micro" "always")])
8225 (define_insn "*stmsi4"
8226   [(match_parallel 0 "store_multiple_operation"
8227     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8228           (match_operand:SI 2 "gpc_reg_operand" "r"))
8229      (clobber (match_scratch:SI 3 "=X"))
8230      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8231           (match_operand:SI 4 "gpc_reg_operand" "r"))
8232      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8233           (match_operand:SI 5 "gpc_reg_operand" "r"))
8234      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
8235           (match_operand:SI 6 "gpc_reg_operand" "r"))])]
8236   "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8237   "stswi %2,%1,%O0"
8238   [(set_attr "type" "store")
8239    (set_attr "update" "yes")
8240    (set_attr "indexed" "yes")
8241    (set_attr "cell_micro" "always")])
8243 (define_insn "*stmsi3"
8244   [(match_parallel 0 "store_multiple_operation"
8245     [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
8246           (match_operand:SI 2 "gpc_reg_operand" "r"))
8247      (clobber (match_scratch:SI 3 "=X"))
8248      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
8249           (match_operand:SI 4 "gpc_reg_operand" "r"))
8250      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
8251           (match_operand:SI 5 "gpc_reg_operand" "r"))])]
8252   "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8253   "stswi %2,%1,%O0"
8254   [(set_attr "type" "store")
8255    (set_attr "update" "yes")
8256    (set_attr "indexed" "yes")
8257    (set_attr "cell_micro" "always")])
8259 (define_expand "setmemsi"
8260   [(parallel [(set (match_operand:BLK 0 "" "")
8261                    (match_operand 2 "const_int_operand" ""))
8262               (use (match_operand:SI 1 "" ""))
8263               (use (match_operand:SI 3 "" ""))])]
8264   ""
8265   "
8267   /* If value to set is not zero, use the library routine.  */
8268   if (operands[2] != const0_rtx)
8269     FAIL;
8271   if (expand_block_clear (operands))
8272     DONE;
8273   else
8274     FAIL;
8277 ;; String/block move insn.
8278 ;; Argument 0 is the destination
8279 ;; Argument 1 is the source
8280 ;; Argument 2 is the length
8281 ;; Argument 3 is the alignment
8283 (define_expand "movmemsi"
8284   [(parallel [(set (match_operand:BLK 0 "" "")
8285                    (match_operand:BLK 1 "" ""))
8286               (use (match_operand:SI 2 "" ""))
8287               (use (match_operand:SI 3 "" ""))])]
8288   ""
8289   "
8291   if (expand_block_move (operands))
8292     DONE;
8293   else
8294     FAIL;
8297 ;; Move up to 32 bytes at a time.  The fixed registers are needed because the
8298 ;; register allocator doesn't have a clue about allocating 8 word registers.
8299 ;; rD/rS = r5 is preferred, efficient form.
8300 (define_expand "movmemsi_8reg"
8301   [(parallel [(set (match_operand 0 "" "")
8302                    (match_operand 1 "" ""))
8303               (use (match_operand 2 "" ""))
8304               (use (match_operand 3 "" ""))
8305               (clobber (reg:SI  5))
8306               (clobber (reg:SI  6))
8307               (clobber (reg:SI  7))
8308               (clobber (reg:SI  8))
8309               (clobber (reg:SI  9))
8310               (clobber (reg:SI 10))
8311               (clobber (reg:SI 11))
8312               (clobber (reg:SI 12))
8313               (clobber (match_scratch:SI 4 ""))])]
8314   "TARGET_STRING"
8315   "")
8317 (define_insn ""
8318   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8319         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8320    (use (match_operand:SI 2 "immediate_operand" "i"))
8321    (use (match_operand:SI 3 "immediate_operand" "i"))
8322    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8323    (clobber (reg:SI  6))
8324    (clobber (reg:SI  7))
8325    (clobber (reg:SI  8))
8326    (clobber (reg:SI  9))
8327    (clobber (reg:SI 10))
8328    (clobber (reg:SI 11))
8329    (clobber (reg:SI 12))
8330    (clobber (match_scratch:SI 5 "=X"))]
8331   "TARGET_STRING
8332    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
8333        || INTVAL (operands[2]) == 0)
8334    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
8335    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
8336    && REGNO (operands[4]) == 5"
8337   "lswi %4,%1,%2\;stswi %4,%0,%2"
8338   [(set_attr "type" "store")
8339    (set_attr "update" "yes")
8340    (set_attr "indexed" "yes")
8341    (set_attr "cell_micro" "always")
8342    (set_attr "length" "8")])
8344 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
8345 ;; register allocator doesn't have a clue about allocating 6 word registers.
8346 ;; rD/rS = r5 is preferred, efficient form.
8347 (define_expand "movmemsi_6reg"
8348   [(parallel [(set (match_operand 0 "" "")
8349                    (match_operand 1 "" ""))
8350               (use (match_operand 2 "" ""))
8351               (use (match_operand 3 "" ""))
8352               (clobber (reg:SI  5))
8353               (clobber (reg:SI  6))
8354               (clobber (reg:SI  7))
8355               (clobber (reg:SI  8))
8356               (clobber (reg:SI  9))
8357               (clobber (reg:SI 10))
8358               (clobber (match_scratch:SI 4 ""))])]
8359   "TARGET_STRING"
8360   "")
8362 (define_insn ""
8363   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8364         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8365    (use (match_operand:SI 2 "immediate_operand" "i"))
8366    (use (match_operand:SI 3 "immediate_operand" "i"))
8367    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8368    (clobber (reg:SI  6))
8369    (clobber (reg:SI  7))
8370    (clobber (reg:SI  8))
8371    (clobber (reg:SI  9))
8372    (clobber (reg:SI 10))
8373    (clobber (match_scratch:SI 5 "=X"))]
8374   "TARGET_STRING
8375    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
8376    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
8377    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
8378    && REGNO (operands[4]) == 5"
8379   "lswi %4,%1,%2\;stswi %4,%0,%2"
8380   [(set_attr "type" "store")
8381    (set_attr "update" "yes")
8382    (set_attr "indexed" "yes")
8383    (set_attr "cell_micro" "always")
8384    (set_attr "length" "8")])
8386 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
8387 ;; problems with TImode.
8388 ;; rD/rS = r5 is preferred, efficient form.
8389 (define_expand "movmemsi_4reg"
8390   [(parallel [(set (match_operand 0 "" "")
8391                    (match_operand 1 "" ""))
8392               (use (match_operand 2 "" ""))
8393               (use (match_operand 3 "" ""))
8394               (clobber (reg:SI 5))
8395               (clobber (reg:SI 6))
8396               (clobber (reg:SI 7))
8397               (clobber (reg:SI 8))
8398               (clobber (match_scratch:SI 4 ""))])]
8399   "TARGET_STRING"
8400   "")
8402 (define_insn ""
8403   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8404         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8405    (use (match_operand:SI 2 "immediate_operand" "i"))
8406    (use (match_operand:SI 3 "immediate_operand" "i"))
8407    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
8408    (clobber (reg:SI 6))
8409    (clobber (reg:SI 7))
8410    (clobber (reg:SI 8))
8411    (clobber (match_scratch:SI 5 "=X"))]
8412   "TARGET_STRING
8413    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
8414    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
8415    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
8416    && REGNO (operands[4]) == 5"
8417   "lswi %4,%1,%2\;stswi %4,%0,%2"
8418   [(set_attr "type" "store")
8419    (set_attr "update" "yes")
8420    (set_attr "indexed" "yes")
8421    (set_attr "cell_micro" "always")
8422    (set_attr "length" "8")])
8424 ;; Move up to 8 bytes at a time.
8425 (define_expand "movmemsi_2reg"
8426   [(parallel [(set (match_operand 0 "" "")
8427                    (match_operand 1 "" ""))
8428               (use (match_operand 2 "" ""))
8429               (use (match_operand 3 "" ""))
8430               (clobber (match_scratch:DI 4 ""))
8431               (clobber (match_scratch:SI 5 ""))])]
8432   "TARGET_STRING && ! TARGET_POWERPC64"
8433   "")
8435 (define_insn ""
8436   [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
8437         (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
8438    (use (match_operand:SI 2 "immediate_operand" "i"))
8439    (use (match_operand:SI 3 "immediate_operand" "i"))
8440    (clobber (match_scratch:DI 4 "=&r"))
8441    (clobber (match_scratch:SI 5 "=X"))]
8442   "TARGET_STRING && ! TARGET_POWERPC64
8443    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
8444   "lswi %4,%1,%2\;stswi %4,%0,%2"
8445   [(set_attr "type" "store")
8446    (set_attr "update" "yes")
8447    (set_attr "indexed" "yes")
8448    (set_attr "cell_micro" "always")
8449    (set_attr "length" "8")])
8451 ;; Move up to 4 bytes at a time.
8452 (define_expand "movmemsi_1reg"
8453   [(parallel [(set (match_operand 0 "" "")
8454                    (match_operand 1 "" ""))
8455               (use (match_operand 2 "" ""))
8456               (use (match_operand 3 "" ""))
8457               (clobber (match_scratch:SI 4 ""))
8458               (clobber (match_scratch:SI 5 ""))])]
8459   "TARGET_STRING"
8460   "")
8462 (define_insn ""
8463   [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
8464         (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
8465    (use (match_operand:SI 2 "immediate_operand" "i"))
8466    (use (match_operand:SI 3 "immediate_operand" "i"))
8467    (clobber (match_scratch:SI 4 "=&r"))
8468    (clobber (match_scratch:SI 5 "=X"))]
8469   "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
8470   "lswi %4,%1,%2\;stswi %4,%0,%2"
8471   [(set_attr "type" "store")
8472    (set_attr "update" "yes")
8473    (set_attr "indexed" "yes")
8474    (set_attr "cell_micro" "always")
8475    (set_attr "length" "8")])
8477 ;; Define insns that do load or store with update.  Some of these we can
8478 ;; get by using pre-decrement or pre-increment, but the hardware can also
8479 ;; do cases where the increment is not the size of the object.
8481 ;; In all these cases, we use operands 0 and 1 for the register being
8482 ;; incremented because those are the operands that local-alloc will
8483 ;; tie and these are the pair most likely to be tieable (and the ones
8484 ;; that will benefit the most).
8486 (define_insn "*movdi_update1"
8487   [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8488         (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8489                          (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8490    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8491         (plus:DI (match_dup 1) (match_dup 2)))]
8492   "TARGET_POWERPC64 && TARGET_UPDATE
8493    && (!avoiding_indexed_address_p (DImode)
8494        || !gpc_reg_operand (operands[2], DImode))"
8495   "@
8496    ldux %3,%0,%2
8497    ldu %3,%2(%0)"
8498   [(set_attr "type" "load")
8499    (set_attr "update" "yes")
8500    (set_attr "indexed" "yes,no")])
8502 (define_insn "movdi_<mode>_update"
8503   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8504                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8505         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8506    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8507         (plus:P (match_dup 1) (match_dup 2)))]
8508   "TARGET_POWERPC64 && TARGET_UPDATE
8509    && (!avoiding_indexed_address_p (Pmode)
8510        || !gpc_reg_operand (operands[2], Pmode)
8511        || (REG_P (operands[0])
8512            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8513   "@
8514    stdux %3,%0,%2
8515    stdu %3,%2(%0)"
8516   [(set_attr "type" "store")
8517    (set_attr "update" "yes")
8518    (set_attr "indexed" "yes,no")])
8520 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8521 ;; needed for stack allocation, even if the user passes -mno-update.
8522 (define_insn "movdi_<mode>_update_stack"
8523   [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8524                          (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8525         (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8526    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8527         (plus:P (match_dup 1) (match_dup 2)))]
8528   "TARGET_POWERPC64"
8529   "@
8530    stdux %3,%0,%2
8531    stdu %3,%2(%0)"
8532   [(set_attr "type" "store")
8533    (set_attr "update" "yes")
8534    (set_attr "indexed" "yes,no")])
8536 (define_insn "*movsi_update1"
8537   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8538         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8539                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8540    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8541         (plus:SI (match_dup 1) (match_dup 2)))]
8542   "TARGET_UPDATE
8543    && (!avoiding_indexed_address_p (SImode)
8544        || !gpc_reg_operand (operands[2], SImode))"
8545   "@
8546    lwzux %3,%0,%2
8547    lwzu %3,%2(%0)"
8548   [(set_attr "type" "load")
8549    (set_attr "update" "yes")
8550    (set_attr "indexed" "yes,no")])
8552 (define_insn "*movsi_update2"
8553   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8554         (sign_extend:DI
8555          (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8556                           (match_operand:DI 2 "gpc_reg_operand" "r")))))
8557    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8558         (plus:DI (match_dup 1) (match_dup 2)))]
8559   "TARGET_POWERPC64 && rs6000_gen_cell_microcode
8560    && !avoiding_indexed_address_p (DImode)"
8561   "lwaux %3,%0,%2"
8562   [(set_attr "type" "load")
8563    (set_attr "sign_extend" "yes")
8564    (set_attr "update" "yes")
8565    (set_attr "indexed" "yes")])
8567 (define_insn "movsi_update"
8568   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8569                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8570         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8571    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8572         (plus:SI (match_dup 1) (match_dup 2)))]
8573   "TARGET_UPDATE
8574    && (!avoiding_indexed_address_p (SImode)
8575        || !gpc_reg_operand (operands[2], SImode)
8576        || (REG_P (operands[0])
8577            && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8578   "@
8579    stwux %3,%0,%2
8580    stwu %3,%2(%0)"
8581   [(set_attr "type" "store")
8582    (set_attr "update" "yes")
8583    (set_attr "indexed" "yes,no")])
8585 ;; This is an unconditional pattern; needed for stack allocation, even
8586 ;; if the user passes -mno-update.
8587 (define_insn "movsi_update_stack"
8588   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8589                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8590         (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8591    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8592         (plus:SI (match_dup 1) (match_dup 2)))]
8593   ""
8594   "@
8595    stwux %3,%0,%2
8596    stwu %3,%2(%0)"
8597   [(set_attr "type" "store")
8598    (set_attr "update" "yes")
8599    (set_attr "indexed" "yes,no")])
8601 (define_insn "*movhi_update1"
8602   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8603         (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8604                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8605    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8606         (plus:SI (match_dup 1) (match_dup 2)))]
8607   "TARGET_UPDATE
8608    && (!avoiding_indexed_address_p (SImode)
8609        || !gpc_reg_operand (operands[2], SImode))"
8610   "@
8611    lhzux %3,%0,%2
8612    lhzu %3,%2(%0)"
8613   [(set_attr "type" "load")
8614    (set_attr "update" "yes")
8615    (set_attr "indexed" "yes,no")])
8617 (define_insn "*movhi_update2"
8618   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8619         (zero_extend:SI
8620          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8621                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8622    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8623         (plus:SI (match_dup 1) (match_dup 2)))]
8624   "TARGET_UPDATE
8625    && (!avoiding_indexed_address_p (SImode)
8626        || !gpc_reg_operand (operands[2], SImode))"
8627   "@
8628    lhzux %3,%0,%2
8629    lhzu %3,%2(%0)"
8630   [(set_attr "type" "load")
8631    (set_attr "update" "yes")
8632    (set_attr "indexed" "yes,no")])
8634 (define_insn "*movhi_update3"
8635   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8636         (sign_extend:SI
8637          (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8638                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8639    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8640         (plus:SI (match_dup 1) (match_dup 2)))]
8641   "TARGET_UPDATE && rs6000_gen_cell_microcode
8642    && (!avoiding_indexed_address_p (SImode)
8643        || !gpc_reg_operand (operands[2], SImode))"
8644   "@
8645    lhaux %3,%0,%2
8646    lhau %3,%2(%0)"
8647   [(set_attr "type" "load")
8648    (set_attr "sign_extend" "yes")
8649    (set_attr "update" "yes")
8650    (set_attr "indexed" "yes,no")])
8652 (define_insn "*movhi_update4"
8653   [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8654                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8655         (match_operand:HI 3 "gpc_reg_operand" "r,r"))
8656    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8657         (plus:SI (match_dup 1) (match_dup 2)))]
8658   "TARGET_UPDATE
8659    && (!avoiding_indexed_address_p (SImode)
8660        || !gpc_reg_operand (operands[2], SImode))"
8661   "@
8662    sthux %3,%0,%2
8663    sthu %3,%2(%0)"
8664   [(set_attr "type" "store")
8665    (set_attr "update" "yes")
8666    (set_attr "indexed" "yes,no")])
8668 (define_insn "*movqi_update1"
8669   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
8670         (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8671                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8672    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8673         (plus:SI (match_dup 1) (match_dup 2)))]
8674   "TARGET_UPDATE
8675    && (!avoiding_indexed_address_p (SImode)
8676        || !gpc_reg_operand (operands[2], SImode))"
8677   "@
8678    lbzux %3,%0,%2
8679    lbzu %3,%2(%0)"
8680   [(set_attr "type" "load")
8681    (set_attr "update" "yes")
8682    (set_attr "indexed" "yes,no")])
8684 (define_insn "*movqi_update2"
8685   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8686         (zero_extend:SI
8687          (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8688                           (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
8689    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8690         (plus:SI (match_dup 1) (match_dup 2)))]
8691   "TARGET_UPDATE
8692    && (!avoiding_indexed_address_p (SImode)
8693        || !gpc_reg_operand (operands[2], SImode))"
8694   "@
8695    lbzux %3,%0,%2
8696    lbzu %3,%2(%0)"
8697   [(set_attr "type" "load")
8698    (set_attr "update" "yes")
8699    (set_attr "indexed" "yes,no")])
8701 (define_insn "*movqi_update3"
8702   [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8703                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8704         (match_operand:QI 3 "gpc_reg_operand" "r,r"))
8705    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8706         (plus:SI (match_dup 1) (match_dup 2)))]
8707   "TARGET_UPDATE
8708    && (!avoiding_indexed_address_p (SImode)
8709        || !gpc_reg_operand (operands[2], SImode))"
8710   "@
8711    stbux %3,%0,%2
8712    stbu %3,%2(%0)"
8713   [(set_attr "type" "store")
8714    (set_attr "update" "yes")
8715    (set_attr "indexed" "yes,no")])
8717 (define_insn "*movsf_update1"
8718   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
8719         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8720                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8721    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8722         (plus:SI (match_dup 1) (match_dup 2)))]
8723   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8724    && (!avoiding_indexed_address_p (SImode)
8725        || !gpc_reg_operand (operands[2], SImode))"
8726   "@
8727    lfsux %3,%0,%2
8728    lfsu %3,%2(%0)"
8729   [(set_attr "type" "fpload")
8730    (set_attr "update" "yes")
8731    (set_attr "indexed" "yes,no")])
8733 (define_insn "*movsf_update2"
8734   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8735                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8736         (match_operand:SF 3 "gpc_reg_operand" "f,f"))
8737    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8738         (plus:SI (match_dup 1) (match_dup 2)))]
8739   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
8740    && (!avoiding_indexed_address_p (SImode)
8741        || !gpc_reg_operand (operands[2], SImode))"
8742   "@
8743    stfsux %3,%0,%2
8744    stfsu %3,%2(%0)"
8745   [(set_attr "type" "fpstore")
8746    (set_attr "update" "yes")
8747    (set_attr "indexed" "yes,no")])
8749 (define_insn "*movsf_update3"
8750   [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
8751         (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8752                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8753    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8754         (plus:SI (match_dup 1) (match_dup 2)))]
8755   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8756    && (!avoiding_indexed_address_p (SImode)
8757        || !gpc_reg_operand (operands[2], SImode))"
8758   "@
8759    lwzux %3,%0,%2
8760    lwzu %3,%2(%0)"
8761   [(set_attr "type" "load")
8762    (set_attr "update" "yes")
8763    (set_attr "indexed" "yes,no")])
8765 (define_insn "*movsf_update4"
8766   [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8767                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8768         (match_operand:SF 3 "gpc_reg_operand" "r,r"))
8769    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8770         (plus:SI (match_dup 1) (match_dup 2)))]
8771   "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
8772    && (!avoiding_indexed_address_p (SImode)
8773        || !gpc_reg_operand (operands[2], SImode))"
8774   "@
8775    stwux %3,%0,%2
8776    stwu %3,%2(%0)"
8777   [(set_attr "type" "store")
8778    (set_attr "update" "yes")
8779    (set_attr "indexed" "yes,no")])
8781 (define_insn "*movdf_update1"
8782   [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
8783         (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8784                          (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8785    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8786         (plus:SI (match_dup 1) (match_dup 2)))]
8787   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8788    && (!avoiding_indexed_address_p (SImode)
8789        || !gpc_reg_operand (operands[2], SImode))"
8790   "@
8791    lfdux %3,%0,%2
8792    lfdu %3,%2(%0)"
8793   [(set_attr "type" "fpload")
8794    (set_attr "update" "yes")
8795    (set_attr "indexed" "yes,no")])
8797 (define_insn "*movdf_update2"
8798   [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8799                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8800         (match_operand:DF 3 "gpc_reg_operand" "d,d"))
8801    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8802         (plus:SI (match_dup 1) (match_dup 2)))]
8803   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
8804    && (!avoiding_indexed_address_p (SImode)
8805        || !gpc_reg_operand (operands[2], SImode))"
8806   "@
8807    stfdux %3,%0,%2
8808    stfdu %3,%2(%0)"
8809   [(set_attr "type" "fpstore")
8810    (set_attr "update" "yes")
8811    (set_attr "indexed" "yes,no")])
8814 ;; After inserting conditional returns we can sometimes have
8815 ;; unnecessary register moves.  Unfortunately we cannot have a
8816 ;; modeless peephole here, because some single SImode sets have early
8817 ;; clobber outputs.  Although those sets expand to multi-ppc-insn
8818 ;; sequences, using get_attr_length here will smash the operands
8819 ;; array.  Neither is there an early_cobbler_p predicate.
8820 ;; Disallow subregs for E500 so we don't munge frob_di_df_2.
8821 ;; Also this optimization interferes with scalars going into
8822 ;; altivec registers (the code does reloading through the FPRs).
8823 (define_peephole2
8824   [(set (match_operand:DF 0 "gpc_reg_operand" "")
8825         (match_operand:DF 1 "any_operand" ""))
8826    (set (match_operand:DF 2 "gpc_reg_operand" "")
8827         (match_dup 0))]
8828   "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
8829    && !TARGET_UPPER_REGS_DF
8830    && peep2_reg_dead_p (2, operands[0])"
8831   [(set (match_dup 2) (match_dup 1))])
8833 (define_peephole2
8834   [(set (match_operand:SF 0 "gpc_reg_operand" "")
8835         (match_operand:SF 1 "any_operand" ""))
8836    (set (match_operand:SF 2 "gpc_reg_operand" "")
8837         (match_dup 0))]
8838   "!TARGET_UPPER_REGS_SF
8839    && peep2_reg_dead_p (2, operands[0])"
8840   [(set (match_dup 2) (match_dup 1))])
8843 ;; TLS support.
8845 ;; Mode attributes for different ABIs.
8846 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
8847 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
8848 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
8849 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
8851 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
8852   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8853         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8854               (match_operand 4 "" "g")))
8855    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8856                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8857                    UNSPEC_TLSGD)
8858    (clobber (reg:SI LR_REGNO))]
8859   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8861   if (TARGET_CMODEL != CMODEL_SMALL)
8862     return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
8863            "bl %z3\;nop";
8864   else
8865     return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
8867   "&& TARGET_TLS_MARKERS"
8868   [(set (match_dup 0)
8869         (unspec:TLSmode [(match_dup 1)
8870                          (match_dup 2)]
8871                         UNSPEC_TLSGD))
8872    (parallel [(set (match_dup 0)
8873                    (call (mem:TLSmode (match_dup 3))
8874                          (match_dup 4)))
8875               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8876               (clobber (reg:SI LR_REGNO))])]
8877   ""
8878   [(set_attr "type" "two")
8879    (set (attr "length")
8880      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8881                    (const_int 16)
8882                    (const_int 12)))])
8884 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
8885   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8886         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
8887               (match_operand 4 "" "g")))
8888    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8889                     (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8890                    UNSPEC_TLSGD)
8891    (clobber (reg:SI LR_REGNO))]
8892   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
8894   if (flag_pic)
8895     {
8896       if (TARGET_SECURE_PLT && flag_pic == 2)
8897         return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
8898       else
8899         return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
8900     }
8901   else
8902     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
8904   "&& TARGET_TLS_MARKERS"
8905   [(set (match_dup 0)
8906         (unspec:TLSmode [(match_dup 1)
8907                          (match_dup 2)]
8908                         UNSPEC_TLSGD))
8909    (parallel [(set (match_dup 0)
8910                    (call (mem:TLSmode (match_dup 3))
8911                          (match_dup 4)))
8912               (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
8913               (clobber (reg:SI LR_REGNO))])]
8914   ""
8915   [(set_attr "type" "two")
8916    (set_attr "length" "8")])
8918 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
8919   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8920         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8921                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8922                         UNSPEC_TLSGD))]
8923   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
8924   "addi %0,%1,%2@got@tlsgd"
8925   "&& TARGET_CMODEL != CMODEL_SMALL"
8926   [(set (match_dup 3)
8927         (high:TLSmode
8928             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
8929    (set (match_dup 0)
8930         (lo_sum:TLSmode (match_dup 3)
8931             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
8932   "
8934   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
8936   [(set (attr "length")
8937      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
8938                    (const_int 8)
8939                    (const_int 4)))])
8941 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
8942   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8943      (high:TLSmode
8944        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
8945                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8946                        UNSPEC_TLSGD)))]
8947   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8948   "addis %0,%1,%2@got@tlsgd@ha"
8949   [(set_attr "length" "4")])
8951 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
8952   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8953      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
8954        (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
8955                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
8956                        UNSPEC_TLSGD)))]
8957   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
8958   "addi %0,%1,%2@got@tlsgd@l"
8959   [(set_attr "length" "4")])
8961 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
8962   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8963         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8964               (match_operand 2 "" "g")))
8965    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8966                    UNSPEC_TLSGD)
8967    (clobber (reg:SI LR_REGNO))]
8968   "HAVE_AS_TLS && TARGET_TLS_MARKERS
8969    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
8970   "bl %z1(%3@tlsgd)\;nop"
8971   [(set_attr "type" "branch")
8972    (set_attr "length" "8")])
8974 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
8975   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8976         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
8977               (match_operand 2 "" "g")))
8978    (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
8979                    UNSPEC_TLSGD)
8980    (clobber (reg:SI LR_REGNO))]
8981   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
8983   if (flag_pic)
8984     {
8985       if (TARGET_SECURE_PLT && flag_pic == 2)
8986         return "bl %z1+32768(%3@tlsgd)@plt";
8987       return "bl %z1(%3@tlsgd)@plt";
8988     }
8989   return "bl %z1(%3@tlsgd)";
8991   [(set_attr "type" "branch")
8992    (set_attr "length" "4")])
8994 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
8995   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
8996         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
8997               (match_operand 3 "" "g")))
8998    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
8999                    UNSPEC_TLSLD)
9000    (clobber (reg:SI LR_REGNO))]
9001   "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9003   if (TARGET_CMODEL != CMODEL_SMALL)
9004     return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9005            "bl %z2\;nop";
9006   else
9007     return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9009   "&& TARGET_TLS_MARKERS"
9010   [(set (match_dup 0)
9011         (unspec:TLSmode [(match_dup 1)]
9012                         UNSPEC_TLSLD))
9013    (parallel [(set (match_dup 0)
9014                    (call (mem:TLSmode (match_dup 2))
9015                          (match_dup 3)))
9016               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9017               (clobber (reg:SI LR_REGNO))])]
9018   ""
9019   [(set_attr "type" "two")
9020    (set (attr "length")
9021      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9022                    (const_int 16)
9023                    (const_int 12)))])
9025 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9026   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9027         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9028               (match_operand 3 "" "g")))
9029    (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9030                    UNSPEC_TLSLD)
9031    (clobber (reg:SI LR_REGNO))]
9032   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9034   if (flag_pic)
9035     {
9036       if (TARGET_SECURE_PLT && flag_pic == 2)
9037         return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9038       else
9039         return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9040     }
9041   else
9042     return "addi %0,%1,%&@got@tlsld\;bl %z2";
9044   "&& TARGET_TLS_MARKERS"
9045   [(set (match_dup 0)
9046         (unspec:TLSmode [(match_dup 1)]
9047                         UNSPEC_TLSLD))
9048    (parallel [(set (match_dup 0)
9049                    (call (mem:TLSmode (match_dup 2))
9050                          (match_dup 3)))
9051               (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9052               (clobber (reg:SI LR_REGNO))])]
9053   ""
9054   [(set_attr "length" "8")])
9056 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9057   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9058         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9059                         UNSPEC_TLSLD))]
9060   "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9061   "addi %0,%1,%&@got@tlsld"
9062   "&& TARGET_CMODEL != CMODEL_SMALL"
9063   [(set (match_dup 2)
9064         (high:TLSmode
9065             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9066    (set (match_dup 0)
9067         (lo_sum:TLSmode (match_dup 2)
9068             (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9069   "
9071   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9073   [(set (attr "length")
9074      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9075                    (const_int 8)
9076                    (const_int 4)))])
9078 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9079   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9080      (high:TLSmode
9081        (unspec:TLSmode [(const_int 0)
9082                         (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9083                        UNSPEC_TLSLD)))]
9084   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9085   "addis %0,%1,%&@got@tlsld@ha"
9086   [(set_attr "length" "4")])
9088 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9089   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9090      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9091        (unspec:TLSmode [(const_int 0)
9092                         (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9093                        UNSPEC_TLSLD)))]
9094   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9095   "addi %0,%1,%&@got@tlsld@l"
9096   [(set_attr "length" "4")])
9098 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9099   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9100         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9101               (match_operand 2 "" "g")))
9102    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9103    (clobber (reg:SI LR_REGNO))]
9104   "HAVE_AS_TLS && TARGET_TLS_MARKERS
9105    && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9106   "bl %z1(%&@tlsld)\;nop"
9107   [(set_attr "type" "branch")
9108    (set_attr "length" "8")])
9110 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9111   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9112         (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9113               (match_operand 2 "" "g")))
9114    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9115    (clobber (reg:SI LR_REGNO))]
9116   "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9118   if (flag_pic)
9119     {
9120       if (TARGET_SECURE_PLT && flag_pic == 2)
9121         return "bl %z1+32768(%&@tlsld)@plt";
9122       return "bl %z1(%&@tlsld)@plt";
9123     }
9124   return "bl %z1(%&@tlsld)";
9126   [(set_attr "type" "branch")
9127    (set_attr "length" "4")])
9129 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9130   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9131         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9132                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9133                         UNSPEC_TLSDTPREL))]
9134   "HAVE_AS_TLS"
9135   "addi %0,%1,%2@dtprel")
9137 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9138   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9139         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9140                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9141                         UNSPEC_TLSDTPRELHA))]
9142   "HAVE_AS_TLS"
9143   "addis %0,%1,%2@dtprel@ha")
9145 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9146   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9147         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9148                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9149                         UNSPEC_TLSDTPRELLO))]
9150   "HAVE_AS_TLS"
9151   "addi %0,%1,%2@dtprel@l")
9153 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9154   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9155         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9156                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9157                         UNSPEC_TLSGOTDTPREL))]
9158   "HAVE_AS_TLS"
9159   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9160   "&& TARGET_CMODEL != CMODEL_SMALL"
9161   [(set (match_dup 3)
9162         (high:TLSmode
9163             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9164    (set (match_dup 0)
9165         (lo_sum:TLSmode (match_dup 3)
9166             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9167   "
9169   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9171   [(set (attr "length")
9172      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9173                    (const_int 8)
9174                    (const_int 4)))])
9176 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9177   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9178      (high:TLSmode
9179        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9180                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9181                        UNSPEC_TLSGOTDTPREL)))]
9182   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9183   "addis %0,%1,%2@got@dtprel@ha"
9184   [(set_attr "length" "4")])
9186 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9187   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9188      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9189          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9190                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9191                          UNSPEC_TLSGOTDTPREL)))]
9192   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9193   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9194   [(set_attr "length" "4")])
9196 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9197   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9198         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9199                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9200                         UNSPEC_TLSTPREL))]
9201   "HAVE_AS_TLS"
9202   "addi %0,%1,%2@tprel")
9204 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9205   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9206         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9207                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9208                         UNSPEC_TLSTPRELHA))]
9209   "HAVE_AS_TLS"
9210   "addis %0,%1,%2@tprel@ha")
9212 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9213   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9214         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9215                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9216                         UNSPEC_TLSTPRELLO))]
9217   "HAVE_AS_TLS"
9218   "addi %0,%1,%2@tprel@l")
9220 ;; "b" output constraint here and on tls_tls input to support linker tls
9221 ;; optimization.  The linker may edit the instructions emitted by a
9222 ;; tls_got_tprel/tls_tls pair to addis,addi.
9223 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9224   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9225         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9226                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9227                         UNSPEC_TLSGOTTPREL))]
9228   "HAVE_AS_TLS"
9229   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9230   "&& TARGET_CMODEL != CMODEL_SMALL"
9231   [(set (match_dup 3)
9232         (high:TLSmode
9233             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9234    (set (match_dup 0)
9235         (lo_sum:TLSmode (match_dup 3)
9236             (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9237   "
9239   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9241   [(set (attr "length")
9242      (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9243                    (const_int 8)
9244                    (const_int 4)))])
9246 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9247   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9248      (high:TLSmode
9249        (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9250                         (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9251                        UNSPEC_TLSGOTTPREL)))]
9252   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9253   "addis %0,%1,%2@got@tprel@ha"
9254   [(set_attr "length" "4")])
9256 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9257   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9258      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9259          (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9260                           (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9261                          UNSPEC_TLSGOTTPREL)))]
9262   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9263   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9264   [(set_attr "length" "4")])
9266 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9267   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9268         (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9269                          (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9270                         UNSPEC_TLSTLS))]
9271   "TARGET_ELF && HAVE_AS_TLS"
9272   "add %0,%1,%2@tls")
9274 (define_expand "tls_get_tpointer"
9275   [(set (match_operand:SI 0 "gpc_reg_operand" "")
9276         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9277   "TARGET_XCOFF && HAVE_AS_TLS"
9278   "
9280   emit_insn (gen_tls_get_tpointer_internal ());
9281   emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9282   DONE;
9285 (define_insn "tls_get_tpointer_internal"
9286   [(set (reg:SI 3)
9287         (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9288    (clobber (reg:SI LR_REGNO))]
9289   "TARGET_XCOFF && HAVE_AS_TLS"
9290   "bla __get_tpointer")
9292 (define_expand "tls_get_addr<mode>"
9293   [(set (match_operand:P 0 "gpc_reg_operand" "")
9294         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
9295                    (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
9296   "TARGET_XCOFF && HAVE_AS_TLS"
9297   "
9299   emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9300   emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9301   emit_insn (gen_tls_get_addr_internal<mode> ());
9302   emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9303   DONE;
9306 (define_insn "tls_get_addr_internal<mode>"
9307   [(set (reg:P 3)
9308         (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9309    (clobber (reg:P 0))
9310    (clobber (reg:P 4))
9311    (clobber (reg:P 5))
9312    (clobber (reg:P 11))
9313    (clobber (reg:CC CR0_REGNO))
9314    (clobber (reg:P LR_REGNO))]
9315   "TARGET_XCOFF && HAVE_AS_TLS"
9316   "bla __tls_get_addr")
9318 ;; Next come insns related to the calling sequence.
9320 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9321 ;; We move the back-chain and decrement the stack pointer.
9323 (define_expand "allocate_stack"
9324   [(set (match_operand 0 "gpc_reg_operand" "")
9325         (minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
9326    (set (reg 1)
9327         (minus (reg 1) (match_dup 1)))]
9328   ""
9329   "
9330 { rtx chain = gen_reg_rtx (Pmode);
9331   rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9332   rtx neg_op0;
9333   rtx insn, par, set, mem;
9335   emit_move_insn (chain, stack_bot);
9337   /* Check stack bounds if necessary.  */
9338   if (crtl->limit_stack)
9339     {
9340       rtx available;
9341       available = expand_binop (Pmode, sub_optab,
9342                                 stack_pointer_rtx, stack_limit_rtx,
9343                                 NULL_RTX, 1, OPTAB_WIDEN);
9344       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9345     }
9347   if (GET_CODE (operands[1]) != CONST_INT
9348       || INTVAL (operands[1]) < -32767
9349       || INTVAL (operands[1]) > 32768)
9350     {
9351       neg_op0 = gen_reg_rtx (Pmode);
9352       if (TARGET_32BIT)
9353         emit_insn (gen_negsi2 (neg_op0, operands[1]));
9354       else
9355         emit_insn (gen_negdi2 (neg_op0, operands[1]));
9356     }
9357   else
9358     neg_op0 = GEN_INT (- INTVAL (operands[1]));
9360   insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9361                                        : gen_movdi_di_update_stack))
9362                         (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9363                          chain));
9364   /* Since we didn't use gen_frame_mem to generate the MEM, grab
9365      it now and set the alias set/attributes. The above gen_*_update
9366      calls will generate a PARALLEL with the MEM set being the first
9367      operation. */
9368   par = PATTERN (insn);
9369   gcc_assert (GET_CODE (par) == PARALLEL);
9370   set = XVECEXP (par, 0, 0);
9371   gcc_assert (GET_CODE (set) == SET);
9372   mem = SET_DEST (set);
9373   gcc_assert (MEM_P (mem));
9374   MEM_NOTRAP_P (mem) = 1;
9375   set_mem_alias_set (mem, get_frame_alias_set ());
9377   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9378   DONE;
9381 ;; These patterns say how to save and restore the stack pointer.  We need not
9382 ;; save the stack pointer at function level since we are careful to
9383 ;; preserve the backchain.  At block level, we have to restore the backchain
9384 ;; when we restore the stack pointer.
9386 ;; For nonlocal gotos, we must save both the stack pointer and its
9387 ;; backchain and restore both.  Note that in the nonlocal case, the
9388 ;; save area is a memory location.
9390 (define_expand "save_stack_function"
9391   [(match_operand 0 "any_operand" "")
9392    (match_operand 1 "any_operand" "")]
9393   ""
9394   "DONE;")
9396 (define_expand "restore_stack_function"
9397   [(match_operand 0 "any_operand" "")
9398    (match_operand 1 "any_operand" "")]
9399   ""
9400   "DONE;")
9402 ;; Adjust stack pointer (op0) to a new value (op1).
9403 ;; First copy old stack backchain to new location, and ensure that the
9404 ;; scheduler won't reorder the sp assignment before the backchain write.
9405 (define_expand "restore_stack_block"
9406   [(set (match_dup 2) (match_dup 3))
9407    (set (match_dup 4) (match_dup 2))
9408    (match_dup 5)
9409    (set (match_operand 0 "register_operand" "")
9410         (match_operand 1 "register_operand" ""))]
9411   ""
9412   "
9414   rtvec p;
9416   operands[1] = force_reg (Pmode, operands[1]);
9417   operands[2] = gen_reg_rtx (Pmode);
9418   operands[3] = gen_frame_mem (Pmode, operands[0]);
9419   operands[4] = gen_frame_mem (Pmode, operands[1]);
9420   p = rtvec_alloc (1);
9421   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9422                                   const0_rtx);
9423   operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9426 (define_expand "save_stack_nonlocal"
9427   [(set (match_dup 3) (match_dup 4))
9428    (set (match_operand 0 "memory_operand" "") (match_dup 3))
9429    (set (match_dup 2) (match_operand 1 "register_operand" ""))]
9430   ""
9431   "
9433   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9435   /* Copy the backchain to the first word, sp to the second.  */
9436   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9437   operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9438   operands[3] = gen_reg_rtx (Pmode);
9439   operands[4] = gen_frame_mem (Pmode, operands[1]);
9442 (define_expand "restore_stack_nonlocal"
9443   [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
9444    (set (match_dup 3) (match_dup 4))
9445    (set (match_dup 5) (match_dup 2))
9446    (match_dup 6)
9447    (set (match_operand 0 "register_operand" "") (match_dup 3))]
9448   ""
9449   "
9451   int units_per_word = (TARGET_32BIT) ? 4 : 8;
9452   rtvec p;
9454   /* Restore the backchain from the first word, sp from the second.  */
9455   operands[2] = gen_reg_rtx (Pmode);
9456   operands[3] = gen_reg_rtx (Pmode);
9457   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9458   operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9459   operands[5] = gen_frame_mem (Pmode, operands[3]);
9460   p = rtvec_alloc (1);
9461   RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9462                                   const0_rtx);
9463   operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9466 ;; TOC register handling.
9468 ;; Code to initialize the TOC register...
9470 (define_insn "load_toc_aix_si"
9471   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9472                    (unspec:SI [(const_int 0)] UNSPEC_TOC))
9473               (use (reg:SI 2))])]
9474   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9475   "*
9477   char buf[30];
9478   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9479   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9480   operands[2] = gen_rtx_REG (Pmode, 2);
9481   return \"lwz %0,%1(%2)\";
9483   [(set_attr "type" "load")
9484    (set_attr "update" "no")
9485    (set_attr "indexed" "no")])
9487 (define_insn "load_toc_aix_di"
9488   [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9489                    (unspec:DI [(const_int 0)] UNSPEC_TOC))
9490               (use (reg:DI 2))])]
9491   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9492   "*
9494   char buf[30];
9495 #ifdef TARGET_RELOCATABLE
9496   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
9497                                !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
9498 #else
9499   ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
9500 #endif
9501   if (TARGET_ELF)
9502     strcat (buf, \"@toc\");
9503   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9504   operands[2] = gen_rtx_REG (Pmode, 2);
9505   return \"ld %0,%1(%2)\";
9507   [(set_attr "type" "load")
9508    (set_attr "update" "no")
9509    (set_attr "indexed" "no")])
9511 (define_insn "load_toc_v4_pic_si"
9512   [(set (reg:SI LR_REGNO)
9513         (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9514   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9515   "bl _GLOBAL_OFFSET_TABLE_@local-4"
9516   [(set_attr "type" "branch")
9517    (set_attr "length" "4")])
9519 (define_expand "load_toc_v4_PIC_1"
9520   [(parallel [(set (reg:SI LR_REGNO)
9521                    (match_operand:SI 0 "immediate_operand" "s"))
9522               (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9523   "TARGET_ELF && DEFAULT_ABI == ABI_V4
9524    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9525   "")
9527 (define_insn "load_toc_v4_PIC_1_normal"
9528   [(set (reg:SI LR_REGNO)
9529         (match_operand:SI 0 "immediate_operand" "s"))
9530    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9531   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9532    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9533   "bcl 20,31,%0\\n%0:"
9534   [(set_attr "type" "branch")
9535    (set_attr "length" "4")
9536    (set_attr "cannot_copy" "yes")])
9538 (define_insn "load_toc_v4_PIC_1_476"
9539   [(set (reg:SI LR_REGNO)
9540         (match_operand:SI 0 "immediate_operand" "s"))
9541    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9542   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9543    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9544   "*
9546   char name[32];
9547   static char templ[32];
9549   get_ppc476_thunk_name (name);
9550   sprintf (templ, \"bl %s\\n%%0:\", name);
9551   return templ;
9553   [(set_attr "type" "branch")
9554    (set_attr "length" "4")
9555    (set_attr "cannot_copy" "yes")])
9557 (define_expand "load_toc_v4_PIC_1b"
9558   [(parallel [(set (reg:SI LR_REGNO)
9559                    (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9560                                (label_ref (match_operand 1 "" ""))]
9561                            UNSPEC_TOCPTR))
9562               (match_dup 1)])]
9563   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9564   "")
9566 (define_insn "load_toc_v4_PIC_1b_normal"
9567   [(set (reg:SI LR_REGNO)
9568         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9569                     (label_ref (match_operand 1 "" ""))]
9570                 UNSPEC_TOCPTR))
9571    (match_dup 1)]
9572   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9573   "bcl 20,31,$+8\;.long %0-$"
9574   [(set_attr "type" "branch")
9575    (set_attr "length" "8")])
9577 (define_insn "load_toc_v4_PIC_1b_476"
9578   [(set (reg:SI LR_REGNO)
9579         (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9580                     (label_ref (match_operand 1 "" ""))]
9581                 UNSPEC_TOCPTR))
9582    (match_dup 1)]
9583   "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9584   "*
9586   char name[32];
9587   static char templ[32];
9589   get_ppc476_thunk_name (name);
9590   sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
9591   return templ;
9593   [(set_attr "type" "branch")
9594    (set_attr "length" "16")])
9596 (define_insn "load_toc_v4_PIC_2"
9597   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9598         (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9599                    (minus:SI (match_operand:SI 2 "immediate_operand" "s")
9600                              (match_operand:SI 3 "immediate_operand" "s")))))]
9601   "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9602   "lwz %0,%2-%3(%1)"
9603   [(set_attr "type" "load")])
9605 (define_insn "load_toc_v4_PIC_3b"
9606   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9607         (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9608                  (high:SI
9609                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9610                              (match_operand:SI 3 "symbol_ref_operand" "s")))))]
9611   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9612   "addis %0,%1,%2-%3@ha")
9614 (define_insn "load_toc_v4_PIC_3c"
9615   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9616         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9617                    (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
9618                              (match_operand:SI 3 "symbol_ref_operand" "s"))))]
9619   "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
9620   "addi %0,%1,%2-%3@l")
9622 ;; If the TOC is shared over a translation unit, as happens with all
9623 ;; the kinds of PIC that we support, we need to restore the TOC
9624 ;; pointer only when jumping over units of translation.
9625 ;; On Darwin, we need to reload the picbase.
9627 (define_expand "builtin_setjmp_receiver"
9628   [(use (label_ref (match_operand 0 "" "")))]
9629   "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9630    || (TARGET_TOC && TARGET_MINIMAL_TOC)
9631    || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
9632   "
9634 #if TARGET_MACHO
9635   if (DEFAULT_ABI == ABI_DARWIN)
9636     {
9637       rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
9638       rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
9639       rtx tmplabrtx;
9640       char tmplab[20];
9642       crtl->uses_pic_offset_table = 1;
9643       ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
9644                                   CODE_LABEL_NUMBER (operands[0]));
9645       tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
9647       emit_insn (gen_load_macho_picbase (tmplabrtx));
9648       emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
9649       emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
9650     }
9651   else
9652 #endif
9653     rs6000_emit_load_toc_table (FALSE);
9654   DONE;
9657 ;; Largetoc support
9658 (define_insn "*largetoc_high"
9659   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9660         (high:DI
9661           (unspec [(match_operand:DI 1 "" "")
9662                    (match_operand:DI 2 "gpc_reg_operand" "b")]
9663                   UNSPEC_TOCREL)))]
9664    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9665    "addis %0,%2,%1@toc@ha")
9667 (define_insn "*largetoc_high_aix<mode>"
9668   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9669         (high:P
9670           (unspec [(match_operand:P 1 "" "")
9671                    (match_operand:P 2 "gpc_reg_operand" "b")]
9672                   UNSPEC_TOCREL)))]
9673    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9674    "addis %0,%1@u(%2)")
9676 (define_insn "*largetoc_high_plus"
9677   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
9678         (high:DI
9679           (plus:DI
9680             (unspec [(match_operand:DI 1 "" "")
9681                      (match_operand:DI 2 "gpc_reg_operand" "b")]
9682                     UNSPEC_TOCREL)
9683             (match_operand:DI 3 "add_cint_operand" "n"))))]
9684    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9685    "addis %0,%2,%1+%3@toc@ha")
9687 (define_insn "*largetoc_high_plus_aix<mode>"
9688   [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
9689         (high:P
9690           (plus:P
9691             (unspec [(match_operand:P 1 "" "")
9692                      (match_operand:P 2 "gpc_reg_operand" "b")]
9693                     UNSPEC_TOCREL)
9694             (match_operand:P 3 "add_cint_operand" "n"))))]
9695    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9696    "addis %0,%1+%3@u(%2)")
9698 (define_insn "*largetoc_low"
9699   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9700         (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
9701                    (match_operand:DI 2 "" "")))]
9702    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9703    "addi %0,%1,%2@l")
9705 (define_insn "*largetoc_low_aix<mode>"
9706   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9707         (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9708                    (match_operand:P 2 "" "")))]
9709    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
9710    "la %0,%2@l(%1)")
9712 (define_insn_and_split "*tocref<mode>"
9713   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9714         (match_operand:P 1 "small_toc_ref" "R"))]
9715    "TARGET_TOC"
9716    "la %0,%a1"
9717    "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
9718   [(set (match_dup 0) (high:P (match_dup 1)))
9719    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
9721 ;; Elf specific ways of loading addresses for non-PIC code.
9722 ;; The output of this could be r0, but we make a very strong
9723 ;; preference for a base register because it will usually
9724 ;; be needed there.
9725 (define_insn "elf_high"
9726   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
9727         (high:SI (match_operand 1 "" "")))]
9728   "TARGET_ELF && ! TARGET_64BIT"
9729   "lis %0,%1@ha")
9731 (define_insn "elf_low"
9732   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9733         (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
9734                    (match_operand 2 "" "")))]
9735    "TARGET_ELF && ! TARGET_64BIT"
9736    "la %0,%2@l(%1)")
9738 ;; Call and call_value insns
9739 (define_expand "call"
9740   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
9741                     (match_operand 1 "" ""))
9742               (use (match_operand 2 "" ""))
9743               (clobber (reg:SI LR_REGNO))])]
9744   ""
9745   "
9747 #if TARGET_MACHO
9748   if (MACHOPIC_INDIRECT)
9749     operands[0] = machopic_indirect_call_target (operands[0]);
9750 #endif
9752   gcc_assert (GET_CODE (operands[0]) == MEM);
9753   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
9755   operands[0] = XEXP (operands[0], 0);
9757   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9758     {
9759       rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
9760       DONE;
9761     }
9763   if (GET_CODE (operands[0]) != SYMBOL_REF
9764       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
9765     {
9766       if (INTVAL (operands[2]) & CALL_LONG)
9767         operands[0] = rs6000_longcall_ref (operands[0]);
9769       switch (DEFAULT_ABI)
9770         {
9771         case ABI_V4:
9772         case ABI_DARWIN:
9773           operands[0] = force_reg (Pmode, operands[0]);
9774           break;
9776         default:
9777           gcc_unreachable ();
9778         }
9779     }
9782 (define_expand "call_value"
9783   [(parallel [(set (match_operand 0 "" "")
9784                    (call (mem:SI (match_operand 1 "address_operand" ""))
9785                          (match_operand 2 "" "")))
9786               (use (match_operand 3 "" ""))
9787               (clobber (reg:SI LR_REGNO))])]
9788   ""
9789   "
9791 #if TARGET_MACHO
9792   if (MACHOPIC_INDIRECT)
9793     operands[1] = machopic_indirect_call_target (operands[1]);
9794 #endif
9796   gcc_assert (GET_CODE (operands[1]) == MEM);
9797   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
9799   operands[1] = XEXP (operands[1], 0);
9801   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
9802     {
9803       rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
9804       DONE;
9805     }
9807   if (GET_CODE (operands[1]) != SYMBOL_REF
9808       || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
9809     {
9810       if (INTVAL (operands[3]) & CALL_LONG)
9811         operands[1] = rs6000_longcall_ref (operands[1]);
9813       switch (DEFAULT_ABI)
9814         {
9815         case ABI_V4:
9816         case ABI_DARWIN:
9817           operands[1] = force_reg (Pmode, operands[1]);
9818           break;
9820         default:
9821           gcc_unreachable ();
9822         }
9823     }
9826 ;; Call to function in current module.  No TOC pointer reload needed.
9827 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
9828 ;; either the function was not prototyped, or it was prototyped as a
9829 ;; variable argument function.  It is > 0 if FP registers were passed
9830 ;; and < 0 if they were not.
9832 (define_insn "*call_local32"
9833   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
9834          (match_operand 1 "" "g,g"))
9835    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9836    (clobber (reg:SI LR_REGNO))]
9837   "(INTVAL (operands[2]) & CALL_LONG) == 0"
9838   "*
9840   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9841     output_asm_insn (\"crxor 6,6,6\", operands);
9843   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9844     output_asm_insn (\"creqv 6,6,6\", operands);
9846   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9848   [(set_attr "type" "branch")
9849    (set_attr "length" "4,8")])
9851 (define_insn "*call_local64"
9852   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
9853          (match_operand 1 "" "g,g"))
9854    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9855    (clobber (reg:SI LR_REGNO))]
9856   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
9857   "*
9859   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9860     output_asm_insn (\"crxor 6,6,6\", operands);
9862   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9863     output_asm_insn (\"creqv 6,6,6\", operands);
9865   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
9867   [(set_attr "type" "branch")
9868    (set_attr "length" "4,8")])
9870 (define_insn "*call_value_local32"
9871   [(set (match_operand 0 "" "")
9872         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
9873               (match_operand 2 "" "g,g")))
9874    (use (match_operand:SI 3 "immediate_operand" "O,n"))
9875    (clobber (reg:SI LR_REGNO))]
9876   "(INTVAL (operands[3]) & CALL_LONG) == 0"
9877   "*
9879   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9880     output_asm_insn (\"crxor 6,6,6\", operands);
9882   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9883     output_asm_insn (\"creqv 6,6,6\", operands);
9885   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9887   [(set_attr "type" "branch")
9888    (set_attr "length" "4,8")])
9891 (define_insn "*call_value_local64"
9892   [(set (match_operand 0 "" "")
9893         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
9894               (match_operand 2 "" "g,g")))
9895    (use (match_operand:SI 3 "immediate_operand" "O,n"))
9896    (clobber (reg:SI LR_REGNO))]
9897   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
9898   "*
9900   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
9901     output_asm_insn (\"crxor 6,6,6\", operands);
9903   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
9904     output_asm_insn (\"creqv 6,6,6\", operands);
9906   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
9908   [(set_attr "type" "branch")
9909    (set_attr "length" "4,8")])
9912 ;; A function pointer under System V is just a normal pointer
9913 ;; operands[0] is the function pointer
9914 ;; operands[1] is the stack size to clean up
9915 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
9916 ;; which indicates how to set cr1
9918 (define_insn "*call_indirect_nonlocal_sysv<mode>"
9919   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
9920          (match_operand 1 "" "g,g,g,g"))
9921    (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
9922    (clobber (reg:SI LR_REGNO))]
9923   "DEFAULT_ABI == ABI_V4
9924    || DEFAULT_ABI == ABI_DARWIN"
9926   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9927     output_asm_insn ("crxor 6,6,6", operands);
9929   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9930     output_asm_insn ("creqv 6,6,6", operands);
9932   return "b%T0l";
9934   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
9935    (set_attr "length" "4,4,8,8")])
9937 (define_insn_and_split "*call_nonlocal_sysv<mode>"
9938   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9939          (match_operand 1 "" "g,g"))
9940    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9941    (clobber (reg:SI LR_REGNO))]
9942   "(DEFAULT_ABI == ABI_DARWIN
9943    || (DEFAULT_ABI == ABI_V4
9944        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
9946   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9947     output_asm_insn ("crxor 6,6,6", operands);
9949   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9950     output_asm_insn ("creqv 6,6,6", operands);
9952 #if TARGET_MACHO
9953   return output_call(insn, operands, 0, 2);
9954 #else
9955   if (DEFAULT_ABI == ABI_V4 && flag_pic)
9956     {
9957       gcc_assert (!TARGET_SECURE_PLT);
9958       return "bl %z0@plt";
9959     }
9960   else
9961     return "bl %z0";
9962 #endif
9964   "DEFAULT_ABI == ABI_V4
9965    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9966    && (INTVAL (operands[2]) & CALL_LONG) == 0"
9967   [(parallel [(call (mem:SI (match_dup 0))
9968                     (match_dup 1))
9969               (use (match_dup 2))
9970               (use (match_dup 3))
9971               (clobber (reg:SI LR_REGNO))])]
9973   operands[3] = pic_offset_table_rtx;
9975   [(set_attr "type" "branch,branch")
9976    (set_attr "length" "4,8")])
9978 (define_insn "*call_nonlocal_sysv_secure<mode>"
9979   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
9980          (match_operand 1 "" "g,g"))
9981    (use (match_operand:SI 2 "immediate_operand" "O,n"))
9982    (use (match_operand:SI 3 "register_operand" "r,r"))
9983    (clobber (reg:SI LR_REGNO))]
9984   "(DEFAULT_ABI == ABI_V4
9985     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
9986     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
9988   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
9989     output_asm_insn ("crxor 6,6,6", operands);
9991   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
9992     output_asm_insn ("creqv 6,6,6", operands);
9994   if (flag_pic == 2)
9995     /* The magic 32768 offset here and in the other sysv call insns
9996        corresponds to the offset of r30 in .got2, as given by LCTOC1.
9997        See sysv4.h:toc_section.  */
9998     return "bl %z0+32768@plt";
9999   else
10000     return "bl %z0@plt";
10002   [(set_attr "type" "branch,branch")
10003    (set_attr "length" "4,8")])
10005 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10006   [(set (match_operand 0 "" "")
10007         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10008               (match_operand 2 "" "g,g,g,g")))
10009    (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10010    (clobber (reg:SI LR_REGNO))]
10011   "DEFAULT_ABI == ABI_V4
10012    || DEFAULT_ABI == ABI_DARWIN"
10014   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10015     output_asm_insn ("crxor 6,6,6", operands);
10017   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10018     output_asm_insn ("creqv 6,6,6", operands);
10020   return "b%T1l";
10022   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10023    (set_attr "length" "4,4,8,8")])
10025 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10026   [(set (match_operand 0 "" "")
10027         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10028               (match_operand 2 "" "g,g")))
10029    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10030    (clobber (reg:SI LR_REGNO))]
10031   "(DEFAULT_ABI == ABI_DARWIN
10032    || (DEFAULT_ABI == ABI_V4
10033        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10035   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10036     output_asm_insn ("crxor 6,6,6", operands);
10038   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10039     output_asm_insn ("creqv 6,6,6", operands);
10041 #if TARGET_MACHO
10042   return output_call(insn, operands, 1, 3);
10043 #else
10044   if (DEFAULT_ABI == ABI_V4 && flag_pic)
10045     {
10046       gcc_assert (!TARGET_SECURE_PLT);
10047       return "bl %z1@plt";
10048     }
10049   else
10050     return "bl %z1";
10051 #endif
10053   "DEFAULT_ABI == ABI_V4
10054    && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10055    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10056   [(parallel [(set (match_dup 0)
10057                    (call (mem:SI (match_dup 1))
10058                          (match_dup 2)))
10059               (use (match_dup 3))
10060               (use (match_dup 4))
10061               (clobber (reg:SI LR_REGNO))])]
10063   operands[4] = pic_offset_table_rtx;
10065   [(set_attr "type" "branch,branch")
10066    (set_attr "length" "4,8")])
10068 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10069   [(set (match_operand 0 "" "")
10070         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10071               (match_operand 2 "" "g,g")))
10072    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10073    (use (match_operand:SI 4 "register_operand" "r,r"))
10074    (clobber (reg:SI LR_REGNO))]
10075   "(DEFAULT_ABI == ABI_V4
10076     && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10077     && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10079   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10080     output_asm_insn ("crxor 6,6,6", operands);
10082   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10083     output_asm_insn ("creqv 6,6,6", operands);
10085   if (flag_pic == 2)
10086     return "bl %z1+32768@plt";
10087   else
10088     return "bl %z1@plt";
10090   [(set_attr "type" "branch,branch")
10091    (set_attr "length" "4,8")])
10094 ;; Call to AIX abi function in the same module.
10096 (define_insn "*call_local_aix<mode>"
10097   [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10098          (match_operand 1 "" "g"))
10099    (clobber (reg:P LR_REGNO))]
10100   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10101   "bl %z0"
10102   [(set_attr "type" "branch")
10103    (set_attr "length" "4")])
10105 (define_insn "*call_value_local_aix<mode>"
10106   [(set (match_operand 0 "" "")
10107         (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10108               (match_operand 2 "" "g")))
10109    (clobber (reg:P LR_REGNO))]
10110   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10111   "bl %z1"
10112   [(set_attr "type" "branch")
10113    (set_attr "length" "4")])
10115 ;; Call to AIX abi function which may be in another module.
10116 ;; Restore the TOC pointer (r2) after the call.
10118 (define_insn "*call_nonlocal_aix<mode>"
10119   [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10120          (match_operand 1 "" "g"))
10121    (clobber (reg:P LR_REGNO))]
10122   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10123   "bl %z0\;nop"
10124   [(set_attr "type" "branch")
10125    (set_attr "length" "8")])
10127 (define_insn "*call_value_nonlocal_aix<mode>"
10128   [(set (match_operand 0 "" "")
10129         (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10130               (match_operand 2 "" "g")))
10131    (clobber (reg:P LR_REGNO))]
10132   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10133   "bl %z1\;nop"
10134   [(set_attr "type" "branch")
10135    (set_attr "length" "8")])
10137 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10138 ;; Operand0 is the addresss of the function to call
10139 ;; Operand2 is the location in the function descriptor to load r2 from
10140 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10142 (define_insn "*call_indirect_aix<mode>"
10143   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10144          (match_operand 1 "" "g,g"))
10145    (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10146    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10147    (clobber (reg:P LR_REGNO))]
10148   "DEFAULT_ABI == ABI_AIX"
10149   "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10150   [(set_attr "type" "jmpreg")
10151    (set_attr "length" "12")])
10153 (define_insn "*call_value_indirect_aix<mode>"
10154   [(set (match_operand 0 "" "")
10155         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10156               (match_operand 2 "" "g,g")))
10157    (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10158    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10159    (clobber (reg:P LR_REGNO))]
10160   "DEFAULT_ABI == ABI_AIX"
10161   "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10162   [(set_attr "type" "jmpreg")
10163    (set_attr "length" "12")])
10165 ;; Call to indirect functions with the ELFv2 ABI.
10166 ;; Operand0 is the addresss of the function to call
10167 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10169 (define_insn "*call_indirect_elfv2<mode>"
10170   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10171          (match_operand 1 "" "g,g"))
10172    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10173    (clobber (reg:P LR_REGNO))]
10174   "DEFAULT_ABI == ABI_ELFv2"
10175   "b%T0l\;<ptrload> 2,%2(1)"
10176   [(set_attr "type" "jmpreg")
10177    (set_attr "length" "8")])
10179 (define_insn "*call_value_indirect_elfv2<mode>"
10180   [(set (match_operand 0 "" "")
10181         (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10182               (match_operand 2 "" "g,g")))
10183    (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10184    (clobber (reg:P LR_REGNO))]
10185   "DEFAULT_ABI == ABI_ELFv2"
10186   "b%T1l\;<ptrload> 2,%3(1)"
10187   [(set_attr "type" "jmpreg")
10188    (set_attr "length" "8")])
10191 ;; Call subroutine returning any type.
10192 (define_expand "untyped_call"
10193   [(parallel [(call (match_operand 0 "" "")
10194                     (const_int 0))
10195               (match_operand 1 "" "")
10196               (match_operand 2 "" "")])]
10197   ""
10198   "
10200   int i;
10202   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10204   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10205     {
10206       rtx set = XVECEXP (operands[2], 0, i);
10207       emit_move_insn (SET_DEST (set), SET_SRC (set));
10208     }
10210   /* The optimizer does not know that the call sets the function value
10211      registers we stored in the result block.  We avoid problems by
10212      claiming that all hard registers are used and clobbered at this
10213      point.  */
10214   emit_insn (gen_blockage ());
10216   DONE;
10219 ;; sibling call patterns
10220 (define_expand "sibcall"
10221   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10222                     (match_operand 1 "" ""))
10223               (use (match_operand 2 "" ""))
10224               (use (reg:SI LR_REGNO))
10225               (simple_return)])]
10226   ""
10227   "
10229 #if TARGET_MACHO
10230   if (MACHOPIC_INDIRECT)
10231     operands[0] = machopic_indirect_call_target (operands[0]);
10232 #endif
10234   gcc_assert (GET_CODE (operands[0]) == MEM);
10235   gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10237   operands[0] = XEXP (operands[0], 0);
10239   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10240     {
10241       rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10242       DONE;
10243     }
10246 (define_expand "sibcall_value"
10247   [(parallel [(set (match_operand 0 "register_operand" "")
10248                 (call (mem:SI (match_operand 1 "address_operand" ""))
10249                       (match_operand 2 "" "")))
10250               (use (match_operand 3 "" ""))
10251               (use (reg:SI LR_REGNO))
10252               (simple_return)])]
10253   ""
10254   "
10256 #if TARGET_MACHO
10257   if (MACHOPIC_INDIRECT)
10258     operands[1] = machopic_indirect_call_target (operands[1]);
10259 #endif
10261   gcc_assert (GET_CODE (operands[1]) == MEM);
10262   gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10264   operands[1] = XEXP (operands[1], 0);
10266   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10267     {
10268       rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10269       DONE;
10270     }
10273 ;; this and similar patterns must be marked as using LR, otherwise
10274 ;; dataflow will try to delete the store into it.  This is true
10275 ;; even when the actual reg to jump to is in CTR, when LR was
10276 ;; saved and restored around the PIC-setting BCL.
10277 (define_insn "*sibcall_local32"
10278   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10279          (match_operand 1 "" "g,g"))
10280    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10281    (use (reg:SI LR_REGNO))
10282    (simple_return)]
10283   "(INTVAL (operands[2]) & CALL_LONG) == 0"
10284   "*
10286   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10287     output_asm_insn (\"crxor 6,6,6\", operands);
10289   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10290     output_asm_insn (\"creqv 6,6,6\", operands);
10292   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10294   [(set_attr "type" "branch")
10295    (set_attr "length" "4,8")])
10297 (define_insn "*sibcall_local64"
10298   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10299          (match_operand 1 "" "g,g"))
10300    (use (match_operand:SI 2 "immediate_operand" "O,n"))
10301    (use (reg:SI LR_REGNO))
10302    (simple_return)]
10303   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10304   "*
10306   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10307     output_asm_insn (\"crxor 6,6,6\", operands);
10309   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10310     output_asm_insn (\"creqv 6,6,6\", operands);
10312   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10314   [(set_attr "type" "branch")
10315    (set_attr "length" "4,8")])
10317 (define_insn "*sibcall_value_local32"
10318   [(set (match_operand 0 "" "")
10319         (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10320               (match_operand 2 "" "g,g")))
10321    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10322    (use (reg:SI LR_REGNO))
10323    (simple_return)]
10324   "(INTVAL (operands[3]) & CALL_LONG) == 0"
10325   "*
10327   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10328     output_asm_insn (\"crxor 6,6,6\", operands);
10330   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10331     output_asm_insn (\"creqv 6,6,6\", operands);
10333   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10335   [(set_attr "type" "branch")
10336    (set_attr "length" "4,8")])
10338 (define_insn "*sibcall_value_local64"
10339   [(set (match_operand 0 "" "")
10340         (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10341               (match_operand 2 "" "g,g")))
10342    (use (match_operand:SI 3 "immediate_operand" "O,n"))
10343    (use (reg:SI LR_REGNO))
10344    (simple_return)]
10345   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10346   "*
10348   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10349     output_asm_insn (\"crxor 6,6,6\", operands);
10351   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10352     output_asm_insn (\"creqv 6,6,6\", operands);
10354   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10356   [(set_attr "type" "branch")
10357    (set_attr "length" "4,8")])
10359 (define_insn "*sibcall_nonlocal_sysv<mode>"
10360   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10361          (match_operand 1 "" ""))
10362    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10363    (use (reg:SI LR_REGNO))
10364    (simple_return)]
10365   "(DEFAULT_ABI == ABI_DARWIN
10366     || DEFAULT_ABI == ABI_V4)
10367    && (INTVAL (operands[2]) & CALL_LONG) == 0"
10368   "*
10370   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10371     output_asm_insn (\"crxor 6,6,6\", operands);
10373   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10374     output_asm_insn (\"creqv 6,6,6\", operands);
10376   if (which_alternative >= 2)
10377     return \"b%T0\";
10378   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10379     {
10380       gcc_assert (!TARGET_SECURE_PLT);
10381       return \"b %z0@plt\";
10382     }
10383   else
10384     return \"b %z0\";
10386   [(set_attr "type" "branch")
10387    (set_attr "length" "4,8,4,8")])
10389 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10390   [(set (match_operand 0 "" "")
10391         (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10392               (match_operand 2 "" "")))
10393    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10394    (use (reg:SI LR_REGNO))
10395    (simple_return)]
10396   "(DEFAULT_ABI == ABI_DARWIN
10397     || DEFAULT_ABI == ABI_V4)
10398    && (INTVAL (operands[3]) & CALL_LONG) == 0"
10399   "*
10401   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10402     output_asm_insn (\"crxor 6,6,6\", operands);
10404   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10405     output_asm_insn (\"creqv 6,6,6\", operands);
10407   if (which_alternative >= 2)
10408     return \"b%T1\";
10409   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10410     {
10411       gcc_assert (!TARGET_SECURE_PLT);
10412       return \"b %z1@plt\";
10413     }
10414   else
10415     return \"b %z1\";
10417   [(set_attr "type" "branch")
10418    (set_attr "length" "4,8,4,8")])
10420 ;; AIX ABI sibling call patterns.
10422 (define_insn "*sibcall_aix<mode>"
10423   [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10424          (match_operand 1 "" "g,g"))
10425    (simple_return)]
10426   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10427   "@
10428    b %z0
10429    b%T0"
10430   [(set_attr "type" "branch")
10431    (set_attr "length" "4")])
10433 (define_insn "*sibcall_value_aix<mode>"
10434   [(set (match_operand 0 "" "")
10435         (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10436               (match_operand 2 "" "g,g")))
10437    (simple_return)]
10438   "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10439   "@
10440    b %z1
10441    b%T1"
10442   [(set_attr "type" "branch")
10443    (set_attr "length" "4")])
10445 (define_expand "sibcall_epilogue"
10446   [(use (const_int 0))]
10447   ""
10449   if (!TARGET_SCHED_PROLOG)
10450     emit_insn (gen_blockage ());
10451   rs6000_emit_epilogue (TRUE);
10452   DONE;
10455 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10456 ;; all of memory.  This blocks insns from being moved across this point.
10458 (define_insn "blockage"
10459   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
10460   ""
10461   "")
10463 (define_expand "probe_stack_address"
10464   [(use (match_operand 0 "address_operand"))]
10465   ""
10467   operands[0] = gen_rtx_MEM (Pmode, operands[0]);
10468   MEM_VOLATILE_P (operands[0]) = 1;
10470   if (TARGET_64BIT)
10471     emit_insn (gen_probe_stack_di (operands[0]));
10472   else
10473     emit_insn (gen_probe_stack_si (operands[0]));
10474   DONE;
10477 (define_insn "probe_stack_<mode>"
10478   [(set (match_operand:P 0 "memory_operand" "=m")
10479         (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
10480   ""
10482   operands[1] = gen_rtx_REG (Pmode, 0);
10483   return "st<wd>%U0%X0 %1,%0";
10485   [(set_attr "type" "store")
10486    (set (attr "update")
10487         (if_then_else (match_operand 0 "update_address_mem")
10488                       (const_string "yes")
10489                       (const_string "no")))
10490    (set (attr "indexed")
10491         (if_then_else (match_operand 0 "indexed_address_mem")
10492                       (const_string "yes")
10493                       (const_string "no")))
10494    (set_attr "length" "4")])
10496 (define_insn "probe_stack_range<P:mode>"
10497   [(set (match_operand:P 0 "register_operand" "=r")
10498         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
10499                             (match_operand:P 2 "register_operand" "r")]
10500                            UNSPECV_PROBE_STACK_RANGE))]
10501   ""
10502   "* return output_probe_stack_range (operands[0], operands[2]);"
10503   [(set_attr "type" "three")])
10505 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
10506 ;; signed & unsigned, and one type of branch.
10508 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
10509 ;; insns, and branches.
10511 (define_expand "cbranch<mode>4"
10512   [(use (match_operator 0 "rs6000_cbranch_operator"
10513          [(match_operand:GPR 1 "gpc_reg_operand" "")
10514           (match_operand:GPR 2 "reg_or_short_operand" "")]))
10515    (use (match_operand 3 ""))]
10516   ""
10517   "
10519   /* Take care of the possibility that operands[2] might be negative but
10520      this might be a logical operation.  That insn doesn't exist.  */
10521   if (GET_CODE (operands[2]) == CONST_INT
10522       && INTVAL (operands[2]) < 0)
10523     {
10524       operands[2] = force_reg (<MODE>mode, operands[2]);
10525       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
10526                                     GET_MODE (operands[0]),
10527                                     operands[1], operands[2]);
10528    }
10530   rs6000_emit_cbranch (<MODE>mode, operands);
10531   DONE;
10534 (define_expand "cbranch<mode>4"
10535   [(use (match_operator 0 "rs6000_cbranch_operator"
10536          [(match_operand:FP 1 "gpc_reg_operand" "")
10537           (match_operand:FP 2 "gpc_reg_operand" "")]))
10538    (use (match_operand 3 ""))]
10539   ""
10540   "
10542   rs6000_emit_cbranch (<MODE>mode, operands);
10543   DONE;
10546 (define_expand "cstore<mode>4_signed"
10547   [(use (match_operator 1 "signed_comparison_operator"
10548          [(match_operand:P 2 "gpc_reg_operand")
10549           (match_operand:P 3 "gpc_reg_operand")]))
10550    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10551   ""
10553   enum rtx_code cond_code = GET_CODE (operands[1]);
10555   rtx op0 = operands[0];
10556   rtx op1 = operands[2];
10557   rtx op2 = operands[3];
10559   if (cond_code == GE || cond_code == LT)
10560     {
10561       cond_code = swap_condition (cond_code);
10562       std::swap (op1, op2);
10563     }
10565   rtx tmp1 = gen_reg_rtx (<MODE>mode);
10566   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10567   rtx tmp3 = gen_reg_rtx (<MODE>mode);
10569   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10570   emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
10571   emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
10573   emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
10575   if (cond_code == LE)
10576     emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
10577   else
10578     {
10579       rtx tmp4 = gen_reg_rtx (<MODE>mode);
10580       emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
10581       emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
10582     }
10584   DONE;
10587 (define_expand "cstore<mode>4_unsigned"
10588   [(use (match_operator 1 "unsigned_comparison_operator"
10589          [(match_operand:P 2 "gpc_reg_operand")
10590           (match_operand:P 3 "reg_or_short_operand")]))
10591    (clobber (match_operand:P 0 "gpc_reg_operand"))]
10592   ""
10594   enum rtx_code cond_code = GET_CODE (operands[1]);
10596   rtx op0 = operands[0];
10597   rtx op1 = operands[2];
10598   rtx op2 = operands[3];
10600   if (cond_code == GEU || cond_code == LTU)
10601     {
10602       cond_code = swap_condition (cond_code);
10603       std::swap (op1, op2);
10604     }
10606   if (!gpc_reg_operand (op1, <MODE>mode))
10607     op1 = force_reg (<MODE>mode, op1);
10608   if (!reg_or_short_operand (op2, <MODE>mode))
10609     op2 = force_reg (<MODE>mode, op2);
10611   rtx tmp = gen_reg_rtx (<MODE>mode);
10612   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10614   emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
10615   emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
10617   if (cond_code == LEU)
10618     emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
10619   else
10620     emit_insn (gen_neg<mode>2 (op0, tmp2));
10622   DONE;
10625 (define_expand "cstore_si_as_di"
10626   [(use (match_operator 1 "unsigned_comparison_operator"
10627          [(match_operand:SI 2 "gpc_reg_operand")
10628           (match_operand:SI 3 "reg_or_short_operand")]))
10629    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10630   ""
10632   int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
10633   enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
10635   operands[2] = force_reg (SImode, operands[2]);
10636   operands[3] = force_reg (SImode, operands[3]);
10637   rtx op1 = gen_reg_rtx (DImode);
10638   rtx op2 = gen_reg_rtx (DImode);
10639   convert_move (op1, operands[2], uns_flag);
10640   convert_move (op2, operands[3], uns_flag);
10642   if (cond_code == GT || cond_code == LE)
10643     {
10644       cond_code = swap_condition (cond_code);
10645       std::swap (op1, op2);
10646     }
10648   rtx tmp = gen_reg_rtx (DImode);
10649   rtx tmp2 = gen_reg_rtx (DImode);
10650   emit_insn (gen_subdi3 (tmp, op1, op2));
10651   emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
10653   rtx tmp3;
10654   switch (cond_code)
10655     {
10656     default:
10657       gcc_unreachable ();
10658     case LT:
10659       tmp3 = tmp2;
10660       break;
10661     case GE:
10662       tmp3 = gen_reg_rtx (DImode);
10663       emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
10664       break;
10665     }
10667   convert_move (operands[0], tmp3, 1);
10669   DONE;
10672 (define_expand "cstore<mode>4_signed_imm"
10673   [(use (match_operator 1 "signed_comparison_operator"
10674          [(match_operand:GPR 2 "gpc_reg_operand")
10675           (match_operand:GPR 3 "immediate_operand")]))
10676    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10677   ""
10679   bool invert = false;
10681   enum rtx_code cond_code = GET_CODE (operands[1]);
10683   rtx op0 = operands[0];
10684   rtx op1 = operands[2];
10685   HOST_WIDE_INT val = INTVAL (operands[3]);
10687   if (cond_code == GE || cond_code == GT)
10688     {
10689       cond_code = reverse_condition (cond_code);
10690       invert = true;
10691     }
10693   if (cond_code == LE)
10694     val++;
10696   rtx tmp = gen_reg_rtx (<MODE>mode);
10697   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10698   rtx x = gen_reg_rtx (<MODE>mode);
10699   if (val < 0)
10700     emit_insn (gen_and<mode>3 (x, op1, tmp));
10701   else
10702     emit_insn (gen_ior<mode>3 (x, op1, tmp));
10704   if (invert)
10705     {
10706       rtx tmp = gen_reg_rtx (<MODE>mode);
10707       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10708       x = tmp;
10709     }
10711   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10712   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10714   DONE;
10717 (define_expand "cstore<mode>4_unsigned_imm"
10718   [(use (match_operator 1 "unsigned_comparison_operator"
10719          [(match_operand:GPR 2 "gpc_reg_operand")
10720           (match_operand:GPR 3 "immediate_operand")]))
10721    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10722   ""
10724   bool invert = false;
10726   enum rtx_code cond_code = GET_CODE (operands[1]);
10728   rtx op0 = operands[0];
10729   rtx op1 = operands[2];
10730   HOST_WIDE_INT val = INTVAL (operands[3]);
10732   if (cond_code == GEU || cond_code == GTU)
10733     {
10734       cond_code = reverse_condition (cond_code);
10735       invert = true;
10736     }
10738   if (cond_code == LEU)
10739     val++;
10741   rtx tmp = gen_reg_rtx (<MODE>mode);
10742   rtx tmp2 = gen_reg_rtx (<MODE>mode);
10743   emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
10744   emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
10745   rtx x = gen_reg_rtx (<MODE>mode);
10746   if (val < 0)
10747     emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
10748   else
10749     emit_insn (gen_and<mode>3 (x, tmp, tmp2));
10751   if (invert)
10752     {
10753       rtx tmp = gen_reg_rtx (<MODE>mode);
10754       emit_insn (gen_one_cmpl<mode>2 (tmp, x));
10755       x = tmp;
10756     }
10758   int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
10759   emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
10761   DONE;
10764 (define_expand "cstore<mode>4"
10765   [(use (match_operator 1 "rs6000_cbranch_operator"
10766          [(match_operand:GPR 2 "gpc_reg_operand")
10767           (match_operand:GPR 3 "reg_or_short_operand")]))
10768    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
10769   ""
10771   /* Use ISEL if the user asked for it.  */
10772   if (TARGET_ISEL)
10773     rs6000_emit_sISEL (<MODE>mode, operands);
10775   /* Expanding EQ and NE directly to some machine instructions does not help
10776      but does hurt combine.  So don't.  */
10777   else if (GET_CODE (operands[1]) == EQ)
10778     emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
10779   else if (<MODE>mode == Pmode
10780            && GET_CODE (operands[1]) == NE)
10781     emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
10782   else if (GET_CODE (operands[1]) == NE)
10783     {
10784       rtx tmp = gen_reg_rtx (<MODE>mode);
10785       emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
10786       emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
10787     }
10789   /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu
10790      etc. combinations magically work out just right.  */
10791   else if (<MODE>mode == Pmode
10792            && unsigned_comparison_operator (operands[1], VOIDmode))
10793     emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
10794                                            operands[2], operands[3]));
10796   /* For comparisons smaller than Pmode we can cheaply do things in Pmode.  */
10797   else if (<MODE>mode == SImode && Pmode == DImode)
10798     emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
10799                                     operands[2], operands[3]));
10801   /* For signed comparisons against a constant, we can do some simple
10802      bit-twiddling.  */
10803   else if (signed_comparison_operator (operands[1], VOIDmode)
10804            && CONST_INT_P (operands[3]))
10805     emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
10806                                              operands[2], operands[3]));
10808   /* And similarly for unsigned comparisons.  */
10809   else if (unsigned_comparison_operator (operands[1], VOIDmode)
10810            && CONST_INT_P (operands[3]))
10811     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
10812                                                operands[2], operands[3]));
10814   /* We also do not want to use mfcr for signed comparisons.  */
10815   else if (<MODE>mode == Pmode
10816            && signed_comparison_operator (operands[1], VOIDmode))
10817     emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
10818                                          operands[2], operands[3]));
10820   /* Everything else, use the mfcr brute force.  */
10821   else
10822     rs6000_emit_sCOND (<MODE>mode, operands);
10824   DONE;
10827 (define_expand "cstore<mode>4"
10828   [(use (match_operator 1 "rs6000_cbranch_operator"
10829          [(match_operand:FP 2 "gpc_reg_operand")
10830           (match_operand:FP 3 "gpc_reg_operand")]))
10831    (clobber (match_operand:SI 0 "gpc_reg_operand"))]
10832   ""
10834   rs6000_emit_sCOND (<MODE>mode, operands);
10835   DONE;
10839 (define_expand "stack_protect_set"
10840   [(match_operand 0 "memory_operand" "")
10841    (match_operand 1 "memory_operand" "")]
10842   ""
10844 #ifdef TARGET_THREAD_SSP_OFFSET
10845   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10846   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10847   operands[1] = gen_rtx_MEM (Pmode, addr);
10848 #endif
10849   if (TARGET_64BIT)
10850     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10851   else
10852     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10853   DONE;
10856 (define_insn "stack_protect_setsi"
10857   [(set (match_operand:SI 0 "memory_operand" "=m")
10858         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
10859    (set (match_scratch:SI 2 "=&r") (const_int 0))]
10860   "TARGET_32BIT"
10861   "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
10862   [(set_attr "type" "three")
10863    (set_attr "length" "12")])
10865 (define_insn "stack_protect_setdi"
10866   [(set (match_operand:DI 0 "memory_operand" "=Y")
10867         (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
10868    (set (match_scratch:DI 2 "=&r") (const_int 0))]
10869   "TARGET_64BIT"
10870   "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
10871   [(set_attr "type" "three")
10872    (set_attr "length" "12")])
10874 (define_expand "stack_protect_test"
10875   [(match_operand 0 "memory_operand" "")
10876    (match_operand 1 "memory_operand" "")
10877    (match_operand 2 "" "")]
10878   ""
10880   rtx test, op0, op1;
10881 #ifdef TARGET_THREAD_SSP_OFFSET
10882   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
10883   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
10884   operands[1] = gen_rtx_MEM (Pmode, addr);
10885 #endif
10886   op0 = operands[0];
10887   op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
10888   test = gen_rtx_EQ (VOIDmode, op0, op1);
10889   emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
10890   DONE;
10893 (define_insn "stack_protect_testsi"
10894   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10895         (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
10896                       (match_operand:SI 2 "memory_operand" "m,m")]
10897                      UNSPEC_SP_TEST))
10898    (set (match_scratch:SI 4 "=r,r") (const_int 0))
10899    (clobber (match_scratch:SI 3 "=&r,&r"))]
10900   "TARGET_32BIT"
10901   "@
10902    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10903    lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
10904   [(set_attr "length" "16,20")])
10906 (define_insn "stack_protect_testdi"
10907   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
10908         (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
10909                       (match_operand:DI 2 "memory_operand" "Y,Y")]
10910                      UNSPEC_SP_TEST))
10911    (set (match_scratch:DI 4 "=r,r") (const_int 0))
10912    (clobber (match_scratch:DI 3 "=&r,&r"))]
10913   "TARGET_64BIT"
10914   "@
10915    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
10916    ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
10917   [(set_attr "length" "16,20")])
10920 ;; Here are the actual compare insns.
10921 (define_insn "*cmp<mode>_signed"
10922   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
10923         (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
10924                     (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
10925   ""
10926   "cmp<wd>%I2 %0,%1,%2"
10927   [(set_attr "type" "cmp")])
10929 (define_insn "*cmp<mode>_unsigned"
10930   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
10931         (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
10932                        (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
10933   ""
10934   "cmpl<wd>%I2 %0,%1,%2"
10935   [(set_attr "type" "cmp")])
10937 ;; If we are comparing a register for equality with a large constant,
10938 ;; we can do this with an XOR followed by a compare.  But this is profitable
10939 ;; only if the large constant is only used for the comparison (and in this
10940 ;; case we already have a register to reuse as scratch).
10942 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
10943 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
10945 (define_peephole2
10946   [(set (match_operand:SI 0 "register_operand")
10947         (match_operand:SI 1 "logical_const_operand" ""))
10948    (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
10949                        [(match_dup 0)
10950                         (match_operand:SI 2 "logical_const_operand" "")]))
10951    (set (match_operand:CC 4 "cc_reg_operand" "")
10952         (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
10953                     (match_dup 0)))
10954    (set (pc)
10955         (if_then_else (match_operator 6 "equality_operator"
10956                        [(match_dup 4) (const_int 0)])
10957                       (match_operand 7 "" "")
10958                       (match_operand 8 "" "")))]
10959   "peep2_reg_dead_p (3, operands[0])
10960    && peep2_reg_dead_p (4, operands[4])
10961    && REGNO (operands[0]) != REGNO (operands[5])"
10962  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
10963   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
10964   (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
10967   /* Get the constant we are comparing against, and see what it looks like
10968      when sign-extended from 16 to 32 bits.  Then see what constant we could
10969      XOR with SEXTC to get the sign-extended value.  */
10970   rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
10971                                               SImode,
10972                                               operands[1], operands[2]);
10973   HOST_WIDE_INT c = INTVAL (cnst);
10974   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
10975   HOST_WIDE_INT xorv = c ^ sextc;
10977   operands[9] = GEN_INT (xorv);
10978   operands[10] = GEN_INT (sextc);
10981 ;; The following two insns don't exist as single insns, but if we provide
10982 ;; them, we can swap an add and compare, which will enable us to overlap more
10983 ;; of the required delay between a compare and branch.  We generate code for
10984 ;; them by splitting.
10986 (define_insn ""
10987   [(set (match_operand:CC 3 "cc_reg_operand" "=y")
10988         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
10989                     (match_operand:SI 2 "short_cint_operand" "i")))
10990    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
10991         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
10992   ""
10993   "#"
10994   [(set_attr "length" "8")])
10996 (define_insn ""
10997   [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
10998         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
10999                        (match_operand:SI 2 "u_short_cint_operand" "i")))
11000    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11001         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11002   ""
11003   "#"
11004   [(set_attr "length" "8")])
11006 (define_split
11007   [(set (match_operand:CC 3 "cc_reg_operand" "")
11008         (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
11009                     (match_operand:SI 2 "short_cint_operand" "")))
11010    (set (match_operand:SI 0 "gpc_reg_operand" "")
11011         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11012   ""
11013   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11014    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11016 (define_split
11017   [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
11018         (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
11019                        (match_operand:SI 2 "u_short_cint_operand" "")))
11020    (set (match_operand:SI 0 "gpc_reg_operand" "")
11021         (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
11022   ""
11023   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11024    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11026 ;; Only need to compare second words if first words equal
11027 (define_insn "*cmp<mode>_internal1"
11028   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11029         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11030                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11031   "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11032    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11033   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11034   [(set_attr "type" "fpcompare")
11035    (set_attr "length" "12")])
11037 (define_insn_and_split "*cmp<mode>_internal2"
11038   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11039         (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11040                       (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11041     (clobber (match_scratch:DF 3 "=d"))
11042     (clobber (match_scratch:DF 4 "=d"))
11043     (clobber (match_scratch:DF 5 "=d"))
11044     (clobber (match_scratch:DF 6 "=d"))
11045     (clobber (match_scratch:DF 7 "=d"))
11046     (clobber (match_scratch:DF 8 "=d"))
11047     (clobber (match_scratch:DF 9 "=d"))
11048     (clobber (match_scratch:DF 10 "=d"))
11049     (clobber (match_scratch:GPR 11 "=b"))]
11050   "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11051    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11052   "#"
11053   "&& reload_completed"
11054   [(set (match_dup 3) (match_dup 14))
11055    (set (match_dup 4) (match_dup 15))
11056    (set (match_dup 9) (abs:DF (match_dup 5)))
11057    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11058    (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11059                            (label_ref (match_dup 12))
11060                            (pc)))
11061    (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11062    (set (pc) (label_ref (match_dup 13)))
11063    (match_dup 12)
11064    (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11065    (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11066    (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11067    (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11068    (match_dup 13)]
11070   REAL_VALUE_TYPE rv;
11071   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11072   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11074   operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11075   operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11076   operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11077   operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11078   operands[12] = gen_label_rtx ();
11079   operands[13] = gen_label_rtx ();
11080   real_inf (&rv);
11081   operands[14] = force_const_mem (DFmode,
11082                                   const_double_from_real_value (rv, DFmode));
11083   operands[15] = force_const_mem (DFmode,
11084                                   const_double_from_real_value (dconst0,
11085                                                                 DFmode));
11086   if (TARGET_TOC)
11087     {
11088       rtx tocref;
11089       tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11090       operands[14] = gen_const_mem (DFmode, tocref);
11091       tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11092       operands[15] = gen_const_mem (DFmode, tocref);
11093       set_mem_alias_set (operands[14], get_TOC_alias_set ());
11094       set_mem_alias_set (operands[15], get_TOC_alias_set ());
11095     }
11098 ;; Now we have the scc insns.  We can do some combinations because of the
11099 ;; way the machine works.
11101 ;; Note that this is probably faster if we can put an insn between the
11102 ;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
11103 ;; cases the insns below which don't use an intermediate CR field will
11104 ;; be used instead.
11105 (define_insn ""
11106   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11107         (match_operator:SI 1 "scc_comparison_operator"
11108                            [(match_operand 2 "cc_reg_operand" "y")
11109                             (const_int 0)]))]
11110   ""
11111   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11112   [(set (attr "type")
11113      (cond [(match_test "TARGET_MFCRF")
11114                 (const_string "mfcrf")
11115            ]
11116         (const_string "mfcr")))
11117    (set_attr "length" "8")])
11119 ;; Same as above, but get the GT bit.
11120 (define_insn "move_from_CR_gt_bit"
11121   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11122         (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11123   "TARGET_HARD_FLOAT && !TARGET_FPRS"
11124   "mfcr %0\;rlwinm %0,%0,%D1,31,31"
11125   [(set_attr "type" "mfcr")
11126    (set_attr "length" "8")])
11128 ;; Same as above, but get the OV/ORDERED bit.
11129 (define_insn "move_from_CR_ov_bit"
11130   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11131         (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11132                    UNSPEC_MV_CR_OV))]
11133   "TARGET_ISEL"
11134   "mfcr %0\;rlwinm %0,%0,%t1,1"
11135   [(set_attr "type" "mfcr")
11136    (set_attr "length" "8")])
11138 (define_insn ""
11139   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11140         (match_operator:DI 1 "scc_comparison_operator"
11141                            [(match_operand 2 "cc_reg_operand" "y")
11142                             (const_int 0)]))]
11143   "TARGET_POWERPC64"
11144   "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11145   [(set (attr "type")
11146      (cond [(match_test "TARGET_MFCRF")
11147                 (const_string "mfcrf")
11148            ]
11149         (const_string "mfcr")))
11150    (set_attr "length" "8")])
11152 (define_insn ""
11153   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11154         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11155                                        [(match_operand 2 "cc_reg_operand" "y,y")
11156                                         (const_int 0)])
11157                     (const_int 0)))
11158    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11159         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11160   "TARGET_32BIT"
11161   "@
11162    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11163    #"
11164   [(set_attr "type" "shift")
11165    (set_attr "dot" "yes")
11166    (set_attr "length" "8,16")])
11168 (define_split
11169   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
11170         (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11171                                        [(match_operand 2 "cc_reg_operand" "")
11172                                         (const_int 0)])
11173                     (const_int 0)))
11174    (set (match_operand:SI 3 "gpc_reg_operand" "")
11175         (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11176   "TARGET_32BIT && reload_completed"
11177   [(set (match_dup 3)
11178         (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11179    (set (match_dup 0)
11180         (compare:CC (match_dup 3)
11181                     (const_int 0)))]
11182   "")
11184 (define_insn ""
11185   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11186         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11187                                       [(match_operand 2 "cc_reg_operand" "y")
11188                                        (const_int 0)])
11189                    (match_operand:SI 3 "const_int_operand" "n")))]
11190   ""
11191   "*
11193   int is_bit = ccr_bit (operands[1], 1);
11194   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11195   int count;
11197   if (is_bit >= put_bit)
11198     count = is_bit - put_bit;
11199   else
11200     count = 32 - (put_bit - is_bit);
11202   operands[4] = GEN_INT (count);
11203   operands[5] = GEN_INT (put_bit);
11205   return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
11207   [(set (attr "type")
11208      (cond [(match_test "TARGET_MFCRF")
11209                 (const_string "mfcrf")
11210            ]
11211         (const_string "mfcr")))
11212    (set_attr "length" "8")])
11214 (define_insn ""
11215   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11216         (compare:CC
11217          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11218                                        [(match_operand 2 "cc_reg_operand" "y,y")
11219                                         (const_int 0)])
11220                     (match_operand:SI 3 "const_int_operand" "n,n"))
11221          (const_int 0)))
11222    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11223         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11224                    (match_dup 3)))]
11225   ""
11226   "*
11228   int is_bit = ccr_bit (operands[1], 1);
11229   int put_bit = 31 - (INTVAL (operands[3]) & 31);
11230   int count;
11232   /* Force split for non-cc0 compare.  */
11233   if (which_alternative == 1)
11234      return \"#\";
11236   if (is_bit >= put_bit)
11237     count = is_bit - put_bit;
11238   else
11239     count = 32 - (put_bit - is_bit);
11241   operands[5] = GEN_INT (count);
11242   operands[6] = GEN_INT (put_bit);
11244   return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
11246   [(set_attr "type" "shift")
11247    (set_attr "dot" "yes")
11248    (set_attr "length" "8,16")])
11250 (define_split
11251   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
11252         (compare:CC
11253          (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11254                                        [(match_operand 2 "cc_reg_operand" "")
11255                                         (const_int 0)])
11256                     (match_operand:SI 3 "const_int_operand" ""))
11257          (const_int 0)))
11258    (set (match_operand:SI 4 "gpc_reg_operand" "")
11259         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11260                    (match_dup 3)))]
11261   "reload_completed"
11262   [(set (match_dup 4)
11263         (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11264                    (match_dup 3)))
11265    (set (match_dup 0)
11266         (compare:CC (match_dup 4)
11267                     (const_int 0)))]
11268   "")
11270 ;; There is a 3 cycle delay between consecutive mfcr instructions
11271 ;; so it is useful to combine 2 scc instructions to use only one mfcr.
11273 (define_peephole
11274   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11275         (match_operator:SI 1 "scc_comparison_operator"
11276                            [(match_operand 2 "cc_reg_operand" "y")
11277                             (const_int 0)]))
11278    (set (match_operand:SI 3 "gpc_reg_operand" "=r")
11279         (match_operator:SI 4 "scc_comparison_operator"
11280                            [(match_operand 5 "cc_reg_operand" "y")
11281                             (const_int 0)]))]
11282   "REGNO (operands[2]) != REGNO (operands[5])"
11283   "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11284   [(set_attr "type" "mfcr")
11285    (set_attr "length" "12")])
11287 (define_peephole
11288   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11289         (match_operator:DI 1 "scc_comparison_operator"
11290                            [(match_operand 2 "cc_reg_operand" "y")
11291                             (const_int 0)]))
11292    (set (match_operand:DI 3 "gpc_reg_operand" "=r")
11293         (match_operator:DI 4 "scc_comparison_operator"
11294                            [(match_operand 5 "cc_reg_operand" "y")
11295                             (const_int 0)]))]
11296   "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11297   "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
11298   [(set_attr "type" "mfcr")
11299    (set_attr "length" "12")])
11302 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11303                               (DI "rKJI")])
11305 (define_insn_and_split "eq<mode>3"
11306   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11307         (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11308                 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11309    (clobber (match_scratch:GPR 3 "=r"))
11310    (clobber (match_scratch:GPR 4 "=r"))]
11311   ""
11312   "#"
11313   ""
11314   [(set (match_dup 4)
11315         (clz:GPR (match_dup 3)))
11316    (set (match_dup 0)
11317         (lshiftrt:GPR (match_dup 4)
11318                       (match_dup 5)))]
11320   operands[3] = rs6000_emit_eqne (<MODE>mode,
11321                                   operands[1], operands[2], operands[3]);
11323   if (GET_CODE (operands[4]) == SCRATCH)
11324     operands[4] = gen_reg_rtx (<MODE>mode);
11326   operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11328   [(set (attr "length")
11329         (if_then_else (match_test "operands[2] == const0_rtx")
11330                       (const_string "8")
11331                       (const_string "12")))])
11333 (define_insn_and_split "ne<mode>3"
11334   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11335         (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11336               (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11337    (clobber (match_scratch:P 3 "=r"))
11338    (clobber (match_scratch:P 4 "=r"))
11339    (clobber (reg:P CA_REGNO))]
11340   "!TARGET_ISEL"
11341   "#"
11342   ""
11343   [(parallel [(set (match_dup 4)
11344                    (plus:P (match_dup 3)
11345                            (const_int -1)))
11346               (set (reg:P CA_REGNO)
11347                    (ne:P (match_dup 3)
11348                          (const_int 0)))])
11349    (parallel [(set (match_dup 0)
11350                    (plus:P (plus:P (not:P (match_dup 4))
11351                                    (reg:P CA_REGNO))
11352                            (match_dup 3)))
11353               (clobber (reg:P CA_REGNO))])]
11355   operands[3] = rs6000_emit_eqne (<MODE>mode,
11356                                   operands[1], operands[2], operands[3]);
11358   if (GET_CODE (operands[4]) == SCRATCH)
11359     operands[4] = gen_reg_rtx (<MODE>mode);
11361   [(set (attr "length")
11362         (if_then_else (match_test "operands[2] == const0_rtx")
11363                       (const_string "8")
11364                       (const_string "12")))])
11366 (define_insn_and_split "*neg_eq_<mode>"
11367   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11368         (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11369                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11370    (clobber (match_scratch:P 3 "=r"))
11371    (clobber (match_scratch:P 4 "=r"))
11372    (clobber (reg:P CA_REGNO))]
11373   ""
11374   "#"
11375   ""
11376   [(parallel [(set (match_dup 4)
11377                    (plus:P (match_dup 3)
11378                            (const_int -1)))
11379               (set (reg:P CA_REGNO)
11380                    (ne:P (match_dup 3)
11381                          (const_int 0)))])
11382    (parallel [(set (match_dup 0)
11383                    (plus:P (reg:P CA_REGNO)
11384                            (const_int -1)))
11385               (clobber (reg:P CA_REGNO))])]
11387   operands[3] = rs6000_emit_eqne (<MODE>mode,
11388                                   operands[1], operands[2], operands[3]);
11390   if (GET_CODE (operands[4]) == SCRATCH)
11391     operands[4] = gen_reg_rtx (<MODE>mode);
11393   [(set (attr "length")
11394         (if_then_else (match_test "operands[2] == const0_rtx")
11395                       (const_string "8")
11396                       (const_string "12")))])
11398 (define_insn_and_split "*neg_ne_<mode>"
11399   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11400         (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11401                      (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11402    (clobber (match_scratch:P 3 "=r"))
11403    (clobber (match_scratch:P 4 "=r"))
11404    (clobber (reg:P CA_REGNO))]
11405   ""
11406   "#"
11407   ""
11408   [(parallel [(set (match_dup 4)
11409                    (neg:P (match_dup 3)))
11410               (set (reg:P CA_REGNO)
11411                    (eq:P (match_dup 3)
11412                          (const_int 0)))])
11413    (parallel [(set (match_dup 0)
11414                    (plus:P (reg:P CA_REGNO)
11415                            (const_int -1)))
11416               (clobber (reg:P CA_REGNO))])]
11418   operands[3] = rs6000_emit_eqne (<MODE>mode,
11419                                   operands[1], operands[2], operands[3]);
11421   if (GET_CODE (operands[4]) == SCRATCH)
11422     operands[4] = gen_reg_rtx (<MODE>mode);
11424   [(set (attr "length")
11425         (if_then_else (match_test "operands[2] == const0_rtx")
11426                       (const_string "8")
11427                       (const_string "12")))])
11429 (define_insn_and_split "*plus_eq_<mode>"
11430   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11431         (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11432                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11433                 (match_operand:P 3 "gpc_reg_operand" "r")))
11434    (clobber (match_scratch:P 4 "=r"))
11435    (clobber (match_scratch:P 5 "=r"))
11436    (clobber (reg:P CA_REGNO))]
11437   ""
11438   "#"
11439   ""
11440   [(parallel [(set (match_dup 5)
11441                    (neg:P (match_dup 4)))
11442               (set (reg:P CA_REGNO)
11443                    (eq:P (match_dup 4)
11444                          (const_int 0)))])
11445    (parallel [(set (match_dup 0)
11446                    (plus:P (match_dup 3)
11447                            (reg:P CA_REGNO)))
11448               (clobber (reg:P CA_REGNO))])]
11450   operands[4] = rs6000_emit_eqne (<MODE>mode,
11451                                   operands[1], operands[2], operands[4]);
11453   if (GET_CODE (operands[5]) == SCRATCH)
11454     operands[5] = gen_reg_rtx (<MODE>mode);
11456   [(set (attr "length")
11457         (if_then_else (match_test "operands[2] == const0_rtx")
11458                       (const_string "8")
11459                       (const_string "12")))])
11461 (define_insn_and_split "*plus_ne_<mode>"
11462   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11463         (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11464                       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11465                 (match_operand:P 3 "gpc_reg_operand" "r")))
11466    (clobber (match_scratch:P 4 "=r"))
11467    (clobber (match_scratch:P 5 "=r"))
11468    (clobber (reg:P CA_REGNO))]
11469   ""
11470   "#"
11471   ""
11472   [(parallel [(set (match_dup 5)
11473                    (plus:P (match_dup 4)
11474                            (const_int -1)))
11475               (set (reg:P CA_REGNO)
11476                    (ne:P (match_dup 4)
11477                          (const_int 0)))])
11478    (parallel [(set (match_dup 0)
11479                    (plus:P (match_dup 3)
11480                            (reg:P CA_REGNO)))
11481               (clobber (reg:P CA_REGNO))])]
11483   operands[4] = rs6000_emit_eqne (<MODE>mode,
11484                                   operands[1], operands[2], operands[4]);
11486   if (GET_CODE (operands[5]) == SCRATCH)
11487     operands[5] = gen_reg_rtx (<MODE>mode);
11489   [(set (attr "length")
11490         (if_then_else (match_test "operands[2] == const0_rtx")
11491                       (const_string "8")
11492                       (const_string "12")))])
11494 (define_insn_and_split "*minus_eq_<mode>"
11495   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11496         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11497                  (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11498                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11499    (clobber (match_scratch:P 4 "=r"))
11500    (clobber (match_scratch:P 5 "=r"))
11501    (clobber (reg:P CA_REGNO))]
11502   ""
11503   "#"
11504   ""
11505   [(parallel [(set (match_dup 5)
11506                    (plus:P (match_dup 4)
11507                            (const_int -1)))
11508               (set (reg:P CA_REGNO)
11509                    (ne:P (match_dup 4)
11510                          (const_int 0)))])
11511    (parallel [(set (match_dup 0)
11512                    (plus:P (plus:P (match_dup 3)
11513                                    (reg:P CA_REGNO))
11514                            (const_int -1)))
11515               (clobber (reg:P CA_REGNO))])]
11517   operands[4] = rs6000_emit_eqne (<MODE>mode,
11518                                   operands[1], operands[2], operands[4]);
11520   if (GET_CODE (operands[5]) == SCRATCH)
11521     operands[5] = gen_reg_rtx (<MODE>mode);
11523   [(set (attr "length")
11524         (if_then_else (match_test "operands[2] == const0_rtx")
11525                       (const_string "8")
11526                       (const_string "12")))])
11528 (define_insn_and_split "*minus_ne_<mode>"
11529   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11530         (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
11531                  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11532                        (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11533    (clobber (match_scratch:P 4 "=r"))
11534    (clobber (match_scratch:P 5 "=r"))
11535    (clobber (reg:P CA_REGNO))]
11536   ""
11537   "#"
11538   ""
11539   [(parallel [(set (match_dup 5)
11540                    (neg:P (match_dup 4)))
11541               (set (reg:P CA_REGNO)
11542                    (eq:P (match_dup 4)
11543                          (const_int 0)))])
11544    (parallel [(set (match_dup 0)
11545                    (plus:P (plus:P (match_dup 3)
11546                                    (reg:P CA_REGNO))
11547                            (const_int -1)))
11548               (clobber (reg:P CA_REGNO))])]
11550   operands[4] = rs6000_emit_eqne (<MODE>mode,
11551                                   operands[1], operands[2], operands[4]);
11553   if (GET_CODE (operands[5]) == SCRATCH)
11554     operands[5] = gen_reg_rtx (<MODE>mode);
11556   [(set (attr "length")
11557         (if_then_else (match_test "operands[2] == const0_rtx")
11558                       (const_string "8")
11559                       (const_string "12")))])
11561 (define_insn_and_split "*eqsi3_ext<mode>"
11562   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11563         (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11564                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11565    (clobber (match_scratch:SI 3 "=r"))
11566    (clobber (match_scratch:SI 4 "=r"))]
11567   ""
11568   "#"
11569   ""
11570   [(set (match_dup 4)
11571         (clz:SI (match_dup 3)))
11572    (set (match_dup 0)
11573         (zero_extend:EXTSI
11574           (lshiftrt:SI (match_dup 4)
11575                        (const_int 5))))]
11577   operands[3] = rs6000_emit_eqne (SImode,
11578                                   operands[1], operands[2], operands[3]);
11580   if (GET_CODE (operands[4]) == SCRATCH)
11581     operands[4] = gen_reg_rtx (SImode);
11583   [(set (attr "length")
11584         (if_then_else (match_test "operands[2] == const0_rtx")
11585                       (const_string "8")
11586                       (const_string "12")))])
11588 (define_insn_and_split "*nesi3_ext<mode>"
11589   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
11590         (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
11591                   (match_operand:SI 2 "scc_eq_operand" "rKLI")))
11592    (clobber (match_scratch:SI 3 "=r"))
11593    (clobber (match_scratch:SI 4 "=r"))
11594    (clobber (match_scratch:EXTSI 5 "=r"))]
11595   ""
11596   "#"
11597   ""
11598   [(set (match_dup 4)
11599         (clz:SI (match_dup 3)))
11600    (set (match_dup 5)
11601         (zero_extend:EXTSI
11602           (lshiftrt:SI (match_dup 4)
11603                        (const_int 5))))
11604    (set (match_dup 0)
11605         (xor:EXTSI (match_dup 5)
11606                    (const_int 1)))]
11608   operands[3] = rs6000_emit_eqne (SImode,
11609                                   operands[1], operands[2], operands[3]);
11611   if (GET_CODE (operands[4]) == SCRATCH)
11612     operands[4] = gen_reg_rtx (SImode);
11613   if (GET_CODE (operands[5]) == SCRATCH)
11614     operands[5] = gen_reg_rtx (<MODE>mode);
11616   [(set (attr "length")
11617         (if_then_else (match_test "operands[2] == const0_rtx")
11618                       (const_string "12")
11619                       (const_string "16")))])
11621 ;; Define both directions of branch and return.  If we need a reload
11622 ;; register, we'd rather use CR0 since it is much easier to copy a
11623 ;; register CC value to there.
11625 (define_insn ""
11626   [(set (pc)
11627         (if_then_else (match_operator 1 "branch_comparison_operator"
11628                                       [(match_operand 2
11629                                                       "cc_reg_operand" "y")
11630                                        (const_int 0)])
11631                       (label_ref (match_operand 0 "" ""))
11632                       (pc)))]
11633   ""
11634   "*
11636   return output_cbranch (operands[1], \"%l0\", 0, insn);
11638   [(set_attr "type" "branch")])
11640 (define_insn ""
11641   [(set (pc)
11642         (if_then_else (match_operator 0 "branch_comparison_operator"
11643                                       [(match_operand 1
11644                                                       "cc_reg_operand" "y")
11645                                        (const_int 0)])
11646                       (any_return)
11647                       (pc)))]
11648   "<return_pred>"
11649   "*
11651   return output_cbranch (operands[0], NULL, 0, insn);
11653   [(set_attr "type" "jmpreg")
11654    (set_attr "length" "4")])
11656 (define_insn ""
11657   [(set (pc)
11658         (if_then_else (match_operator 1 "branch_comparison_operator"
11659                                       [(match_operand 2
11660                                                       "cc_reg_operand" "y")
11661                                        (const_int 0)])
11662                       (pc)
11663                       (label_ref (match_operand 0 "" ""))))]
11664   ""
11665   "*
11667   return output_cbranch (operands[1], \"%l0\", 1, insn);
11669   [(set_attr "type" "branch")])
11671 (define_insn ""
11672   [(set (pc)
11673         (if_then_else (match_operator 0 "branch_comparison_operator"
11674                                       [(match_operand 1
11675                                                       "cc_reg_operand" "y")
11676                                        (const_int 0)])
11677                       (pc)
11678                       (any_return)))]
11679   "<return_pred>"
11680   "*
11682   return output_cbranch (operands[0], NULL, 1, insn);
11684   [(set_attr "type" "jmpreg")
11685    (set_attr "length" "4")])
11687 ;; Logic on condition register values.
11689 ; This pattern matches things like
11690 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
11691 ;                                          (eq:SI (reg:CCFP 68) (const_int 0)))
11692 ;                                  (const_int 1)))
11693 ; which are generated by the branch logic.
11694 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
11696 (define_insn "*cceq_ior_compare"
11697   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11698         (compare:CCEQ (match_operator:SI 1 "boolean_operator"
11699                         [(match_operator:SI 2
11700                                       "branch_positive_comparison_operator"
11701                                       [(match_operand 3
11702                                                       "cc_reg_operand" "y,y")
11703                                        (const_int 0)])
11704                          (match_operator:SI 4
11705                                       "branch_positive_comparison_operator"
11706                                       [(match_operand 5
11707                                                       "cc_reg_operand" "0,y")
11708                                        (const_int 0)])])
11709                       (const_int 1)))]
11710   ""
11711   "cr%q1 %E0,%j2,%j4"
11712   [(set_attr "type" "cr_logical,delayed_cr")])
11714 ; Why is the constant -1 here, but 1 in the previous pattern?
11715 ; Because ~1 has all but the low bit set.
11716 (define_insn ""
11717   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11718         (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
11719                         [(not:SI (match_operator:SI 2
11720                                       "branch_positive_comparison_operator"
11721                                       [(match_operand 3
11722                                                       "cc_reg_operand" "y,y")
11723                                        (const_int 0)]))
11724                          (match_operator:SI 4
11725                                 "branch_positive_comparison_operator"
11726                                 [(match_operand 5
11727                                                 "cc_reg_operand" "0,y")
11728                                  (const_int 0)])])
11729                       (const_int -1)))]
11730   ""
11731   "cr%q1 %E0,%j2,%j4"
11732   [(set_attr "type" "cr_logical,delayed_cr")])
11734 (define_insn "*cceq_rev_compare"
11735   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
11736         (compare:CCEQ (match_operator:SI 1
11737                                       "branch_positive_comparison_operator"
11738                                       [(match_operand 2
11739                                                       "cc_reg_operand" "0,y")
11740                                        (const_int 0)])
11741                       (const_int 0)))]
11742   ""
11743   "crnot %E0,%j1"
11744   [(set_attr "type" "cr_logical,delayed_cr")])
11746 ;; If we are comparing the result of two comparisons, this can be done
11747 ;; using creqv or crxor.
11749 (define_insn_and_split ""
11750   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
11751         (compare:CCEQ (match_operator 1 "branch_comparison_operator"
11752                               [(match_operand 2 "cc_reg_operand" "y")
11753                                (const_int 0)])
11754                       (match_operator 3 "branch_comparison_operator"
11755                               [(match_operand 4 "cc_reg_operand" "y")
11756                                (const_int 0)])))]
11757   ""
11758   "#"
11759   ""
11760   [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
11761                                     (match_dup 5)))]
11762   "
11764   int positive_1, positive_2;
11766   positive_1 = branch_positive_comparison_operator (operands[1],
11767                                                     GET_MODE (operands[1]));
11768   positive_2 = branch_positive_comparison_operator (operands[3],
11769                                                     GET_MODE (operands[3]));
11771   if (! positive_1)
11772     operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
11773                                                             GET_CODE (operands[1])),
11774                                   SImode,
11775                                   operands[2], const0_rtx);
11776   else if (GET_MODE (operands[1]) != SImode)
11777     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
11778                                   operands[2], const0_rtx);
11780   if (! positive_2)
11781     operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
11782                                                             GET_CODE (operands[3])),
11783                                   SImode,
11784                                   operands[4], const0_rtx);
11785   else if (GET_MODE (operands[3]) != SImode)
11786     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
11787                                   operands[4], const0_rtx);
11789   if (positive_1 == positive_2)
11790     {
11791       operands[1] = gen_rtx_NOT (SImode, operands[1]);
11792       operands[5] = constm1_rtx;
11793     }
11794   else
11795     {
11796       operands[5] = const1_rtx;
11797     }
11800 ;; Unconditional branch and return.
11802 (define_insn "jump"
11803   [(set (pc)
11804         (label_ref (match_operand 0 "" "")))]
11805   ""
11806   "b %l0"
11807   [(set_attr "type" "branch")])
11809 (define_insn "<return_str>return"
11810   [(any_return)]
11811   "<return_pred>"
11812   "blr"
11813   [(set_attr "type" "jmpreg")])
11815 (define_expand "indirect_jump"
11816   [(set (pc) (match_operand 0 "register_operand" ""))])
11818 (define_insn "*indirect_jump<mode>"
11819   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
11820   ""
11821   "@
11822    bctr
11823    blr"
11824   [(set_attr "type" "jmpreg")])
11826 ;; Table jump for switch statements:
11827 (define_expand "tablejump"
11828   [(use (match_operand 0 "" ""))
11829    (use (label_ref (match_operand 1 "" "")))]
11830   ""
11831   "
11833   if (TARGET_32BIT)
11834     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
11835   else
11836     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
11837   DONE;
11840 (define_expand "tablejumpsi"
11841   [(set (match_dup 3)
11842         (plus:SI (match_operand:SI 0 "" "")
11843                  (match_dup 2)))
11844    (parallel [(set (pc) (match_dup 3))
11845               (use (label_ref (match_operand 1 "" "")))])]
11846   "TARGET_32BIT"
11847   "
11848 { operands[0] = force_reg (SImode, operands[0]);
11849   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
11850   operands[3] = gen_reg_rtx (SImode);
11853 (define_expand "tablejumpdi"
11854   [(set (match_dup 4)
11855         (sign_extend:DI (match_operand:SI 0 "lwa_operand" "")))
11856    (set (match_dup 3)
11857         (plus:DI (match_dup 4)
11858                  (match_dup 2)))
11859    (parallel [(set (pc) (match_dup 3))
11860               (use (label_ref (match_operand 1 "" "")))])]
11861   "TARGET_64BIT"
11862   "
11863 { operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
11864   operands[3] = gen_reg_rtx (DImode);
11865   operands[4] = gen_reg_rtx (DImode);
11868 (define_insn "*tablejump<mode>_internal1"
11869   [(set (pc)
11870         (match_operand:P 0 "register_operand" "c,*l"))
11871    (use (label_ref (match_operand 1 "" "")))]
11872   ""
11873   "@
11874    bctr
11875    blr"
11876   [(set_attr "type" "jmpreg")])
11878 (define_insn "nop"
11879   [(unspec [(const_int 0)] UNSPEC_NOP)]
11880   ""
11881   "nop")
11883 (define_insn "group_ending_nop"
11884   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
11885   ""
11886   "*
11888   if (rs6000_cpu_attr == CPU_POWER6)
11889     return \"ori 1,1,0\";
11890   return \"ori 2,2,0\";
11893 ;; Define the subtract-one-and-jump insns, starting with the template
11894 ;; so loop.c knows what to generate.
11896 (define_expand "doloop_end"
11897   [(use (match_operand 0 "" ""))        ; loop pseudo
11898    (use (match_operand 1 "" ""))]       ; label
11899   ""
11900   "
11902   if (TARGET_64BIT)
11903     {
11904       if (GET_MODE (operands[0]) != DImode)
11905         FAIL;
11906       emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
11907     }
11908   else
11909     {
11910       if (GET_MODE (operands[0]) != SImode)
11911         FAIL;
11912       emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
11913     }
11914   DONE;
11917 (define_expand "ctr<mode>"
11918   [(parallel [(set (pc)
11919                    (if_then_else (ne (match_operand:P 0 "register_operand" "")
11920                                      (const_int 1))
11921                                  (label_ref (match_operand 1 "" ""))
11922                                  (pc)))
11923               (set (match_dup 0)
11924                    (plus:P (match_dup 0)
11925                             (const_int -1)))
11926               (clobber (match_scratch:CC 2 ""))
11927               (clobber (match_scratch:P 3 ""))])]
11928   ""
11929   "")
11931 ;; We need to be able to do this for any operand, including MEM, or we
11932 ;; will cause reload to blow up since we don't allow output reloads on
11933 ;; JUMP_INSNs.
11934 ;; For the length attribute to be calculated correctly, the
11935 ;; label MUST be operand 0.
11937 (define_insn "*ctr<mode>_internal1"
11938   [(set (pc)
11939         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11940                           (const_int 1))
11941                       (label_ref (match_operand 0 "" ""))
11942                       (pc)))
11943    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11944         (plus:P (match_dup 1)
11945                  (const_int -1)))
11946    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11947    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11948   ""
11949   "*
11951   if (which_alternative != 0)
11952     return \"#\";
11953   else if (get_attr_length (insn) == 4)
11954     return \"bdnz %l0\";
11955   else
11956     return \"bdz $+8\;b %l0\";
11958   [(set_attr "type" "branch")
11959    (set_attr "length" "*,16,20,20")])
11961 (define_insn "*ctr<mode>_internal2"
11962   [(set (pc)
11963         (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11964                           (const_int 1))
11965                       (pc)
11966                       (label_ref (match_operand 0 "" ""))))
11967    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11968         (plus:P (match_dup 1)
11969                  (const_int -1)))
11970    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11971    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11972   ""
11973   "*
11975   if (which_alternative != 0)
11976     return \"#\";
11977   else if (get_attr_length (insn) == 4)
11978     return \"bdz %l0\";
11979   else
11980     return \"bdnz $+8\;b %l0\";
11982   [(set_attr "type" "branch")
11983    (set_attr "length" "*,16,20,20")])
11985 ;; Similar but use EQ
11987 (define_insn "*ctr<mode>_internal5"
11988   [(set (pc)
11989         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
11990                           (const_int 1))
11991                       (label_ref (match_operand 0 "" ""))
11992                       (pc)))
11993    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
11994         (plus:P (match_dup 1)
11995                  (const_int -1)))
11996    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
11997    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
11998   ""
11999   "*
12001   if (which_alternative != 0)
12002     return \"#\";
12003   else if (get_attr_length (insn) == 4)
12004     return \"bdz %l0\";
12005   else
12006     return \"bdnz $+8\;b %l0\";
12008   [(set_attr "type" "branch")
12009    (set_attr "length" "*,16,20,20")])
12011 (define_insn "*ctr<mode>_internal6"
12012   [(set (pc)
12013         (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12014                           (const_int 1))
12015                       (pc)
12016                       (label_ref (match_operand 0 "" ""))))
12017    (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l")
12018         (plus:P (match_dup 1)
12019                  (const_int -1)))
12020    (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12021    (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12022   ""
12023   "*
12025   if (which_alternative != 0)
12026     return \"#\";
12027   else if (get_attr_length (insn) == 4)
12028     return \"bdnz %l0\";
12029   else
12030     return \"bdz $+8\;b %l0\";
12032   [(set_attr "type" "branch")
12033    (set_attr "length" "*,16,20,20")])
12035 ;; Now the splitters if we could not allocate the CTR register
12037 (define_split
12038   [(set (pc)
12039         (if_then_else (match_operator 2 "comparison_operator"
12040                                       [(match_operand:P 1 "gpc_reg_operand" "")
12041                                        (const_int 1)])
12042                       (match_operand 5 "" "")
12043                       (match_operand 6 "" "")))
12044    (set (match_operand:P 0 "gpc_reg_operand" "")
12045         (plus:P (match_dup 1) (const_int -1)))
12046    (clobber (match_scratch:CC 3 ""))
12047    (clobber (match_scratch:P 4 ""))]
12048   "reload_completed"
12049   [(set (match_dup 3)
12050         (compare:CC (match_dup 1)
12051                     (const_int 1)))
12052    (set (match_dup 0)
12053         (plus:P (match_dup 1)
12054                 (const_int -1)))
12055    (set (pc) (if_then_else (match_dup 7)
12056                            (match_dup 5)
12057                            (match_dup 6)))]
12058   "
12059 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12060                                 operands[3], const0_rtx); }")
12062 (define_split
12063   [(set (pc)
12064         (if_then_else (match_operator 2 "comparison_operator"
12065                                       [(match_operand:P 1 "gpc_reg_operand" "")
12066                                        (const_int 1)])
12067                       (match_operand 5 "" "")
12068                       (match_operand 6 "" "")))
12069    (set (match_operand:P 0 "nonimmediate_operand" "")
12070         (plus:P (match_dup 1) (const_int -1)))
12071    (clobber (match_scratch:CC 3 ""))
12072    (clobber (match_scratch:P 4 ""))]
12073   "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
12074   [(set (match_dup 3)
12075         (compare:CC (match_dup 1)
12076                     (const_int 1)))
12077    (set (match_dup 4)
12078         (plus:P (match_dup 1)
12079                 (const_int -1)))
12080    (set (match_dup 0)
12081         (match_dup 4))
12082    (set (pc) (if_then_else (match_dup 7)
12083                            (match_dup 5)
12084                            (match_dup 6)))]
12085   "
12086 { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
12087                                 operands[3], const0_rtx); }")
12089 (define_insn "trap"
12090   [(trap_if (const_int 1) (const_int 0))]
12091   ""
12092   "trap"
12093   [(set_attr "type" "trap")])
12095 (define_expand "ctrap<mode>4"
12096   [(trap_if (match_operator 0 "ordered_comparison_operator"
12097                             [(match_operand:GPR 1 "register_operand")
12098                              (match_operand:GPR 2 "reg_or_short_operand")])
12099             (match_operand 3 "zero_constant" ""))]
12100   ""
12101   "")
12103 (define_insn ""
12104   [(trap_if (match_operator 0 "ordered_comparison_operator"
12105                             [(match_operand:GPR 1 "register_operand" "r")
12106                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12107             (const_int 0))]
12108   ""
12109   "t<wd>%V0%I2 %1,%2"
12110   [(set_attr "type" "trap")])
12112 ;; Insns related to generating the function prologue and epilogue.
12114 (define_expand "prologue"
12115   [(use (const_int 0))]
12116   ""
12118   rs6000_emit_prologue ();
12119   if (!TARGET_SCHED_PROLOG)
12120     emit_insn (gen_blockage ());
12121   DONE;
12124 (define_insn "*movesi_from_cr_one"
12125   [(match_parallel 0 "mfcr_operation"
12126                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12127                          (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12128                                      (match_operand 3 "immediate_operand" "n")]
12129                           UNSPEC_MOVESI_FROM_CR))])]
12130   "TARGET_MFCRF"
12131   "*
12133   int mask = 0;
12134   int i;
12135   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12136   {
12137     mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12138     operands[4] = GEN_INT (mask);
12139     output_asm_insn (\"mfcr %1,%4\", operands);
12140   }
12141   return \"\";
12143   [(set_attr "type" "mfcrf")])
12145 (define_insn "movesi_from_cr"
12146   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12147         (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
12148                     (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12149                     (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
12150                     (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
12151                    UNSPEC_MOVESI_FROM_CR))]
12152   ""
12153   "mfcr %0"
12154   [(set_attr "type" "mfcr")])
12156 (define_insn "*crsave"
12157   [(match_parallel 0 "crsave_operation"
12158                    [(set (match_operand:SI 1 "memory_operand" "=m")
12159                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12160   ""
12161   "stw %2,%1"
12162   [(set_attr "type" "store")])
12164 (define_insn "*stmw"
12165   [(match_parallel 0 "stmw_operation"
12166                    [(set (match_operand:SI 1 "memory_operand" "=m")
12167                          (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12168   "TARGET_MULTIPLE"
12169   "stmw %2,%1"
12170   [(set_attr "type" "store")
12171    (set_attr "update" "yes")
12172    (set_attr "indexed" "yes")])
12174 ; The following comment applies to:
12175 ;     save_gpregs_*
12176 ;     save_fpregs_*
12177 ;     restore_gpregs*
12178 ;     return_and_restore_gpregs*
12179 ;     return_and_restore_fpregs*
12180 ;     return_and_restore_fpregs_aix*
12182 ; The out-of-line save / restore functions expects one input argument.
12183 ; Since those are not standard call_insn's, we must avoid using
12184 ; MATCH_OPERAND for that argument. That way the register rename
12185 ; optimization will not try to rename this register.
12186 ; Each pattern is repeated for each possible register number used in 
12187 ; various ABIs (r11, r1, and for some functions r12)
12189 (define_insn "*save_gpregs_<mode>_r11"
12190   [(match_parallel 0 "any_parallel_operand"
12191                    [(clobber (reg:P 65))
12192                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12193                     (use (reg:P 11))
12194                     (set (match_operand:P 2 "memory_operand" "=m")
12195                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12196   ""
12197   "bl %1"
12198   [(set_attr "type" "branch")
12199    (set_attr "length" "4")])
12201 (define_insn "*save_gpregs_<mode>_r12"
12202   [(match_parallel 0 "any_parallel_operand"
12203                    [(clobber (reg:P 65))
12204                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12205                     (use (reg:P 12))
12206                     (set (match_operand:P 2 "memory_operand" "=m")
12207                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12208   ""
12209   "bl %1"
12210   [(set_attr "type" "branch")
12211    (set_attr "length" "4")])
12213 (define_insn "*save_gpregs_<mode>_r1"
12214   [(match_parallel 0 "any_parallel_operand"
12215                    [(clobber (reg:P 65))
12216                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12217                     (use (reg:P 1))
12218                     (set (match_operand:P 2 "memory_operand" "=m")
12219                          (match_operand:P 3 "gpc_reg_operand" "r"))])]
12220   ""
12221   "bl %1"
12222   [(set_attr "type" "branch")
12223    (set_attr "length" "4")])
12225 (define_insn "*save_fpregs_<mode>_r11"
12226   [(match_parallel 0 "any_parallel_operand"
12227                    [(clobber (reg:P 65))
12228                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12229                     (use (reg:P 11))
12230                     (set (match_operand:DF 2 "memory_operand" "=m")
12231                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12232   ""
12233   "bl %1"
12234   [(set_attr "type" "branch")
12235    (set_attr "length" "4")])
12237 (define_insn "*save_fpregs_<mode>_r12"
12238   [(match_parallel 0 "any_parallel_operand"
12239                    [(clobber (reg:P 65))
12240                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12241                     (use (reg:P 12))
12242                     (set (match_operand:DF 2 "memory_operand" "=m")
12243                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12244   ""
12245   "bl %1"
12246   [(set_attr "type" "branch")
12247    (set_attr "length" "4")])
12249 (define_insn "*save_fpregs_<mode>_r1"
12250   [(match_parallel 0 "any_parallel_operand"
12251                    [(clobber (reg:P 65))
12252                     (use (match_operand:P 1 "symbol_ref_operand" "s"))
12253                     (use (reg:P 1))
12254                     (set (match_operand:DF 2 "memory_operand" "=m")
12255                          (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12256   ""
12257   "bl %1"
12258   [(set_attr "type" "branch")
12259    (set_attr "length" "4")])
12261 ; This is to explain that changes to the stack pointer should
12262 ; not be moved over loads from or stores to stack memory.
12263 (define_insn "stack_tie"
12264   [(match_parallel 0 "tie_operand"
12265                    [(set (mem:BLK (reg 1)) (const_int 0))])]
12266   ""
12267   ""
12268   [(set_attr "length" "0")])
12270 (define_expand "epilogue"
12271   [(use (const_int 0))]
12272   ""
12274   if (!TARGET_SCHED_PROLOG)
12275     emit_insn (gen_blockage ());
12276   rs6000_emit_epilogue (FALSE);
12277   DONE;
12280 ; On some processors, doing the mtcrf one CC register at a time is
12281 ; faster (like on the 604e).  On others, doing them all at once is
12282 ; faster; for instance, on the 601 and 750.
12284 (define_expand "movsi_to_cr_one"
12285   [(set (match_operand:CC 0 "cc_reg_operand" "")
12286         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
12287                     (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12288   ""
12289   "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12291 (define_insn "*movsi_to_cr"
12292   [(match_parallel 0 "mtcrf_operation"
12293                    [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12294                          (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12295                                      (match_operand 3 "immediate_operand" "n")]
12296                                     UNSPEC_MOVESI_TO_CR))])]
12297  ""
12298  "*
12300   int mask = 0;
12301   int i;
12302   for (i = 0; i < XVECLEN (operands[0], 0); i++)
12303     mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12304   operands[4] = GEN_INT (mask);
12305   return \"mtcrf %4,%2\";
12307   [(set_attr "type" "mtcr")])
12309 (define_insn "*mtcrfsi"
12310   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12311         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12312                     (match_operand 2 "immediate_operand" "n")]
12313                    UNSPEC_MOVESI_TO_CR))]
12314   "GET_CODE (operands[0]) == REG
12315    && CR_REGNO_P (REGNO (operands[0]))
12316    && GET_CODE (operands[2]) == CONST_INT
12317    && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12318   "mtcrf %R0,%1"
12319   [(set_attr "type" "mtcr")])
12321 ; The load-multiple instructions have similar properties.
12322 ; Note that "load_multiple" is a name known to the machine-independent
12323 ; code that actually corresponds to the PowerPC load-string.
12325 (define_insn "*lmw"
12326   [(match_parallel 0 "lmw_operation"
12327                    [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12328                          (match_operand:SI 2 "memory_operand" "m"))])]
12329   "TARGET_MULTIPLE"
12330   "lmw %1,%2"
12331   [(set_attr "type" "load")
12332    (set_attr "update" "yes")
12333    (set_attr "indexed" "yes")
12334    (set_attr "cell_micro" "always")])
12336 (define_insn "*return_internal_<mode>"
12337   [(simple_return)
12338    (use (match_operand:P 0 "register_operand" "lc"))]
12339   ""
12340   "b%T0"
12341   [(set_attr "type" "jmpreg")])
12343 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
12344 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
12346 ; The following comment applies to:
12347 ;     save_gpregs_*
12348 ;     save_fpregs_*
12349 ;     restore_gpregs*
12350 ;     return_and_restore_gpregs*
12351 ;     return_and_restore_fpregs*
12352 ;     return_and_restore_fpregs_aix*
12354 ; The out-of-line save / restore functions expects one input argument.
12355 ; Since those are not standard call_insn's, we must avoid using
12356 ; MATCH_OPERAND for that argument. That way the register rename
12357 ; optimization will not try to rename this register.
12358 ; Each pattern is repeated for each possible register number used in 
12359 ; various ABIs (r11, r1, and for some functions r12)
12361 (define_insn "*restore_gpregs_<mode>_r11"
12362  [(match_parallel 0 "any_parallel_operand"
12363                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12364                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12365                    (use (reg:P 11))
12366                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12367                         (match_operand:P 4 "memory_operand" "m"))])]
12368  ""
12369  "bl %2"
12370  [(set_attr "type" "branch")
12371   (set_attr "length" "4")])
12373 (define_insn "*restore_gpregs_<mode>_r12"
12374  [(match_parallel 0 "any_parallel_operand"
12375                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12376                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12377                    (use (reg:P 12))
12378                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12379                         (match_operand:P 4 "memory_operand" "m"))])]
12380  ""
12381  "bl %2"
12382  [(set_attr "type" "branch")
12383   (set_attr "length" "4")])
12385 (define_insn "*restore_gpregs_<mode>_r1"
12386  [(match_parallel 0 "any_parallel_operand"
12387                   [(clobber (match_operand:P 1 "register_operand" "=l"))
12388                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12389                    (use (reg:P 1))
12390                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12391                         (match_operand:P 4 "memory_operand" "m"))])]
12392  ""
12393  "bl %2"
12394  [(set_attr "type" "branch")
12395   (set_attr "length" "4")])
12397 (define_insn "*return_and_restore_gpregs_<mode>_r11"
12398  [(match_parallel 0 "any_parallel_operand"
12399                   [(return)
12400                    (clobber (match_operand:P 1 "register_operand" "=l"))
12401                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12402                    (use (reg:P 11))
12403                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12404                         (match_operand:P 4 "memory_operand" "m"))])]
12405  ""
12406  "b %2"
12407  [(set_attr "type" "branch")
12408   (set_attr "length" "4")])
12410 (define_insn "*return_and_restore_gpregs_<mode>_r12"
12411  [(match_parallel 0 "any_parallel_operand"
12412                   [(return)
12413                    (clobber (match_operand:P 1 "register_operand" "=l"))
12414                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12415                    (use (reg:P 12))
12416                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12417                         (match_operand:P 4 "memory_operand" "m"))])]
12418  ""
12419  "b %2"
12420  [(set_attr "type" "branch")
12421   (set_attr "length" "4")])
12423 (define_insn "*return_and_restore_gpregs_<mode>_r1"
12424  [(match_parallel 0 "any_parallel_operand"
12425                   [(return)
12426                    (clobber (match_operand:P 1 "register_operand" "=l"))
12427                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12428                    (use (reg:P 1))
12429                    (set (match_operand:P 3 "gpc_reg_operand" "=r")
12430                         (match_operand:P 4 "memory_operand" "m"))])]
12431  ""
12432  "b %2"
12433  [(set_attr "type" "branch")
12434   (set_attr "length" "4")])
12436 (define_insn "*return_and_restore_fpregs_<mode>_r11"
12437  [(match_parallel 0 "any_parallel_operand"
12438                   [(return)
12439                    (clobber (match_operand:P 1 "register_operand" "=l"))
12440                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12441                    (use (reg:P 11))
12442                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12443                         (match_operand:DF 4 "memory_operand" "m"))])]
12444  ""
12445  "b %2"
12446  [(set_attr "type" "branch")
12447   (set_attr "length" "4")])
12449 (define_insn "*return_and_restore_fpregs_<mode>_r12"
12450  [(match_parallel 0 "any_parallel_operand"
12451                   [(return)
12452                    (clobber (match_operand:P 1 "register_operand" "=l"))
12453                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12454                    (use (reg:P 12))
12455                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12456                         (match_operand:DF 4 "memory_operand" "m"))])]
12457  ""
12458  "b %2"
12459  [(set_attr "type" "branch")
12460   (set_attr "length" "4")])
12462 (define_insn "*return_and_restore_fpregs_<mode>_r1"
12463  [(match_parallel 0 "any_parallel_operand"
12464                   [(return)
12465                    (clobber (match_operand:P 1 "register_operand" "=l"))
12466                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12467                    (use (reg:P 1))
12468                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12469                         (match_operand:DF 4 "memory_operand" "m"))])]
12470  ""
12471  "b %2"
12472  [(set_attr "type" "branch")
12473   (set_attr "length" "4")])
12475 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
12476  [(match_parallel 0 "any_parallel_operand"
12477                   [(return)
12478                    (use (match_operand:P 1 "register_operand" "l"))
12479                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12480                    (use (reg:P 11))
12481                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12482                         (match_operand:DF 4 "memory_operand" "m"))])]
12483  ""
12484  "b %2"
12485  [(set_attr "type" "branch")
12486   (set_attr "length" "4")])
12488 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
12489  [(match_parallel 0 "any_parallel_operand"
12490                   [(return)
12491                    (use (match_operand:P 1 "register_operand" "l"))
12492                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
12493                    (use (reg:P 1))
12494                    (set (match_operand:DF 3 "gpc_reg_operand" "=d")
12495                         (match_operand:DF 4 "memory_operand" "m"))])]
12496  ""
12497  "b %2"
12498  [(set_attr "type" "branch")
12499   (set_attr "length" "4")])
12501 ; This is used in compiling the unwind routines.
12502 (define_expand "eh_return"
12503   [(use (match_operand 0 "general_operand" ""))]
12504   ""
12505   "
12507   if (TARGET_32BIT)
12508     emit_insn (gen_eh_set_lr_si (operands[0]));
12509   else
12510     emit_insn (gen_eh_set_lr_di (operands[0]));
12511   DONE;
12514 ; We can't expand this before we know where the link register is stored.
12515 (define_insn "eh_set_lr_<mode>"
12516   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
12517                     UNSPECV_EH_RR)
12518    (clobber (match_scratch:P 1 "=&b"))]
12519   ""
12520   "#")
12522 (define_split
12523   [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
12524    (clobber (match_scratch 1 ""))]
12525   "reload_completed"
12526   [(const_int 0)]
12527   "
12529   rs6000_emit_eh_reg_restore (operands[0], operands[1]);
12530   DONE;
12533 (define_insn "prefetch"
12534   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
12535              (match_operand:SI 1 "const_int_operand" "n")
12536              (match_operand:SI 2 "const_int_operand" "n"))]
12537   ""
12538   "*
12540   if (GET_CODE (operands[0]) == REG)
12541     return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
12542   return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
12544   [(set_attr "type" "load")])
12546 ;; Handle -fsplit-stack.
12548 (define_expand "split_stack_prologue"
12549   [(const_int 0)]
12550   ""
12552   rs6000_expand_split_stack_prologue ();
12553   DONE;
12556 (define_expand "load_split_stack_limit"
12557   [(set (match_operand 0)
12558         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
12559   ""
12561   emit_insn (gen_rtx_SET (operands[0],
12562                           gen_rtx_UNSPEC (Pmode,
12563                                           gen_rtvec (1, const0_rtx),
12564                                           UNSPEC_STACK_CHECK)));
12565   DONE;
12568 (define_insn "load_split_stack_limit_di"
12569   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12570         (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
12571   "TARGET_64BIT"
12572   "ld %0,-0x7040(13)"
12573   [(set_attr "type" "load")
12574    (set_attr "update" "no")
12575    (set_attr "indexed" "no")])
12577 (define_insn "load_split_stack_limit_si"
12578   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12579         (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
12580   "!TARGET_64BIT"
12581   "lwz %0,-0x7020(2)"
12582   [(set_attr "type" "load")
12583    (set_attr "update" "no")
12584    (set_attr "indexed" "no")])
12586 ;; A return instruction which the middle-end doesn't see.
12587 (define_insn "split_stack_return"
12588   [(unspec_volatile [(const_int 0)] UNSPECV_SPLIT_STACK_RETURN)]
12589   ""
12590   "blr"
12591   [(set_attr "type" "jmpreg")])
12593 ;; If there are operand 0 bytes available on the stack, jump to
12594 ;; operand 1.
12595 (define_expand "split_stack_space_check"
12596   [(set (match_dup 2)
12597         (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12598    (set (match_dup 3)
12599         (minus (reg STACK_POINTER_REGNUM)
12600                (match_operand 0)))
12601    (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
12602    (set (pc) (if_then_else
12603               (geu (match_dup 4) (const_int 0))
12604               (label_ref (match_operand 1))
12605               (pc)))]
12606   ""
12608   rs6000_split_stack_space_check (operands[0], operands[1]);
12609   DONE;
12612 (define_insn "bpermd_<mode>"
12613   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12614         (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
12615                    (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
12616   "TARGET_POPCNTD"
12617   "bpermd %0,%1,%2"
12618   [(set_attr "type" "popcnt")])
12621 ;; Builtin fma support.  Handle 
12622 ;; Note that the conditions for expansion are in the FMA_F iterator.
12624 (define_expand "fma<mode>4"
12625   [(set (match_operand:FMA_F 0 "register_operand" "")
12626         (fma:FMA_F
12627           (match_operand:FMA_F 1 "register_operand" "")
12628           (match_operand:FMA_F 2 "register_operand" "")
12629           (match_operand:FMA_F 3 "register_operand" "")))]
12630   ""
12631   "")
12633 (define_insn "*fma<mode>4_fpr"
12634   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12635         (fma:SFDF
12636           (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
12637           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12638           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
12639   "TARGET_<MODE>_FPR"
12640   "@
12641    fmadd<Ftrad> %0,%1,%2,%3
12642    xsmadda<Fvsx> %x0,%x1,%x2
12643    xsmaddm<Fvsx> %x0,%x1,%x3"
12644   [(set_attr "type" "fp")
12645    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12647 ; Altivec only has fma and nfms.
12648 (define_expand "fms<mode>4"
12649   [(set (match_operand:FMA_F 0 "register_operand" "")
12650         (fma:FMA_F
12651           (match_operand:FMA_F 1 "register_operand" "")
12652           (match_operand:FMA_F 2 "register_operand" "")
12653           (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
12654   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12655   "")
12657 (define_insn "*fms<mode>4_fpr"
12658   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12659         (fma:SFDF
12660          (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12661          (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12662          (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12663   "TARGET_<MODE>_FPR"
12664   "@
12665    fmsub<Ftrad> %0,%1,%2,%3
12666    xsmsuba<Fvsx> %x0,%x1,%x2
12667    xsmsubm<Fvsx> %x0,%x1,%x3"
12668   [(set_attr "type" "fp")
12669    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12671 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
12672 (define_expand "fnma<mode>4"
12673   [(set (match_operand:FMA_F 0 "register_operand" "")
12674         (neg:FMA_F
12675           (fma:FMA_F
12676             (match_operand:FMA_F 1 "register_operand" "")
12677             (match_operand:FMA_F 2 "register_operand" "")
12678             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12679   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
12680   "")
12682 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
12683 (define_expand "fnms<mode>4"
12684   [(set (match_operand:FMA_F 0 "register_operand" "")
12685         (neg:FMA_F
12686           (fma:FMA_F
12687             (match_operand:FMA_F 1 "register_operand" "")
12688             (match_operand:FMA_F 2 "register_operand" "")
12689             (match_operand:FMA_F 3 "register_operand" ""))))]
12690   "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12691   "")
12693 ; Not an official optab name, but used from builtins.
12694 (define_expand "nfma<mode>4"
12695   [(set (match_operand:FMA_F 0 "register_operand" "")
12696         (neg:FMA_F
12697           (fma:FMA_F
12698             (match_operand:FMA_F 1 "register_operand" "")
12699             (match_operand:FMA_F 2 "register_operand" "")
12700             (match_operand:FMA_F 3 "register_operand" ""))))]
12701   "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
12702   "")
12704 (define_insn "*nfma<mode>4_fpr"
12705   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12706         (neg:SFDF
12707          (fma:SFDF
12708           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12709           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12710           (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
12711   "TARGET_<MODE>_FPR"
12712   "@
12713    fnmadd<Ftrad> %0,%1,%2,%3
12714    xsnmadda<Fvsx> %x0,%x1,%x2
12715    xsnmaddm<Fvsx> %x0,%x1,%x3"
12716   [(set_attr "type" "fp")
12717    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12719 ; Not an official optab name, but used from builtins.
12720 (define_expand "nfms<mode>4"
12721   [(set (match_operand:FMA_F 0 "register_operand" "")
12722         (neg:FMA_F
12723           (fma:FMA_F
12724             (match_operand:FMA_F 1 "register_operand" "")
12725             (match_operand:FMA_F 2 "register_operand" "")
12726             (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
12727   ""
12728   "")
12730 (define_insn "*nfmssf4_fpr"
12731   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
12732         (neg:SFDF
12733          (fma:SFDF
12734           (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
12735           (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
12736           (neg:SFDF
12737            (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
12738   "TARGET_<MODE>_FPR"
12739   "@
12740    fnmsub<Ftrad> %0,%1,%2,%3
12741    xsnmsuba<Fvsx> %x0,%x1,%x2
12742    xsnmsubm<Fvsx> %x0,%x1,%x3"
12743   [(set_attr "type" "fp")
12744    (set_attr "fp_type" "fp_maddsub_<Fs>")])
12747 (define_expand "rs6000_get_timebase"
12748   [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
12749   ""
12751   if (TARGET_POWERPC64)
12752     emit_insn (gen_rs6000_mftb_di (operands[0]));
12753   else
12754     emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
12755   DONE;
12758 (define_insn "rs6000_get_timebase_ppc32"
12759   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12760         (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
12761    (clobber (match_scratch:SI 1 "=r"))
12762    (clobber (match_scratch:CC 2 "=y"))]
12763   "!TARGET_POWERPC64"
12765   if (WORDS_BIG_ENDIAN)
12766     if (TARGET_MFCRF)
12767       {
12768         return "mfspr %0,269\;"
12769                "mfspr %L0,268\;"
12770                "mfspr %1,269\;"
12771                "cmpw %2,%0,%1\;"
12772                "bne- %2,$-16";
12773       }
12774     else
12775       {
12776         return "mftbu %0\;"
12777                "mftb %L0\;"
12778                "mftbu %1\;"
12779                "cmpw %2,%0,%1\;"
12780                "bne- %2,$-16";
12781       }
12782   else
12783     if (TARGET_MFCRF)
12784       {
12785         return "mfspr %L0,269\;"
12786                "mfspr %0,268\;"
12787                "mfspr %1,269\;"
12788                "cmpw %2,%L0,%1\;"
12789                "bne- %2,$-16";
12790       }
12791     else
12792       {
12793         return "mftbu %L0\;"
12794                "mftb %0\;"
12795                "mftbu %1\;"
12796                "cmpw %2,%L0,%1\;"
12797                "bne- %2,$-16";
12798       }
12800   [(set_attr "length" "20")])
12802 (define_insn "rs6000_mftb_<mode>"
12803   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12804         (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
12805   ""
12807   if (TARGET_MFCRF)
12808     return "mfspr %0,268";
12809   else
12810     return "mftb %0";
12814 (define_insn "rs6000_mffs"
12815   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
12816         (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
12817   "TARGET_HARD_FLOAT && TARGET_FPRS"
12818   "mffs %0")
12820 (define_insn "rs6000_mtfsf"
12821   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
12822                      (match_operand:DF 1 "gpc_reg_operand" "d")]
12823                     UNSPECV_MTFSF)]
12824   "TARGET_HARD_FLOAT && TARGET_FPRS"
12825   "mtfsf %0,%1")
12828 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
12829 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
12830 ;; register that is being loaded.  The fused ops must be physically adjacent.
12832 ;; There are two parts to addis fusion.  The support for fused TOCs occur
12833 ;; before register allocation, and is meant to reduce the lifetime for the
12834 ;; tempoary register that holds the ADDIS result.  On Power8 GPR loads, we try
12835 ;; to use the register that is being load.  The peephole2 then gathers any
12836 ;; other fused possibilities that it can find after register allocation.  If
12837 ;; power9 fusion is selected, we also fuse floating point loads/stores.
12839 ;; Fused TOC support: Replace simple GPR loads with a fused form.  This is done
12840 ;; before register allocation, so that we can avoid allocating a temporary base
12841 ;; register that won't be used, and that we try to load into base registers,
12842 ;; and not register 0.  If we can't get a fused GPR load, generate a P9 fusion
12843 ;; (addis followed by load) even on power8.
12845 (define_split
12846   [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
12847         (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
12848   "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
12849   [(parallel [(set (match_dup 0) (match_dup 2))
12850               (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12851               (use (match_dup 3))
12852               (clobber (scratch:DI))])]
12854   operands[2] = fusion_wrap_memory_address (operands[1]);
12855   operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
12858 (define_insn "*toc_fusionload_<mode>"
12859   [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
12860         (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
12861    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12862    (use (match_operand:DI 2 "base_reg_operand" "r,r"))
12863    (clobber (match_scratch:DI 3 "=X,&b"))]
12864   "TARGET_TOC_FUSION_INT"
12866   if (base_reg_operand (operands[0], <MODE>mode))
12867     return emit_fusion_gpr_load (operands[0], operands[1]);
12869   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12871   [(set_attr "type" "load")
12872    (set_attr "length" "8")])
12874 (define_insn "*toc_fusionload_di"
12875   [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
12876         (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
12877    (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
12878    (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
12879    (clobber (match_scratch:DI 3 "=X,&b,&b"))]
12880   "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
12881    && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
12883   if (base_reg_operand (operands[0], DImode))
12884     return emit_fusion_gpr_load (operands[0], operands[1]);
12886   return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
12888   [(set_attr "type" "load")
12889    (set_attr "length" "8")])
12892 ;; Find cases where the addis that feeds into a load instruction is either used
12893 ;; once or is the same as the target register, and replace it with the fusion
12894 ;; insn
12896 (define_peephole2
12897   [(set (match_operand:P 0 "base_reg_operand" "")
12898         (match_operand:P 1 "fusion_gpr_addis" ""))
12899    (set (match_operand:INT1 2 "base_reg_operand" "")
12900         (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
12901   "TARGET_P8_FUSION
12902    && fusion_gpr_load_p (operands[0], operands[1], operands[2],
12903                          operands[3])"
12904   [(const_int 0)]
12906   expand_fusion_gpr_load (operands);
12907   DONE;
12910 ;; Fusion insn, created by the define_peephole2 above (and eventually by
12911 ;; reload)
12913 (define_insn "fusion_gpr_load_<mode>"
12914   [(set (match_operand:INT1 0 "base_reg_operand" "=&b")
12915         (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "")]
12916                      UNSPEC_FUSION_GPR))]
12917   "TARGET_P8_FUSION"
12919   return emit_fusion_gpr_load (operands[0], operands[1]);
12921   [(set_attr "type" "load")
12922    (set_attr "length" "8")])
12925 ;; ISA 3.0 (power9) fusion support
12926 ;; Merge addis with floating load/store to FPRs (or GPRs).
12927 (define_peephole2
12928   [(set (match_operand:P 0 "base_reg_operand" "")
12929         (match_operand:P 1 "fusion_gpr_addis" ""))
12930    (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
12931         (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
12932   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12933    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12934   [(const_int 0)]
12936   expand_fusion_p9_load (operands);
12937   DONE;
12940 (define_peephole2
12941   [(set (match_operand:P 0 "base_reg_operand" "")
12942         (match_operand:P 1 "fusion_gpr_addis" ""))
12943    (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
12944         (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
12945   "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
12946    && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
12947   [(const_int 0)]
12949   expand_fusion_p9_store (operands);
12950   DONE;
12953 (define_peephole2
12954   [(set (match_operand:SDI 0 "int_reg_operand" "")
12955         (match_operand:SDI 1 "upper16_cint_operand" ""))
12956    (set (match_dup 0)
12957         (ior:SDI (match_dup 0)
12958                  (match_operand:SDI 2 "u_short_cint_operand" "")))]
12959   "TARGET_P9_FUSION"
12960   [(set (match_dup 0)
12961         (unspec:SDI [(match_dup 1)
12962                      (match_dup 2)] UNSPEC_FUSION_P9))])
12964 (define_peephole2
12965   [(set (match_operand:SDI 0 "int_reg_operand" "")
12966         (match_operand:SDI 1 "upper16_cint_operand" ""))
12967    (set (match_operand:SDI 2 "int_reg_operand" "")
12968         (ior:SDI (match_dup 0)
12969                  (match_operand:SDI 3 "u_short_cint_operand" "")))]
12970   "TARGET_P9_FUSION
12971    && !rtx_equal_p (operands[0], operands[2])
12972    && peep2_reg_dead_p (2, operands[0])"
12973   [(set (match_dup 2)
12974         (unspec:SDI [(match_dup 1)
12975                      (match_dup 3)] UNSPEC_FUSION_P9))])
12977 ;; Fusion insns, created by the define_peephole2 above (and eventually by
12978 ;; reload).  Because we want to eventually have secondary_reload generate
12979 ;; these, they have to have a single alternative that gives the register
12980 ;; classes.  This means we need to have separate gpr/fpr/altivec versions.
12981 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
12982   [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
12983         (unspec:GPR_FUSION
12984          [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
12985          UNSPEC_FUSION_P9))
12986    (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
12987   "TARGET_P9_FUSION"
12989   /* This insn is a secondary reload insn, which cannot have alternatives.
12990      If we are not loading up register 0, use the power8 fusion instead.  */
12991   if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
12992     return emit_fusion_gpr_load (operands[0], operands[1]);
12994   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
12996   [(set_attr "type" "load")
12997    (set_attr "length" "8")])
12999 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13000   [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13001         (unspec:GPR_FUSION
13002          [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13003          UNSPEC_FUSION_P9))
13004    (clobber (match_operand:P 2 "base_reg_operand" "=&b"))]
13005   "TARGET_P9_FUSION"
13007   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13009   [(set_attr "type" "store")
13010    (set_attr "length" "8")])
13012 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_load"
13013   [(set (match_operand:FPR_FUSION 0 "fpr_reg_operand" "=d")
13014         (unspec:FPR_FUSION
13015          [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13016          UNSPEC_FUSION_P9))
13017    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13018   "TARGET_P9_FUSION"
13020   return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13022   [(set_attr "type" "fpload")
13023    (set_attr "length" "8")])
13025 (define_insn "fusion_fpr_<P:mode>_<FPR_FUSION:mode>_store"
13026   [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13027         (unspec:FPR_FUSION
13028          [(match_operand:FPR_FUSION 1 "fpr_reg_operand" "d")]
13029          UNSPEC_FUSION_P9))
13030    (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13031   "TARGET_P9_FUSION"
13033   return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13035   [(set_attr "type" "fpstore")
13036    (set_attr "length" "8")])
13038 (define_insn "*fusion_p9_<mode>_constant"
13039   [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13040         (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13041                      (match_operand:SDI 2 "u_short_cint_operand" "K")]
13042                     UNSPEC_FUSION_P9))] 
13043   "TARGET_P9_FUSION"
13045   emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>");
13046   return "ori %0,%0,%2";
13048   [(set_attr "type" "two")
13049    (set_attr "length" "8")])
13052 ;; Miscellaneous ISA 2.06 (power7) instructions
13053 (define_insn "addg6s"
13054   [(set (match_operand:SI 0 "register_operand" "=r")
13055         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13056                     (match_operand:SI 2 "register_operand" "r")]
13057                    UNSPEC_ADDG6S))]
13058   "TARGET_POPCNTD"
13059   "addg6s %0,%1,%2"
13060   [(set_attr "type" "integer")
13061    (set_attr "length" "4")])
13063 (define_insn "cdtbcd"
13064   [(set (match_operand:SI 0 "register_operand" "=r")
13065         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13066                    UNSPEC_CDTBCD))]
13067   "TARGET_POPCNTD"
13068   "cdtbcd %0,%1"
13069   [(set_attr "type" "integer")
13070    (set_attr "length" "4")])
13072 (define_insn "cbcdtd"
13073   [(set (match_operand:SI 0 "register_operand" "=r")
13074         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13075                    UNSPEC_CBCDTD))]
13076   "TARGET_POPCNTD"
13077   "cbcdtd %0,%1"
13078   [(set_attr "type" "integer")
13079    (set_attr "length" "4")])
13081 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13082                                         UNSPEC_DIVEO
13083                                         UNSPEC_DIVEU
13084                                         UNSPEC_DIVEUO])
13086 (define_int_attr div_extend [(UNSPEC_DIVE       "e")
13087                              (UNSPEC_DIVEO      "eo")
13088                              (UNSPEC_DIVEU      "eu")
13089                              (UNSPEC_DIVEUO     "euo")])
13091 (define_insn "div<div_extend>_<mode>"
13092   [(set (match_operand:GPR 0 "register_operand" "=r")
13093         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13094                      (match_operand:GPR 2 "register_operand" "r")]
13095                     UNSPEC_DIV_EXTEND))]
13096   "TARGET_POPCNTD"
13097   "div<wd><div_extend> %0,%1,%2"
13098   [(set_attr "type" "div")
13099    (set_attr "size" "<bits>")])
13102 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13104 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13105 (define_mode_attr FP128_64 [(TF "DF")
13106                             (IF "DF")
13107                             (TD "DI")
13108                             (KF "DI")])
13110 (define_expand "unpack<mode>"
13111   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
13112         (unspec:<FP128_64>
13113          [(match_operand:FMOVE128 1 "register_operand" "")
13114           (match_operand:QI 2 "const_0_to_1_operand" "")]
13115          UNSPEC_UNPACK_128BIT))]
13116   "FLOAT128_2REG_P (<MODE>mode)"
13117   "")
13119 (define_insn_and_split "unpack<mode>_dm"
13120   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13121         (unspec:<FP128_64>
13122          [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13123           (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13124          UNSPEC_UNPACK_128BIT))]
13125   "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13126   "#"
13127   "&& reload_completed"
13128   [(set (match_dup 0) (match_dup 3))]
13130   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13132   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13133     {
13134       emit_note (NOTE_INSN_DELETED);
13135       DONE;
13136     }
13138   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13140   [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13141    (set_attr "length" "4")])
13143 (define_insn_and_split "unpack<mode>_nodm"
13144   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13145         (unspec:<FP128_64>
13146          [(match_operand:FMOVE128 1 "register_operand" "d,d")
13147           (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13148          UNSPEC_UNPACK_128BIT))]
13149   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13150   "#"
13151   "&& reload_completed"
13152   [(set (match_dup 0) (match_dup 3))]
13154   unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13156   if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13157     {
13158       emit_note (NOTE_INSN_DELETED);
13159       DONE;
13160     }
13162   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13164   [(set_attr "type" "fp,fpstore")
13165    (set_attr "length" "4")])
13167 (define_insn_and_split "pack<mode>"
13168   [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13169         (unspec:FMOVE128
13170          [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13171           (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13172          UNSPEC_PACK_128BIT))]
13173   "FLOAT128_2REG_P (<MODE>mode)"
13174   "@
13175    fmr %L0,%2
13176    #"
13177   "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13178   [(set (match_dup 3) (match_dup 1))
13179    (set (match_dup 4) (match_dup 2))]
13181   unsigned dest_hi = REGNO (operands[0]);
13182   unsigned dest_lo = dest_hi + 1;
13184   gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13185   gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13187   operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13188   operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13190   [(set_attr "type" "fp,fp")
13191    (set_attr "length" "4,8")])
13193 (define_insn "unpack<mode>"
13194   [(set (match_operand:DI 0 "register_operand" "=d,d")
13195         (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13196                     (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13197          UNSPEC_UNPACK_128BIT))]
13198   "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13200   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13201     return ASM_COMMENT_START " xxpermdi to same register";
13203   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13204   return "xxpermdi %x0,%x1,%x1,%3";
13206   [(set_attr "type" "vecperm")])
13208 (define_insn "pack<mode>"
13209   [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13210         (unspec:FMOVE128_VSX
13211          [(match_operand:DI 1 "register_operand" "d")
13212           (match_operand:DI 2 "register_operand" "d")]
13213          UNSPEC_PACK_128BIT))]
13214   "TARGET_VSX"
13215   "xxpermdi %x0,%x1,%x2,0"
13216   [(set_attr "type" "vecperm")])
13220 ;; ISA 2.08 IEEE 128-bit floating point support.
13222 (define_insn "add<mode>3"
13223   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13224         (plus:IEEE128
13225          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13226          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13227   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13228   "xsaddqp %0,%1,%2"
13229   [(set_attr "type" "vecfloat")])
13231 (define_insn "sub<mode>3"
13232   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13233         (minus:IEEE128
13234          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13235          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13236   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13237   "xssubqp %0,%1,%2"
13238   [(set_attr "type" "vecfloat")])
13240 (define_insn "mul<mode>3"
13241   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13242         (mult:IEEE128
13243          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13244          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13245   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13246   "xsmulqp %0,%1,%2"
13247   [(set_attr "type" "vecfloat")])
13249 (define_insn "div<mode>3"
13250   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13251         (div:IEEE128
13252          (match_operand:IEEE128 1 "altivec_register_operand" "v")
13253          (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13254   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13255   "xsdivqp %0,%1,%2"
13256   [(set_attr "type" "vecdiv")])
13258 (define_insn "sqrt<mode>2"
13259   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13260         (sqrt:IEEE128
13261          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13262   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13263    "xssqrtqp %0,%1"
13264   [(set_attr "type" "vecdiv")])
13266 (define_insn "copysign<mode>3"
13267   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13268         (unspec:IEEE128
13269          [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13270           (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13271          UNSPEC_COPYSIGN))]
13272   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13273    "xscpsgnqp %0,%2,%1"
13274   [(set_attr "type" "vecsimple")])
13276 (define_insn "neg<mode>2_hw"
13277   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13278         (neg:IEEE128
13279          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13280   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13281   "xsnegqp %0,%1"
13282   [(set_attr "type" "vecfloat")])
13285 (define_insn "abs<mode>2_hw"
13286   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13287         (abs:IEEE128
13288          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13289   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13290   "xsabsqp %0,%1"
13291   [(set_attr "type" "vecfloat")])
13294 (define_insn "*nabs<mode>2_hw"
13295   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13296         (neg:IEEE128
13297          (abs:IEEE128
13298           (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13299   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13300   "xsnabsqp %0,%1"
13301   [(set_attr "type" "vecfloat")])
13303 ;; Initially don't worry about doing fusion
13304 (define_insn "*fma<mode>4_hw"
13305   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13306         (fma:IEEE128
13307          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13308          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13309          (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13310   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13311   "xsmaddqp %0,%1,%2"
13312   [(set_attr "type" "vecfloat")])
13314 (define_insn "*fms<mode>4_hw"
13315   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13316         (fma:IEEE128
13317          (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13318          (match_operand:IEEE128 2 "altivec_register_operand" "v")
13319          (neg:IEEE128
13320           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13321   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13322   "xsmsubqp %0,%1,%2"
13323   [(set_attr "type" "vecfloat")])
13325 (define_insn "*nfma<mode>4_hw"
13326   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13327         (neg:IEEE128
13328          (fma:IEEE128
13329           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13330           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13331           (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13332   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13333   "xsnmaddqp %0,%1,%2"
13334   [(set_attr "type" "vecfloat")])
13336 (define_insn "*nfms<mode>4_hw"
13337   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13338         (neg:IEEE128
13339          (fma:IEEE128
13340           (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13341           (match_operand:IEEE128 2 "altivec_register_operand" "v")
13342           (neg:IEEE128
13343            (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13344   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13345   "xsnmsubqp %0,%1,%2"
13346   [(set_attr "type" "vecfloat")])
13348 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13349   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13350         (float_extend:IEEE128
13351          (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13352   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13353   "xscvdpqp %0,%1"
13354   [(set_attr "type" "vecfloat")])
13356 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13357 ;; point is a simple copy.
13358 (define_insn_and_split "extendkftf2"
13359   [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13360         (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13361   "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13362   "@
13363    #
13364    xxlor %x0,%x1,%x1"
13365   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13366   [(const_int 0)]
13368   emit_note (NOTE_INSN_DELETED);
13369   DONE;
13371   [(set_attr "type" "*,vecsimple")
13372    (set_attr "length" "0,4")])
13374 (define_insn_and_split "trunctfkf2"
13375   [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13376         (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13377   "TARGET_FLOAT128 && TARGET_IEEEQUAD"
13378   "@
13379    #
13380    xxlor %x0,%x1,%x1"
13381   "&& reload_completed  && REGNO (operands[0]) == REGNO (operands[1])"
13382   [(const_int 0)]
13384   emit_note (NOTE_INSN_DELETED);
13385   DONE;
13387   [(set_attr "type" "*,vecsimple")
13388    (set_attr "length" "0,4")])
13390 (define_insn "trunc<mode>df2_hw"
13391   [(set (match_operand:DF 0 "altivec_register_operand" "=v")
13392         (float_truncate:DF
13393          (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13394   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13395   "xscvqpdp %0,%1"
13396   [(set_attr "type" "vecfloat")])
13398 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
13399 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
13400 ;; conversion
13401 (define_insn_and_split "trunc<mode>sf2_hw"
13402   [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
13403         (float_truncate:SF
13404          (match_operand:IEEE128 1 "altivec_register_operand" "v")))
13405    (clobber (match_scratch:DF 2 "=v"))]
13406   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13407   "#"
13408   "&& 1"
13409   [(set (match_dup 2)
13410         (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD))
13411    (set (match_dup 0)
13412         (float_truncate:SF (match_dup 2)))]
13414   if (GET_CODE (operands[2]) == SCRATCH)
13415     operands[2] = gen_reg_rtx (DFmode);
13417   [(set_attr "type" "vecfloat")
13418    (set_attr "length" "8")])
13420 ;; At present SImode is not allowed in VSX registers at all, and DImode is only
13421 ;; allowed in the traditional floating point registers. Use V2DImode so that
13422 ;; we can get a value in an Altivec register.
13424 (define_insn_and_split "fix<uns>_<mode>si2_hw"
13425   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z")
13426         (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v")))
13427    (clobber (match_scratch:V2DI 2 "=v,v"))]
13428   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13429   "#"
13430   "&& 1"
13431   [(pc)]
13433   convert_float128_to_int (operands, <CODE>);
13434   DONE;
13436   [(set_attr "length" "8")
13437    (set_attr "type" "mftgpr,fpstore")])
13439 (define_insn_and_split "fix<uns>_<mode>di2_hw"
13440   [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z")
13441         (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v")))
13442    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13443   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13444   "#"
13445   "&& 1"
13446   [(pc)]
13448   convert_float128_to_int (operands, <CODE>);
13449   DONE;
13451   [(set_attr "length" "8")
13452    (set_attr "type" "mftgpr,vecsimple,fpstore")])
13454 (define_insn_and_split "float<uns>_<mode>si2_hw"
13455   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v")
13456         (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z")))
13457    (clobber (match_scratch:V2DI 2 "=v,v"))]
13458   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13459   "#"
13460   "&& 1"
13461   [(pc)]
13463   convert_int_to_float128 (operands, <CODE>);
13464   DONE;
13466   [(set_attr "length" "8")
13467    (set_attr "type" "vecfloat")])
13469 (define_insn_and_split "float<uns>_<mode>di2_hw"
13470   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
13471         (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z")))
13472    (clobber (match_scratch:V2DI 2 "=v,v,v"))]
13473   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13474   "#"
13475   "&& 1"
13476   [(pc)]
13478   convert_int_to_float128 (operands, <CODE>);
13479   DONE;
13481   [(set_attr "length" "8")
13482    (set_attr "type" "vecfloat")])
13484 ;; Integer conversion instructions, using V2DImode to get an Altivec register
13485 (define_insn "*xscvqp<su>wz_<mode>"
13486   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13487         (unspec:V2DI
13488          [(any_fix:SI
13489            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13490          UNSPEC_IEEE128_CONVERT))]
13491   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13492   "xscvqp<su>wz %0,%1"
13493   [(set_attr "type" "vecfloat")])
13495 (define_insn "*xscvqp<su>dz_<mode>"
13496   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
13497         (unspec:V2DI
13498          [(any_fix:DI
13499            (match_operand:IEEE128 1 "altivec_register_operand" "v"))]
13500          UNSPEC_IEEE128_CONVERT))]
13501   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13502   "xscvqp<su>dz %0,%1"
13503   [(set_attr "type" "vecfloat")])
13505 (define_insn "*xscv<su>dqp_<mode>"
13506   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13507         (any_float:IEEE128
13508          (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")]
13509                     UNSPEC_IEEE128_CONVERT)))]
13510   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13511   "xscv<su>dqp %0,%1"
13512   [(set_attr "type" "vecfloat")])
13514 (define_insn "*ieee128_mfvsrd_64bit"
13515   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi")
13516         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")]
13517                    UNSPEC_IEEE128_MOVE))]
13518   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13519   "@
13520    mfvsrd %0,%x1
13521    stxsdx %x1,%y0
13522    xxlor %x0,%x1,%x1"
13523   [(set_attr "type" "mftgpr,vecsimple,fpstore")])
13526 (define_insn "*ieee128_mfvsrd_32bit"
13527   [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi")
13528         (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13529                    UNSPEC_IEEE128_MOVE))]
13530   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13531   "@
13532    stxsdx %x1,%y0
13533    xxlor %x0,%x1,%x1"
13534   [(set_attr "type" "vecsimple,fpstore")])
13536 (define_insn "*ieee128_mfvsrwz"
13537   [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z")
13538         (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")]
13539                    UNSPEC_IEEE128_MOVE))]
13540   "TARGET_FLOAT128_HW"
13541   "@
13542    mfvsrwz %0,%x1
13543    stxsiwx %x1,%y0"
13544   [(set_attr "type" "mftgpr,fpstore")])
13546 ;; 0 says do sign-extension, 1 says zero-extension
13547 (define_insn "*ieee128_mtvsrw"
13548   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v")
13549         (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z")
13550                       (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")]
13551                      UNSPEC_IEEE128_MOVE))]
13552   "TARGET_FLOAT128_HW"
13553   "@
13554    mtvsrwa %x0,%1
13555    lxsiwax %x0,%y1
13556    mtvsrwz %x0,%1
13557    lxsiwzx %x0,%y1"
13558   [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")])
13561 (define_insn "*ieee128_mtvsrd_64bit"
13562   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v")
13563         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")]
13564                      UNSPEC_IEEE128_MOVE))]
13565   "TARGET_FLOAT128_HW && TARGET_POWERPC64"
13566   "@
13567    mtvsrd %x0,%1
13568    lxsdx %x0,%y1
13569    xxlor %x0,%x1,%x1"
13570   [(set_attr "type" "mffgpr,fpload,vecsimple")])
13572 (define_insn "*ieee128_mtvsrd_32bit"
13573   [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v")
13574         (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")]
13575                      UNSPEC_IEEE128_MOVE))]
13576   "TARGET_FLOAT128_HW && !TARGET_POWERPC64"
13577   "@
13578    lxsdx %x0,%y1
13579    xxlor %x0,%x1,%x1"
13580   [(set_attr "type" "fpload,vecsimple")])
13582 ;; IEEE 128-bit instructions with round to odd semantics
13583 (define_insn "*trunc<mode>df2_odd"
13584   [(set (match_operand:DF 0 "vsx_register_operand" "=v")
13585         (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
13586                    UNSPEC_ROUND_TO_ODD))]
13587   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13588   "xscvqpdpo %0,%1"
13589   [(set_attr "type" "vecfloat")])
13591 ;; IEEE 128-bit comparisons
13592 (define_insn "*cmp<mode>_hw"
13593   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
13594         (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
13595                       (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13596   "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13597    "xscmpuqp %0,%1,%2"
13598   [(set_attr "type" "fpcompare")])
13602 (include "sync.md")
13603 (include "vector.md")
13604 (include "vsx.md")
13605 (include "altivec.md")
13606 (include "spe.md")
13607 (include "dfp.md")
13608 (include "paired.md")
13609 (include "crypto.md")
13610 (include "htm.md")